[cdo] 01/06: upstream 1.9.2rc1
Alastair McKinstry
mckinstry at moszumanska.debian.org
Tue Nov 14 14:26:03 UTC 2017
This is an automated email from the git hooks/post-receive script.
mckinstry pushed a commit to branch debian/master
in repository cdo.
commit 97a3dd36b647b8ddd7bb06d3bde89201064d3754
Author: Alastair McKinstry <mckinstry at debian.org>
Date: Mon Nov 6 11:44:11 2017 +0000
upstream 1.9.2rc1
---
ChangeLog | 33 +
Makefile.am | 13 +-
Makefile.in | 93 +-
NEWS | 8 +
OPERATORS | 5 +
aclocal.m4 | 113 +-
cdo.settings.in | 116 +-
cdo.spec | 2 +-
config/default | 12 +-
configure | 4445 +-
configure.ac | 73 +-
contrib/Makefile.in | 35 +-
contrib/cdoCompletion.bash | 3 +-
contrib/cdoCompletion.tcsh | 3 +-
contrib/cdoCompletion.zsh | 3 +-
doc/cdo.pdf | Bin 2720332 -> 2309417 bytes
doc/cdo_cmor.pdf | Bin 261892 -> 261888 bytes
doc/cdo_eca.pdf | Bin 214702 -> 205826 bytes
doc/cdo_magics.pdf | Bin 829854 -> 829885 bytes
doc/cdo_refcard.pdf | Bin 97632 -> 99176 bytes
libcdi/ChangeLog | 8 +
libcdi/Makefile.in | 72 +-
libcdi/aclocal.m4 | 71 +-
libcdi/app/Makefile.in | 25 +-
libcdi/app/cdi.c | 39 +-
libcdi/configure | 393 +-
libcdi/configure.ac | 2 +-
libcdi/doc/cdi_cman.pdf | Bin 335148 -> 338053 bytes
libcdi/doc/cdi_fman.pdf | Bin 363677 -> 366205 bytes
libcdi/examples/Makefile.in | 25 +-
libcdi/examples/cdi_copy.c | 2 +-
libcdi/examples/cdi_read.c | 6 +-
libcdi/examples/cdi_read_f2003.f90 | 5 +-
libcdi/examples/cdi_write.c | 6 +-
libcdi/examples/cdi_write_const.c | 2 +-
libcdi/examples/cdi_write_ens.c | 2 +-
libcdi/examples/cdi_write_f2003.f90 | 5 +-
libcdi/examples/cdi_write_hybrid.c | 20 +-
libcdi/examples/pio/Makefile.in | 25 +-
libcdi/interfaces/Makefile.in | 25 +-
libcdi/interfaces/cdi.cpp | 18 +-
libcdi/src/Makefile.in | 29 +-
libcdi/src/cdf_lazy_grid.c | 8 +-
libcdi/src/cdf_read.c | 36 +-
libcdi/src/cdf_write.c | 18 +-
libcdi/src/cdi.h | 62 +-
libcdi/src/cdi.inc | 4 +
libcdi/src/cdiFortran.c | 211 +-
libcdi/src/cdi_int.h | 14 +-
libcdi/src/cdilib.c | 77967 +++++++++++++++++----------------
libcdi/src/cdipio.h | 4 +-
libcdi/src/cdipioFortran.c | 4 +-
libcdi/src/config.h.in | 5 +
libcdi/src/grb_read.c | 32 +-
libcdi/src/grb_write.c | 42 +-
libcdi/src/gribapi_utilities.c | 47 +-
libcdi/src/grid.c | 322 +-
libcdi/src/grid.h | 24 +-
libcdi/src/iterator_fallback.c | 4 +-
libcdi/src/mo_cdi.f90 | 163 +-
libcdi/src/pio_client.c | 10 +-
libcdi/src/pio_interface.c | 14 +-
libcdi/src/pio_interface.h | 4 +-
libcdi/src/pio_server.c | 8 +-
libcdi/src/stream.c | 8 +-
libcdi/src/stream_cdf.h | 14 +-
libcdi/src/stream_cdf_i.c | 55 +-
libcdi/src/stream_cdf_o.c | 77 +-
libcdi/src/stream_cgribex.c | 80 +-
libcdi/src/stream_cgribex.h | 12 +-
libcdi/src/stream_ext.c | 35 +-
libcdi/src/stream_ext.h | 6 +-
libcdi/src/stream_grb.c | 7 +-
libcdi/src/stream_grb.h | 12 +-
libcdi/src/stream_gribapi.c | 98 +-
libcdi/src/stream_gribapi.h | 10 +-
libcdi/src/stream_ieg.c | 50 +-
libcdi/src/stream_ieg.h | 6 +-
libcdi/src/stream_read.c | 34 +-
libcdi/src/stream_srv.c | 41 +-
libcdi/src/stream_srv.h | 6 +-
libcdi/src/stream_write.c | 50 +-
libcdi/src/varscan.c | 2 +-
libcdi/src/vlist.c | 14 +-
libcdi/src/vlist_var.c | 16 +-
libcdi/src/zaxis.c | 12 +-
libcdi/tests/Makefile.in | 54 +-
libcdi/tests/stream_cksum.c | 2 +-
libcdi/tests/test_cdf_read.c | 4 +-
libcdi/tests/test_grib.c | 2 +-
m4/acx_cfortran_flags.m4 | 171 +
m4/acx_check_cfortran.m4 | 275 +
src/Adisit.cc | 2 +-
src/Afterburner.cc | 6 +-
src/Arith.cc | 18 +-
src/Arithc.cc | 6 +-
src/Arithdays.cc | 6 +-
src/Arithlat.cc | 2 +-
src/CDIread.cc | 2 +-
src/CDItest.cc | 2 +-
src/CMOR.cc | 12 +-
src/CMOR_lite.cc | 2 +-
src/Cat.cc | 2 +-
src/Change.cc | 2 +-
src/Change_e5slm.cc | 6 +-
src/Cloudlayer.cc | 2 +-
src/Collgrid.cc | 14 +-
src/Command.cc | 4 +-
src/Comp.cc | 66 +-
src/Compc.cc | 48 +-
src/Complextorect.cc | 2 +-
src/Cond.cc | 19 +-
src/Cond2.cc | 17 +-
src/Condc.cc | 2 +-
src/Consecstat.cc | 10 +-
src/Copy.cc | 4 +-
src/Deltat.cc | 2 +-
src/Deltime.cc | 2 +-
src/Derivepar.cc | 2 +-
src/Detrend.cc | 2 +-
src/Diff.cc | 10 +-
src/Distgrid.cc | 104 +-
src/Duplicate.cc | 2 +-
src/EOFs.cc | 9 +-
src/Echam5ini.cc | 3 +-
src/Enlarge.cc | 31 +-
src/Enlargegrid.cc | 5 +-
src/Ensstat.cc | 4 +-
src/Ensstat3.cc | 3 +-
src/Ensval.cc | 3 +-
src/Eof3d.cc | 3 +-
src/Eofcoeff.cc | 11 +-
src/Eofcoeff3d.cc | 13 +-
src/EstFreq.cc | 3 +-
src/Exprf.cc | 10 +-
src/FC.cc | 22 +-
src/Fillmiss.cc | 10 +-
src/Filter.cc | 4 +-
src/Fldrms.cc | 8 +-
src/Fldstat.cc | 2 +-
src/Fldstat2.cc | 4 +-
src/Fourier.cc | 2 +-
src/Gengrid.cc | 5 +-
src/Gradsdes.cc | 4 +-
src/Gridboxstat.cc | 66 +-
src/Harmonic.cc | 2 +-
src/Hi.cc | 26 +-
src/Histogram.cc | 2 +-
src/Importamsr.cc | 6 +-
src/Importbinary.cc | 4 +-
src/Importcmsaf.cc | 6 +-
src/Importobs.cc | 2 +-
src/Info.cc | 30 +-
src/Input.cc | 2 +-
src/Intgrid.cc | 92 +-
src/Intgridtraj.cc | 2 +-
src/Intlevel.cc | 10 +-
src/Intlevel3d.cc | 14 +-
src/Intntime.cc | 10 +-
src/Inttime.cc | 10 +-
src/Intyear.cc | 2 +-
src/Invert.cc | 2 +-
src/Invertlev.cc | 6 +-
src/Isosurface.cc | 2 +-
src/Maggraph.cc | 2 +-
src/Magplot.cc | 2 +-
src/Magvector.cc | 2 +-
src/Makefile.am | 36 +-
src/Makefile.in | 239 +-
src/MapReduce.cc | 11 +-
src/Maskbox.cc | 2 +-
src/Mastrfu.cc | 4 +-
src/Math.cc | 2 +-
src/Merge.cc | 2 +-
src/Mergegrid.cc | 2 +-
src/Mergetime.cc | 2 +-
src/Merstat.cc | 6 +-
src/Monarith.cc | 10 +-
src/Mrotuv.cc | 30 +-
src/Mrotuvb.cc | 54 +-
src/NCL_wind.cc | 328 +
src/Output.cc | 2 +-
src/Outputgmt.cc | 2 +-
src/Pack.cc | 2 +-
src/Pardup.cc | 6 +-
src/Pinfo.cc | 8 +-
src/Pressure.cc | 2 +-
src/Regres.cc | 2 +-
src/Remap.cc | 78 +-
src/Remapeta.cc | 2 +-
src/Replace.cc | 8 +-
src/Replacevalues.cc | 2 +-
src/Rhopot.cc | 2 +-
src/Rotuv.cc | 4 +-
src/Runpctl.cc | 2 +-
src/Runstat.cc | 2 +-
src/Samplegrid.cc | 2 +-
src/Samplegridicon.cc | 127 +-
src/Seascount.cc | 6 +-
src/Seaspctl.cc | 2 +-
src/Seasstat.cc | 8 +-
src/Selbox.cc | 2 +-
src/Select.cc | 6 +-
src/Selgridcell.cc | 3 +-
src/Selmulti.cc | 2 +-
src/Seloperator.cc | 2 +-
src/Seltime.cc | 2 +-
src/Selvar.cc | 2 +-
src/Set.cc | 2 +-
src/Setattribute.cc | 2 +-
src/Setbox.cc | 2 +-
src/Setgatt.cc | 2 +-
src/Setgrid.cc | 2 +-
src/Sethalo.cc | 2 +-
src/Setmiss.cc | 2 +-
src/Setpartab.cc | 2 +-
src/Setrcaname.cc | 2 +-
src/Settime.cc | 2 +-
src/Setzaxis.cc | 2 +-
src/Shiftxy.cc | 2 +-
src/Sinfo.cc | 4 +-
src/Smooth.cc | 20 +-
src/Sort.cc | 6 +-
src/Sorttimestamp.cc | 2 +-
src/Spectral.cc | 2 +-
src/Spectrum.cc | 2 +-
src/Split.cc | 2 +-
src/Splitrec.cc | 2 +-
src/Splitsel.cc | 2 +-
src/Splittime.cc | 2 +-
src/Splityear.cc | 2 +-
src/Subtrend.cc | 2 +-
src/Tee.cc | 2 +-
src/Templates.cc | 4 +-
src/Test.cc | 2 +-
src/Tests.cc | 2 +-
src/Timcount.cc | 6 +-
src/Timcumsum.cc | 8 +-
src/Timpctl.cc | 2 +-
src/Timselpctl.cc | 2 +-
src/Timselstat.cc | 10 +-
src/Timsort.cc | 2 +-
src/Timstat.cc | 2 +-
src/Timstat2.cc | 2 +-
src/Timstat3.cc | 2 +-
src/Tocomplex.cc | 2 +-
src/Transpose.cc | 2 +-
src/Trend.cc | 2 +-
src/Trms.cc | 19 +-
src/Tstepcount.cc | 2 +-
src/Vargen.cc | 62 +-
src/Varrms.cc | 2 +-
src/Verifygrid.cc | 43 +-
src/Vertcum.cc | 6 +-
src/Vertintap.cc | 12 +-
src/Vertintml.cc | 12 +-
src/Vertstat.cc | 10 +-
src/Vertwind.cc | 4 +-
src/Wct.cc | 15 +-
src/Wind.cc | 2 +-
src/WindTrans.cc | 56 +-
src/Writerandom.cc | 2 +-
src/XTimstat.cc | 9 +-
src/YAR.cc | 6 +-
src/Ydayarith.cc | 12 +-
src/Ydaypctl.cc | 2 +-
src/Ydaystat.cc | 71 +-
src/Ydrunpctl.cc | 2 +-
src/Ydrunstat.cc | 2 +-
src/Yearmonstat.cc | 8 +-
src/Yhourarith.cc | 12 +-
src/Yhourstat.cc | 8 +-
src/Ymonarith.cc | 14 +-
src/Ymonpctl.cc | 2 +-
src/Ymonstat.cc | 8 +-
src/Yseaspctl.cc | 2 +-
src/Yseasstat.cc | 8 +-
src/Zonstat.cc | 6 +-
src/after_vertint.cc | 2 +-
src/after_vertint.h | 30 +-
src/afterburner.h | 10 +-
src/afterburnerlib.cc | 14 +-
src/argument.cc | 32 +-
src/argument.h | 2 +-
src/cdo.cc | 58 +-
src/cdoDebugOutput.cc | 22 +
src/cdoDebugOutput.h | 112 +
src/cdo_int.h | 19 +-
src/cdo_read.cc | 4 +-
src/cdo_vlist.cc | 22 +-
src/cdotest.cc | 5 +-
src/cellsearchorder.h | 30000 +++++++++++++
src/cf_interface.h | 23 +
src/cfortran.h | 2559 ++
src/cmortable_parser.cc | 2 +-
src/compare.h | 10 +-
src/config.h.in | 17 +
src/ecacore.cc | 8 +-
src/ecautil.cc | 26 +-
src/expr.cc | 43 +-
src/expr.h | 1 +
src/expr_lex.cc | 310 +-
src/expr_yacc.cc | 210 +-
src/features.cc | 20 +-
src/field.cc | 48 +-
src/field2.cc | 243 +-
src/fieldc.cc | 6 +-
src/fieldmer.cc | 42 +-
src/fieldzon.cc | 42 +-
src/getMemorySize.c | 97 +
src/getRSS.c | 122 +
src/grid.cc | 16 +-
src/grid.h | 2 +-
src/grid_area.cc | 20 +-
src/grid_from_name.cc | 14 +-
src/grid_print.cc | 42 +-
src/grid_read.cc | 10 +-
src/grid_search.cc | 122 +-
src/grid_search.h | 21 +-
src/griddes.cc | 12 +-
src/griddes.h | 6 +-
src/griddes_h5.cc | 34 +-
src/griddes_nc.cc | 6 +-
src/gridreference.cc | 4 +-
src/interpol.cc | 44 +-
src/kdtreelib/kdtree.h | 52 +-
src/kdtreelib/kdtree_cartesian.cc | 126 +-
src/kdtreelib/kdtree_common.cc | 84 +-
src/kdtreelib/kdtree_spherical.cc | 26 +-
src/kdtreelib/pmergesort.cc | 13 +-
src/kdtreelib/pqueue.cc | 46 +-
src/kdtreelib/pqueue.h | 22 +-
src/lib/ncl/Makefile.am | 6 +
{contrib => src/lib/ncl}/Makefile.in | 222 +-
src/lib/ncl/rvdv.f | 456 +
src/libncl.h | 26 +
src/modules.cc | 5 +-
src/nearpt3c.cc | 32 +
src/nearpt3c.h | 6 -
src/nearpt3x.h | 645 +
src/operator_help.h | 30 +-
src/par_io.cc | 5 +-
src/par_io.h | 14 +-
src/pipe.cc | 8 +-
src/pipe.h | 10 +-
src/printinfo.h | 16 +-
src/process.cc | 367 +-
src/process.h | 112 +-
src/pstream.cc | 136 +-
src/pstream.h | 9 +-
src/pstream_write.h | 4 +-
src/remap.h | 17 +-
src/remap_bicubic_scrip.cc | 68 +-
src/remap_bilinear_scrip.cc | 68 +-
src/remap_conserv.cc | 4 +-
src/remap_distwgt.cc | 56 +-
src/remap_scrip_io.cc | 16 +-
src/remap_search_latbins.cc | 68 +-
src/remap_search_reg2d.cc | 57 +-
src/remap_store_link_cnsrv.cc | 2 +-
src/remaplib.cc | 25 +-
src/sellist.cc | 32 +-
src/util.cc | 106 +-
src/util.h | 19 +-
test/Arithc.test.in | 15 +-
test/Expr.test.in | 3 +-
test/Makefile.in | 80 +-
test/data/Makefile.in | 35 +-
test/data/expr2_ref | Bin 6720 -> 6720 bytes
369 files changed, 82877 insertions(+), 43079 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5a3dfee..eacecb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2017-11-23 Uwe Schulzweida
+
+ * Using CDI library version 1.9.2
+ * Version 1.9.2 release
+
+2017-11-02 Uwe Schulzweida
+
+ * expr: nesting of ?: operator lost in cdo-1.9.1 [Bug #7992]
+
+2017-10-26 Uwe Schulzweida
+
+ * select with start=end range aborts with 'Invalid character' [Bug #7976]
+
+2017-10-25 Uwe Schulzweida
+
+ * Expr: convert constant parameter to float for 32-bit float data (bug fix)
+ * Condc: convert constant parameter to float for 32-bit float data (bug fix)
+ * Cond: convert data to float for 32-bit float data (bug fix)
+
+2017-10-23 Uwe Schulzweida
+
+ * Added operator uv2vr_cfd: U and V wind to relative vorticity (interface to NCL)
+ * Added operator uv2dv_cfd: U and V wind to divergence (interface to NCL)
+ * gengrid: bug fix
+
+2017-10-20 Uwe Schulzweida
+
+ * Ydaystat: don't adjust the output year if the last input year is incomplete (bug fix)
+
+2017-10-08 Uwe Schulzweida
+
+ * changed type of nmiss to size_t
+
2017-10-05 Uwe Schulzweida
* Using CDI library version 1.9.1
diff --git a/Makefile.am b/Makefile.am
index 73f00df..041c301 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,19 @@
# Process this file with automake to produce Makefile.in
-SUBDIRS = libcdi src contrib test/data test
+SUBDIRS = libcdi src/lib/ncl src contrib test/data test
#
EXTRA_DIST=config/default OPERATORS doc/cdo.pdf doc/cdo_cmor.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
#
+doc/cdo.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdf ; cp cdo.pdf ..
+doc/cdo_cmor.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfcmor ; cp cdo_cmor.pdf ..
+doc/cdo_eca.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfeca ; cp cdo_eca.pdf ..
+doc/cdo_magics.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfmagics ; cp cdo_magics.pdf ..
+doc/cdo_refcard.pdf:
+ cd doc/tex ; ./makedoc ; ./makerefcard ; cp cdo_refcard.pdf ..
+#
ACLOCAL_AMFLAGS = -I m4
#
CLEANFILES = `ls *~ 2> /dev/null`
diff --git a/Makefile.in b/Makefile.in
index 8a5cb0f..4dc885a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -78,21 +88,10 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/configure $(am__configure_deps) \
- $(top_srcdir)/config/mkinstalldirs $(srcdir)/cdo.spec.in \
- $(srcdir)/cdo.settings.in AUTHORS COPYING ChangeLog INSTALL \
- NEWS README config/ar-lib config/compile config/config.guess \
- config/config.sub config/depcomp config/install-sh \
- config/missing config/mkinstalldirs config/ltmain.sh \
- $(top_srcdir)/config/ar-lib $(top_srcdir)/config/compile \
- $(top_srcdir)/config/config.guess \
- $(top_srcdir)/config/config.sub \
- $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
- $(top_srcdir)/config/missing \
- $(top_srcdir)/config/tap-driver.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -101,6 +100,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -163,6 +164,18 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/cdo.settings.in \
+ $(srcdir)/cdo.spec.in $(top_srcdir)/config/ar-lib \
+ $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \
+ $(top_srcdir)/config/config.sub \
+ $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
+ $(top_srcdir)/config/missing \
+ $(top_srcdir)/config/mkinstalldirs \
+ $(top_srcdir)/config/tap-driver.sh AUTHORS COPYING ChangeLog \
+ INSTALL NEWS README config/ar-lib config/compile \
+ config/config.guess config/config.sub config/depcomp \
+ config/install-sh config/ltmain.sh config/missing \
+ config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -246,18 +259,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -333,6 +350,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -382,7 +400,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# Process this file with automake to produce Makefile.in
-SUBDIRS = libcdi src contrib test/data test
+SUBDIRS = libcdi src/lib/ncl src contrib test/data test
#
EXTRA_DIST = config/default OPERATORS doc/cdo.pdf doc/cdo_cmor.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
#
@@ -407,7 +425,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -611,7 +628,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@@ -627,17 +644,17 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@@ -655,7 +672,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@@ -665,22 +682,23 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_inst
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -857,6 +875,19 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
+#
+doc/cdo.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdf ; cp cdo.pdf ..
+doc/cdo_cmor.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfcmor ; cp cdo_cmor.pdf ..
+doc/cdo_eca.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfeca ; cp cdo_eca.pdf ..
+doc/cdo_magics.pdf:
+ cd doc/tex ; ./makedoc ; ./makepdfmagics ; cp cdo_magics.pdf ..
+doc/cdo_refcard.pdf:
+ cd doc/tex ; ./makedoc ; ./makerefcard ; cp cdo_refcard.pdf ..
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/NEWS b/NEWS
index f938a48..09510bb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,14 @@
CDO NEWS
--------
+Version 1.9.2 (23 November 2017):
+
+ Fixed bugs:
+ * sign of grid size increment changes [Bug #7974]
+ * compilation fails on OpenBSD [Bug #7961]
+ * expr: nesting of ?: operator lost in cdo-1.9.1 [Bug #7992]
+ * select with start=end range aborts with 'Invalid character' [Bug #7976]
+
Version 1.9.1 (27 September 2017):
New features:
diff --git a/OPERATORS b/OPERATORS
index 15828bc..3078e86 100644
--- a/OPERATORS
+++ b/OPERATORS
@@ -583,6 +583,11 @@ Operator catalog:
Hurr hurr Hurricane days index per time period
CMORlite cmorlite CMOR lite
-------------------------------------------------------------
+ NCL
+-------------------------------------------------------------
+ NCL_wind uv2vr_cfd U and V wind to relative vorticity
+ NCL_wind uv2dv_cfd U and V wind to divergence
+-------------------------------------------------------------
CMOR
-------------------------------------------------------------
CMOR cmor Climate Model Output Rewriting
diff --git a/aclocal.m4 b/aclocal.m4
index 5d21d17..47fbefd 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.14 -*- Autoconf -*-
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,13 +14,51 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
-[m4_warning([this file was generated for autoconf 2.68.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier at gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
+
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -32,10 +70,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.14'
+[am__api_version='1.15'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.14], [],
+m4_if([$1], [1.15.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -51,12 +89,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.14])dnl
+[AM_AUTOMAKE_VERSION([1.15.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+# Copyright (C) 2011-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -118,7 +156,7 @@ AC_SUBST([AR])dnl
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -163,15 +201,14 @@ AC_SUBST([AR])dnl
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -202,7 +239,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -393,7 +430,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -469,7 +506,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -559,8 +596,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -633,7 +670,11 @@ to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
-fi])
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -662,7 +703,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -673,7 +714,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -683,7 +724,7 @@ if test x"${install_sh}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -705,7 +746,7 @@ AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -740,7 +781,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -790,7 +831,7 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -829,7 +870,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -858,7 +899,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -905,7 +946,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -924,7 +965,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1005,7 +1046,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1065,7 +1106,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1093,7 +1134,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1112,7 +1153,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1243,6 +1284,8 @@ AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
+m4_include([m4/acx_cfortran_flags.m4])
+m4_include([m4/acx_check_cfortran.m4])
m4_include([m4/acx_options.m4])
m4_include([m4/ax_cxx_compile_stdcxx.m4])
m4_include([m4/ax_cxx_compile_stdcxx_11.m4])
diff --git a/cdo.settings.in b/cdo.settings.in
index 514d0c5..6492811 100644
--- a/cdo.settings.in
+++ b/cdo.settings.in
@@ -1,54 +1,68 @@
{
- "CXX" : "@CXX@",
- "CC" : "@CC@",
- "CPP" : "@CPP@",
- "CPPFLAGS" : "@CPPFLAGS@",
- "CXXFLAGS" : "@CXXFLAGS@",
- "CFLAGS" : "@CFLAGS@",
- "LDFLAGS" : "@LDFLAGS@",
- "LIBS" : "@LIBS@",
- "FCFLAGS" : "@FCFLAGS@",
- "INCLUDES" : "@INCLUDES@",
- "LD" : "@LD@",
- "NM" : "@NM@",
- "AR" : "@AR@",
- "AS" : "@AS@",
- "DLLTOOL" : "@DLLTOOL@",
- "OBJDUMP" : "@OBJDUMP@",
- "STRIP" : "@STRIP@",
- "RANLIB" : "@RANLIB@",
- "INSTALL" : "@INSTALL@",
- "cdi" : {
- "enable_cdi_lib" : @ENABLE_CDI_LIB@
- },
- "threads" : {
- "lib" : "@THREADS_LIBS@",
- "include" : "@THREADS_INCLUDE@"
- "szlib" : {
- "lib" : "@SZLIB_LIBS@",
- "include" : "@SZLIB_INCLUDE@"
+ "build" : {
+ "tools" : {
+ "CXX" : "@CXX@",
+ "CC" : "@CC@",
+ "CPP" : "@CPP@",
+ "CPPFLAGS" : "@CPPFLAGS@",
+ "CXXFLAGS" : "@CXXFLAGS@",
+ "CFLAGS" : "@CFLAGS@",
+ "F77" : "@F77@",
+ "FFLAGS" : "@FFLAGS@",
+ "LDFLAGS" : "@LDFLAGS@",
+ "LIBS" : "@LIBS@",
+ "FCFLAGS" : "@FCFLAGS@",
+ "INCLUDES" : "@INCLUDES@",
+ "LD" : "@LD@",
+ "NM" : "@NM@",
+ "AR" : "@AR@",
+ "AS" : "@AS@",
+ "DLLTOOL" : "@DLLTOOL@",
+ "OBJDUMP" : "@OBJDUMP@",
+ "STRIP" : "@STRIP@",
+ "RANLIB" : "@RANLIB@",
+ "INSTALL" : "@INSTALL@",
+ },
+ "libraries" : {
+ "threads" : {
+ "lib" : "@THREADS_LIBS@",
+ "include" : "@THREADS_INCLUDE@"
+ },
+ "szlib" : {
+ "lib" : "@SZLIB_LIBS@",
+ "include" : "@SZLIB_INCLUDE@"
+ },
+ "hdf5" : {
+ "lib" : "@HDF5_LIBS@",
+ "include" : "@HDF5_INCLUDE@"
+ },
+ "netcdf" : {
+ "lib" : "@NETCDF_LIBS@",
+ "include" : "@NETCDF_INCLUDE@"
+ },
+ "udunits2" : {
+ "lib" : "@UDUNITS_LDFLAGS@",
+ "include" : "@UDUNITS_INCLUDE@"
+ },
+ "proj" : {
+ "lib" : "@PROJ_LDFLAGS@",
+ "include" : "@PROJ_INCLUDE@"
+ },
+ "magics" : {
+ "lib" : "@MAGICS_LIBS@",
+ "include" : "@MAGICS_INCLUDE@"
+ }
+ },
+ "platform" : {
+ "USER_NAME" : "@USER_NAME@",
+ "HOST_NAME" : "@HOST_NAME@",
+ "SYSTEM_TYPE" : "@SYSTEM_TYPE@"
+ },
},
- "hdf5" : {
- "lib" : "@HDF5_LIBS@",
- "include" : "@HDF5_INCLUDE@"
- },
- "netcdf" : {
- "lib" : "@NETCDF_LIBS@",
- "include" : "@NETCDF_INCLUDE@"
- },
- "udunits2" : {
- "lib" : "@UDUNITS_LDFLAGS@",
- "include" : "@UDUNITS_INCLUDE@"
- },
- "proj" : {
- "lib" : "@PROJ_LDFLAGS@",
- "include" : "@PROJ_INCLUDE@"
- },
- "magics" : {
- "lib" : "@MAGICS_LIBS@",
- "include" : "@MAGICS_INCLUDE@"
- },
- "USER_NAME" : "@USER_NAME@",
- "HOST_NAME" : "@HOST_NAME@",
- "SYSTEM_TYPE" : "@SYSTEM_TYPE@"
+ "features" : {
+ "enable_cdi_lib" : @ENABLE_CDI_LIB@,
+ "enable_data" : @ENABLE_DATA@,
+ "enable_fortran" : @ENABLE_FORTRAN@,
+ "fortran_works" : "@FORTRAN_WORKS@",
+ }
}
diff --git a/cdo.spec b/cdo.spec
index 501232c..41a1c25 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
Name: cdo
#BuildRequires:
-Version: 1.9.1
+Version: 1.9.2rc1
Release: 1
Summary: Climate Data Operators
License: GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/config/default b/config/default
index e5600d6..9bc02aa 100755
--- a/config/default
+++ b/config/default
@@ -109,7 +109,8 @@ case "${HOSTNAME}" in
CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=native" \
CC=icc CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native"
elif test "$COMP" = clang ; then
- ${CONFPATH}configure \
+ ${CONFPATH}configure --prefix=$HOME/local \
+ --enable-maintainer-mode \
$CDOLIBS LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib" \
CXX=clang++ CXXFLAGS="-g -Wall -pedantic -O3" \
CC=clang CFLAGS="-g -Wall -pedantic -O3"
@@ -127,8 +128,9 @@ case "${HOSTNAME}" in
${CONFPATH}configure --prefix=$HOME/local \
--enable-maintainer-mode \
$CDOLIBS LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib" \
- CXX=g++ CXXFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -march=native -Wa,-q -fstack-protector" \
- CC=gcc CFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -march=native -Wa,-q -fstack-protector"
+ F77=gfortran FFLAGS="-g -O2" \
+ CXX=g++ CXXFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -fstack-protector" \
+ CC=gcc CFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -fstack-protector"
# --with-libxml2=/usr \
# --with-magics=/Users/m214003/local/Magics-2.18.14nio \
fi
@@ -231,6 +233,7 @@ case "${HOSTNAME}" in
--with-fftw3 \
$CDOLIBS \
LDFLAGS="-Wl,-rpath,/sw/rhel6-x64/eccodes/eccodes-2.3.0-gcc48/lib" \
+ F77=ifort FFLAGS="-g -O2" \
CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=core-avx2" \
CC=icc CFLAGS="-g -Wall -O2 -qopt-report=5 -march=core-avx2"
elif test "$COMP" = pgi ; then
@@ -244,6 +247,7 @@ case "${HOSTNAME}" in
--with-fftw3 \
$CDOLIBS \
LDFLAGS="-Wl,-rpath,/sw/rhel6-x64/eccodes/eccodes-2.3.0-gcc48/lib" \
+ F77=gfortran FFLAGS="-g -O2" \
CXX=g++ CXXFLAGS='-g -Wall -O3 -march=native -mavx2' \
CC=gcc CFLAGS='-g -Wall -O3 -march=native -mavx2'
fi
@@ -279,7 +283,7 @@ case "${HOSTNAME}" in
CC=icc CFLAGS="-g -O2 -Wall -fno-alias"
;;
# x86_64-archlinux
- luthien*)
+ melian)
case "$COMP" in
gcc|clang)
${CONFPATH}configure --prefix=$HOME/local \
diff --git a/configure b/configure
index a5ddc92..d2e8b4c 100755
--- a/configure
+++ b/configure
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdo 1.9.1.
+# Generated by GNU Autoconf 2.69 for cdo 1.9.2rc1.
#
# Report bugs to <http://mpimet.mpg.de/cdo>.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -222,21 +246,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -339,6 +367,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -460,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -494,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -515,28 +555,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -570,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='cdo'
PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.9.1'
-PACKAGE_STRING='cdo 1.9.1'
+PACKAGE_VERSION='1.9.2rc1'
+PACKAGE_STRING='cdo 1.9.2rc1'
PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdo'
PACKAGE_URL=''
@@ -620,7 +640,6 @@ LIBOBJS
AM_CPPFLAGS
CLIBS
CLDFLAGS
-FCFLAGS
BUILD_AVX2_TESTS_FALSE
BUILD_AVX2_TESTS_TRUE
BUILD_AVX_TESTS_FALSE
@@ -679,12 +698,22 @@ PTHREAD_LIBS
PTHREAD_CC
ax_pthread_config
ENABLE_DATA
+ENABLE_NEARPT3_FALSE
+ENABLE_NEARPT3_TRUE
+ENABLE_NEARPT3
+FORTRAN_WORKS
+USE_F77_FALSE
+USE_F77_TRUE
+ENABLE_FORTRAN
SYSTEM_TYPE
HOST_NAME
USER_NAME
AS
OPENMP_CFLAGS
HAVE_CXX11
+ac_ct_F77
+FFLAGS
+F77
CXXCPP
am__fastdepCXX_FALSE
am__fastdepCXX_TRUE
@@ -823,6 +852,8 @@ with_sysroot
enable_libtool_lock
enable_openmp
enable_largefile
+enable_fortran
+enable_nearpt3
enable_data
with_threads
with_szlib
@@ -858,7 +889,9 @@ CPP
CXX
CXXFLAGS
CCC
-CXXCPP'
+CXXCPP
+F77
+FFLAGS'
ac_subdirs_all='libcdi'
# Initialize some variables set by options.
@@ -1314,8 +1347,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1401,7 +1432,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures cdo 1.9.1 to adapt to many kinds of systems.
+\`configure' configures cdo 1.9.2rc1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1471,7 +1502,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of cdo 1.9.1:";;
+ short | recursive ) echo "Configuration of cdo 1.9.2rc1:";;
esac
cat <<\_ACEOF
@@ -1495,6 +1526,8 @@ Optional Features:
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-openmp do not use OpenMP
--disable-largefile omit support for large files
+ --disable-fortran Omit building of Fortran routines
+ --enable-nearpt3 nearpt3 support [default=no]
--enable-data DATA support [default=yes]
--enable-grib GRIB support [default=yes]
--enable-cgribex Use the CGRIBEX library [default=yes]
@@ -1556,6 +1589,8 @@ Some influential environment variables:
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CXXCPP C++ preprocessor
+ F77 Fortran 77 compiler command
+ FFLAGS Fortran 77 compiler flags
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -1623,10 +1658,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-cdo configure 1.9.1
-generated by GNU Autoconf 2.68
+cdo configure 1.9.2rc1
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1702,7 +1737,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2000,7 +2035,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2019,6 +2054,90 @@ fi
} # ac_fn_cxx_try_link
+# ac_fn_f77_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_f77_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_f77_try_compile
+
+# ac_fn_f77_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_f77_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_f77_try_link
+
# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
# ----------------------------------------------------
# Tries to find if the field MEMBER exists in type AGGR, after including
@@ -2212,12 +2331,54 @@ $as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_decl
+
+# ac_fn_f77_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_f77_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_f77_try_run
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by cdo $as_me 1.9.1, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+It was created by cdo $as_me 1.9.2rc1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2679,7 +2840,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
# AM_INIT_AUTOMAKE([foreign -Wall -Werror])
-am__api_version='1.14'
+am__api_version='1.15'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2718,7 +2879,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -2851,8 +3012,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -2871,7 +3032,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2902,7 +3063,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2942,7 +3103,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2993,7 +3154,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -3040,7 +3201,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3165,7 +3326,7 @@ fi
# Define the identity of the package.
PACKAGE='cdo'
- VERSION='1.9.1'
+ VERSION='1.9.2rc1'
cat >>confdefs.h <<_ACEOF
@@ -3199,8 +3360,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -3257,6 +3418,7 @@ END
as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
fi
fi
+
ac_config_headers="$ac_config_headers src/config.h"
@@ -3369,7 +3531,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3409,7 +3571,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3462,7 +3624,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3503,7 +3665,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -3561,7 +3723,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3605,7 +3767,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4051,8 +4213,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4344,7 +4505,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4388,7 +4549,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4615,7 +4776,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -4691,7 +4852,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -4757,7 +4918,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -4824,7 +4985,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -5080,7 +5241,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5124,7 +5285,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5548,7 +5709,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5588,7 +5749,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5894,7 +6055,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5934,7 +6095,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6037,7 +6198,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6081,7 +6242,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6206,7 +6367,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6246,7 +6407,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6305,7 +6466,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6345,7 +6506,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6994,7 +7155,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7034,7 +7195,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7114,7 +7275,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7154,7 +7315,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7206,7 +7367,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7246,7 +7407,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7298,7 +7459,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7338,7 +7499,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7390,7 +7551,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7430,7 +7591,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7482,7 +7643,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7522,7 +7683,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12030,7 +12191,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BASH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12073,7 +12234,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_BASH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12128,7 +12289,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12168,7 +12329,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12220,7 +12381,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="${ac_tool_prefix}g++"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12260,7 +12421,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="g++"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12441,7 +12602,7 @@ main ()
return 0;
}
_ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
do
CC="$ac_save_CC $ac_arg"
if ac_fn_c_try_compile "$LINENO"; then :
@@ -12501,7 +12662,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12545,7 +12706,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -16057,86 +16218,3015 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
-$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
-if ${ac_cv_c_restrict+:} false; then :
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_F77+:} false; then :
$as_echo_n "(cached) " >&6
else
- ac_cv_c_restrict=no
- # The order here caters to the fact that C++ does not require restrict.
- for ac_kw in __restrict __restrict__ _Restrict restrict; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef int * int_ptr;
- int foo (int_ptr $ac_kw ip) {
- return ip[0];
- }
-int
-main ()
-{
-int s[1];
- int * $ac_kw t = s;
- t[0] = 0;
- return foo(t)
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_restrict=$ac_kw
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- test "$ac_cv_c_restrict" != no && break
- done
+ if test -n "$F77"; then
+ ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
-$as_echo "$ac_cv_c_restrict" >&6; }
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
- case $ac_cv_c_restrict in
- restrict) ;;
- no) $as_echo "#define restrict /**/" >>confdefs.h
- ;;
- *) cat >>confdefs.h <<_ACEOF
-#define restrict $ac_cv_c_restrict
-_ACEOF
- ;;
- esac
- ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
- ac_success=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
-$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
-if ${ax_cv_cxx_compile_cxx11+:} false; then :
+ test -n "$F77" && break
+ done
+fi
+if test -z "$F77"; then
+ ac_ct_F77=$F77
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_F77+:} false; then :
$as_echo_n "(cached) " >&6
else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-// If the compiler admits that it is not ready for C++11, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
+ if test -n "$ac_ct_F77"; then
+ ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_F77="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
-#error "This is not a C++ compiler"
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
-#elif __cplusplus < 201103L
-#error "This is not a C++11 compiler"
+ test -n "$ac_ct_F77" && break
+done
-#else
+ if test "x$ac_ct_F77" = x; then
+ F77=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ F77=$ac_ct_F77
+ fi
+fi
-namespace cxx11
-{
- namespace test_static_assert
- {
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file. (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if ${ac_cv_f77_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+#ifndef __GNUC__
+ choke me
+#endif
+
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if ${ac_cv_prog_f77_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ FFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_prog_f77_g=yes
+else
+ ac_cv_prog_f77_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+ FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-g -O2"
+ else
+ FFLAGS="-g"
+ fi
+else
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-O2"
+ else
+ FFLAGS=
+ fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+ G77=yes
+else
+ G77=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_direct_absolute_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+inherit_rpath_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+reload_flag_F77=$reload_flag
+reload_cmds_F77=$reload_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ compiler_F77=$CC
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+ GCC=$G77
+ if test -n "$compiler"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+ GCC_F77="$G77"
+ LD_F77="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_static_F77='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_F77='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_F77='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_F77='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_F77=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_F77='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared_F77=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_F77='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_F77=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic_F77='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl_F77='-Xlinker '
+ if test -n "$lt_prog_compiler_pic_F77"; then
+ lt_prog_compiler_pic_F77="-Xcompiler $lt_prog_compiler_pic_F77"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_F77='-Bstatic'
+ else
+ lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_F77='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static_F77='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-fPIC'
+ lt_prog_compiler_static_F77='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='--shared'
+ lt_prog_compiler_static_F77='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl_F77='-Wl,-Wl,,'
+ lt_prog_compiler_pic_F77='-PIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-fpic'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static_F77='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-qpic'
+ lt_prog_compiler_static_F77='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ lt_prog_compiler_wl_F77=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ lt_prog_compiler_wl_F77='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ lt_prog_compiler_wl_F77='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-fPIC'
+ lt_prog_compiler_static_F77='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-fpic'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_F77='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static_F77='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static_F77='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl_F77='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl_F77='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl_F77='-Qoption ld '
+ lt_prog_compiler_pic_F77='-PIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic_F77='-Kconform_pic'
+ lt_prog_compiler_static_F77='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_can_build_shared_F77=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic_F77='-pic'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared_F77=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_F77=
+ ;;
+ *)
+ lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_F77=$lt_prog_compiler_pic_F77
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_F77" >&5
+$as_echo "$lt_cv_prog_compiler_pic_F77" >&6; }
+lt_prog_compiler_pic_F77=$lt_cv_prog_compiler_pic_F77
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_F77=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_F77"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_F77=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_F77" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_F77" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then
+ case $lt_prog_compiler_pic_F77 in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+ esac
+else
+ lt_prog_compiler_pic_F77=
+ lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_F77=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_F77=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_F77=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_F77" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_F77" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then
+ :
+else
+ lt_prog_compiler_static_F77=
+fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_F77=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_F77=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_F77=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_F77=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag_F77=
+ always_export_symbols_F77=no
+ archive_cmds_F77=
+ archive_expsym_cmds_F77=
+ compiler_needs_object_F77=no
+ enable_shared_with_static_runtimes_F77=no
+ export_dynamic_flag_spec_F77=
+ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic_F77=no
+ hardcode_direct_F77=no
+ hardcode_direct_absolute_F77=no
+ hardcode_libdir_flag_spec_F77=
+ hardcode_libdir_separator_F77=
+ hardcode_minus_L_F77=no
+ hardcode_shlibpath_var_F77=unsupported
+ inherit_rpath_F77=no
+ link_all_deplibs_F77=unknown
+ module_cmds_F77=
+ module_expsym_cmds_F77=
+ old_archive_from_new_cmds_F77=
+ old_archive_from_expsyms_cmds_F77=
+ thread_safe_flag_spec_F77=
+ whole_archive_flag_spec_F77=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms_F77=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs_F77=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_F77=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs_F77=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77=''
+ ;;
+ m68k)
+ archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_minus_L_F77=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_F77=unsupported
+ # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ export_dynamic_flag_spec_F77='${wl}--export-all-symbols'
+ allow_undefined_flag_F77=unsupported
+ always_export_symbols_F77=no
+ enable_shared_with_static_runtimes_F77=yes
+ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_F77='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs_F77=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_F77=no
+ hardcode_shlibpath_var_F77=no
+ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_F77='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec_F77=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_F77=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_F77=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec_F77='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs_F77=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs_F77=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs_F77" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec_F77=
+ export_dynamic_flag_spec_F77=
+ whole_archive_flag_spec_F77=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag_F77=unsupported
+ always_export_symbols_F77=yes
+ archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L_F77=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct_F77=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_F77=''
+ hardcode_direct_F77=yes
+ hardcode_direct_absolute_F77=yes
+ hardcode_libdir_separator_F77=':'
+ link_all_deplibs_F77=yes
+ file_list_spec_F77='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_F77=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_F77=yes
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_libdir_separator_F77=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec_F77='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols_F77=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag_F77='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__F77=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__F77"; then
+ lt_cv_aix_libpath__F77=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__F77"; then
+ lt_cv_aix_libpath__F77="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__F77
+fi
+
+ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds_F77='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_F77="-z nodefs"
+ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__F77=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__F77"; then
+ lt_cv_aix_libpath__F77=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__F77"; then
+ lt_cv_aix_libpath__F77="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__F77
+fi
+
+ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_F77=' ${wl}-bernotok'
+ allow_undefined_flag_F77=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_F77='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_F77='$convenience'
+ fi
+ archive_cmds_need_lc_F77=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_F77=''
+ ;;
+ m68k)
+ archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_minus_L_F77=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec_F77=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec_F77=' '
+ allow_undefined_flag_F77=unsupported
+ always_export_symbols_F77=yes
+ file_list_spec_F77='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_F77='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, F77)='true'
+ enable_shared_with_static_runtimes_F77=yes
+ exclude_expsyms_F77='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds_F77='chmod 644 $oldlib'
+ postlink_cmds_F77='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec_F77=' '
+ allow_undefined_flag_F77=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds_F77='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes_F77=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_F77=no
+ hardcode_direct_F77=no
+ hardcode_automatic_F77=yes
+ hardcode_shlibpath_var_F77=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec_F77='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ compiler_needs_object_F77=yes
+ else
+ whole_archive_flag_spec_F77=''
+ fi
+ link_all_deplibs_F77=yes
+ allow_undefined_flag_F77="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs_F77=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_F77=yes
+ hardcode_minus_L_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds_F77='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds_F77='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+ hardcode_direct_F77=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+ hardcode_direct_F77=yes
+ hardcode_direct_absolute_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_F77=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_F77=no
+ hardcode_shlibpath_var_F77=no
+ ;;
+ *)
+ hardcode_direct_F77=yes
+ hardcode_direct_absolute_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_F77=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine foo
+ end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc_F77='no'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+ inherit_rpath_F77=yes
+ link_all_deplibs_F77=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ newsos6)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_F77=yes
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ hardcode_direct_absolute_F77=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_F77='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ ;;
+ *)
+ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_minus_L_F77=yes
+ allow_undefined_flag_F77=unsupported
+ archive_cmds_F77='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag_F77=' -expect_unresolved \*'
+ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc_F77='no'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_F77='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag_F77=' -expect_unresolved \*'
+ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec_F77='-rpath $libdir'
+ fi
+ archive_cmds_need_lc_F77='no'
+ hardcode_libdir_separator_F77=:
+ ;;
+
+ solaris*)
+ no_undefined_flag_F77=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds_F77='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds_F77='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ hardcode_shlibpath_var_F77=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs_F77=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_direct_F77=yes
+ hardcode_minus_L_F77=yes
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_F77=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds_F77='$CC -r -o $output$reload_objs'
+ hardcode_direct_F77=no
+ ;;
+ motorola)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var_F77=no
+ export_dynamic_flag_spec_F77='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var_F77=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs_F77=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_F77='${wl}-z,text'
+ archive_cmds_need_lc_F77=no
+ hardcode_shlibpath_var_F77=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_F77='${wl}-z,text'
+ allow_undefined_flag_F77='${wl}-z,nodefs'
+ archive_cmds_need_lc_F77=no
+ hardcode_shlibpath_var_F77=no
+ hardcode_libdir_flag_spec_F77='${wl}-R,$libdir'
+ hardcode_libdir_separator_F77=':'
+ link_all_deplibs_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_F77='-L$libdir'
+ hardcode_shlibpath_var_F77=no
+ ;;
+
+ *)
+ ld_shlibs_F77=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec_F77='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_F77" >&5
+$as_echo "$ld_shlibs_F77" >&6; }
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+with_gnu_ld_F77=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_F77=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds_F77 in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_F77
+ pic_flag=$lt_prog_compiler_pic_F77
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+ allow_undefined_flag_F77=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc_F77=no
+ else
+ lt_cv_archive_cmds_need_lc_F77=yes
+ fi
+ allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_F77" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_F77" >&6; }
+ archive_cmds_need_lc_F77=$lt_cv_archive_cmds_need_lc_F77
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_F77\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_F77\""
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" ||
+ test -n "$runpath_var_F77" ||
+ test "X$hardcode_automatic_F77" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct_F77" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+ test "$hardcode_minus_L_F77" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_F77=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_F77=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_F77=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_F77" >&5
+$as_echo "$hardcode_action_F77" >&6; }
+
+if test "$hardcode_action_F77" = relink ||
+ test "$inherit_rpath_F77" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_restrict=no
+ # The order here caters to the fact that C++ does not require restrict.
+ for ac_kw in __restrict __restrict__ _Restrict restrict; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef int * int_ptr;
+ int foo (int_ptr $ac_kw ip) {
+ return ip[0];
+ }
+int
+main ()
+{
+int s[1];
+ int * $ac_kw t = s;
+ t[0] = 0;
+ return foo(t)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_restrict" != no && break
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+ ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ ac_success=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+ namespace test_static_assert
+ {
template <typename T>
struct check
@@ -17115,7 +20205,8 @@ if ac_fn_c_try_link "$LINENO"; then :
ac_cv_prog_c_openmp='none needed'
else
ac_cv_prog_c_openmp='unsupported'
- for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp; do
+ for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \
+ -Popenmp --openmp; do
ac_save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $ac_option"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -17170,7 +20261,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17210,7 +20301,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17262,7 +20353,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CPP="${ac_tool_prefix}cpp"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17302,7 +20393,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CPP="cpp"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17354,7 +20445,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LD="${ac_tool_prefix}ld"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17394,7 +20485,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LD="ld"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17446,7 +20537,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NM="${ac_tool_prefix}nm"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17486,7 +20577,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NM="nm"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17538,7 +20629,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17578,7 +20669,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17630,7 +20721,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AS="${ac_tool_prefix}as"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17670,7 +20761,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AS="as"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17722,7 +20813,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17762,7 +20853,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17814,7 +20905,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17854,7 +20945,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17906,7 +20997,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17946,7 +21037,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17998,7 +21089,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -18038,7 +21129,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -18077,6 +21168,7 @@ fi
#
FC=no
export FC
+#
# ----------------------------------------------------------------------
# Check large file support on 32 bit system
# Check whether --enable-largefile was given.
@@ -18275,6 +21367,8 @@ _ACEOF
esac
rm -rf conftest*
fi
+
+
fi
# ----------------------------------------------------------------------
@@ -18697,6 +21791,12 @@ case "$CC" in
*) C_VERSION=`$CC -V 2>&1 | head -n 1 | grep -v error`;;
esac
+case "$F77" in
+ pgf*) F77_VERSION=`$F77 -V | head -2 | tail -n 1`;;
+ gfortran*) F77_VERSION=`$F77 --version | head -n 1`;;
+ *) F77_VERSION=`$F77 -V 2>&1 | head -n 1 | grep -v error`;;
+esac
+
if test -z "$CXX_VERSION" ; then CXX_VERSION="unknown"; fi;
cat >>confdefs.h <<_ACEOF
@@ -18711,6 +21811,13 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+if test -z "$F77_VERSION" ; then F77_VERSION="unknown"; fi;
+
+cat >>confdefs.h <<_ACEOF
+#define F77_VERSION "$F77_VERSION"
+_ACEOF
+
+
# Checks for username, hostname and system type
USERNAME=$LOGNAME
if test -z "$USERNAME" ; then USERNAME=$USER; fi;
@@ -18728,143 +21835,524 @@ if test -z "$HOST"; then :
if test -x /bin/hostname; then :
HOST=$(hostname)
else
- if test -x /bin/uname; then :
- HOST=$(uname -n)
-fi
+ if test -x /bin/uname; then :
+ HOST=$(uname -n)
+fi
+fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HOST_NAME "$HOST"
+_ACEOF
+
+HOST_NAME="$HOST"
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SYSTEM_TYPE "$ac_cv_build"
+_ACEOF
+
+SYSTEM_TYPE="$ac_cv_build"
+
+# ----------------------------------------------------------------------
+# Check for math library
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
+$as_echo_n "checking for floor in -lm... " >&6; }
+if ${ac_cv_lib_m_floor+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floor ();
+int
+main ()
+{
+return floor ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_floor=yes
+else
+ ac_cv_lib_m_floor=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
+$as_echo "$ac_cv_lib_m_floor" >&6; }
+if test "x$ac_cv_lib_m_floor" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+ LIBS="-lm $LIBS"
+
+fi
+
+# ----------------------------------------------------------------------
+# Checks for the availability of ANSI-C99 math functions
+ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "$ac_includes_default
+#include <math.h>
+"
+if test "x$ac_cv_have_decl_isnan" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ISNAN $ac_have_decl
+_ACEOF
+
+for ac_func in sqrtl
+do :
+ ac_fn_c_check_func "$LINENO" "sqrtl" "ac_cv_func_sqrtl"
+if test "x$ac_cv_func_sqrtl" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTL 1
+_ACEOF
+
+fi
+done
+
+for ac_func in feenableexcept
+do :
+ ac_fn_c_check_func "$LINENO" "feenableexcept" "ac_cv_func_feenableexcept"
+if test "x$ac_cv_func_feenableexcept" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FEENABLEEXCEPT 1
+_ACEOF
+
+fi
+done
+
+#
+ac_fn_c_check_member "$LINENO" "fenv_t" "__control" "ac_cv_member_fenv_t___control" "#include <fenv.h>
+"
+if test "x$ac_cv_member_fenv_t___control" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FENV_T___CONTROL 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "fenv_t" "__mxcsr" "ac_cv_member_fenv_t___mxcsr" "#include <fenv.h>
+"
+if test "x$ac_cv_member_fenv_t___mxcsr" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FENV_T___MXCSR 1
+_ACEOF
+
+
+fi
+
+
+# ----------------------------------------------------------------------
+# Create the Interface to Fortran77 routines via cfortran.h
+# Check whether --enable-fortran was given.
+if test "${enable_fortran+set}" = set; then :
+ enableval=$enable_fortran; enable_fortran=${enableval}
+else
+ enable_fortran=yes
+fi
+
+if test "x${enable_fortran}" = "xyes"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking C preprocessor flags for Fortran calling convention cfortran.h" >&5
+$as_echo_n "checking C preprocessor flags for Fortran calling convention cfortran.h... " >&6; }
+if ${acx_cv_cf_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ acx_cv_cf_flag=''
+ for macro in pgiFortran NAGf90Fortran f2cFortran hpuxFortran apolloFortran sunFortran IBMR2Fortran CRAYFortran PATHSCALE_COMPILER gFortran mipsFortran DECFortran vmsFortran CONVEXFortran PowerStationFortran AbsoftUNIXFortran AbsoftProFortran SXFortran
+do :
+ acx_temp=`echo "$CPPFLAGS $CFLAGS" | sed -n 's/^\(.* \)*-D\('"$macro"'\)\( .*\)*$/\2/;t print
+b
+: print
+p'`
+ if test x"$acx_temp" != x; then :
+ if test x"$acx_cv_cf_flag" = x; then :
+ acx_cv_cf_flag="$acx_temp (user-specified)"
+else
+ echo ; echo '"'"$acx_cv_cf_flag $acx_temp"'"'
+ as_fn_error $? "Multiple specification of cfortran.h flags" "$LINENO" 5
+fi
+fi
+done
+ if test x"$acx_cv_cf_flag" = x; then :
+
+ if test -n "$F77" -a X"$F77" != Xno; then :
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+
+
+ save_F77=$F77 ; acx_FC=$F77
+ case $host in #(
+ x86_64-*-linux-*|i*86-*-linux-*|*-apple-darwin*|ia64-*-linux-*|x86_64-*-freebsd*|i*86-*-freebsd*) :
+ acx_temp=`$acx_FC -V 2>&1`
+ if echo "$acx_temp" | grep '^Copyright.*\(The Portland Group\|NVIDIA CORPORATION\)' >/dev/null; then :
+ acx_cv_f77_cf_flag=-DgFortran
+elif echo "$acx_temp" | grep '^NAG Fortran Compiler Release' >/dev/null; then :
+ acx_cv_f77_cf_flag=-DNAGf90Fortran
+elif echo "$acx_temp" | grep '^Intel(R) Fortran.*Compiler' >/dev/null; then :
+ acx_cv_f77_cf_flag=-DgFortran
+elif echo "$acx_temp" | grep '^Cray Fortran' >/dev/null; then :
+ acx_cv_f77_cf_flag=-DgFortran
+elif acx_temp=`$acx_FC --version 2>&1` \
+ && echo $acx_temp | grep '^GNU Fortran' >/dev/null; then :
+ if echo $acx_temp | grep g77 >/dev/null; then :
+ acx_cv_f77_cf_flag=-Dg77Fortran
+else
+ if echo "$FFLAGS" | grep '^\(.* \)*-ff2c\( .*\)*$' >/dev/null; then :
+ acx_cv_f77_cf_flag=-Df2cFortran
+else
+ acx_cv_f77_cf_flag=-DgFortran
+fi
+fi
+elif acx_temp=`$acx_FC -v 2>&1` \
+ && echo $acx_temp | grep '^f2c'; then :
+ acx_cv_f77_cf_flag=-Df2cFortran
+fi ;; #(
+ *-ibm-aix*) :
+ if $CC -qversion 2>&1 | grep '^IBM XL C' >/dev/null; then :
+
+else
+ acx_cv_f77_cf_flag=-DIBMR2Fortran
+fi
+ ;; #(
+ *-*-hpux*) :
+ acx_cv_f77_cf_flag=-DhpuxFortran ;; #(
+ sx*-*-*|es*-*-*) :
+ acx_cv_f77_cf_flag=-DSXFortran ;; #(
+ *) :
+ ;;
+esac
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+ acx_cv_cf_flag="$acx_cv_f77_cf_flag (probed)"
+
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_cf_flag" >&5
+$as_echo "$acx_cv_cf_flag" >&6; }
+ if echo "$acx_cv_cf_flag" | grep ' (probed)$' >/dev/null; then :
+ CPPFLAGS="${CPPFLAGS+$CPPFLAGS }`echo "$acx_cv_cf_flag" | sed 's/ (probed)$//'`"
+fi
+
+case $host in #(
+ *-ibm-aix*) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -Dappendus needs to be added to CPPFLAGS for cfortran.h" >&5
+$as_echo_n "checking if -Dappendus needs to be added to CPPFLAGS for cfortran.h... " >&6; }
+ if $CC -qversion 2>&1 | grep '^IBM XL C' >/dev/null; then :
+ acx_temp_qextname_f77flags=`echo "$FFLAGS" | sed -n '/-qextname/{ s/^\(.* \)*-qextname\( .*\)*$/-qextname/;p;}'`
+ acx_temp_qextname_fcflags=`echo "$FCFLAGS" | sed -n '/-qextname/{ s/^\(.* \)*-qextname\( .*\)*$/-qextname/;p;}'`
+
+ acx_temp_qextname_fcflags=$acx_temp_qextname_f77flags
+ case x"$acx_temp_qextname_fcflags$acx_temp_qextname_f77flags" in #(
+ x-qextname) :
+ as_fn_error $? "Option -qextname must be provided consistently to F77 and FC" "$LINENO" 5 ;; #(
+ x-qextname-qextname) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CPPFLAGS="${CPPFLAGS+$CPPFLAGS }-Dappendus" ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; } ;;
+esac
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi ;; #(
+ *) :
+ ;;
+esac
+if test -n "$F77" -a X"$F77" != Xno; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C externals constructed with cfortran.h work" >&5
+$as_echo_n "checking if C externals constructed with cfortran.h work... " >&6; }
+if ${acx_cv_cfortran_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ acx_cv_cfortran_works=no
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="-I$srcdir/src $CPPFLAGS"
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "cfortran.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+PROTOCCALLSFFUN1(FLOAT,CFTSTF,cftstf,FLOAT)
+#define conftest_F(v) \
+ CCALLSFFUN1(CFTSTF,cftstf,FLOAT,(v));
+
+static float
+cftstC(int i, float v, int *p, float *q)
+{
+ float f;
+ *p = (int)roundf(v * i);
+ *q = f = conftest_F(v * i);
+ return f;
+}
+
+FCALLSCFUN4(FLOAT,cftstC,CFTSTC,cftstc,INT,FLOAT,PINT,PFLOAT)
+
+/* test string returns */
+static const char *
+conftest_str_C(void)
+{
+ static const char msg[100] = "AAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ return msg;
+}
+
+FCALLSCFUN0(STRING,conftest_str_C,CHTST,chtst)
+
+/* This function is required simply because some Fortran compilers
+ * won't stop with exit code n when encountering STOP n */
+static void
+errExit(void)
+{
+ exit(1);
+}
+
+FCALLSCSUB0(errExit,ERR_EXIT,err_exit)
+
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: Renaming C object file." >&5; } >&5
+ (mv "conftest.$ac_objext" "conftest_c.$ac_objext") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+ cat > conftest.$ac_ext <<_ACEOF
+ REAL FUNCTION CFTSTF(v)
+ REAL RI
+ COMMON /CFTSTD/ RI
+ REAL V
+ REAL R
+ CFTSTF = V * 100.0
+ RI = 1.0 / V
+ END FUNCTION CFTSTF
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: Renaming Fortran object file." >&5; } >&5
+ (mv "conftest.$ac_objext" "conftest_f.$ac_objext") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ save_LIBS=$LIBS
+ LIBS="conftest_c.$ac_objext conftest_f.$ac_objext $LIBS"
+ if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Skipping run test for cfortran.h in cross-compilation mode," >&5
+$as_echo "$as_me: Skipping run test for cfortran.h in cross-compilation mode," >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: link test succeeded." >&5
+$as_echo "$as_me: link test succeeded." >&6;}
+ acx_cv_cfortran_works=yes
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+ REAL RI
+ COMMON /CFTSTD/ RI
+ REAL EPS
+ PARAMETER(EPS=10E-6)
+ REAL FOO, BOO, TOO
+ INTEGER BAR, BAZ, I
+ CHARACTER(99) AAAAAA
+ EXTERNAL CFTSTC, CFTSTF, CHTST, ERR_EXIT
+ REAL CFTSTC, CFTSTF
+ CHARACTER(99) CHTST
+ BAR = 5
+ FOO = 0.3
+ TOO = CFTSTC(BAR, FOO, BAZ, BOO)
+ IF (ABS(BAZ - NINT(BAR * FOO)) /= 0) THEN
+ WRITE (0, '(2(A,I0))') "ERROR CHECKING, WHEN BAZ, BAZ=", BAZ,
+ & ", NINT(BAR * FOO) =", NINT(BAR * FOO)
+ CALL ERR_EXIT
+ END IF
+ IF (ABS((RI - 1.0 / (BAR * FOO)) / ABS(RI)) > EPS) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING RI, RI=", RI, ",
+ & 1.0 / (BAR * FOO) = ", 1.0 / (BAR * FOO)
+ CALL err_exit
+ END IF
+ IF (ABS((BOO - (BAR * FOO * 100.0))/ABS(BOO)) > EPS) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING BOO, BOO=", BOO,
+ & ", BAR * FOO * 100.0 = ", BAR * FOO * 100.0
+ CALL ERR_EXIT
+ END IF
+ IF (TOO /= BOO) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING TOO VS. BOO, TOO=",
+ & TOO, ", BOO = ", BOO
+ CALL ERR_EXIT
+ END IF
+ AAAAAA = CHTST()
+ DO i = 1, 99
+ IF (AAAAAA(I:I) /= 'A') THEN
+ WRITE (0, '(A,I0,2A)') "ERROR CHECKING AAAAAA(", I, ")=",
+ & AAAAAA(I:I)
+ CALL ERR_EXIT
+ END IF
+ END DO
+ end
+_ACEOF
+if ac_fn_f77_try_run "$LINENO"; then :
+ acx_cv_cfortran_works=yes
+else
+ acx_cv_cfortran_works="error"
fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
-cat >>confdefs.h <<_ACEOF
-#define HOST_NAME "$HOST"
-_ACEOF
+ LIBS=$save_LIBS
+else
+ acx_cv_cfortran_works="error compiling Fortran subroutine"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
-HOST_NAME="$HOST"
+else
+ acx_cv_cfortran_works="compiling with cfortran.h failed"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ CPPFLAGS=$save_CPPFLAGS
-cat >>confdefs.h <<_ACEOF
-#define SYSTEM_TYPE "$ac_cv_build"
-_ACEOF
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_cfortran_works" >&5
+$as_echo "$acx_cv_cfortran_works" >&6; }
+ if test x"$acx_cv_cfortran_works" = xyes; then :
-SYSTEM_TYPE="$ac_cv_build"
+$as_echo "#define HAVE_CF_INTERFACE 1" >>confdefs.h
-# ----------------------------------------------------------------------
-# Check for math library
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
-$as_echo_n "checking for floor in -lm... " >&6; }
-if ${ac_cv_lib_m_floor+:} false; then :
- $as_echo_n "(cached) " >&6
else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lm $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+ case x"$acx_cv_cfortran_works" in #(
+ x"error") :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Linking/Running with C EXTERNAL built with cfortran.h does not work!" >&5
+$as_echo "$as_me: Linking/Running with C EXTERNAL built with cfortran.h does not work!" >&6;} ;; #(
+ x"compiling with cfortran.h failed") :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Compilation with cfortran.h is not working!" >&5
+$as_echo "$as_me: Compilation with cfortran.h is not working!" >&6;} ;; #(
+ x"error compiling Fortran subroutine") :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: compilation of simple Fortran source failed!" >&5
+$as_echo "$as_me: compilation of simple Fortran source failed!" >&6;} ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Unexpected error when linking C and Fortran via cfortran.h!" >&5
+$as_echo "$as_me: Unexpected error when linking C and Fortran via cfortran.h!" >&6;} ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling cfortran.h bindings generation" >&5
+$as_echo "$as_me: Disabling cfortran.h bindings generation" >&6;}
+ acx_cv_cfortran_works=no
+fi
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char floor ();
-int
-main ()
-{
-return floor ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_m_floor=yes
-else
- ac_cv_lib_m_floor=no
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
-$as_echo "$ac_cv_lib_m_floor" >&6; }
-if test "x$ac_cv_lib_m_floor" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBM 1
-_ACEOF
+if test x$enable_fortran = 'xno'; then :
+ ENABLE_FORTRAN=false
- LIBS="-lm $LIBS"
+else
+ ENABLE_FORTRAN=true
fi
-
-# ----------------------------------------------------------------------
-# Checks for the availability of ANSI-C99 math functions
-ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "$ac_includes_default
-#include <math.h>
-"
-if test "x$ac_cv_have_decl_isnan" = xyes; then :
- ac_have_decl=1
+#
+ if test -n "$F77" -a X"$F77" != Xno -a x"$acx_cv_cfortran_works" = xyes; then
+ USE_F77_TRUE=
+ USE_F77_FALSE='#'
else
- ac_have_decl=0
+ USE_F77_TRUE='#'
+ USE_F77_FALSE=
fi
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ISNAN $ac_have_decl
-_ACEOF
+if test x$acx_cv_cfortran_works = 'xno'; then :
+ FORTRAN_WORKS=no
-for ac_func in sqrtl
-do :
- ac_fn_c_check_func "$LINENO" "sqrtl" "ac_cv_func_sqrtl"
-if test "x$ac_cv_func_sqrtl" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_SQRTL 1
-_ACEOF
+else
+ FORTRAN_WORKS=yes
fi
-done
-
-for ac_func in feenableexcept
-do :
- ac_fn_c_check_func "$LINENO" "feenableexcept" "ac_cv_func_feenableexcept"
-if test "x$ac_cv_func_feenableexcept" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FEENABLEEXCEPT 1
-_ACEOF
+# ----------------------------------------------------------------------
+# ----------------------------------------------------------------------
+# Enable NEARPT3 support
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nearpt3 support" >&5
+$as_echo_n "checking for nearpt3 support... " >&6; }
+# Check whether --enable-nearpt3 was given.
+if test "${enable_nearpt3+set}" = set; then :
+ enableval=$enable_nearpt3;
fi
-done
-
-#
-ac_fn_c_check_member "$LINENO" "fenv_t" "__control" "ac_cv_member_fenv_t___control" "#include <fenv.h>
-"
-if test "x$ac_cv_member_fenv_t___control" = xyes; then :
-cat >>confdefs.h <<_ACEOF
-#define HAVE_FENV_T___CONTROL 1
-_ACEOF
+if test "x$enable_nearpt3" = "xyes"; then :
-fi
-ac_fn_c_check_member "$LINENO" "fenv_t" "__mxcsr" "ac_cv_member_fenv_t___mxcsr" "#include <fenv.h>
-"
-if test "x$ac_cv_member_fenv_t___mxcsr" = xyes; then :
+$as_echo "#define ENABLE_NEARPT3 1" >>confdefs.h
-cat >>confdefs.h <<_ACEOF
-#define HAVE_FENV_T___MXCSR 1
-_ACEOF
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_nearpt3" >&5
+$as_echo "$enable_nearpt3" >&6; }
+ENABLE_NEARPT3=$enable_nearpt3
+ if test x$enable_nearpt3 = 'xyes'; then
+ ENABLE_NEARPT3_TRUE=
+ ENABLE_NEARPT3_FALSE='#'
+else
+ ENABLE_NEARPT3_TRUE='#'
+ ENABLE_NEARPT3_FALSE=
fi
# ----------------------------------------------------------------------
-# Enable NEARPT3 support
-# AC_MSG_CHECKING([for nearpt3 support])
-# AC_ARG_ENABLE([nearpt3], AS_HELP_STRING([--enable-nearpt3],[nearpt3 support [default=no]]))
-# AS_IF([test "x$enable_nearpt3" = "xyes"], [
-# AC_DEFINE(ENABLE_NEARPT3, [1], [Define to 1 for nearpt3 support])
-# ])
-# AC_MSG_RESULT([$enable_nearpt3])
-# AC_SUBST([ENABLE_NEARPT3],[$enable_nearpt3])
-# AM_CONDITIONAL([ENABLE_NEARPT3],[test x$enable_nearpt3 = 'xyes'])
-# ----------------------------------------------------------------------
# Enable DATA support
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DATA support" >&5
$as_echo_n "checking for DATA support... " >&6; }
@@ -18882,8 +22370,13 @@ $as_echo "#define ENABLE_DATA 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_data" >&5
$as_echo "$enable_data" >&6; }
-ENABLE_DATA=$enable_data
+if test x$enable_data = 'xno'; then :
+ ENABLE_DATA=false
+
+else
+ ENABLE_DATA=true
+fi
# ----------------------------------------------------------------------
CFLAGS="$CFLAGS ${OPENMP_CFLAGS}"
CXXFLAGS="$CXXFLAGS ${OPENMP_CFLAGS}"
@@ -19084,7 +22577,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ax_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -19276,7 +22769,7 @@ fi
#handle absolute path differently from PATH based program lookup
case "x$CC" in #(
x/*) :
- if { test -f ${CC}_r && $as_test_x ${CC}_r; }; then :
+ if as_fn_executable_p ${CC}_r; then :
PTHREAD_CC="${CC}_r"
fi ;; #(
*) :
@@ -19298,7 +22791,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PTHREAD_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20035,7 +23528,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NC_CONFIG="nc-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20209,7 +23702,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NC_CONFIG="$NETCDF_ROOT/bin/nc-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -22163,8 +25656,6 @@ fi
#
-# ----------------------------------------------------------------------
-
# configure code from valgrind
# does the x86/amd64 assembler understand SSE 4.2 instructions?
@@ -22338,6 +25829,12 @@ cat >>confdefs.h <<_ACEOF
#define CXX_COMPILER "$CXX_COMPILER"
_ACEOF
+F77_COMPILER="$F77 $FFLAGS"
+
+cat >>confdefs.h <<_ACEOF
+#define F77_COMPILER "$F77_COMPILER"
+_ACEOF
+
for ac_prog in gawk mawk nawk awk
@@ -22358,7 +25855,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -22403,7 +25900,7 @@ ac_config_files="$ac_config_files test/Gradsdes.test test/Collgrid.test test/thr
ac_config_files="$ac_config_files test/MapReduce.test test/Ninfo.test"
-ac_config_files="$ac_config_files Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings"
+ac_config_files="$ac_config_files Makefile src/lib/ncl/Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -22546,6 +26043,14 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${USE_F77_TRUE}" && test -z "${USE_F77_FALSE}"; then
+ as_fn_error $? "conditional \"USE_F77\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_NEARPT3_TRUE}" && test -z "${ENABLE_NEARPT3_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_NEARPT3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${ENABLE_MAGICS_TRUE}" && test -z "${ENABLE_MAGICS_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_MAGICS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -22872,16 +26377,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -22941,28 +26446,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -22983,8 +26476,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by cdo $as_me 1.9.1, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+This file was extended by cdo $as_me 1.9.2rc1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -23049,11 +26542,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-cdo config.status 1.9.1
-configured by $0, generated by GNU Autoconf 2.68,
+cdo config.status 1.9.2rc1
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -23144,7 +26637,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -23315,53 +26808,101 @@ predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+LD_F77='`$ECHO "$LD_F77" | $SED "$delay_single_quote_subst"`'
reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_F77='`$ECHO "$reload_flag_F77" | $SED "$delay_single_quote_subst"`'
reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_F77='`$ECHO "$reload_cmds_F77" | $SED "$delay_single_quote_subst"`'
old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_F77='`$ECHO "$old_archive_cmds_F77" | $SED "$delay_single_quote_subst"`'
compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_F77='`$ECHO "$compiler_F77" | $SED "$delay_single_quote_subst"`'
GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_F77='`$ECHO "$GCC_F77" | $SED "$delay_single_quote_subst"`'
lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_F77='`$ECHO "$lt_prog_compiler_no_builtin_flag_F77" | $SED "$delay_single_quote_subst"`'
lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_F77='`$ECHO "$lt_prog_compiler_pic_F77" | $SED "$delay_single_quote_subst"`'
lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_F77='`$ECHO "$lt_prog_compiler_wl_F77" | $SED "$delay_single_quote_subst"`'
lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_F77='`$ECHO "$lt_prog_compiler_static_F77" | $SED "$delay_single_quote_subst"`'
lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_F77='`$ECHO "$lt_cv_prog_compiler_c_o_F77" | $SED "$delay_single_quote_subst"`'
archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_F77='`$ECHO "$archive_cmds_need_lc_F77" | $SED "$delay_single_quote_subst"`'
enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_F77='`$ECHO "$enable_shared_with_static_runtimes_F77" | $SED "$delay_single_quote_subst"`'
export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_F77='`$ECHO "$export_dynamic_flag_spec_F77" | $SED "$delay_single_quote_subst"`'
whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_F77='`$ECHO "$whole_archive_flag_spec_F77" | $SED "$delay_single_quote_subst"`'
compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_F77='`$ECHO "$compiler_needs_object_F77" | $SED "$delay_single_quote_subst"`'
old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_F77='`$ECHO "$old_archive_from_new_cmds_F77" | $SED "$delay_single_quote_subst"`'
old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_F77='`$ECHO "$old_archive_from_expsyms_cmds_F77" | $SED "$delay_single_quote_subst"`'
archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_F77='`$ECHO "$archive_cmds_F77" | $SED "$delay_single_quote_subst"`'
archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_F77='`$ECHO "$archive_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`'
module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_F77='`$ECHO "$module_cmds_F77" | $SED "$delay_single_quote_subst"`'
module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_F77='`$ECHO "$module_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`'
with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_F77='`$ECHO "$with_gnu_ld_F77" | $SED "$delay_single_quote_subst"`'
allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_F77='`$ECHO "$allow_undefined_flag_F77" | $SED "$delay_single_quote_subst"`'
no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_F77='`$ECHO "$no_undefined_flag_F77" | $SED "$delay_single_quote_subst"`'
hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_F77='`$ECHO "$hardcode_libdir_flag_spec_F77" | $SED "$delay_single_quote_subst"`'
hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_F77='`$ECHO "$hardcode_libdir_separator_F77" | $SED "$delay_single_quote_subst"`'
hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_F77='`$ECHO "$hardcode_direct_F77" | $SED "$delay_single_quote_subst"`'
hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_F77='`$ECHO "$hardcode_direct_absolute_F77" | $SED "$delay_single_quote_subst"`'
hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_F77='`$ECHO "$hardcode_minus_L_F77" | $SED "$delay_single_quote_subst"`'
hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_F77='`$ECHO "$hardcode_shlibpath_var_F77" | $SED "$delay_single_quote_subst"`'
hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_F77='`$ECHO "$hardcode_automatic_F77" | $SED "$delay_single_quote_subst"`'
inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_F77='`$ECHO "$inherit_rpath_F77" | $SED "$delay_single_quote_subst"`'
link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_F77='`$ECHO "$link_all_deplibs_F77" | $SED "$delay_single_quote_subst"`'
always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_F77='`$ECHO "$always_export_symbols_F77" | $SED "$delay_single_quote_subst"`'
export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_F77='`$ECHO "$export_symbols_cmds_F77" | $SED "$delay_single_quote_subst"`'
exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_F77='`$ECHO "$exclude_expsyms_F77" | $SED "$delay_single_quote_subst"`'
include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_F77='`$ECHO "$include_expsyms_F77" | $SED "$delay_single_quote_subst"`'
prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_F77='`$ECHO "$prelink_cmds_F77" | $SED "$delay_single_quote_subst"`'
postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_F77='`$ECHO "$postlink_cmds_F77" | $SED "$delay_single_quote_subst"`'
file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_F77='`$ECHO "$file_list_spec_F77" | $SED "$delay_single_quote_subst"`'
hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_F77='`$ECHO "$hardcode_action_F77" | $SED "$delay_single_quote_subst"`'
compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_F77='`$ECHO "$compiler_lib_search_dirs_F77" | $SED "$delay_single_quote_subst"`'
predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_F77='`$ECHO "$predep_objects_F77" | $SED "$delay_single_quote_subst"`'
postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_F77='`$ECHO "$postdep_objects_F77" | $SED "$delay_single_quote_subst"`'
predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_F77='`$ECHO "$predeps_F77" | $SED "$delay_single_quote_subst"`'
postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_F77='`$ECHO "$postdeps_F77" | $SED "$delay_single_quote_subst"`'
compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_F77='`$ECHO "$compiler_lib_search_path_F77" | $SED "$delay_single_quote_subst"`'
LTCC='$LTCC'
LTCFLAGS='$LTCFLAGS'
@@ -23448,30 +26989,55 @@ predeps \
postdeps \
compiler_lib_search_path \
LD_CXX \
+LD_F77 \
reload_flag_CXX \
+reload_flag_F77 \
compiler_CXX \
+compiler_F77 \
lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_no_builtin_flag_F77 \
lt_prog_compiler_pic_CXX \
+lt_prog_compiler_pic_F77 \
lt_prog_compiler_wl_CXX \
+lt_prog_compiler_wl_F77 \
lt_prog_compiler_static_CXX \
+lt_prog_compiler_static_F77 \
lt_cv_prog_compiler_c_o_CXX \
+lt_cv_prog_compiler_c_o_F77 \
export_dynamic_flag_spec_CXX \
+export_dynamic_flag_spec_F77 \
whole_archive_flag_spec_CXX \
+whole_archive_flag_spec_F77 \
compiler_needs_object_CXX \
+compiler_needs_object_F77 \
with_gnu_ld_CXX \
+with_gnu_ld_F77 \
allow_undefined_flag_CXX \
+allow_undefined_flag_F77 \
no_undefined_flag_CXX \
+no_undefined_flag_F77 \
hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_F77 \
hardcode_libdir_separator_CXX \
+hardcode_libdir_separator_F77 \
exclude_expsyms_CXX \
+exclude_expsyms_F77 \
include_expsyms_CXX \
+include_expsyms_F77 \
file_list_spec_CXX \
+file_list_spec_F77 \
compiler_lib_search_dirs_CXX \
+compiler_lib_search_dirs_F77 \
predep_objects_CXX \
+predep_objects_F77 \
postdep_objects_CXX \
+postdep_objects_F77 \
predeps_CXX \
+predeps_F77 \
postdeps_CXX \
-compiler_lib_search_path_CXX; do
+postdeps_F77 \
+compiler_lib_search_path_CXX \
+compiler_lib_search_path_F77; do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
@@ -23503,16 +27069,27 @@ finish_cmds \
sys_lib_search_path_spec \
sys_lib_dlsearch_path_spec \
reload_cmds_CXX \
+reload_cmds_F77 \
old_archive_cmds_CXX \
+old_archive_cmds_F77 \
old_archive_from_new_cmds_CXX \
+old_archive_from_new_cmds_F77 \
old_archive_from_expsyms_cmds_CXX \
+old_archive_from_expsyms_cmds_F77 \
archive_cmds_CXX \
+archive_cmds_F77 \
archive_expsym_cmds_CXX \
+archive_expsym_cmds_F77 \
module_cmds_CXX \
+module_cmds_F77 \
module_expsym_cmds_CXX \
+module_expsym_cmds_F77 \
export_symbols_cmds_CXX \
+export_symbols_cmds_F77 \
prelink_cmds_CXX \
-postlink_cmds_CXX; do
+prelink_cmds_F77 \
+postlink_cmds_CXX \
+postlink_cmds_F77; do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[\\\\\\\`\\"\\\$]*)
eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
@@ -23545,6 +27122,8 @@ fi
+
+
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
@@ -23600,6 +27179,7 @@ do
"test/MapReduce.test") CONFIG_FILES="$CONFIG_FILES test/MapReduce.test" ;;
"test/Ninfo.test") CONFIG_FILES="$CONFIG_FILES test/Ninfo.test" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "src/lib/ncl/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/ncl/Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;;
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
@@ -24344,7 +27924,7 @@ $as_echo X"$file" |
# The names of the tagged configurations supported by this script.
-available_tags="CXX "
+available_tags="CXX F77 "
# ### BEGIN LIBTOOL CONFIG
@@ -25090,6 +28670,159 @@ compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
# ### END LIBTOOL TAG CONFIG: CXX
_LT_EOF
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: F77
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_F77
+reload_cmds=$lt_reload_cmds_F77
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_F77
+
+# A language specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_F77
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_F77
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_F77
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_F77
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_F77
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_F77
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_F77
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_F77
+postdep_objects=$lt_postdep_objects_F77
+predeps=$lt_predeps_F77
+postdeps=$lt_postdeps_F77
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+
+# ### END LIBTOOL TAG CONFIG: F77
+_LT_EOF
+
;;
"test/File.test":F) chmod a+x "$ac_file" ;;
"test/Read_grib.test":F) chmod a+x "$ac_file" ;;
diff --git a/configure.ac b/configure.ac
index 0e21606..c5bcd2f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
# autoconf 2.68
# libtool 2.4.2
-AC_INIT([cdo], [1.9.1], [http://mpimet.mpg.de/cdo])
+AC_INIT([cdo], [1.9.2rc1], [http://mpimet.mpg.de/cdo])
AC_DEFINE_UNQUOTED(CDO, ["$PACKAGE_VERSION"], [CDO version])
@@ -34,6 +34,7 @@ AC_CHECK_TOOL([CXX],[g++],[:])
AC_PROG_CC_C99
AM_PROG_CC_C_O
AC_PROG_CXX
+AC_PROG_F77
AC_C_RESTRICT
AX_CXX_COMPILE_STDCXX_11
AC_OPENMP
@@ -51,6 +52,7 @@ AC_PROG_INSTALL
#
FC=no
export FC
+#
# ----------------------------------------------------------------------
# Check large file support on 32 bit system
AC_SYS_LARGEFILE
@@ -104,12 +106,21 @@ case "$CC" in
*) C_VERSION=`$CC -V 2>&1 | head -n 1 | grep -v error`;;
esac
+case "$F77" in
+ pgf*) F77_VERSION=`$F77 -V | head -2 | tail -n 1`;;
+ gfortran*) F77_VERSION=`$F77 --version | head -n 1`;;
+ *) F77_VERSION=`$F77 -V 2>&1 | head -n 1 | grep -v error`;;
+esac
+
if test -z "$CXX_VERSION" ; then CXX_VERSION="unknown"; fi;
AC_DEFINE_UNQUOTED(CXX_VERSION, ["$CXX_VERSION"], [CXX Compiler version])
if test -z "$C_VERSION" ; then C_VERSION="unknown"; fi;
AC_DEFINE_UNQUOTED(C_VERSION, ["$C_VERSION"], [C Compiler version])
+if test -z "$F77_VERSION" ; then F77_VERSION="unknown"; fi;
+AC_DEFINE_UNQUOTED(F77_VERSION, ["$F77_VERSION"], [F77 Compiler version])
+
# Checks for username, hostname and system type
USERNAME=$LOGNAME
if test -z "$USERNAME" ; then USERNAME=$USER; fi;
@@ -138,16 +149,50 @@ AC_CHECK_FUNCS(sqrtl)
AC_CHECK_FUNCS(feenableexcept)
#
AC_CHECK_MEMBERS([fenv_t.__control, fenv_t.__mxcsr],,,[[#include <fenv.h>]])
+
+# ----------------------------------------------------------------------
+# Create the Interface to Fortran77 routines via cfortran.h
+AC_ARG_ENABLE([fortran],
+ [AS_HELP_STRING([--disable-fortran],
+ [Omit building of Fortran routines])],
+ [enable_fortran=${enableval}],[enable_fortran=yes])
+AS_IF([test "x${enable_fortran}" = "xyes"], [
+dnl ######################################################################
+dnl Test whether cfortran.h works correctly
+dnl ######################################################################
+ACX_FIND_CFORTRAN_DEF
+ACX_XLF_QEXTNAME_ADD_APPENDUS
+AS_IF([test -n "$F77" -a X"$F77" != Xno],
+ [ACX_CHECK_CFORTRAN([$srcdir/src],
+ [AC_DEFINE([HAVE_CF_INTERFACE],[1],
+ [Defined to 1 if C / Fortran interface cfortran.h works])],
+ [AS_CASE([x"$acx_cv_cfortran_works"],
+ [x"error"],
+ [AC_MSG_NOTICE([Linking/Running with C EXTERNAL built with cfortran.h does not work!])],
+ [x"compiling with cfortran.h failed"],
+ [AC_MSG_NOTICE([Compilation with cfortran.h is not working!])],
+ [x"error compiling Fortran subroutine"],
+ [AC_MSG_NOTICE([compilation of simple Fortran source failed!])],
+ [AC_MSG_NOTICE([Unexpected error when linking C and Fortran via cfortran.h!])])
+ AC_MSG_NOTICE([Disabling cfortran.h bindings generation])
+ acx_cv_cfortran_works=no])])
+])
+AS_IF([test x$enable_fortran = 'xno'],[AC_SUBST([ENABLE_FORTRAN],[false])],[AC_SUBST([ENABLE_FORTRAN],[true])])
+#
+AM_CONDITIONAL([USE_F77],[test -n "$F77" -a X"$F77" != Xno -a x"$acx_cv_cfortran_works" = xyes])
+AS_IF([test x$acx_cv_cfortran_works = 'xno'],[AC_SUBST([FORTRAN_WORKS],[no])],[AC_SUBST([FORTRAN_WORKS],[yes])])
+# ----------------------------------------------------------------------
+
# ----------------------------------------------------------------------
# Enable NEARPT3 support
-# AC_MSG_CHECKING([for nearpt3 support])
-# AC_ARG_ENABLE([nearpt3], AS_HELP_STRING([--enable-nearpt3],[nearpt3 support [default=no]]))
-# AS_IF([test "x$enable_nearpt3" = "xyes"], [
-# AC_DEFINE(ENABLE_NEARPT3, [1], [Define to 1 for nearpt3 support])
-# ])
-# AC_MSG_RESULT([$enable_nearpt3])
-# AC_SUBST([ENABLE_NEARPT3],[$enable_nearpt3])
-# AM_CONDITIONAL([ENABLE_NEARPT3],[test x$enable_nearpt3 = 'xyes'])
+AC_MSG_CHECKING([for nearpt3 support])
+AC_ARG_ENABLE([nearpt3], AS_HELP_STRING([--enable-nearpt3],[nearpt3 support [default=no]]))
+AS_IF([test "x$enable_nearpt3" = "xyes"], [
+ AC_DEFINE(ENABLE_NEARPT3, [1], [Define to 1 for nearpt3 support])
+])
+AC_MSG_RESULT([$enable_nearpt3])
+AC_SUBST([ENABLE_NEARPT3],[$enable_nearpt3])
+AM_CONDITIONAL([ENABLE_NEARPT3],[test x$enable_nearpt3 = 'xyes'])
# ----------------------------------------------------------------------
# Enable DATA support
AC_MSG_CHECKING([for DATA support])
@@ -156,7 +201,7 @@ AS_IF([test "x$enable_data" != 'xno'], [
AC_DEFINE(ENABLE_DATA, [1], [Define to 1 for DATA support])
])
AC_MSG_RESULT([$enable_data])
-AC_SUBST([ENABLE_DATA],[$enable_data])
+AS_IF([test x$enable_data = 'xno'],[AC_SUBST([ENABLE_DATA],[false])],[AC_SUBST([ENABLE_DATA],[true])])
# ----------------------------------------------------------------------
CFLAGS="$CFLAGS ${OPENMP_CFLAGS}"
CXXFLAGS="$CXXFLAGS ${OPENMP_CFLAGS}"
@@ -165,8 +210,6 @@ CXXFLAGS="$CXXFLAGS ${OPENMP_CFLAGS}"
# Add configure options
ACX_OPTIONS
-# ----------------------------------------------------------------------
-
# configure code from valgrind
# does the x86/amd64 assembler understand SSE 4.2 instructions?
@@ -242,7 +285,7 @@ AM_CONDITIONAL(BUILD_AVX2_TESTS, test x$ac_have_as_avx2 = xyes)
# ----------------------------------------------------------------------
AC_SUBST([CXXFLAGS])
AC_SUBST([CPPFLAGS])
-AC_SUBST([FCFLAGS])
+AC_SUBST([FFLAGS])
AC_SUBST([CLDFLAGS])
AC_SUBST([CLIBS])
#AC_SUBST([INCLUDES])
@@ -254,6 +297,8 @@ C_COMPILER="$CC $CFLAGS"
AC_DEFINE_UNQUOTED(C_COMPILER, ["$C_COMPILER"], [C Compiler])
CXX_COMPILER="$CXX $CXXFLAGS"
AC_DEFINE_UNQUOTED(CXX_COMPILER, ["$CXX_COMPILER"], [CXX Compiler])
+F77_COMPILER="$F77 $FFLAGS"
+AC_DEFINE_UNQUOTED(F77_COMPILER, ["$F77_COMPILER"], [F77 Compiler])
AC_REQUIRE_AUX_FILE([tap-driver.sh])
AC_PROG_AWK
@@ -268,7 +313,7 @@ AC_CONFIG_FILES([test/Merstat.test test/Zonstat.test test/Mergetime.test],[chmod
AC_CONFIG_FILES([test/Afterburner.test test/Detrend.test test/Arithc.test test/Arith.test test/Expr.test],[chmod a+x "$ac_file"])
AC_CONFIG_FILES([test/Gradsdes.test test/Collgrid.test test/threads.test test/tsformat.test test/wildcard.test],[chmod a+x "$ac_file"])
AC_CONFIG_FILES([test/MapReduce.test test/Ninfo.test],[chmod a+x "$ac_file"])
-AC_CONFIG_FILES([Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings])
+AC_CONFIG_FILES([Makefile src/lib/ncl/Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings])
AC_OUTPUT
# ----------------------------------------------------------------------
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
index a9577ba..e41e590 100644
--- a/contrib/Makefile.in
+++ b/contrib/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -78,10 +88,10 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = contrib
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs COPYING
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -90,6 +100,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -114,6 +125,8 @@ am__can_run_installinfo = \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/config/mkinstalldirs COPYING
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -156,18 +169,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -243,6 +260,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -307,7 +325,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign contrib/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -484,6 +501,8 @@ uninstall-am:
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
uninstall-am
+.PRECIOUS: Makefile
+
completions:
if hash ruby >/dev/null 2>&1 ; then \
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index 4bc3ce8..4ab1698 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -8,7 +8,6 @@ complete -W "
--percentile \
--precision \
--reduce_dim \
---remap_genweights \
--sortname \
--timestat_date \
-C, \
@@ -693,7 +692,9 @@ tstepcount -tstepcount \
unsetgridmask -unsetgridmask \
usegridnumber -usegridnumber \
uv2dv -uv2dv \
+uv2dv_cfd -uv2dv_cfd \
uv2dvl -uv2dvl \
+uv2vr_cfd -uv2vr_cfd \
uvDestag -uvDestag \
vardes -vardes \
varquot2test -varquot2test \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index 73da97f..f15535c 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -8,7 +8,6 @@ set cdoCmpl = (\
-percentile \
-precision \
-reduce_dim \
--remap_genweights \
-sortname \
-timestat_date \
C, \
@@ -693,7 +692,9 @@ tstepcount \
unsetgridmask \
usegridnumber \
uv2dv \
+uv2dv_cfd \
uv2dvl \
+uv2vr_cfd \
uvDestag \
vardes \
varquot2test \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index 8179992..3547109 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -8,7 +8,6 @@ compctl -k "(
--percentile \
--precision \
--reduce_dim \
---remap_genweights \
--sortname \
--timestat_date \
-C, \
@@ -693,7 +692,9 @@ tstepcount -tstepcount \
unsetgridmask -unsetgridmask \
usegridnumber -usegridnumber \
uv2dv -uv2dv \
+uv2dv_cfd -uv2dv_cfd \
uv2dvl -uv2dvl \
+uv2vr_cfd -uv2vr_cfd \
uvDestag -uvDestag \
vardes -vardes \
varquot2test -varquot2test \
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index 582f288..f2b53c4 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_cmor.pdf b/doc/cdo_cmor.pdf
index a7d3022..5a1fdf0 100644
Binary files a/doc/cdo_cmor.pdf and b/doc/cdo_cmor.pdf differ
diff --git a/doc/cdo_eca.pdf b/doc/cdo_eca.pdf
index 9478a28..49b17e2 100644
Binary files a/doc/cdo_eca.pdf and b/doc/cdo_eca.pdf differ
diff --git a/doc/cdo_magics.pdf b/doc/cdo_magics.pdf
index 641c3d4..c94fe9f 100644
Binary files a/doc/cdo_magics.pdf and b/doc/cdo_magics.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index 554fb87..de51b2f 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index 54014e4..29ed032 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,11 @@
+2017-11-05 Uwe Schulzweida
+
+ * Version 1.9.2 released
+
+2017-10-09 Uwe Schulzweida
+
+ * changed type of gridsize from int to size_t
+
2017-10-05 Uwe Schulzweida
* using CGRIBEX library version 1.9.0
diff --git a/libcdi/Makefile.in b/libcdi/Makefile.in
index 93e11e7..1a630ff 100644
--- a/libcdi/Makefile.in
+++ b/libcdi/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -78,21 +88,6 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/configure $(am__configure_deps) \
- $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/tables/gen_tableheaderfile.in \
- $(top_srcdir)/util/serialrun.in $(srcdir)/cdi.settings.in \
- $(top_srcdir)/src/pkgconfig/cdi.pc.in \
- $(top_srcdir)/src/pkgconfig/cdipio.pc.in AUTHORS COPYING \
- ChangeLog INSTALL NEWS README config/compile \
- config/config.guess config/config.sub config/depcomp \
- config/install-sh config/missing config/mkinstalldirs \
- config/ltmain.sh $(top_srcdir)/config/compile \
- $(top_srcdir)/config/config.guess \
- $(top_srcdir)/config/config.sub \
- $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
- $(top_srcdir)/config/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -124,6 +119,8 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -187,6 +184,19 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/cdi.settings.in \
+ $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \
+ $(top_srcdir)/config/config.sub \
+ $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
+ $(top_srcdir)/config/missing \
+ $(top_srcdir)/config/mkinstalldirs \
+ $(top_srcdir)/src/pkgconfig/cdi.pc.in \
+ $(top_srcdir)/src/pkgconfig/cdipio.pc.in \
+ $(top_srcdir)/tables/gen_tableheaderfile.in \
+ $(top_srcdir)/util/serialrun.in AUTHORS COPYING ChangeLog \
+ INSTALL NEWS README config/compile config/config.guess \
+ config/config.sub config/depcomp config/install-sh \
+ config/ltmain.sh config/missing config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -450,7 +460,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -660,7 +669,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@@ -676,17 +685,17 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@@ -704,7 +713,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@@ -714,22 +723,23 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_inst
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -906,6 +916,8 @@ uninstall-am:
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
#
doc/cdi_cman.pdf:
(cd $(top_srcdir)/doc/tex ; ./makepdf_c ; mv cdi_cman.pdf .. ; ./cleanup)
diff --git a/libcdi/aclocal.m4 b/libcdi/aclocal.m4
index 74a336f..ca9ecf4 100644
--- a/libcdi/aclocal.m4
+++ b/libcdi/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.14 -*- Autoconf -*-
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,13 +14,13 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
-[m4_warning([this file was generated for autoconf 2.68.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.14'
+[am__api_version='1.15'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.14], [],
+m4_if([$1], [1.15.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.14])dnl
+[AM_AUTOMAKE_VERSION([1.15.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -103,15 +103,14 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -142,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -333,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -409,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -499,8 +498,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -573,7 +572,11 @@ to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
-fi])
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -602,7 +605,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -613,7 +616,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -623,7 +626,7 @@ if test x"${install_sh}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -645,7 +648,7 @@ AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -680,7 +683,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -730,7 +733,7 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -769,7 +772,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -798,7 +801,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -845,7 +848,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -864,7 +867,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -945,7 +948,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1005,7 +1008,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1033,7 +1036,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1052,7 +1055,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
diff --git a/libcdi/app/Makefile.in b/libcdi/app/Makefile.in
index f3c05a5..9d99541 100644
--- a/libcdi/app/Makefile.in
+++ b/libcdi/app/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -83,9 +93,6 @@ noinst_PROGRAMS = $(am__EXEEXT_2) createtable$(EXEEXT)
@ENABLE_CDI_LIB_TRUE at am__append_1 = cdi
@ENABLE_CDI_LIB_FALSE at am__append_2 = cdi
subdir = app
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -117,6 +124,7 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -201,6 +209,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -416,7 +426,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign app/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign app/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -745,6 +754,8 @@ uninstall-am: uninstall-binPROGRAMS
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+.PRECIOUS: Makefile
+
#
clean-local: clean-local-dirs
.PHONY: clean-local-dirs
diff --git a/libcdi/app/cdi.c b/libcdi/app/cdi.c
index 701a204..87526c6 100644
--- a/libcdi/app/cdi.c
+++ b/libcdi/app/cdi.c
@@ -184,10 +184,10 @@ void usage(void)
static
void printInfo(int vdate, int vtime, char *varname, double level,
- int datasize, int number, int nmiss, double missval, const double *data, int vardis)
+ size_t datasize, int number, size_t nmiss, double missval, const double *data, int vardis)
{
static int rec = 0;
- int i, ivals = 0, imiss = 0;
+ size_t ivals = 0, imiss = 0;
double arrmean, arrmin, arrmax;
char vdatestr[32], vtimestr[32];
@@ -208,9 +208,9 @@ void printInfo(int vdate, int vtime, char *varname, double level,
fprintf(stdout, "%6d :%s %s %7g ", ++rec, vdatestr, vtimestr, level);
- fprintf(stdout, "%8d ", datasize);
+ fprintf(stdout, "%8zu ", datasize);
- fprintf(stdout, "%7d :", nmiss);
+ fprintf(stdout, "%7zu :", nmiss);
if ( number == CDI_REAL )
{
@@ -219,7 +219,7 @@ void printInfo(int vdate, int vtime, char *varname, double level,
arrmean = 0;
arrmin = 1.e300;
arrmax = -1.e300;
- for ( i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
{
if ( !DBL_IS_EQUAL(data[i], missval) )
{
@@ -237,7 +237,7 @@ void printInfo(int vdate, int vtime, char *varname, double level,
arrmean = data[0];
arrmin = data[0];
arrmax = data[0];
- for ( i = 1; i < datasize; i++ )
+ for ( size_t i = 1; i < datasize; i++ )
{
if ( data[i] < arrmin ) arrmin = data[i];
if ( data[i] > arrmax ) arrmax = data[i];
@@ -251,10 +251,10 @@ void printInfo(int vdate, int vtime, char *varname, double level,
}
else
{
- int nvals_r = 0, nvals_i = 0;
+ size_t nvals_r = 0, nvals_i = 0;
double arrsum_r = 0, arrsum_i = 0, arrmean_r = 0, arrmean_i = 0;
- for ( i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
{
if ( !DBL_IS_EQUAL(data[i*2], missval) )
{
@@ -278,7 +278,7 @@ void printInfo(int vdate, int vtime, char *varname, double level,
fprintf(stdout, " : %-14s\n", varname);
if ( imiss != nmiss && nmiss > 0 )
- fprintf(stdout, "Found %d of %d missing values!\n", imiss, nmiss);
+ fprintf(stdout, "Found %zu of %zu missing values!\n", imiss, nmiss);
}
static const char *tunit2str(int tunits)
@@ -406,8 +406,8 @@ void printShortinfo(int streamID, int vlistID, int vardis)
fprintf(stdout, "%3d ", vlistZaxisIndex(vlistID, zaxisID) + 1);
/* grid info */
- int gridsize = gridInqSize(gridID);
- fprintf(stdout, "%9d ", gridsize);
+ size_t gridsize = gridInqSize(gridID);
+ fprintf(stdout, "%9zu ", gridsize);
fprintf(stdout, "%3d ", vlistGridIndex(vlistID, gridID) + 1);
/* datatype */
@@ -836,9 +836,9 @@ int main(int argc, char *argv[])
if ( fname1 )
{
- int nmiss;
+ size_t nmiss;
int number;
- int datasize = 0;
+ size_t datasize = 0;
int streamID2 = CDI_UNDEFID;
int filetype;
int gridID, zaxisID;
@@ -846,7 +846,7 @@ int main(int argc, char *argv[])
int nrecs;
int levelID, levelsize;
int nts = 0;
- int gridsize = 0;
+ size_t gridsize = 0;
int recID;
int taxisID2 = CDI_UNDEFID;
int vlistID2 = CDI_UNDEFID;
@@ -911,7 +911,7 @@ int main(int argc, char *argv[])
}
if ( vlistNumber(vlistID1) != CDI_REAL ) datasize *= 2;
- double *data = (double *) malloc((size_t)datasize * sizeof (double));
+ double *data = (double *) malloc(datasize * sizeof (double));
/*
nts = cdiInqTimeSize(streamID1);
@@ -925,6 +925,7 @@ int main(int argc, char *argv[])
printShortinfo(streamID1, vlistID1, Vardis);
}
+ size_t idum;
int tsID = 0;
if ( Info || fname2 )
while ( (nrecs = streamInqTimestep(streamID1, tsID)) > 0 )
@@ -945,7 +946,8 @@ int main(int argc, char *argv[])
for ( recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
- streamReadRecord(streamID1, data, &nmiss);
+ streamReadRecord(streamID1, data, &idum);
+ nmiss = idum;
number = vlistInqVarNumber(vlistID1, varID);
gridID = vlistInqVarGrid(vlistID1, varID);
@@ -973,7 +975,7 @@ int main(int argc, char *argv[])
if ( Move )
streamCopyRecord(streamID2, streamID1);
else
- streamWriteRecord(streamID2, data, nmiss);
+ streamWriteRecord(streamID2, data, idum);
}
}
}
@@ -1004,7 +1006,8 @@ int main(int argc, char *argv[])
for ( levelID = 0; levelID < levelsize; levelID++ )
{
double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
- streamReadVarSlice(streamID1, varID, levelID, data, &nmiss);
+ streamReadVarSlice(streamID1, varID, levelID, data, &idum);
+ nmiss = idum;
if ( Info )
printInfo(vdate, vtime, varname, level, gridsize, number, nmiss, missval, data, Vardis);
diff --git a/libcdi/configure b/libcdi/configure
index 436c24f..c453347 100755
--- a/libcdi/configure
+++ b/libcdi/configure
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdi 1.9.1.
+# Generated by GNU Autoconf 2.69 for cdi 1.9.2.
#
# Report bugs to <http://mpimet.mpg.de/cdi>.
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -222,21 +246,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -339,6 +367,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -460,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -494,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -515,28 +555,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -570,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='cdi'
PACKAGE_TARNAME='cdi'
-PACKAGE_VERSION='1.9.1'
-PACKAGE_STRING='cdi 1.9.1'
+PACKAGE_VERSION='1.9.2'
+PACKAGE_STRING='cdi 1.9.2'
PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdi'
PACKAGE_URL=''
@@ -1379,8 +1399,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1466,7 +1484,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures cdi 1.9.1 to adapt to many kinds of systems.
+\`configure' configures cdi 1.9.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1536,7 +1554,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of cdi 1.9.1:";;
+ short | recursive ) echo "Configuration of cdi 1.9.2:";;
esac
cat <<\_ACEOF
@@ -1735,10 +1753,10 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-cdi configure 1.9.1
-generated by GNU Autoconf 2.68
+cdi configure 1.9.2
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1928,7 +1946,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2188,7 +2206,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2234,7 +2252,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2280,7 +2298,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2580,8 +2598,8 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by cdi $as_me 1.9.1, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+It was created by cdi $as_me 1.9.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3046,7 +3064,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-am__api_version='1.14'
+am__api_version='1.15'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -3085,7 +3103,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -3218,8 +3236,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -3238,7 +3256,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -3269,7 +3287,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3309,7 +3327,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3360,7 +3378,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -3407,7 +3425,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3532,7 +3550,7 @@ fi
# Define the identity of the package.
PACKAGE='cdi'
- VERSION='1.9.1'
+ VERSION='1.9.2'
cat >>confdefs.h <<_ACEOF
@@ -3566,8 +3584,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -3624,6 +3642,7 @@ END
as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
fi
fi
+
ac_config_headers="$ac_config_headers src/config.h"
@@ -3668,7 +3687,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3708,7 +3727,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3828,7 +3847,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3868,7 +3887,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3921,7 +3940,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3962,7 +3981,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -4020,7 +4039,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4064,7 +4083,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4510,8 +4529,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4929,7 +4947,7 @@ main ()
return 0;
}
_ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
do
CC="$ac_save_CC $ac_arg"
if ac_fn_c_try_compile "$LINENO"; then :
@@ -5061,7 +5079,7 @@ ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_fc_compiler_gnu
if test -n "$ac_tool_prefix"; then
- for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
+ for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -5079,7 +5097,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_FC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5105,7 +5123,7 @@ fi
fi
if test -z "$FC"; then
ac_ct_FC=$FC
- for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
+ for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -5123,7 +5141,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_FC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5256,6 +5274,11 @@ else
fi
fi
+if test $ac_compiler_gnu = yes; then
+ GFC=yes
+else
+ GFC=
+fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5277,7 +5300,11 @@ else
ac_fcflags_srcext_save=$ac_fcflags_srcext
ac_fcflags_srcext=
ac_cv_fc_srcext_f90=unknown
-for ac_flag in none -qsuffix=f=f90 -Tf; do
+case $ac_ext in #(
+ [fF]77) ac_try=f77;; #(
+ *) ac_try=f95;;
+esac
+for ac_flag in none -qsuffix=f=f90 -Tf "-x $ac_try"; do
test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
cat > conftest.$ac_ext <<_ACEOF
program conftest
@@ -6041,7 +6068,7 @@ ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_f77_compiler_gnu
if test -n "$ac_tool_prefix"; then
- for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -6059,7 +6086,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6085,7 +6112,7 @@ fi
fi
if test -z "$F77"; then
ac_ct_F77=$F77
- for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -6103,7 +6130,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_F77="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6275,7 +6302,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6319,7 +6346,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6849,7 +6876,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -6925,7 +6952,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -6991,7 +7018,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -7058,7 +7085,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -7314,7 +7341,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7358,7 +7385,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7782,7 +7809,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7822,7 +7849,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8128,7 +8155,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8168,7 +8195,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DLLTOOL="dlltool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8271,7 +8298,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8315,7 +8342,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8440,7 +8467,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8480,7 +8507,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8539,7 +8566,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8579,7 +8606,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9228,7 +9255,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9268,7 +9295,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9348,7 +9375,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9388,7 +9415,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9440,7 +9467,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9480,7 +9507,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9532,7 +9559,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9572,7 +9599,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9624,7 +9651,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9664,7 +9691,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9716,7 +9743,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9756,7 +9783,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -23318,16 +23345,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -23387,28 +23414,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -23449,8 +23464,8 @@ Usage: $0 [OPTIONS]
Report bugs to <bug-libtool at gnu.org>."
lt_cl_version="\
-cdi config.lt 1.9.1
-configured by $0, generated by GNU Autoconf 2.68.
+cdi config.lt 1.9.2
+configured by $0, generated by GNU Autoconf 2.69.
Copyright (C) 2011 Free Software Foundation, Inc.
This config.lt script is free software; the Free Software Foundation
@@ -25586,6 +25601,8 @@ _ACEOF
esac
rm -rf conftest*
fi
+
+
fi
# ----------------------------------------------------------------------
@@ -26553,7 +26570,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ax_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -26745,7 +26762,7 @@ fi
#handle absolute path differently from PATH based program lookup
case "x$CC" in #(
x/*) :
- if { test -f ${CC}_r && $as_test_x ${CC}_r; }; then :
+ if as_fn_executable_p ${CC}_r; then :
PTHREAD_CC="${CC}_r"
fi ;; #(
*) :
@@ -26767,7 +26784,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PTHREAD_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27188,7 +27205,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NC_CONFIG="nc-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27362,7 +27379,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NC_CONFIG="$NETCDF_ROOT/bin/nc-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -28702,7 +28719,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -28745,7 +28762,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -28819,7 +28836,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_MPI_LAUNCH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -29161,7 +29178,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RUBY="ruby"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -29451,7 +29468,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_SWIG="swig"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -29555,7 +29572,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PYTHON="python"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -30697,16 +30714,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -30766,28 +30783,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -30808,8 +30813,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by cdi $as_me 1.9.1, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+This file was extended by cdi $as_me 1.9.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -30874,11 +30879,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-cdi config.status 1.9.1
-configured by $0, generated by GNU Autoconf 2.68,
+cdi config.status 1.9.2
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -30969,7 +30974,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
diff --git a/libcdi/configure.ac b/libcdi/configure.ac
index eea364f..8aac01a 100644
--- a/libcdi/configure.ac
+++ b/libcdi/configure.ac
@@ -4,7 +4,7 @@
# autoconf 2.68
# libtool 2.4.2
-AC_INIT([cdi], [1.9.1], [http://mpimet.mpg.de/cdi])
+AC_INIT([cdi], [1.9.2], [http://mpimet.mpg.de/cdi])
AC_DEFINE_UNQUOTED(CDI, ["$PACKAGE_VERSION"], [CDI version])
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 2e09c38..7f864f3 100644
Binary files a/libcdi/doc/cdi_cman.pdf and b/libcdi/doc/cdi_cman.pdf differ
diff --git a/libcdi/doc/cdi_fman.pdf b/libcdi/doc/cdi_fman.pdf
index 85d3e4d..9a1ecc6 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/examples/Makefile.in b/libcdi/examples/Makefile.in
index efcfe5f..f414a4c 100644
--- a/libcdi/examples/Makefile.in
+++ b/libcdi/examples/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -85,9 +95,6 @@ noinst_PROGRAMS = cdi_write$(EXEEXT) cdi_write_relativ$(EXEEXT) \
@CREATE_ISOC_TRUE at am__append_1 = cdi_read_f2003 cdi_write_f2003
@ENABLE_NETCDF_TRUE at am__append_2 = cdi_write_const
subdir = examples
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp README
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -119,6 +126,7 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -267,6 +275,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs README
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -504,7 +514,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign examples/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -821,6 +830,8 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
cdi_read_f2003.$(OBJEXT): $(top_builddir)/src/mo_cdi.$(FCMODEXT)
cdi_write_f2003.$(OBJEXT): $(top_builddir)/src/mo_cdi.$(FCMODEXT)
#
diff --git a/libcdi/examples/cdi_copy.c b/libcdi/examples/cdi_copy.c
index 3de9a1c..fd63393 100644
--- a/libcdi/examples/cdi_copy.c
+++ b/libcdi/examples/cdi_copy.c
@@ -7,7 +7,7 @@ int main(void)
const int nlat = 6; // Number of latitudes
const int nlev = 5; // Number of levels
const int nts = 3; // Number of time steps
- int nmiss;
+ size_t nmiss;
double var1[nlon*nlat];
double var2[nlon*nlat*nlev];
diff --git a/libcdi/examples/cdi_read.c b/libcdi/examples/cdi_read.c
index 9c1d238..395bc2a 100644
--- a/libcdi/examples/cdi_read.c
+++ b/libcdi/examples/cdi_read.c
@@ -7,7 +7,7 @@ int main(void)
const int nlat = 6; // Number of latitudes
const int nlev = 5; // Number of levels
const int nts = 3; // Number of time steps
- int nmiss, vdate, vtime;
+ size_t nmiss;
double var1[nlon*nlat];
double var2[nlon*nlat*nlev];
@@ -37,8 +37,8 @@ int main(void)
streamInqTimestep(streamID, tsID);
// Get the verification date and time
- vdate = taxisInqVdate(taxisID);
- vtime = taxisInqVtime(taxisID);
+ int vdate = taxisInqVdate(taxisID);
+ int vtime = taxisInqVtime(taxisID);
printf("read timestep %d: date=%d time=%d\n", tsID+1, vdate, vtime);
// Read var1 and var2
diff --git a/libcdi/examples/cdi_read_f2003.f90 b/libcdi/examples/cdi_read_f2003.f90
index 1281e1b..3cfd36f 100644
--- a/libcdi/examples/cdi_read_f2003.f90
+++ b/libcdi/examples/cdi_read_f2003.f90
@@ -4,8 +4,9 @@ PROGRAM CDIREADF2003
IMPLICIT NONE
- INTEGER :: gsize, nlevel, nvars, code
- INTEGER :: vdate, vtime, nmiss, status, ilev
+ INTEGER(c_size_t) :: gsize, nmiss
+ INTEGER :: nlevel, nvars, code
+ INTEGER :: vdate, vtime, status, ilev
INTEGER :: streamID, varID, gridID, zaxisID
INTEGER :: tsID, vlistID, taxisID
DOUBLE PRECISION, ALLOCATABLE :: field(:,:)
diff --git a/libcdi/examples/cdi_write.c b/libcdi/examples/cdi_write.c
index acc1500..e99698d 100644
--- a/libcdi/examples/cdi_write.c
+++ b/libcdi/examples/cdi_write.c
@@ -7,7 +7,7 @@ int main(void)
const int nlat = 6; // Number of latitudes
const int nlev = 5; // Number of levels
const int nts = 3; // Number of time steps
- int nmiss = 0;
+ size_t nmiss = 0;
double lons[] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
double lats[] = {-75, -45, -15, 15, 45, 75};
double levs[] = {101300, 92500, 85000, 50000, 20000};
@@ -68,8 +68,8 @@ int main(void)
streamDefTimestep(streamID, tsID);
// Init var1 and var2
- for ( int i = 0; i < nlon*nlat; i++ ) var1[i] = 1.1;
- for ( int i = 0; i < nlon*nlat*nlev; i++ ) var2[i] = 2.2;
+ for ( size_t i = 0; i < nlon*nlat; i++ ) var1[i] = 1.1;
+ for ( size_t i = 0; i < nlon*nlat*nlev; i++ ) var2[i] = 2.2;
// Write var1 and var2
streamWriteVar(streamID, varID1, var1, nmiss);
diff --git a/libcdi/examples/cdi_write_const.c b/libcdi/examples/cdi_write_const.c
index 7520c6e..61c68a0 100644
--- a/libcdi/examples/cdi_write_const.c
+++ b/libcdi/examples/cdi_write_const.c
@@ -9,7 +9,7 @@ int main(void)
{
int gridID, zaxisID1, zaxisID2;
int vlistID, varID1, varID2, streamID;
- int i, nmiss = 0;
+ size_t i, nmiss = 0;
double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
double lats[nlat] = {-75, -45, -15, 15, 45, 75};
double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
diff --git a/libcdi/examples/cdi_write_ens.c b/libcdi/examples/cdi_write_ens.c
index 2fea3c9..3e5a5f0 100644
--- a/libcdi/examples/cdi_write_ens.c
+++ b/libcdi/examples/cdi_write_ens.c
@@ -18,7 +18,7 @@ int main(void)
int tsID;
int levelID;
int vlistID, taxisID;
- int nmiss;
+ size_t nmiss;
int instID;
int i1,i2,i3;
diff --git a/libcdi/examples/cdi_write_f2003.f90 b/libcdi/examples/cdi_write_f2003.f90
index 8c53a33..cf4ad53 100644
--- a/libcdi/examples/cdi_write_f2003.f90
+++ b/libcdi/examples/cdi_write_f2003.f90
@@ -5,7 +5,8 @@
IMPLICIT NONE
- INTEGER nlon, nlat, nlev, nts
+ INTEGER :: nlev, nts
+ INTEGER(c_size_t) :: nlon, nlat, nmiss
PARAMETER (nlon = 12) ! Number of longitudes
PARAMETER (nlat = 6) ! Number of latitudes
PARAMETER (nlev = 5) ! Number of levels
@@ -13,7 +14,7 @@
INTEGER gridID, zaxisID1, zaxisID2, taxisID
INTEGER vlistID, varID1, varID2, streamID, tsID
- INTEGER i, nmiss, status
+ INTEGER i, status
DOUBLE PRECISION lons(nlon), lats(nlat), levs(nlev)
DOUBLE PRECISION var1(nlon*nlat), var2(nlon*nlat*nlev)
CHARACTER(len=256, kind=c_char) :: varname
diff --git a/libcdi/examples/cdi_write_hybrid.c b/libcdi/examples/cdi_write_hybrid.c
index 24504c8..f9b9a90 100644
--- a/libcdi/examples/cdi_write_hybrid.c
+++ b/libcdi/examples/cdi_write_hybrid.c
@@ -10,8 +10,8 @@
int main(void)
{
int gridID, zaxisID1, zaxisID2, zaxisID3, zaxisID4, taxisID;
- int vlistID, varID1, varID2, varID3, varID4, streamID, tsID;
- int i, k, nmiss = 0;
+ int vlistID, varID1, varID2, varID3, varID4, streamID;
+ size_t nmiss = 0;
double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
double lats[nlat] = {-75, -45, -15, 15, 45, 75};
double levs[nhlev] = {1, 2, 3, 4, 5, 6};
@@ -83,7 +83,7 @@ int main(void)
streamDefVlist(streamID, vlistID);
// Loop over the number of time steps
- for ( tsID = 0; tsID < nts; tsID++ )
+ for ( int tsID = 0; tsID < nts; tsID++ )
{
// Set the verification date to 1985-01-01 + tsID
taxisDefVdate(taxisID, 19850101+tsID);
@@ -93,13 +93,13 @@ int main(void)
streamDefTimestep(streamID, tsID);
// Init var1 and var2
- for ( i = 0; i < nlon*nlat; ++i ) var1[i] = 1.1;
- for ( k = 0; k < nflev; ++k )
- for ( i = 0; i < nlon*nlat; ++i ) var2[i+k*nlon*nlat] = 2.2+k;
- for ( k = 0; k < nhlev; ++k )
- for ( i = 0; i < nlon*nlat; ++i ) var3[i+k*nlon*nlat] = -2.2-k;
- for ( k = 0; k < nflev; ++k )
- for ( i = 0; i < nlon*nlat; ++i ) var4[i+k*nlon*nlat] = 100+k;
+ for ( size_t i = 0; i < nlon*nlat; ++i ) var1[i] = 1.1;
+ for ( size_t k = 0; k < nflev; ++k )
+ for ( size_t i = 0; i < nlon*nlat; ++i ) var2[i+k*nlon*nlat] = 2.2+k;
+ for ( size_t k = 0; k < nhlev; ++k )
+ for ( size_t i = 0; i < nlon*nlat; ++i ) var3[i+k*nlon*nlat] = -2.2-k;
+ for ( size_t k = 0; k < nflev; ++k )
+ for ( size_t i = 0; i < nlon*nlat; ++i ) var4[i+k*nlon*nlat] = 100+k;
// Write var1 and var2
streamWriteVar(streamID, varID1, var1, nmiss);
diff --git a/libcdi/examples/pio/Makefile.in b/libcdi/examples/pio/Makefile.in
index ebd9c3f..2ab872d 100644
--- a/libcdi/examples/pio/Makefile.in
+++ b/libcdi/examples/pio/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -84,9 +94,6 @@ noinst_PROGRAMS = collectData$(EXEEXT) collectDataNStreams$(EXEEXT) \
@USE_MPI_TRUE at am__append_2 = $(FPP_DEFOPT)USE_MPI
@USE_FC_TRUE at am__append_3 = collectData2003
subdir = examples/pio
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -118,6 +125,7 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -243,6 +251,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -458,7 +468,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/pio/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign examples/pio/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -751,6 +760,8 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
#
clean-local: clean-local-dirs
.PHONY: clean-local-dirs
diff --git a/libcdi/interfaces/Makefile.in b/libcdi/interfaces/Makefile.in
index 38722a6..de0727f 100644
--- a/libcdi/interfaces/Makefile.in
+++ b/libcdi/interfaces/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -16,7 +16,17 @@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -90,9 +100,6 @@ noinst_PROGRAMS = $(am__EXEEXT_1)
# =========================================================
@ENABLE_PYTHON_TRUE at am__append_5 = pythonObj
subdir = interfaces
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -124,6 +131,7 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -227,6 +235,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -464,7 +474,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign interfaces/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign interfaces/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -803,6 +812,8 @@ uninstall-am: uninstall-binPROGRAMS
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+.PRECIOUS: Makefile
+
# Ruby ====================================================
@ENABLE_RUBY_TRUE at rubyLibMakefile:
@ENABLE_RUBY_TRUE@ cd ruby; CFLAGS="$(CFLAGS)" LIBS="$(LIBS)" LDFLAGS="$(locallibs) $(LDFLAGS)" INCFLAGS="-I../../src" ruby extconfLib.rb
diff --git a/libcdi/interfaces/cdi.cpp b/libcdi/interfaces/cdi.cpp
index 7d69e11..835ca2e 100644
--- a/libcdi/interfaces/cdi.cpp
+++ b/libcdi/interfaces/cdi.cpp
@@ -270,14 +270,13 @@ CdiVariable::sinfo() { std::cout << "code:" << std::endl; }
double *
CdiVariable::getValuesAsPointer()
{
- int levelID = 0, tsID = 0, nmiss;
- int vdate, vtime, nrecs;
- double *field;
-
- nrecs = streamInqTimestep(streamID, tsID);
- vdate = taxisInqVdate(taxisID);
- vtime = taxisInqVtime(taxisID);
- field = (double *) malloc(grid.size*sizeof(double));
+ int levelID = 0, tsID = 0;
+ size_t nmiss;
+
+ int nrecs = streamInqTimestep(streamID, tsID);
+ int vdate = taxisInqVdate(taxisID);
+ int vtime = taxisInqVtime(taxisID);
+ double *field = (double *) malloc(grid.size*sizeof(double));
streamReadVarSlice(streamID, varID, levelID, field, &nmiss);
return field;
@@ -286,7 +285,8 @@ CdiVariable::getValuesAsPointer()
double **
CdiVariable::getValuesWithLevelAsPointer(int tsID)
{
- int levelID, nmiss, nrecs;
+ int levelID, nrecs;
+ size_t nmiss;
double **fieldWithLevel, *field;
nrecs = streamInqTimestep(streamID, tsID);
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 4990e5f..f9c969b 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -16,7 +16,17 @@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -99,9 +109,6 @@ host_triplet = @host@
@ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_13 = pkgconfig/cdipio.pc
@ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_14 = pkgconfig/cdipio.pc
subdir = src
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(srcdir)/config.h.in $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp $(am__include_HEADERS_DIST)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -133,6 +140,8 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__include_HEADERS_DIST) \
+ $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
@@ -314,6 +323,9 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -594,7 +606,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -947,8 +958,8 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
- at ENABLE_CDI_LIB_FALSE@uninstall-local:
@ENABLE_CDI_LIB_FALSE at install-exec-local:
+ at ENABLE_CDI_LIB_FALSE@uninstall-local:
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -1043,6 +1054,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
tags tags-am uninstall uninstall-am uninstall-includeHEADERS \
uninstall-libLTLIBRARIES uninstall-local
+.PRECIOUS: Makefile
+
#
mo_cdi.f90: $(top_srcdir)/src/cdi.h $(top_srcdir)/interfaces/f2003/bindGen.rb
$(RUBY) $(top_srcdir)/interfaces/f2003/bindGen.rb $(top_srcdir)/src/cdi.h $@
diff --git a/libcdi/src/cdf_lazy_grid.c b/libcdi/src/cdf_lazy_grid.c
index d287df2..9b104fe 100644
--- a/libcdi/src/cdf_lazy_grid.c
+++ b/libcdi/src/cdf_lazy_grid.c
@@ -198,22 +198,22 @@ cdfLazyGridDefYVals(grid_t *grid, const double *vals)
}
static double
-cdfLazyGridInqXVal(grid_t *grid, int index)
+cdfLazyGridInqXVal(grid_t *grid, size_t index)
{
struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
lock_lazy_load(lazyGrid);
- double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->xValsGet,
+ double rv = cdfLazyGridInqXYVal(grid, index, &lazyGrid->xValsGet,
grid->x.vals, grid->vtable->inqXValsPtr);
unlock_lazy_load(lazyGrid);
return rv;
}
static double
-cdfLazyGridInqYVal(grid_t *grid, int index)
+cdfLazyGridInqYVal(grid_t *grid, size_t index)
{
struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
lock_lazy_load(lazyGrid);
- double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->yValsGet,
+ double rv = cdfLazyGridInqXYVal(grid, index, &lazyGrid->yValsGet,
grid->y.vals, grid->vtable->inqYValsPtr);
unlock_lazy_load(lazyGrid);
return rv;
diff --git a/libcdi/src/cdf_read.c b/libcdi/src/cdf_read.c
index fc72912..50c3de7 100644
--- a/libcdi/src/cdf_read.c
+++ b/libcdi/src/cdf_read.c
@@ -72,8 +72,8 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
} while(0)
if ( timetype != TIME_CONSTANT ) addDimension((size_t)tsID, 1);
if ( zid != CDI_UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
- if ( yid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
- if ( xid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
+ if ( yid != CDI_UNDEFID ) addDimension(0, gridInqYsize(gridID));
+ if ( xid != CDI_UNDEFID ) addDimension(0, gridInqXsize(gridID));
#undef addDimension
assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
@@ -421,7 +421,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
int gridId = vlistInqVarGrid(vlistId, varId);
int timetype = vlistInqVarTimetype(vlistId, varId);
- int gridsize = gridInqSize(gridId);
+ size_t gridsize = gridInqSize(gridId);
streamptr->numvals += gridsize;
@@ -487,7 +487,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
}
static
-void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void cdfReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -505,7 +505,7 @@ void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
cdf_get_vara_double(fileID, ncvarid, start, count, data);
- size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
+ size_t size = gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
@@ -519,7 +519,7 @@ void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
}
static
-void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
+void cdfReadVarSP(stream_t *streamptr, int varID, float *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -537,7 +537,7 @@ void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
cdf_get_vara_float(fileID, ncvarid, start, count, data);
- size_t size = (size_t)gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
+ size_t size = gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
@@ -551,7 +551,7 @@ void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
}
-void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss)
+void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss)
{
if ( memtype == MEMTYPE_DOUBLE )
cdfReadVarDP(streamptr, varID, (double*) data, nmiss);
@@ -560,7 +560,7 @@ void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *
}
static
-void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
+void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss)
{
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
@@ -574,9 +574,9 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
- size_t gridsize = (size_t)gridInqSize(gridId);
- size_t xsize = (size_t)gridInqXsize(gridId);
- size_t ysize = (size_t)gridInqYsize(gridId);
+ size_t gridsize = gridInqSize(gridId);
+ size_t xsize = gridInqXsize(gridId);
+ size_t ysize = gridInqYsize(gridId);
if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT32 )
{
@@ -617,7 +617,7 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
}
static
-void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss)
+void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, size_t *nmiss)
{
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
@@ -631,9 +631,9 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
- size_t gridsize = (size_t)gridInqSize(gridId);
- size_t xsize = (size_t)gridInqXsize(gridId);
- size_t ysize = (size_t)gridInqYsize(gridId);
+ size_t gridsize = gridInqSize(gridId);
+ size_t xsize = gridInqXsize(gridId);
+ size_t ysize = gridInqYsize(gridId);
if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT64 )
{
@@ -674,7 +674,7 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
}
-void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss)
+void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss)
{
if ( memtype == MEMTYPE_DOUBLE )
cdfReadVarSliceDP(streamptr, varID, levelID, (double*) data, nmiss);
@@ -683,7 +683,7 @@ void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
}
-void cdf_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss)
+void cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
diff --git a/libcdi/src/cdf_write.c b/libcdi/src/cdf_write.c
index 49484fe..2852d66 100644
--- a/libcdi/src/cdf_write.c
+++ b/libcdi/src/cdf_write.c
@@ -355,7 +355,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
vlistInqVarDimorder(vlistID, varID, &dimorder);
- size_t gridsize = (size_t)(gridInqSize(gridID));
+ size_t gridsize = gridInqSize(gridID);
bool lchunk = (gridsize >= 16);
int gridtype = gridInqType(gridID);
int gridindex = nc_grid_index(streamptr, gridID);
@@ -808,7 +808,7 @@ void cdfWriteGridTraj(stream_t *streamptr, int gridID)
static
void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, size_t nvals, size_t xsize, size_t ysize,
- bool swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
+ bool swapxy, size_t *start, size_t *count, int memtype, const void *data, size_t nmiss)
{
const double *pdata_dp = (const double *) data;
double *mdata_dp = NULL;
@@ -984,7 +984,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
}
-void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
@@ -1070,14 +1070,14 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID)) * (size_t)(zaxisInqSize(zaxisID));
+ size_t nvals = gridInqSize(gridID) * (size_t)(zaxisInqSize(zaxisID));
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss)
+ const int rect[][2], const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
@@ -1168,14 +1168,14 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID)) * (size_t)(zaxisInqSize(zaxisID));
+ size_t nvals = gridInqSize(gridID) * (size_t)(zaxisInqSize(zaxisID));
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals,
xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
-void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
+void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
@@ -1256,13 +1256,13 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID));
+ size_t nvals = gridInqSize(gridID);
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
-void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss)
{
int varID = streamptr->record->varID;
int levelID = streamptr->record->levelID;
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 4ad9bc0..673a9a2 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -386,39 +386,39 @@ int streamInqCurTimestepID(int streamID);
const char *streamFilename(int streamID);
const char *streamFilesuffix(int filetype);
-off_t streamNvals(int streamID);
+size_t streamNvals(int streamID);
int streamInqNvars(int streamID);
/* STREAM var I/O routines (random access) */
/* streamWriteVar: Write a variable */
-void streamWriteVar(int streamID, int varID, const double data[], int nmiss);
-void streamWriteVarF(int streamID, int varID, const float data[], int nmiss);
+void streamWriteVar(int streamID, int varID, const double data[], size_t nmiss);
+void streamWriteVarF(int streamID, int varID, const float data[], size_t nmiss);
/* streamReadVar: Read a variable */
-void streamReadVar(int streamID, int varID, double data[], int *nmiss);
-void streamReadVarF(int streamID, int varID, float data[], int *nmiss);
+void streamReadVar(int streamID, int varID, double data[], size_t *nmiss);
+void streamReadVarF(int streamID, int varID, float data[], size_t *nmiss);
/* streamWriteVarSlice: Write a horizontal slice of a variable */
-void streamWriteVarSlice(int streamID, int varID, int levelID, const double data[], int nmiss);
-void streamWriteVarSliceF(int streamID, int varID, int levelID, const float data[], int nmiss);
+void streamWriteVarSlice(int streamID, int varID, int levelID, const double data[], size_t nmiss);
+void streamWriteVarSliceF(int streamID, int varID, int levelID, const float data[], size_t nmiss);
/* streamReadVarSlice: Read a horizontal slice of a variable */
-void streamReadVarSlice(int streamID, int varID, int levelID, double data[], int *nmiss);
-void streamReadVarSliceF(int streamID, int varID, int levelID, float data[], int *nmiss);
+void streamReadVarSlice(int streamID, int varID, int levelID, double data[], size_t *nmiss);
+void streamReadVarSliceF(int streamID, int varID, int levelID, float data[], size_t *nmiss);
-void streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double data[], int nmiss);
+void streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double data[], size_t nmiss);
/* STREAM record I/O routines (sequential access) */
void streamDefRecord(int streamID, int varID, int levelID);
void streamInqRecord(int streamID, int *varID, int *levelID);
-void streamWriteRecord(int streamID, const double data[], int nmiss);
-void streamWriteRecordF(int streamID, const float data[], int nmiss);
-void streamReadRecord(int streamID, double data[], int *nmiss);
-void streamReadRecordF(int streamID, float data[], int *nmiss);
+void streamWriteRecord(int streamID, const double data[], size_t nmiss);
+void streamWriteRecordF(int streamID, const float data[], size_t nmiss);
+void streamReadRecord(int streamID, double data[], size_t *nmiss);
+void streamReadRecordF(int streamID, float data[], size_t *nmiss);
void streamCopyRecord(int streamIDdest, int streamIDsrc);
void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
@@ -526,7 +526,7 @@ int vlistNsubtypes(int vlistID);
void vlistDefNtsteps(int vlistID, int nts);
int vlistNtsteps(int vlistID);
-int vlistGridsizeMax(int vlistID);
+size_t vlistGridsizeMax(int vlistID);
int vlistGrid(int vlistID, int index);
int vlistGridIndex(int vlistID, int gridID);
void vlistChangeGridIndex(int vlistID, int index, int gridID);
@@ -672,7 +672,7 @@ int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID);
void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDefinitionTemplate);
int vlistInqVarProductDefinitionTemplate(int vlistID, int varID);
-int vlistInqVarSize(int vlistID, int varID);
+size_t vlistInqVarSize(int vlistID, int varID);
void vlistDefIndex(int vlistID, int varID, int levID, int index);
int vlistInqIndex(int vlistID, int varID, int levID);
@@ -745,7 +745,7 @@ int gridInqMask(int gridID, int mask[]);
void gridPrint(int gridID, int opt);
/* gridCreate: Create a horizontal Grid */
-int gridCreate(int gridtype, int size);
+int gridCreate(int gridtype, size_t size);
/* gridDestroy: Destroy a horizontal Grid */
void gridDestroy(int gridID);
@@ -766,19 +766,19 @@ int gridInqProjType(int gridID);
int gridInqType(int gridID);
/* gridInqSize: Get the size of a Grid */
-int gridInqSize(int gridID);
+size_t gridInqSize(int gridID);
/* gridDefXsize: Define the size of a X-axis */
-void gridDefXsize(int gridID, int xsize);
+void gridDefXsize(int gridID, size_t xsize);
/* gridInqXsize: Get the size of a X-axis */
-int gridInqXsize(int gridID);
+size_t gridInqXsize(int gridID);
/* gridDefYsize: Define the size of a Y-axis */
-void gridDefYsize(int gridID, int ysize);
+void gridDefYsize(int gridID, size_t ysize);
/* gridInqYsize: Get the size of a Y-axis */
-int gridInqYsize(int gridID);
+size_t gridInqYsize(int gridID);
/* gridDefNP: Define the number of parallels between a pole and the equator */
void gridDefNP(int gridID, int np);
@@ -790,25 +790,25 @@ int gridInqNP(int gridID);
void gridDefXvals(int gridID, const double xvals[]);
/* gridInqXvals: Get all values of a X-axis */
-int gridInqXvals(int gridID, double xvals[]);
+size_t gridInqXvals(int gridID, double xvals[]);
/* gridInqXIsc: Find out whether X-coordinate is of type CHAR */
int gridInqXIsc(int gridID);
/* gridInqXCvals: Get strings from X-axis in case grid is of type GRID_CHARXY */
-int gridInqXCvals(int gridID, char *xcvals[]);
+size_t gridInqXCvals(int gridID, char *xcvals[]);
/* gridDefYvals: Define the values of a Y-axis */
void gridDefYvals(int gridID, const double yvals[]);
/* gridInqYvals: Get all values of a Y-axis */
-int gridInqYvals(int gridID, double yvals[]);
+size_t gridInqYvals(int gridID, double yvals[]);
/* gridInqYIsc: Find out whether Y-coordinate is of type CHAR */
int gridInqYIsc(int gridID);
/* gridInqYCvals: Get strings from Y-axis in case grid is of type GRID_CHARXY */
-int gridInqYCvals(int gridID, char *ycvals[]);
+size_t gridInqYCvals(int gridID, char *ycvals[]);
/* CDI grid string key values */
#define CDI_KEY_XNAME 901 // X-axis name
@@ -893,10 +893,10 @@ void gridDefDatatype(int gridID, int prec);
int gridInqDatatype(int gridID);
/* gridInqXval: Get one value of a X-axis */
-double gridInqXval(int gridID, int index);
+double gridInqXval(int gridID, size_t index);
/* gridInqYval: Get one value of a Y-axis */
-double gridInqYval(int gridID, int index);
+double gridInqYval(int gridID, size_t index);
double gridInqXinc(int gridID);
double gridInqYinc(int gridID);
@@ -966,13 +966,13 @@ int gridInqNvertex(int gridID);
void gridDefXbounds(int gridID, const double xbounds[]);
/* gridInqXbounds: Get the bounds of a X-axis */
-int gridInqXbounds(int gridID, double xbounds[]);
+size_t gridInqXbounds(int gridID, double xbounds[]);
/* gridDefYbounds: Define the bounds of a Y-axis */
void gridDefYbounds(int gridID, const double ybounds[]);
/* gridInqYbounds: Get the bounds of a Y-axis */
-int gridInqYbounds(int gridID, double ybounds[]);
+size_t gridInqYbounds(int gridID, double ybounds[]);
void gridDefRowlon(int gridID, int nrowlon, const int rowlon[]);
void gridInqRowlon(int gridID, int rowlon[]);
@@ -1013,7 +1013,7 @@ void zaxisPrint(int zaxisID);
void zaxisDefLevels(int zaxisID, const double levels[]);
/* zaxisDefCvals: Define area types of a Z-axis */
-void zaxisDefCvals(int zaxisID, const char *cvals[], size_t clength);
+void zaxisDefCvals(int zaxisID, const char *cvals[], int clength);
/* zaxisInqLevels: Get all levels of a Z-axis */
int zaxisInqLevels(int zaxisID, double levels[]);
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index bb59831..2769887 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -653,6 +653,10 @@
! (INTEGER filetype)
EXTERNAL streamFilesuffix
+ INTEGER streamNvals
+! (INTEGER streamID)
+ EXTERNAL streamNvals
+
INTEGER streamInqNvars
! (INTEGER streamID)
EXTERNAL streamInqNvars
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index 6b8e702..8de51ed 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -154,28 +154,105 @@ FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT,
FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
+static int streamNvals_fwrap(int streamID)
+{
+ size_t v;
+ v = streamNvals(streamID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, streamNvals_fwrap, STREAMNVALS, streamnvals, INT)
FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
/* STREAM var I/O routines (random access) */
-FCALLSCSUB4 (streamWriteVar, STREAMWRITEVAR, streamwritevar, INT, INT, DOUBLEV, INT)
-FCALLSCSUB4 (streamWriteVarF, STREAMWRITEVARF, streamwritevarf, INT, INT, FLOATV, INT)
-FCALLSCSUB4 (streamReadVar, STREAMREADVAR, streamreadvar, INT, INT, DOUBLEV, PINT)
-FCALLSCSUB4 (streamReadVarF, STREAMREADVARF, streamreadvarf, INT, INT, FLOATV, PINT)
-FCALLSCSUB5 (streamWriteVarSlice, STREAMWRITEVARSLICE, streamwritevarslice, INT, INT, INT, DOUBLEV, INT)
-FCALLSCSUB5 (streamWriteVarSliceF, STREAMWRITEVARSLICEF, streamwritevarslicef, INT, INT, INT, FLOATV, INT)
-FCALLSCSUB5 (streamReadVarSlice, STREAMREADVARSLICE, streamreadvarslice, INT, INT, INT, DOUBLEV, PINT)
-FCALLSCSUB5 (streamReadVarSliceF, STREAMREADVARSLICEF, streamreadvarslicef, INT, INT, INT, FLOATV, PINT)
-FCALLSCSUB5 (streamWriteVarChunk, STREAMWRITEVARCHUNK, streamwritevarchunk, INT, INT, INTVV, DOUBLEV, INT)
+static void streamWriteVar_fwrap(int streamID, int varID, const double data[], int nmiss)
+{
+ streamWriteVar(streamID, varID, data, (size_t)nmiss);
+}
+FCALLSCSUB4 (streamWriteVar_fwrap, STREAMWRITEVAR, streamwritevar, INT, INT, DOUBLEV, INT)
+static void streamWriteVarF_fwrap(int streamID, int varID, const float data[], int nmiss)
+{
+ streamWriteVarF(streamID, varID, data, (size_t)nmiss);
+}
+FCALLSCSUB4 (streamWriteVarF_fwrap, STREAMWRITEVARF, streamwritevarf, INT, INT, FLOATV, INT)
+static void streamReadVar_fwrap(int streamID, int varID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVar(streamID, varID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB4 (streamReadVar_fwrap, STREAMREADVAR, streamreadvar, INT, INT, DOUBLEV, PINT)
+static void streamReadVarF_fwrap(int streamID, int varID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarF(streamID, varID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB4 (streamReadVarF_fwrap, STREAMREADVARF, streamreadvarf, INT, INT, FLOATV, PINT)
+static void streamWriteVarSlice_fwrap(int streamID, int varID, int levelID, const double data[], int nmiss)
+{
+ streamWriteVarSlice(streamID, varID, levelID, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarSlice_fwrap, STREAMWRITEVARSLICE, streamwritevarslice, INT, INT, INT, DOUBLEV, INT)
+static void streamWriteVarSliceF_fwrap(int streamID, int varID, int levelID, const float data[], int nmiss)
+{
+ streamWriteVarSliceF(streamID, varID, levelID, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarSliceF_fwrap, STREAMWRITEVARSLICEF, streamwritevarslicef, INT, INT, INT, FLOATV, INT)
+static void streamReadVarSlice_fwrap(int streamID, int varID, int levelID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarSlice(streamID, varID, levelID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB5 (streamReadVarSlice_fwrap, STREAMREADVARSLICE, streamreadvarslice, INT, INT, INT, DOUBLEV, PINT)
+static void streamReadVarSliceF_fwrap(int streamID, int varID, int levelID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarSliceF(streamID, varID, levelID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB5 (streamReadVarSliceF_fwrap, STREAMREADVARSLICEF, streamreadvarslicef, INT, INT, INT, FLOATV, PINT)
+static void streamWriteVarChunk_fwrap(int streamID, int varID, const int rect[3][2], const double data[], int nmiss)
+{
+ streamWriteVarChunk(streamID, varID, rect, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarChunk_fwrap, STREAMWRITEVARCHUNK, streamwritevarchunk, INT, INT, INTVV, DOUBLEV, INT)
/* STREAM record I/O routines (sequential access) */
FCALLSCSUB3 (streamDefRecord, STREAMDEFRECORD, streamdefrecord, INT, INT, INT)
FCALLSCSUB3 (streamInqRecord, STREAMINQRECORD, streaminqrecord, INT, PINT, PINT)
-FCALLSCSUB3 (streamWriteRecord, STREAMWRITERECORD, streamwriterecord, INT, DOUBLEV, INT)
-FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, FLOATV, INT)
-FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, DOUBLEV, PINT)
-FCALLSCSUB3 (streamReadRecordF, STREAMREADRECORDF, streamreadrecordf, INT, FLOATV, PINT)
+static void streamWriteRecord_fwrap(int streamID, const double data[], int nmiss)
+{
+ streamWriteRecord(streamID, data, (size_t)nmiss);
+}
+FCALLSCSUB3 (streamWriteRecord_fwrap, STREAMWRITERECORD, streamwriterecord, INT, DOUBLEV, INT)
+static void streamWriteRecordF_fwrap(int streamID, const float data[], int nmiss)
+{
+ streamWriteRecordF(streamID, data, (size_t)nmiss);
+}
+FCALLSCSUB3 (streamWriteRecordF_fwrap, STREAMWRITERECORDF, streamwriterecordf, INT, FLOATV, INT)
+static void streamReadRecord_fwrap(int streamID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadRecord(streamID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB3 (streamReadRecord_fwrap, STREAMREADRECORD, streamreadrecord, INT, DOUBLEV, PINT)
+static void streamReadRecordF_fwrap(int streamID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadRecordF(streamID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB3 (streamReadRecordF_fwrap, STREAMREADRECORDF, streamreadrecordf, INT, FLOATV, PINT)
FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
/* File driven I/O (may yield better performance than using the streamXXX functions) */
@@ -199,7 +276,13 @@ FCALLSCFUN1 (INT, vlistNzaxis, VLISTNZAXIS, vlistnzaxis, INT)
FCALLSCFUN1 (INT, vlistNsubtypes, VLISTNSUBTYPES, vlistnsubtypes, INT)
FCALLSCSUB2 (vlistDefNtsteps, VLISTDEFNTSTEPS, vlistdefntsteps, INT, INT)
FCALLSCFUN1 (INT, vlistNtsteps, VLISTNTSTEPS, vlistntsteps, INT)
-FCALLSCFUN1 (INT, vlistGridsizeMax, VLISTGRIDSIZEMAX, vlistgridsizemax, INT)
+static int vlistGridsizeMax_fwrap(int vlistID)
+{
+ size_t v;
+ v = vlistGridsizeMax(vlistID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, vlistGridsizeMax_fwrap, VLISTGRIDSIZEMAX, vlistgridsizemax, INT)
FCALLSCFUN2 (INT, vlistGrid, VLISTGRID, vlistgrid, INT, INT)
FCALLSCFUN2 (INT, vlistGridIndex, VLISTGRIDINDEX, vlistgridindex, INT, INT)
FCALLSCSUB3 (vlistChangeGridIndex, VLISTCHANGEGRIDINDEX, vlistchangegridindex, INT, INT, INT)
@@ -283,7 +366,13 @@ FCALLSCSUB3 (vlistDefVarTypeOfGeneratingProcess, VLISTDEFVARTYPEOFGENERATINGPROC
FCALLSCFUN2 (INT, vlistInqVarTypeOfGeneratingProcess, VLISTINQVARTYPEOFGENERATINGPROCESS, vlistinqvartypeofgeneratingprocess, INT, INT)
FCALLSCSUB3 (vlistDefVarProductDefinitionTemplate, VLISTDEFVARPRODUCTDEFINITIONTEMPLATE, vlistdefvarproductdefinitiontemplate, INT, INT, INT)
FCALLSCFUN2 (INT, vlistInqVarProductDefinitionTemplate, VLISTINQVARPRODUCTDEFINITIONTEMPLATE, vlistinqvarproductdefinitiontemplate, INT, INT)
-FCALLSCFUN2 (INT, vlistInqVarSize, VLISTINQVARSIZE, vlistinqvarsize, INT, INT)
+static int vlistInqVarSize_fwrap(int vlistID, int varID)
+{
+ size_t v;
+ v = vlistInqVarSize(vlistID, varID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, vlistInqVarSize_fwrap, VLISTINQVARSIZE, vlistinqvarsize, INT, INT)
FCALLSCSUB4 (vlistDefIndex, VLISTDEFINDEX, vlistdefindex, INT, INT, INT, INT)
FCALLSCFUN3 (INT, vlistInqIndex, VLISTINQINDEX, vlistinqindex, INT, INT, INT)
FCALLSCSUB4 (vlistDefFlag, VLISTDEFFLAG, vlistdefflag, INT, INT, INT, INT)
@@ -328,25 +417,69 @@ FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, INTV)
FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, INTV)
FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, INTV)
FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
-FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
+static int gridCreate_fwrap(int gridtype, int size)
+{
+ int v;
+ v = gridCreate(gridtype, (size_t)size);
+ return v;
+}
+FCALLSCFUN2 (INT, gridCreate_fwrap, GRIDCREATE, gridcreate, INT, INT)
FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
FCALLSCSUB2 (gridDefProj, GRIDDEFPROJ, griddefproj, INT, INT)
FCALLSCFUN1 (INT, gridInqProj, GRIDINQPROJ, gridinqproj, INT)
FCALLSCFUN1 (INT, gridInqProjType, GRIDINQPROJTYPE, gridinqprojtype, INT)
FCALLSCFUN1 (INT, gridInqType, GRIDINQTYPE, gridinqtype, INT)
-FCALLSCFUN1 (INT, gridInqSize, GRIDINQSIZE, gridinqsize, INT)
-FCALLSCSUB2 (gridDefXsize, GRIDDEFXSIZE, griddefxsize, INT, INT)
-FCALLSCFUN1 (INT, gridInqXsize, GRIDINQXSIZE, gridinqxsize, INT)
-FCALLSCSUB2 (gridDefYsize, GRIDDEFYSIZE, griddefysize, INT, INT)
-FCALLSCFUN1 (INT, gridInqYsize, GRIDINQYSIZE, gridinqysize, INT)
+static int gridInqSize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqSize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqSize_fwrap, GRIDINQSIZE, gridinqsize, INT)
+static void gridDefXsize_fwrap(int gridID, int xsize)
+{
+ gridDefXsize(gridID, (size_t)xsize);
+}
+FCALLSCSUB2 (gridDefXsize_fwrap, GRIDDEFXSIZE, griddefxsize, INT, INT)
+static int gridInqXsize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqXsize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqXsize_fwrap, GRIDINQXSIZE, gridinqxsize, INT)
+static void gridDefYsize_fwrap(int gridID, int ysize)
+{
+ gridDefYsize(gridID, (size_t)ysize);
+}
+FCALLSCSUB2 (gridDefYsize_fwrap, GRIDDEFYSIZE, griddefysize, INT, INT)
+static int gridInqYsize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqYsize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqYsize_fwrap, GRIDINQYSIZE, gridinqysize, INT)
FCALLSCSUB2 (gridDefNP, GRIDDEFNP, griddefnp, INT, INT)
FCALLSCFUN1 (INT, gridInqNP, GRIDINQNP, gridinqnp, INT)
FCALLSCSUB2 (gridDefXvals, GRIDDEFXVALS, griddefxvals, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqXvals, GRIDINQXVALS, gridinqxvals, INT, DOUBLEV)
+static int gridInqXvals_fwrap(int gridID, double xvals[])
+{
+ size_t v;
+ v = gridInqXvals(gridID, xvals);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqXvals_fwrap, GRIDINQXVALS, gridinqxvals, INT, DOUBLEV)
FCALLSCFUN1 (INT, gridInqXIsc, GRIDINQXISC, gridinqxisc, INT)
FCALLSCSUB2 (gridDefYvals, GRIDDEFYVALS, griddefyvals, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqYvals, GRIDINQYVALS, gridinqyvals, INT, DOUBLEV)
+static int gridInqYvals_fwrap(int gridID, double yvals[])
+{
+ size_t v;
+ v = gridInqYvals(gridID, yvals);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqYvals_fwrap, GRIDINQYVALS, gridinqyvals, INT, DOUBLEV)
FCALLSCFUN1 (INT, gridInqYIsc, GRIDINQYISC, gridinqyisc, INT)
/* CDI grid string key values */
@@ -374,8 +507,20 @@ FCALLSCSUB2 (gridInqXstdname, GRIDINQXSTDNAME, gridinqxstdname, INT, PSTRING)
FCALLSCSUB2 (gridInqYstdname, GRIDINQYSTDNAME, gridinqystdname, INT, PSTRING)
FCALLSCSUB2 (gridDefDatatype, GRIDDEFDATATYPE, griddefdatatype, INT, INT)
FCALLSCFUN1 (INT, gridInqDatatype, GRIDINQDATATYPE, gridinqdatatype, INT)
-FCALLSCFUN2 (DOUBLE, gridInqXval, GRIDINQXVAL, gridinqxval, INT, INT)
-FCALLSCFUN2 (DOUBLE, gridInqYval, GRIDINQYVAL, gridinqyval, INT, INT)
+static double gridInqXval_fwrap(int gridID, int index)
+{
+ double v;
+ v = gridInqXval(gridID, (size_t)index);
+ return v;
+}
+FCALLSCFUN2 (DOUBLE, gridInqXval_fwrap, GRIDINQXVAL, gridinqxval, INT, INT)
+static double gridInqYval_fwrap(int gridID, int index)
+{
+ double v;
+ v = gridInqYval(gridID, (size_t)index);
+ return v;
+}
+FCALLSCFUN2 (DOUBLE, gridInqYval_fwrap, GRIDINQYVAL, gridinqyval, INT, INT)
FCALLSCFUN1 (DOUBLE, gridInqXinc, GRIDINQXINC, gridinqxinc, INT)
FCALLSCFUN1 (DOUBLE, gridInqYinc, GRIDINQYINC, gridinqyinc, INT)
FCALLSCFUN1 (INT, gridIsCircular, GRIDISCIRCULAR, gridiscircular, INT)
@@ -413,9 +558,21 @@ FCALLSCFUN1 (INT, gridHasArea, GRIDHASAREA, gridhasarea, INT)
FCALLSCSUB2 (gridDefNvertex, GRIDDEFNVERTEX, griddefnvertex, INT, INT)
FCALLSCFUN1 (INT, gridInqNvertex, GRIDINQNVERTEX, gridinqnvertex, INT)
FCALLSCSUB2 (gridDefXbounds, GRIDDEFXBOUNDS, griddefxbounds, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqXbounds, GRIDINQXBOUNDS, gridinqxbounds, INT, DOUBLEV)
+static int gridInqXbounds_fwrap(int gridID, double xbounds[])
+{
+ size_t v;
+ v = gridInqXbounds(gridID, xbounds);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqXbounds_fwrap, GRIDINQXBOUNDS, gridinqxbounds, INT, DOUBLEV)
FCALLSCSUB2 (gridDefYbounds, GRIDDEFYBOUNDS, griddefybounds, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqYbounds, GRIDINQYBOUNDS, gridinqybounds, INT, DOUBLEV)
+static int gridInqYbounds_fwrap(int gridID, double ybounds[])
+{
+ size_t v;
+ v = gridInqYbounds(gridID, ybounds);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqYbounds_fwrap, GRIDINQYBOUNDS, gridinqybounds, INT, DOUBLEV)
FCALLSCSUB3 (gridDefRowlon, GRIDDEFROWLON, griddefrowlon, INT, INT, INTV)
FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, INTV)
FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
diff --git a/libcdi/src/cdi_int.h b/libcdi/src/cdi_int.h
index 7a0fd20..76fe7f5 100644
--- a/libcdi/src/cdi_int.h
+++ b/libcdi/src/cdi_int.h
@@ -10,6 +10,7 @@
#include <stdbool.h>
#include <string.h>
#include <errno.h>
+#include <limits.h>
#include <math.h>
#include <sys/types.h>
@@ -242,7 +243,7 @@ typedef struct {
int fileID;
int filemode;
int nrecs; /* number of records */
- off_t numvals;
+ size_t numvals;
char *filename;
Record *record;
svarinfo_t *vars;
@@ -443,11 +444,11 @@ void
cdiStreamDefVlist_(int streamID, int vlistID);
int
-cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss);
+cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, size_t nmiss);
void
cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss);
+ const int rect[][2], const void *data, size_t nmiss);
void
cdiStreamCloseDefaultDelegate(stream_t *streamptr,
int recordBufIsToBeDeleted);
@@ -481,6 +482,13 @@ void cdiDefTableID(int tableID);
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals);
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals);
+static inline
+void cdi_check_gridsize_int_limit(const char *format, size_t gridsize)
+{
+ if ( gridsize > INT_MAX ) Error("%s format grid size (%zu) limit exceeded (%zu)!", format, gridsize, INT_MAX);
+}
+
+
#if defined (__cplusplus)
}
#endif
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index 9295e75..5553192 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,7 +1,7 @@
-/* Automatically generated by m214003 at 2016-06-07, do not edit */
+/* Automatically generated by ram at 2017-11-06, do not edit */
-/* CDILIB_VERSION="1.7.2" */
+/* CDILIB_VERSION="1.9.2" */
#ifdef _ARCH_PWR6
#pragma options nostrict
@@ -58,8 +58,8 @@
# define HAVE_LIBIEG 1
#endif
-#ifndef _ERROR_H
-#define _ERROR_H
+#ifndef ERROR_H
+#define ERROR_H
#include <stdarg.h>
#include <stdlib.h>
@@ -130,7 +130,7 @@ cdiAbortC_serial(const char *caller, const char *filename,
}
#endif
-#endif /* _ERROR_H */
+#endif /* ERROR_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -157,102 +157,130 @@ extern "C" {
#endif
-#define CDI_MAX_NAME 256 /* max length of a name */
+#define CDI_MAX_NAME 256 // max length of a name
-#define CDI_UNDEFID -1
-#define CDI_GLOBAL -1 /* Global var ID for vlist */
+#define CDI_UNDEFID -1
+#define CDI_GLOBAL -1 // Global var ID for vlist
/* Byte order */
-#define CDI_BIGENDIAN 0 /* Byte order BIGENDIAN */
-#define CDI_LITTLEENDIAN 1 /* Byte order LITTLEENDIAN */
-#define CDI_PDPENDIAN 2
+#define CDI_BIGENDIAN 0 // Byte order BIGENDIAN
+#define CDI_LITTLEENDIAN 1 // Byte order LITTLEENDIAN
+#define CDI_PDPENDIAN 2
-#define CDI_REAL 1 /* Real numbers */
-#define CDI_COMP 2 /* Complex numbers */
-#define CDI_BOTH 3 /* Both numbers */
+#define CDI_REAL 1 // Real numbers
+#define CDI_COMP 2 // Complex numbers
+#define CDI_BOTH 3 // Both numbers
/* Error identifier */
-#define CDI_NOERR 0 /* No Error */
-#define CDI_EEOF -1 /* The end of file was encountered */
-#define CDI_ESYSTEM -10 /* Operating system error */
-#define CDI_EINVAL -20 /* Invalid argument */
-#define CDI_EUFTYPE -21 /* Unsupported file type */
-#define CDI_ELIBNAVAIL -22 /* xxx library not available */
-#define CDI_EUFSTRUCT -23 /* Unsupported file structure */
-#define CDI_EUNC4 -24 /* Unsupported NetCDF4 structure */
-#define CDI_ELIMIT -99 /* Internal limits exceeded */
+#define CDI_NOERR 0 // No Error
+#define CDI_EEOF -1 // The end of file was encountered
+#define CDI_ESYSTEM -10 // Operating system error
+#define CDI_EINVAL -20 // Invalid argument
+#define CDI_EISDIR -21 // Is a directory
+#define CDI_EISEMPTY -22 // Is empty
+#define CDI_EUFTYPE -23 // Unsupported file type
+#define CDI_ELIBNAVAIL -24 // xxx library not available
+#define CDI_EUFSTRUCT -25 // Unsupported file structure
+#define CDI_EUNC4 -26 // Unsupported NetCDF4 structure
+#define CDI_EDIMSIZE -27 // Invalid dimension size
+#define CDI_ELIMIT -99 // Internal limits exceeded
/* File types */
-#define FILETYPE_UNDEF -1 /* Unknown/not yet defined file type */
-#define FILETYPE_GRB 1 /* File type GRIB */
-#define FILETYPE_GRB2 2 /* File type GRIB version 2 */
-#define FILETYPE_NC 3 /* File type NetCDF */
-#define FILETYPE_NC2 4 /* File type NetCDF version 2 (64-bit) */
-#define FILETYPE_NC4 5 /* File type NetCDF version 4 */
-#define FILETYPE_NC4C 6 /* File type NetCDF version 4 (classic) */
-#define FILETYPE_SRV 7 /* File type SERVICE */
-#define FILETYPE_EXT 8 /* File type EXTRA */
-#define FILETYPE_IEG 9 /* File type IEG */
+#define CDI_FILETYPE_GRB 1 // File type GRIB
+#define CDI_FILETYPE_GRB2 2 // File type GRIB version 2
+#define CDI_FILETYPE_NC 3 // File type NetCDF
+#define CDI_FILETYPE_NC2 4 // File type NetCDF version 2 (64-bit offset)
+#define CDI_FILETYPE_NC4 5 // File type NetCDF version 4
+#define CDI_FILETYPE_NC4C 6 // File type NetCDF version 4 (classic)
+#define CDI_FILETYPE_NC5 7 // File type NetCDF version 5 (64-bit data)
+#define CDI_FILETYPE_SRV 8 // File type SERVICE
+#define CDI_FILETYPE_EXT 9 // File type EXTRA
+#define CDI_FILETYPE_IEG 10 // File type IEG
+
+#define FILETYPE_GRB 1
+#define FILETYPE_GRB2 2
+#define FILETYPE_NC 3
+#define FILETYPE_NC2 4
+#define FILETYPE_NC4 5
+#define FILETYPE_NC4C 6
+#define FILETYPE_SRV 7
+#define FILETYPE_EXT 8
+#define FILETYPE_IEG 9
/* Compress types */
-#define COMPRESS_NONE 0
-#define COMPRESS_SZIP 1
-#define COMPRESS_GZIP 2
-#define COMPRESS_BZIP2 3
-#define COMPRESS_ZIP 4
-#define COMPRESS_JPEG 5
+#define CDI_COMPRESS_NONE 0
+#define CDI_COMPRESS_SZIP 1
+#define CDI_COMPRESS_GZIP 2
+#define CDI_COMPRESS_BZIP2 3
+#define CDI_COMPRESS_ZIP 4
+#define CDI_COMPRESS_JPEG 5
/* external data types */
+#define CDI_DATATYPE_PACK 0
+#define CDI_DATATYPE_PACK1 1
+#define CDI_DATATYPE_PACK2 2
+#define CDI_DATATYPE_PACK3 3
+#define CDI_DATATYPE_PACK4 4
+#define CDI_DATATYPE_PACK5 5
+#define CDI_DATATYPE_PACK6 6
+#define CDI_DATATYPE_PACK7 7
+#define CDI_DATATYPE_PACK8 8
+#define CDI_DATATYPE_PACK9 9
+#define CDI_DATATYPE_PACK10 10
+#define CDI_DATATYPE_PACK11 11
+#define CDI_DATATYPE_PACK12 12
+#define CDI_DATATYPE_PACK13 13
+#define CDI_DATATYPE_PACK14 14
+#define CDI_DATATYPE_PACK15 15
+#define CDI_DATATYPE_PACK16 16
+#define CDI_DATATYPE_PACK17 17
+#define CDI_DATATYPE_PACK18 18
+#define CDI_DATATYPE_PACK19 19
+#define CDI_DATATYPE_PACK20 20
+#define CDI_DATATYPE_PACK21 21
+#define CDI_DATATYPE_PACK22 22
+#define CDI_DATATYPE_PACK23 23
+#define CDI_DATATYPE_PACK24 24
+#define CDI_DATATYPE_PACK25 25
+#define CDI_DATATYPE_PACK26 26
+#define CDI_DATATYPE_PACK27 27
+#define CDI_DATATYPE_PACK28 28
+#define CDI_DATATYPE_PACK29 29
+#define CDI_DATATYPE_PACK30 30
+#define CDI_DATATYPE_PACK31 31
+#define CDI_DATATYPE_PACK32 32
+#define CDI_DATATYPE_CPX32 64
+#define CDI_DATATYPE_CPX64 128
+#define CDI_DATATYPE_FLT32 132
+#define CDI_DATATYPE_FLT64 164
+#define CDI_DATATYPE_INT8 208
+#define CDI_DATATYPE_INT16 216
+#define CDI_DATATYPE_INT32 232
+#define CDI_DATATYPE_UINT8 308
+#define CDI_DATATYPE_UINT16 316
+#define CDI_DATATYPE_UINT32 332
+
#define DATATYPE_PACK 0
-#define DATATYPE_PACK1 1
-#define DATATYPE_PACK2 2
-#define DATATYPE_PACK3 3
-#define DATATYPE_PACK4 4
-#define DATATYPE_PACK5 5
-#define DATATYPE_PACK6 6
-#define DATATYPE_PACK7 7
#define DATATYPE_PACK8 8
-#define DATATYPE_PACK9 9
-#define DATATYPE_PACK10 10
-#define DATATYPE_PACK11 11
-#define DATATYPE_PACK12 12
-#define DATATYPE_PACK13 13
-#define DATATYPE_PACK14 14
-#define DATATYPE_PACK15 15
#define DATATYPE_PACK16 16
-#define DATATYPE_PACK17 17
-#define DATATYPE_PACK18 18
-#define DATATYPE_PACK19 19
-#define DATATYPE_PACK20 20
-#define DATATYPE_PACK21 21
-#define DATATYPE_PACK22 22
-#define DATATYPE_PACK23 23
#define DATATYPE_PACK24 24
-#define DATATYPE_PACK25 25
-#define DATATYPE_PACK26 26
-#define DATATYPE_PACK27 27
-#define DATATYPE_PACK28 28
-#define DATATYPE_PACK29 29
-#define DATATYPE_PACK30 30
-#define DATATYPE_PACK31 31
-#define DATATYPE_PACK32 32
-#define DATATYPE_CPX32 64
-#define DATATYPE_CPX64 128
#define DATATYPE_FLT32 132
#define DATATYPE_FLT64 164
-#define DATATYPE_INT8 208
-#define DATATYPE_INT16 216
#define DATATYPE_INT32 232
-#define DATATYPE_UINT8 308
-#define DATATYPE_UINT16 316
-#define DATATYPE_UINT32 332
/* internal data types */
+#define CDI_DATATYPE_INT 251
+#define CDI_DATATYPE_FLT 252
+#define CDI_DATATYPE_TXT 253
+#define CDI_DATATYPE_CPX 254
+#define CDI_DATATYPE_UCHAR 255
+#define CDI_DATATYPE_LONG 256
+
#define DATATYPE_INT 251
#define DATATYPE_FLT 252
#define DATATYPE_TXT 253
@@ -262,9 +290,9 @@ extern "C" {
/* Chunks */
-#define CHUNK_AUTO 1 /* use default chunk size */
-#define CHUNK_GRID 2
-#define CHUNK_LINES 3
+#define CDI_CHUNK_AUTO 1 /* use default chunk size */
+#define CDI_CHUNK_GRID 2
+#define CDI_CHUNK_LINES 3
/* GRID types */
@@ -279,10 +307,13 @@ extern "C" {
#define GRID_UNSTRUCTURED 9 /* General unstructured grid */
#define GRID_CURVILINEAR 10 /* Curvilinear grid */
#define GRID_LCC 11 /* Lambert Conformal Conic (GRIB) */
-#define GRID_LCC2 12 /* Lambert Conformal Conic (PROJ) */
-#define GRID_LAEA 13 /* Lambert Azimuthal Equal Area */
-#define GRID_SINUSOIDAL 14 /* Sinusoidal */
-#define GRID_PROJECTION 15 /* Projected coordiantes */
+#define GRID_PROJECTION 12 /* Projected coordinates */
+#define GRID_CHARXY 13 /* One horizontal character dimension */
+
+#define CDI_PROJ_RLL 21 /* Rotated Latitude Longitude */
+#define CDI_PROJ_LCC 22 /* Lambert Conformal Conic */
+#define CDI_PROJ_LAEA 23 /* Lambert Azimuthal Equal Area */
+#define CDI_PROJ_SINU 24 /* Sinusoidal */
/* ZAXIS types */
@@ -312,6 +343,7 @@ extern "C" {
#define ZAXIS_SEDIMENT_BOTTOM_TW 23 /* Bottom Of Sediment Layer Penetrated By Thermal Wave */
#define ZAXIS_MIX_LAYER 24 /* Mixing Layer */
#define ZAXIS_REFERENCE 25 /* zaxis reference number */
+#define ZAXIS_CHAR 26 /* Area types */
/* SUBTYPE types */
@@ -335,12 +367,12 @@ typedef struct {
/* TIME types */
-#define TIME_CONSTANT 0 /* obsolate, use TSTEP_CONSTANT */
-#define TIME_VARIABLE 1 /* obsolate, use TSTEP_INSTANT */
+#define TIME_CONSTANT 0 /* Time constant */
+#define TIME_VARYING 1 /* Time varying */
+#define TIME_VARIABLE 1 /* obsolate, use TIME_VARYING */
/* TSTEP types */
-#define TSTEP_CONSTANT 0 /* Constant */
#define TSTEP_INSTANT 1 /* Instant */
#define TSTEP_AVG 2 /* Average */
#define TSTEP_ACCUM 3 /* Accumulation */
@@ -378,11 +410,12 @@ typedef struct {
/* CALENDAR types */
#define CALENDAR_STANDARD 0 /* don't change this value (used also in cgribexlib)! */
-#define CALENDAR_PROLEPTIC 1
-#define CALENDAR_360DAYS 2
-#define CALENDAR_365DAYS 3
-#define CALENDAR_366DAYS 4
-#define CALENDAR_NONE 5
+#define CALENDAR_GREGORIAN 1
+#define CALENDAR_PROLEPTIC 2
+#define CALENDAR_360DAYS 3
+#define CALENDAR_365DAYS 4
+#define CALENDAR_366DAYS 5
+#define CALENDAR_NONE 6
/* number of unsigned char needed to store UUID */
#define CDI_UUID_SIZE 16
@@ -495,39 +528,39 @@ int streamInqCurTimestepID(int streamID);
const char *streamFilename(int streamID);
const char *streamFilesuffix(int filetype);
-off_t streamNvals(int streamID);
+size_t streamNvals(int streamID);
-int streamInqNvars ( int streamID );
+int streamInqNvars(int streamID);
-/* STREAM var I/O routines */
+/* STREAM var I/O routines (random access) */
/* streamWriteVar: Write a variable */
-void streamWriteVar(int streamID, int varID, const double data[], int nmiss);
-void streamWriteVarF(int streamID, int varID, const float data[], int nmiss);
+void streamWriteVar(int streamID, int varID, const double data[], size_t nmiss);
+void streamWriteVarF(int streamID, int varID, const float data[], size_t nmiss);
/* streamReadVar: Read a variable */
-void streamReadVar(int streamID, int varID, double data[], int *nmiss);
-void streamReadVarF(int streamID, int varID, float data[], int *nmiss);
+void streamReadVar(int streamID, int varID, double data[], size_t *nmiss);
+void streamReadVarF(int streamID, int varID, float data[], size_t *nmiss);
/* streamWriteVarSlice: Write a horizontal slice of a variable */
-void streamWriteVarSlice(int streamID, int varID, int levelID, const double data[], int nmiss);
-void streamWriteVarSliceF(int streamID, int varID, int levelID, const float data[], int nmiss);
+void streamWriteVarSlice(int streamID, int varID, int levelID, const double data[], size_t nmiss);
+void streamWriteVarSliceF(int streamID, int varID, int levelID, const float data[], size_t nmiss);
/* streamReadVarSlice: Read a horizontal slice of a variable */
-void streamReadVarSlice(int streamID, int varID, int levelID, double data[], int *nmiss);
-void streamReadVarSliceF(int streamID, int varID, int levelID, float data[], int *nmiss);
+void streamReadVarSlice(int streamID, int varID, int levelID, double data[], size_t *nmiss);
+void streamReadVarSliceF(int streamID, int varID, int levelID, float data[], size_t *nmiss);
-void streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double data[], int nmiss);
+void streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double data[], size_t nmiss);
-/* STREAM record I/O routines */
+/* STREAM record I/O routines (sequential access) */
void streamDefRecord(int streamID, int varID, int levelID);
void streamInqRecord(int streamID, int *varID, int *levelID);
-void streamWriteRecord(int streamID, const double data[], int nmiss);
-void streamWriteRecordF(int streamID, const float data[], int nmiss);
-void streamReadRecord(int streamID, double data[], int *nmiss);
-void streamReadRecordF(int streamID, float data[], int *nmiss);
+void streamWriteRecord(int streamID, const double data[], size_t nmiss);
+void streamWriteRecordF(int streamID, const float data[], size_t nmiss);
+void streamReadRecord(int streamID, double data[], size_t *nmiss);
+void streamReadRecordF(int streamID, float data[], size_t *nmiss);
void streamCopyRecord(int streamIDdest, int streamIDsrc);
void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
@@ -635,7 +668,7 @@ int vlistNsubtypes(int vlistID);
void vlistDefNtsteps(int vlistID, int nts);
int vlistNtsteps(int vlistID);
-int vlistGridsizeMax(int vlistID);
+size_t vlistGridsizeMax(int vlistID);
int vlistGrid(int vlistID, int index);
int vlistGridIndex(int vlistID, int gridID);
void vlistChangeGridIndex(int vlistID, int index, int gridID);
@@ -665,21 +698,24 @@ int vlistInqModel(int vlistID);
/* VLIST VAR routines */
/* vlistDefVarTiles: Create a new tile-based variable */
-int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int tilesetID);
+int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tilesetID);
/* vlistDefVar: Create a new variable */
-int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype);
+int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype);
void vlistChangeVarGrid(int vlistID, int varID, int gridID);
void vlistChangeVarZaxis(int vlistID, int varID, int zaxisID);
-void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype);
+void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *timetype);
int vlistInqVarGrid(int vlistID, int varID);
int vlistInqVarZaxis(int vlistID, int varID);
/* used in MPIOM */
int vlistInqVarID(int vlistID, int code);
+void vlistDefVarTimetype(int vlistID, int varID, int timetype);
+int vlistInqVarTimetype(int vlistID, int varID);
+
void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
/* vlistInqVarTsteptype: Get the timestep type of a Variable */
@@ -778,7 +814,7 @@ int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID);
void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDefinitionTemplate);
int vlistInqVarProductDefinitionTemplate(int vlistID, int varID);
-int vlistInqVarSize(int vlistID, int varID);
+size_t vlistInqVarSize(int vlistID, int varID);
void vlistDefIndex(int vlistID, int varID, int levID, int index);
int vlistInqIndex(int vlistID, int varID, int levID);
@@ -810,32 +846,29 @@ double vlistInqVarDblKey(int vlistID, int varID, const char *name);
/* vlistInqVarIntKey: raw access to GRIB meta-data */
int vlistInqVarIntKey(int vlistID, int varID, const char *name);
-/* needed only for CDO operator after */
-const char *vlistInqVarNamePtr(int vlistID, int varID);
-const char *vlistInqVarLongnamePtr(int vlistID, int varID);
-const char *vlistInqVarUnitsPtr(int vlistID, int varID);
+/* CDI attributes */
-/* VLIST attributes */
+/* cdiInqNatts: Get number of attributes assigned to this variable */
+int cdiInqNatts(int cdiID, int varID, int *nattsp);
+/* cdiInqAtt: Get information about an attribute */
+int cdiInqAtt(int cdiID, int varID, int attrnum, char *name, int *typep, int *lenp);
+int cdiDelAtt(int cdiID, int varID, const char *name);
-/* vlistInqNatts: Get number of variable attributes assigned to this variable */
-int vlistInqNatts(int vlistID, int varID, int *nattsp);
-/* vlistInqAtt: Get information about an attribute */
-int vlistInqAtt(int vlistID, int varID, int attrnum, char *name, int *typep, int *lenp);
-int vlistDelAtt(int vlistID, int varID, const char *name);
+int cdiCopyAtts(int cdiID1, int varID1, int cdiID2, int varID2);
-/* vlistDefAttInt: Define an integer attribute */
-int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int ip[]);
-/* vlistDefAttFlt: Define a floating point attribute */
-int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double dp[]);
-/* vlistDefAttTxt: Define a text attribute */
-int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp_cbuf);
+/* cdiDefAttInt: Define an integer attribute */
+int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int ip[]);
+/* cdiDefAttFlt: Define a floating point attribute */
+int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double dp[]);
+/* cdiDefAttTxt: Define a text attribute */
+int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp_cbuf);
-/* vlistInqAttInt: Get the value(s) of an integer attribute */
-int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int ip[]);
-/* vlistInqAttFlt: Get the value(s) of a floating point attribute */
-int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double dp[]);
-/* vlistInqAttTxt: Get the value(s) of a text attribute */
-int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp_cbuf);
+/* cdiInqAttInt: Get the value(s) of an integer attribute */
+int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int ip[]);
+/* cdiInqAttFlt: Get the value(s) of a floating point attribute */
+int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double dp[]);
+/* cdiInqAttTxt: Get the value(s) of a text attribute */
+int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp_cbuf);
/* GRID routines */
@@ -851,10 +884,10 @@ int gridInqMaskGME(int gridID, int mask[]);
void gridDefMask(int gridID, const int mask[]);
int gridInqMask(int gridID, int mask[]);
-void gridPrint(int gridID, int index, int opt);
+void gridPrint(int gridID, int opt);
/* gridCreate: Create a horizontal Grid */
-int gridCreate(int gridtype, int size);
+int gridCreate(int gridtype, size_t size);
/* gridDestroy: Destroy a horizontal Grid */
void gridDestroy(int gridID);
@@ -862,23 +895,32 @@ void gridDestroy(int gridID);
/* gridDuplicate: Duplicate a Grid */
int gridDuplicate(int gridID);
+/* gridDefProj: Define the projection ID of a Grid */
+void gridDefProj(int gridID, int projID);
+
+/* gridInqProj: Get the projection ID of a Grid */
+int gridInqProj(int gridID);
+
+/* gridInqProjType: Get the projection type */
+int gridInqProjType(int gridID);
+
/* gridInqType: Get the type of a Grid */
int gridInqType(int gridID);
/* gridInqSize: Get the size of a Grid */
-int gridInqSize(int gridID);
+size_t gridInqSize(int gridID);
/* gridDefXsize: Define the size of a X-axis */
-void gridDefXsize(int gridID, int xsize);
+void gridDefXsize(int gridID, size_t xsize);
/* gridInqXsize: Get the size of a X-axis */
-int gridInqXsize(int gridID);
+size_t gridInqXsize(int gridID);
/* gridDefYsize: Define the size of a Y-axis */
-void gridDefYsize(int gridID, int ysize);
+void gridDefYsize(int gridID, size_t ysize);
/* gridInqYsize: Get the size of a Y-axis */
-int gridInqYsize(int gridID);
+size_t gridInqYsize(int gridID);
/* gridDefNP: Define the number of parallels between a pole and the equator */
void gridDefNP(int gridID, int np);
@@ -890,30 +932,59 @@ int gridInqNP(int gridID);
void gridDefXvals(int gridID, const double xvals[]);
/* gridInqXvals: Get all values of a X-axis */
-int gridInqXvals(int gridID, double xvals[]);
+size_t gridInqXvals(int gridID, double xvals[]);
+
+/* gridInqXIsc: Find out whether X-coordinate is of type CHAR */
+int gridInqXIsc(int gridID);
+
+/* gridInqXCvals: Get strings from X-axis in case grid is of type GRID_CHARXY */
+size_t gridInqXCvals(int gridID, char *xcvals[]);
/* gridDefYvals: Define the values of a Y-axis */
void gridDefYvals(int gridID, const double yvals[]);
/* gridInqYvals: Get all values of a Y-axis */
-int gridInqYvals(int gridID, double yvals[]);
+size_t gridInqYvals(int gridID, double yvals[]);
+
+/* gridInqYIsc: Find out whether Y-coordinate is of type CHAR */
+int gridInqYIsc(int gridID);
+
+/* gridInqYCvals: Get strings from Y-axis in case grid is of type GRID_CHARXY */
+size_t gridInqYCvals(int gridID, char *ycvals[]);
/* CDI grid string key values */
-#define CDI_GRID_XNAME 901 // X-axis name
-#define CDI_GRID_YNAME 902 // Y-axis name
-#define CDI_GRID_XDIMNAME 903 // X-axis dimension name
-#define CDI_GRID_YDIMNAME 904 // Y-axis dimension name
-#define CDI_GRID_VDIMNAME 905 // Vertex dimension name
-#define CDI_GRID_XLONGNAME 906 // X-axis longname
-#define CDI_GRID_YLONGNAME 907 // Y-axis longname
-#define CDI_GRID_XUNITS 908 // X-axis units
-#define CDI_GRID_YUNITS 909 // Y-axis units
-
-// cdiGridDefString: Define a CDI grid string value from a key
-int cdiGridDefString(int gridID, int key, int size, const char *mesg);
-
-// cdiGridInqString: Get a CDI grid string value from a key
-int cdiGridInqString(int gridID, int key, int size, char *mesg);
+#define CDI_KEY_XNAME 901 // X-axis name
+#define CDI_KEY_XDIMNAME 902 // X-axis dimension name
+#define CDI_KEY_XLONGNAME 903 // X-axis longname
+#define CDI_KEY_XUNITS 904 // X-axis units
+#define CDI_KEY_YNAME 911 // Y-axis name
+#define CDI_KEY_YDIMNAME 912 // Y-axis dimension name
+#define CDI_KEY_YLONGNAME 913 // Y-axis longname
+#define CDI_KEY_YUNITS 914 // Y-axis units
+#define CDI_KEY_VDIMNAME 920 // Vertex dimension name
+#define CDI_KEY_MAPPING 921 // Grid mapping var name
+#define CDI_KEY_MAPNAME 922 // Grid mapping name
+
+/* CDI zaxis string key values */
+#define CDI_KEY_NAME 941 // Z-axis name
+#define CDI_KEY_DIMNAME 942 // Z-axis dimension name
+#define CDI_KEY_LONGNAME 943 // Z-axis longname
+#define CDI_KEY_UNITS 944 // Z-axis units
+#define CDI_KEY_PSNAME 950 // Z-axis surface pressure name
+#define CDI_KEY_P0NAME 951 // Z-axis reference pressure name
+#define CDI_KEY_P0VALUE 952 // Z-axis reference pressure in Pa
+
+// cdiGridDefKeyStr: Define a CDI grid string value from a key
+int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg);
+
+// cdiGridInqKeyStr: Get a CDI grid string value from a key
+int cdiGridInqKeyStr(int gridID, int key, int size, char *mesg);
+
+// cdiZaxisDefKeyFlt: Define a CDI Z-axis floating point value from a key
+int cdiZaxisDefKeyFlt(int zaxisID, int key, double value);
+
+// cdiZaxisInqKeyFlt: Get a CDI Z-axis floating point value from a key
+int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value);
/* gridDefXname: Define the name of a X-axis */
void gridDefXname(int gridID, const char *xname);
@@ -957,40 +1028,25 @@ void gridInqXstdname(int gridID, char *xstdname);
/* gridInqYstdname: Get the standard name of a Y-axis */
void gridInqYstdname(int gridID, char *ystdname);
-/* gridDefPrec: Define the precision of a Grid */
-void gridDefPrec(int gridID, int prec);
+/* gridDefDatatype: Define the data type of a Grid */
+void gridDefDatatype(int gridID, int prec);
-/* gridInqPrec: Get the precision of a Grid */
-int gridInqPrec(int gridID);
+/* gridInqDatatype: Get the data type of a Grid */
+int gridInqDatatype(int gridID);
/* gridInqXval: Get one value of a X-axis */
-double gridInqXval(int gridID, int index);
+double gridInqXval(int gridID, size_t index);
/* gridInqYval: Get one value of a Y-axis */
-double gridInqYval(int gridID, int index);
+double gridInqYval(int gridID, size_t index);
double gridInqXinc(int gridID);
double gridInqYinc(int gridID);
int gridIsCircular(int gridID);
-int gridIsRotated(int gridID);
-void gridDefXpole(int gridID, double xpole);
-double gridInqXpole(int gridID);
-void gridDefYpole(int gridID, double ypole);
-double gridInqYpole(int gridID);
-void gridDefAngle(int gridID, double angle);
-double gridInqAngle(int gridID);
+
int gridInqTrunc(int gridID);
void gridDefTrunc(int gridID, int trunc);
-/* Hexagonal GME grid */
-void gridDefGMEnd(int gridID, int nd);
-int gridInqGMEnd(int gridID);
-void gridDefGMEni(int gridID, int ni);
-int gridInqGMEni(int gridID);
-void gridDefGMEni2(int gridID, int ni2);
-int gridInqGMEni2(int gridID);
-void gridDefGMEni3(int gridID, int ni3);
-int gridInqGMEni3(int gridID);
/* Reference of an unstructured grid */
@@ -1026,18 +1082,17 @@ void gridInqUUID(int gridID, unsigned char *uuid);
void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE]);
#endif
-/* Lambert Conformal Conic grid (GRIB version) */
-void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag);
-void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag);
+/* Rotated Lon/Lat grid */
+void gridDefParamRLL(int gridID, double xpole, double ypole, double angle);
+void gridInqParamRLL(int gridID, double *xpole, double *ypole, double *angle);
-/* Lambert Conformal Conic 2 grid (PROJ version) */
-void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2);
-void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0, double *lat_1, double *lat_2);
-
-/* Lambert Azimuthal Equal Area grid */
-void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0);
-void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0);
+/* Hexagonal GME grid */
+void gridDefParamGME(int gridID, int nd, int ni, int ni2, int ni3);
+void gridInqParamGME(int gridID, int *nd, int *ni, int *ni2, int *ni3);
+ /* Lambert Conformal Conic grid (GRIB version) */
+void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double xval_0, double yval_0, double x_0, double y_0);
+int gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2, double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0);
void gridDefArea(int gridID, const double area[]);
void gridInqArea(int gridID, double area[]);
@@ -1053,13 +1108,13 @@ int gridInqNvertex(int gridID);
void gridDefXbounds(int gridID, const double xbounds[]);
/* gridInqXbounds: Get the bounds of a X-axis */
-int gridInqXbounds(int gridID, double xbounds[]);
+size_t gridInqXbounds(int gridID, double xbounds[]);
/* gridDefYbounds: Define the bounds of a Y-axis */
void gridDefYbounds(int gridID, const double ybounds[]);
/* gridInqYbounds: Get the bounds of a Y-axis */
-int gridInqYbounds(int gridID, double ybounds[]);
+size_t gridInqYbounds(int gridID, double ybounds[]);
void gridDefRowlon(int gridID, int nrowlon, const int rowlon[]);
void gridInqRowlon(int gridID, int rowlon[]);
@@ -1068,9 +1123,16 @@ void gridChangeType(int gridID, int gridtype);
void gridDefComplexPacking(int gridID, int lpack);
int gridInqComplexPacking(int gridID);
+void gridDefUvRelativeToGrid(int gridID, int uvRelativeToGrid);
+int gridInqUvRelativeToGrid(int gridID);
+
+void gridDefScanningMode(int gridID, int mode);
+int gridInqScanningMode(int gridID);
+
/* ZAXIS routines */
void zaxisName(int zaxistype, char *zaxisname);
+const char *zaxisNamePtr(int leveltype);
/* zaxisCreate: Create a vertical Z-axis */
int zaxisCreate(int zaxistype, int size);
@@ -1087,15 +1149,22 @@ int zaxisInqSize(int zaxisID);
/* zaxisDuplicate: Duplicate a Z-axis */
int zaxisDuplicate(int zaxisID);
-void zaxisResize(int zaxisID, int size);
-
-void zaxisPrint(int zaxisID, int index);
+void zaxisPrint(int zaxisID);
/* zaxisDefLevels: Define the levels of a Z-axis */
void zaxisDefLevels(int zaxisID, const double levels[]);
+/* zaxisDefCvals: Define area types of a Z-axis */
+void zaxisDefCvals(int zaxisID, const char *cvals[], int clength);
+
/* zaxisInqLevels: Get all levels of a Z-axis */
-void zaxisInqLevels(int zaxisID, double levels[]);
+int zaxisInqLevels(int zaxisID, double levels[]);
+
+/* zaxisInqCLen: Get maximal string length of character Z-axis */
+int zaxisInqCLen(int zaxisID);
+
+/* zaxisInqCVals: Get all string values of a character Z-axis */
+int zaxisInqCVals(int zaxisID, char ***clevels);
/* zaxisDefLevel: Define one level of a Z-axis */
void zaxisDefLevel(int zaxisID, int levelID, double levels);
@@ -1121,18 +1190,11 @@ void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE]);
/* zaxisInqUUID: Get the UUID of a generalized Z-axis */
void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE]);
-/* CDI zaxis string key values */
-#define CDI_ZAXIS_NAME 801 // Z-axis name
-#define CDI_ZAXIS_DIMNAME 802 // Z-axis dimension name
-#define CDI_ZAXIS_VDIMNAME 803 // Vertex dimension name
-#define CDI_ZAXIS_LONGNAME 804 // Z-axis longname
-#define CDI_ZAXIS_UNITS 805 // Z-axis units
-
-// cdiZaxisDefString: Define a CDI Z-axis string value from a key
-int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg);
+// cdiZaxisDefKeyStr: Define a CDI Z-axis string value from a key
+int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg);
-// cdiZaxisInqString: Get a CDI Z-axis string value from a key
-int cdiZaxisInqString(int zaxisID, int key, int size, char *mesg);
+// cdiZaxisInqKeyStr: Get a CDI Z-axis string value from a key
+int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg);
/* zaxisDefName: Define the name of a Z-axis */
void zaxisDefName(int zaxisID, const char *name_optional);
@@ -1155,14 +1217,8 @@ void zaxisInqUnits(int zaxisID, char *units);
/* zaxisInqStdname: Get the standard name of a Z-axis */
void zaxisInqStdname(int zaxisID, char *stdname);
-/* zaxisDefPsName: Define the name of the surface pressure variable of a hybrid sigma pressure Z-axis */
-void zaxisDefPsName(int zaxisID, const char *psname_optional);
-
-/* zaxisInqPsName: Get the name of the surface pressure variable of a hybrid sigma pressure Z-axis */
-void zaxisInqPsName(int zaxisID, char *psname);
-
-void zaxisDefPrec(int zaxisID, int prec);
-int zaxisInqPrec(int zaxisID);
+void zaxisDefDatatype(int zaxisID, int prec);
+int zaxisInqDatatype(int zaxisID);
void zaxisDefPositive(int zaxisID, int positive);
int zaxisInqPositive(int zaxisID);
@@ -1173,7 +1229,6 @@ int zaxisInqScalar(int zaxisID);
void zaxisDefLtype(int zaxisID, int ltype);
int zaxisInqLtype(int zaxisID);
-const double *zaxisInqLevelsPtr(int zaxisID);
void zaxisDefVct(int zaxisID, int size, const double vct[]);
void zaxisInqVct(int zaxisID, double vct[]);
int zaxisInqVctSize(int zaxisID);
@@ -1239,6 +1294,7 @@ int taxisInqFdate(int taxisID);
int taxisInqFtime(int taxisID);
int taxisHasBounds(int taxisID);
+void taxisWithBounds(int taxisID);
void taxisDeleteBounds(int taxisID);
@@ -1294,8 +1350,6 @@ const char *modelInqNamePtr(int modelID);
/* Table routines */
-/* tableWriteC: write table of parameters to file in C language format */
-void tableWriteC(const char *filename, int tableID);
/* tableFWriteC: write table of parameters to FILE* in C language format */
void tableFWriteC(FILE *ptfp, int tableID);
/* tableWrite: write table of parameters to file in tabular format */
@@ -1305,7 +1359,6 @@ int tableRead(const char *tablefile);
int tableDef(int modelID, int tablenum, const char *tablename);
const char *tableInqNamePtr(int tableID);
-void tableDefEntry(int tableID, int code, const char *name, const char *longname, const char *units);
int tableInq(int modelID, int tablenum, const char *tablename);
int tableInqNumber(void);
@@ -1313,17 +1366,7 @@ int tableInqNumber(void);
int tableInqNum(int tableID);
int tableInqModel(int tableID);
-void tableInqPar(int tableID, int code, char *name, char *longname, char *units);
-
-int tableInqParCode(int tableID, char *name, int *code);
-int tableInqParName(int tableID, int code, char *name);
-int tableInqParLongname(int tableID, int code, char *longname);
-int tableInqParUnits(int tableID, int code, char *units);
-
-/* needed only for CDO operator after */
-const char *tableInqParNamePtr(int tableID, int parID);
-const char *tableInqParLongnamePtr(int tableID, int parID);
-const char *tableInqParUnitsPtr(int tableID, int parID);
+void tableInqEntry(int tableID, int id, int ltype, char *name, char *longname, char *units);
/* History routines */
@@ -1390,6 +1433,8 @@ void gribapiLibraryVersion(int *major_version, int *minor_version, int *revision
#ifndef _BASETIME_H
#define _BASETIME_H
+#include <stdbool.h>
+
//#define USE_TIMECACHE 1
#define MAX_TIMECACHE_SIZE 1024
@@ -1406,7 +1451,7 @@ typedef struct {
int ncdimid;
int ncvarboundsid;
int leadtimeid;
- int lwrf; /* TRUE for time axis in WRF format */
+ bool lwrf; /* true for time axis in WRF format */
timecache_t *timevar_cache;
}
basetime_t;
@@ -1427,21 +1472,20 @@ void basetimeInit(basetime_t *basetime);
#endif
#include <stdio.h>
+#include <stdbool.h>
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
void basetimeInit(basetime_t *basetime)
{
if ( basetime == NULL )
Error("Internal problem! Basetime not allocated.");
- basetime->ncvarid = UNDEFID;
- basetime->ncdimid = UNDEFID;
- basetime->ncvarboundsid = UNDEFID;
- basetime->leadtimeid = UNDEFID;
- basetime->lwrf = 0;
+ basetime->ncvarid = CDI_UNDEFID;
+ basetime->ncdimid = CDI_UNDEFID;
+ basetime->ncvarboundsid = CDI_UNDEFID;
+ basetime->leadtimeid = CDI_UNDEFID;
+ basetime->lwrf = false;
basetime->timevar_cache = NULL;
}
/*
@@ -1582,8 +1626,8 @@ void swap8byte(void *ptr, size_t size);
* require-trailing-newline: t
* End:
*/
-#ifndef _BINARY_H
-#define _BINARY_H
+#ifndef BINARY_H
+#define BINARY_H
#ifdef HAVE_CONFIG_H
#endif
@@ -1623,7 +1667,7 @@ int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
-#endif /* _BINARY_H */
+#endif /* BINARY_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -1981,9 +2025,9 @@ void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *mo
-static int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
-static int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static const int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
+static const int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static const int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int calendar_dpy(int calendar)
@@ -2000,9 +2044,9 @@ int calendar_dpy(int calendar)
int days_per_month(int calendar, int year, int month)
{
- int *dpm = NULL;
int daysperyear = calendar_dpy(calendar);
+ const int *dpm;
if ( daysperyear == 360 ) dpm = month_360;
else if ( daysperyear == 365 ) dpm = month_365;
else dpm = month_366;
@@ -2032,7 +2076,7 @@ int days_per_year(int calendar, int year)
if ( daysperyear == 0 )
{
- if ( year == 1582 && calendar == CALENDAR_STANDARD )
+ if ( year == 1582 && (calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN) )
daysperyear = 355;
else if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
daysperyear = 366;
@@ -2047,11 +2091,11 @@ int days_per_year(int calendar, int year)
static void decode_day(int dpy, int days, int *year, int *month, int *day)
{
int i = 0;
- int *dpm = NULL;
*year = (days-1) / dpy;
days -= (*year*dpy);
+ const int *dpm = NULL;
if ( dpy == 360 ) dpm = month_360;
else if ( dpy == 365 ) dpm = month_365;
else if ( dpy == 366 ) dpm = month_366;
@@ -2070,9 +2114,9 @@ static void decode_day(int dpy, int days, int *year, int *month, int *day)
static int encode_day(int dpy, int year, int month, int day)
{
- int *dpm = NULL;
long rval = (long)dpy * year + day;
+ const int *dpm = NULL;
if ( dpy == 360 ) dpm = month_360;
else if ( dpy == 365 ) dpm = month_365;
else if ( dpy == 366 ) dpm = month_366;
@@ -2285,8 +2329,8 @@ int main(void)
* require-trailing-newline: t
* End:
*/
-#ifndef _CDF_H
-#define _CDF_H
+#ifndef CDF_H
+#define CDF_H
void cdfDebug(int debug);
@@ -2295,12 +2339,11 @@ extern int CDF_Debug;
const char *cdfLibraryVersion(void);
const char *hdfLibraryVersion(void);
-int cdfOpen(const char *filename, const char *mode);
-int cdfOpen64(const char *filename, const char *mode);
+int cdfOpen(const char *filename, const char *mode, int filetype);
int cdf4Open(const char *filename, const char *mode, int *filetype);
void cdfClose(int fileID);
-#endif /* _CDF_H */
+#endif /* CDF_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -2310,6 +2353,23 @@ void cdfClose(int fileID);
* require-trailing-newline: t
* End:
*/
+#ifndef CDF_CONFIG_H_
+#define CDF_CONFIG_H_
+
+#ifdef HAVE_CONFIG_H
+#endif
+
+#ifdef HAVE_LIBNETCDF
+
+#include <netcdf.h>
+
+#ifdef NC_FORMAT_64BIT_DATA
+#define HAVE_NETCDF5 1
+#endif
+
+#endif
+
+#endif
#ifndef RESOURCE_HANDLE_H
#define RESOURCE_HANDLE_H
@@ -2410,6 +2470,7 @@ enum reshListMismatch {
int reshListCompare(int nsp0, int nsp1);
void reshListPrint(FILE *fp);
+int reshGetTxCode(cdiResH resH);
#endif
/*
@@ -2424,6 +2485,8 @@ void reshListPrint(FILE *fp);
#ifndef _TAXIS_H
#define _TAXIS_H
+#include <stdbool.h>
+
#ifndef RESOURCE_HANDLE_H
#endif
@@ -2431,8 +2494,9 @@ typedef struct {
/* Date format YYYYMMDD */
/* Time format hhmmss */
int self;
- short used;
+ bool used;
short has_bounds;
+ int datatype; // datatype
int type; // time type
int vdate; // verification date
int vtime; // verification time
@@ -2443,15 +2507,16 @@ typedef struct {
int calendar;
int unit; // time unit
int numavg;
- int climatology;
+ bool climatology;
int vdate_lb; // lower bounds of vdate
int vtime_lb; // lower bounds of vtime
int vdate_ub; // upper bounds of vdate
int vtime_ub; // upper bounds of vtime
int fc_unit; // forecast time unit
double fc_period; // forecast time period
- char* name;
- char* longname;
+ char *name;
+ char *longname;
+ char *units;
}
taxis_t;
@@ -2464,8 +2529,10 @@ double cdiEncodeTimeval(int date, int time, taxis_t* taxis);
void timeval2vtime(double timevalue, taxis_t* taxis, int* vdate, int* vtime);
double vtime2timeval(int vdate, int vtime, taxis_t *taxis);
+void ptaxisDefDatatype(taxis_t *taxisptr, int datatype);
void ptaxisDefName(taxis_t *taxisptr, const char *name);
-void ptaxisDefLongname(taxis_t *taxisptr, const char *name);
+void ptaxisDefLongname(taxis_t *taxisptr, const char *longname);
+void ptaxisDefUnits(taxis_t *taxisptr, const char *units);
void taxisDestroyKernel(taxis_t *taxisptr);
#if !defined (SX)
extern const resOps taxisOps;
@@ -2617,7 +2684,6 @@ int extDefDataDP(void *ext, const double *data);
#define IEG_LTYPE_LANDDEPTH 111
#define IEG_LTYPE_LANDDEPTH_LAYER 112
#define IEG_LTYPE_SEADEPTH 160
-#define IEG_LTYPE_99_MARGIN 1000
/*
* Data representation type (Grid Type) [Table 6]
@@ -2703,8 +2769,8 @@ int iegDefDataDP(void *ieg, const double *data);
* require-trailing-newline: t
* End:
*/
-#ifndef _CDI_INT_H
-#define _CDI_INT_H
+#ifndef CDI_INT_H
+#define CDI_INT_H
#if defined (HAVE_CONFIG_H)
#endif
@@ -2714,6 +2780,7 @@ int iegDefDataDP(void *ieg, const double *data);
#include <stdbool.h>
#include <string.h>
#include <errno.h>
+#include <limits.h>
#include <math.h>
#include <sys/types.h>
@@ -2744,7 +2811,7 @@ char *strdup(const char *s);
#endif
-#ifndef _ERROR_H
+#ifndef ERROR_H
#endif
#ifndef _BASETIME_H
#endif
@@ -2846,9 +2913,17 @@ typedef struct
int ilevel2;
int ltype;
short tsteptype;
- short used;
+#ifdef HIRLAM_EXTENSIONS
+ // NOTE: tsteptype MUST be part of attributes used to compare variables!
+ // Modern NWP models (HARMONIE, HIRLAM) use timeRangeIndicator to specify
+ // if the field is instantanous or accumulated.
+ // Both types are typically in the same GRIB-file.
+ // (181; 105, 0, timeRangeIndicator=0) .. instantanous rain
+ // (181; 105, 0, timeRangeIndicator=4) .. accumulated rain .. both can be in the same grib file
+#endif // HIRLAM_EXTENSIONS
short varID;
short levelID;
+ short used;
char varname[32]; /* needed for grib decoding with GRIB_API */
var_tile_t tiles; /* tile-related meta-data, currently for GRIB-API only. */
}
@@ -2864,7 +2939,7 @@ typedef struct {
/* tsID>0 number of non constant records */
int nallrecs; /* number of all records */
int curRecID; /* current record ID */
- long next;
+ bool next;
off_t position; /* timestep file position */
taxis_t taxis;
}
@@ -2882,14 +2957,14 @@ typedef struct {
typedef struct {
int ncvarid;
int subtypeSize;
- sleveltable_t *recordTable; /* record IDs for each subtype */
- int defmiss; /* TRUE if missval is defined in file */
+ sleveltable_t *recordTable; // record IDs for each subtype
+ bool defmiss; // true: if missval is defined in file
+ bool isUsed;
- int isUsed;
int gridID;
int zaxisID;
- int tsteptype; /* TSTEP_* */
- int subtypeID; /* subtype ID, e.g. for tile-related meta-data (currently for GRIB-API only). */
+ int tsteptype; // TSTEP_*
+ int subtypeID; // subtype ID, e.g. for tile-related meta-data (currently for GRIB-API only).
}
svarinfo_t;
@@ -2902,6 +2977,21 @@ typedef struct {
}
VCT;
+#ifdef HAVE_LIBNETCDF
+enum {
+ CDF_DIMID_X,
+ CDF_DIMID_Y,
+ CDF_VARID_X,
+ CDF_VARID_Y,
+ CDF_VARID_A,
+ CDF_SIZE_ncIDs,
+};
+typedef struct {
+ int gridID;
+ int ncIDs[CDF_SIZE_ncIDs];
+}
+ncgrid_t;
+#endif
typedef struct {
int self;
@@ -2912,7 +3002,7 @@ typedef struct {
int fileID;
int filemode;
int nrecs; /* number of records */
- off_t numvals;
+ size_t numvals;
char *filename;
Record *record;
svarinfo_t *vars;
@@ -2927,22 +3017,21 @@ typedef struct {
basetime_t basetime;
int ncmode;
int vlistID;
- int xdimID[MAX_GRIDS_PS]; //Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
- int ydimID[MAX_GRIDS_PS]; //Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
+#ifdef HAVE_LIBNETCDF
+ ncgrid_t ncgrid[MAX_GRIDS_PS];
int zaxisID[MAX_ZAXES_PS]; //Warning: synchronous array to vlist_to_pointer(vlistID)->zaxisIDs
int nczvarID[MAX_ZAXES_PS];
- int ncxvarID[MAX_GRIDS_PS];
- int ncyvarID[MAX_GRIDS_PS];
- int ncavarID[MAX_GRIDS_PS];
+ VCT vct;
+#endif
int historyID;
int globalatts;
int localatts;
- VCT vct;
int unreduced;
- int sortname;
int have_missval;
int comptype; // compression type
int complevel; // compression level
+ bool sortname;
+ bool sortparam;
#if defined (GRIBCONTAINER2D)
void **gribContainers;
#else
@@ -2969,7 +3058,7 @@ typedef enum {
typedef struct
{
char* keyword; /* keyword string */
- int update;
+ bool update;
key_val_pair_datatype data_type; /* data type of this key/value pair */
double dbl_val; /* double value (data_type == t_double) */
int int_val; /* integer value (data_type == t_int) */
@@ -2984,8 +3073,10 @@ typedef enum {
} CdiTimeType;
+#define CDI_FILETYPE_UNDEF -1 /* Unknown/not yet defined file type */
+extern int cdiDebugExt;
extern int CDI_Debug; /* If set to 1, debuggig (default 0) */
extern int CDI_Recopt;
extern int cdiGribApiDebug;
@@ -3001,14 +3092,17 @@ extern int cdiChunkType;
extern int cdiSplitLtype105;
extern int cdiDataUnreduced;
extern int cdiSortName;
+extern int cdiSortParam;
extern int cdiHaveMissval;
-extern int cdiIgnoreAttCoordinates;
-extern int cdiIgnoreValidRange;
+extern bool cdiIgnoreAttCoordinates;
+extern bool cdiCoordinatesLonLat;
+extern bool cdiIgnoreValidRange;
extern int cdiSkipRecords;
extern int cdiConvention;
extern int cdiInventoryMode;
extern int CDI_Version_Info;
extern int CDI_cmor_mode;
+extern int CDI_reduce_dim;
extern size_t CDI_netcdf_hdr_pad;
extern bool CDI_netcdf_lazy_grid_load;
extern int STREAM_Debug;
@@ -3035,8 +3129,6 @@ int streamInqFileID(int streamID);
void gridDefHasDims(int gridID, int hasdims);
int gridInqHasDims(int gridID);
-const char *gridNamePtr(int gridtype);
-const char *zaxisNamePtr(int leveltype);
int zaxisInqLevelID(int zaxisID, double level);
void streamCheckID(const char *caller, int streamID);
@@ -3060,6 +3152,8 @@ void vlist_check_contents(int vlistID);
void cdi_create_records(stream_t *streamptr, int tsID);
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name);
+
int recordNewEntry(stream_t *streamptr, int tsID);
void cdiCreateTimesteps(stream_t *streamptr);
@@ -3068,8 +3162,6 @@ void recordInitEntry(record_t *record);
void cdiCheckZaxis(int zaxisID);
-void cdiPrintDatatypes(void);
-
void cdiDefAccesstype(int streamID, int type);
int cdiInqAccesstype(int streamID);
@@ -3111,11 +3203,11 @@ void
cdiStreamDefVlist_(int streamID, int vlistID);
int
-cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss);
+cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, size_t nmiss);
void
cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss);
+ const int rect[][2], const void *data, size_t nmiss);
void
cdiStreamCloseDefaultDelegate(stream_t *streamptr,
int recordBufIsToBeDeleted);
@@ -3149,11 +3241,18 @@ void cdiDefTableID(int tableID);
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals);
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals);
+static inline
+void cdi_check_gridsize_int_limit(const char *format, size_t gridsize)
+{
+ if ( gridsize > INT_MAX ) Error("%s format grid size (%zu) limit exceeded (%zu)!", format, gridsize, INT_MAX);
+}
+
+
#if defined (__cplusplus)
}
#endif
-#endif /* _CDI_INT_H */
+#endif /* CDI_INT_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -3163,8 +3262,8 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
* require-trailing-newline: t
* End:
*/
-#ifndef _CDF_INT_H
-#define _CDF_INT_H
+#ifndef CDF_INT_H
+#define CDF_INT_H
#if defined (HAVE_LIBNETCDF)
@@ -3241,6 +3340,7 @@ void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype, si
void cdf_get_att_string(int ncid, int varid, const char *name, char **tp);
void cdf_get_att_text (int ncid, int varid, const char *name, char *tp);
void cdf_get_att_int (int ncid, int varid, const char *name, int *ip);
+void cdf_get_att_long (int ncid, int varid, const char *name, long *ip);
void cdf_get_att_double(int ncid, int varid, const char *name, double *dp);
void cdf_inq_att (int ncid, int varid, const char *name, nc_type * xtypep, size_t * lenp);
@@ -3249,6 +3349,8 @@ void cdf_inq_attlen (int ncid, int varid, const char *name, size_t *lenp);
void cdf_inq_attname(int ncid, int varid, int attnum, char *name);
void cdf_inq_attid (int ncid, int varid, const char *name, int *attnump);
+void cdf_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp);
+
typedef int (*cdi_nc__create_funcp)(const char *path, int cmode,
size_t initialsz, size_t *chunksizehintp,
int *ncidp);
@@ -3259,7 +3361,7 @@ typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
#endif
-#endif /* _CDF_INT_H */
+#endif /* CDF_INT_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -3269,7 +3371,7 @@ typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
* require-trailing-newline: t
* End:
*/
-#if defined (HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#endif
#include <stdio.h>
@@ -3282,32 +3384,32 @@ typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
const char *cdfLibraryVersion(void)
{
-#if defined (HAVE_LIBNETCDF)
+#ifdef HAVE_LIBNETCDF
return nc_inq_libvers();
#else
return "library undefined";
#endif
}
-#if defined(HAVE_H5GET_LIBVERSION)
-#if defined(__cplusplus)
+#ifdef HAVE_H5GET_LIBVERSION
+#ifdef __cplusplus
extern "C" {
#endif
int H5get_libversion(unsigned *, unsigned *, unsigned *);
-#if defined(__cplusplus)
+#ifdef __cplusplus
}
#endif
#endif
const char *hdfLibraryVersion(void)
{
-#if defined(HAVE_H5GET_LIBVERSION)
+#ifdef HAVE_H5GET_LIBVERSION
static char hdf_libvers[256];
unsigned majnum, minnum, relnum;
H5get_libversion(&majnum, &minnum, &relnum);
-#if defined(HAVE_NC4HDF5_THREADSAFE)
+#ifdef HAVE_NC4HDF5_THREADSAFE
sprintf(hdf_libvers, "%u.%u.%u threadsafe", majnum, minnum, relnum);
#else
sprintf(hdf_libvers, "%u.%u.%u", majnum, minnum, relnum);
@@ -3330,7 +3432,7 @@ void cdfDebug(int debug)
Message("debug level %d", debug);
}
-#if defined (HAVE_LIBNETCDF)
+#ifdef HAVE_LIBNETCDF
static
void cdfComment(int ncid)
{
@@ -3358,11 +3460,10 @@ void cdfComment(int ncid)
static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
{
int ncid = -1;
-#if defined (HAVE_LIBNETCDF)
+#ifdef HAVE_LIBNETCDF
int fmode = tolower(*mode);
int writemode = NC_CLOBBER;
int readmode = NC_NOWRITE;
- int status;
if ( filename == NULL )
ncid = CDI_EINVAL;
@@ -3371,31 +3472,34 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
switch (fmode)
{
case 'r':
- status = cdf_open(filename, readmode, &ncid);
- if ( status > 0 && ncid < 0 ) ncid = CDI_ESYSTEM;
-#if defined (HAVE_NETCDF4)
- else
- {
- int format;
- (void) nc_inq_format(ncid, &format);
- if ( format == NC_FORMAT_NETCDF4_CLASSIC )
- {
- *filetype = FILETYPE_NC4C;
- }
- }
+ {
+ int status = cdf_open(filename, readmode, &ncid);
+ if ( status > 0 && ncid < 0 ) ncid = CDI_ESYSTEM;
+#ifdef HAVE_NETCDF4
+ else
+ {
+ int format;
+ (void) nc_inq_format(ncid, &format);
+ if ( format == NC_FORMAT_NETCDF4_CLASSIC )
+ *filetype = CDI_FILETYPE_NC4C;
+ }
#endif
+ }
break;
case 'w':
-#if defined (NC_64BIT_OFFSET)
- if ( *filetype == FILETYPE_NC2 ) writemode |= NC_64BIT_OFFSET;
+#ifdef NC_64BIT_OFFSET
+ if ( *filetype == CDI_FILETYPE_NC2 ) writemode |= NC_64BIT_OFFSET;
#endif
-#if defined (HAVE_NETCDF4)
- if ( *filetype == FILETYPE_NC4 ) writemode |= NC_NETCDF4;
- else if ( *filetype == FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
+#ifdef NC_64BIT_DATA
+ if ( *filetype == CDI_FILETYPE_NC5 ) writemode |= NC_64BIT_DATA;
+#endif
+#ifdef HAVE_NETCDF4
+ if ( *filetype == CDI_FILETYPE_NC4 ) writemode |= NC_NETCDF4;
+ else if ( *filetype == CDI_FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
#endif
cdf_create(filename, writemode, &ncid);
if ( CDI_Version_Info ) cdfComment(ncid);
- cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.4");
+ cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.6");
break;
case 'a':
cdf_open(filename, NC_WRITE, &ncid);
@@ -3410,34 +3514,20 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
}
-int cdfOpen(const char *filename, const char *mode)
-{
- int filetype = FILETYPE_NC;
-
- if ( CDF_Debug )
- Message("Open %s with mode %c", filename, *mode);
-
- int fileID = cdfOpenFile(filename, mode, &filetype);
-
- if ( CDF_Debug )
- Message("File %s opened with id %d", filename, fileID);
-
- return fileID;
-}
-
-
-int cdfOpen64(const char *filename, const char *mode)
+int cdfOpen(const char *filename, const char *mode, int filetype)
{
int fileID = -1;
- int open_file = TRUE;
- int filetype = FILETYPE_NC2;
+ bool open_file = true;
if ( CDF_Debug )
Message("Open %s with mode %c", filename, *mode);
-#if defined (HAVE_LIBNETCDF)
-#if ! defined (NC_64BIT_OFFSET)
- open_file = FALSE;
+#ifdef HAVE_LIBNETCDF
+#ifndef NC_64BIT_OFFSET
+ if ( filetype == CDI_FILETYPE_NC2 ) open_file = false;
+#endif
+#ifndef NC_64BIT_DATA
+ if ( filetype == CDI_FILETYPE_NC5 ) open_file = false;
#endif
#endif
@@ -3446,7 +3536,7 @@ int cdfOpen64(const char *filename, const char *mode)
fileID = cdfOpenFile(filename, mode, &filetype);
if ( CDF_Debug )
- Message("File %s opened with id %d", filename, fileID);
+ Message("File %s opened with id %d", filename, fileID);
}
else
{
@@ -3460,13 +3550,13 @@ int cdfOpen64(const char *filename, const char *mode)
int cdf4Open(const char *filename, const char *mode, int *filetype)
{
int fileID = -1;
- int open_file = FALSE;
+ bool open_file = false;
if ( CDF_Debug )
Message("Open %s with mode %c", filename, *mode);
-#if defined (HAVE_NETCDF4)
- open_file = TRUE;
+#ifdef HAVE_NETCDF4
+ open_file = true;
#endif
if ( open_file )
@@ -3487,7 +3577,7 @@ int cdf4Open(const char *filename, const char *mode, int *filetype)
static void cdfCloseFile(int fileID)
{
-#if defined (HAVE_LIBNETCDF)
+#ifdef HAVE_LIBNETCDF
cdf_close(fileID);
#endif
}
@@ -3654,12 +3744,12 @@ void cdf_create(const char *path, int cmode, int *ncidp)
int cdf_open(const char *path, int omode, int *ncidp)
{
int status = 0;
- int dapfile = FALSE;
+ bool dapfile = false;
struct stat filestat;
size_t chunksizehint = 0;
#if defined (HAVE_LIBNC_DAP)
- if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = TRUE;
+ if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = true;
#endif
if ( dapfile )
@@ -3973,6 +4063,52 @@ void cdf_put_var_float(int ncid, int varid, const float *fp)
if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
}
+static
+const char *cdf_var_type(nc_type xtype)
+{
+ const char *ctype = "unknown";
+
+ if ( xtype == NC_BYTE ) ctype = "NC_BYTE";
+ else if ( xtype == NC_CHAR ) ctype = "NC_CHAR";
+ else if ( xtype == NC_SHORT ) ctype = "NC_SHORT";
+ else if ( xtype == NC_INT ) ctype = "NC_INT";
+ else if ( xtype == NC_FLOAT ) ctype = "NC_FLOAT";
+ else if ( xtype == NC_DOUBLE ) ctype = "NC_DOUBLE";
+#if defined (HAVE_NETCDF4)
+ else if ( xtype == NC_UBYTE ) ctype = "NC_UBYTE";
+ else if ( xtype == NC_LONG ) ctype = "NC_LONG";
+ else if ( xtype == NC_USHORT ) ctype = "NC_USHORT";
+ else if ( xtype == NC_UINT ) ctype = "NC_UINT";
+ else if ( xtype == NC_INT64 ) ctype = "NC_INT64";
+ else if ( xtype == NC_UINT64 ) ctype = "NC_UINT64";
+#endif
+
+ return ctype;
+}
+
+static
+void minmaxval(size_t nvals, const double *array, double *minval, double *maxval)
+{
+ *minval = array[0];
+ *maxval = array[0];
+ for ( size_t i = 1; i < nvals; ++i )
+ {
+ if ( array[i] > *maxval ) *maxval = array[i];
+ else if ( array[i] < *minval ) *minval = array[i];
+ }
+}
+
+static
+void minmaxvalf(size_t nvals, const float *array, double *minval, double *maxval)
+{
+ *minval = array[0];
+ *maxval = array[0];
+ for ( size_t i = 1; i < nvals; ++i )
+ {
+ if ( array[i] > *maxval ) *maxval = array[i];
+ else if ( array[i] < *minval ) *minval = array[i];
+ }
+}
void cdf_put_vara_double(int ncid, int varid, const size_t start[],
const size_t count[], const double *dp)
@@ -3980,13 +4116,19 @@ void cdf_put_vara_double(int ncid, int varid, const size_t start[],
int status = nc_put_vara_double(ncid, varid, start, count, dp);
if ( CDF_Debug || status != NC_NOERR )
- Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
-
- if ( status != NC_NOERR )
{
char name[256];
nc_inq_varname(ncid, varid, name);
- Message("varname = %s", name);
+ nc_type xtype;
+ nc_inq_vartype(ncid, varid, &xtype);
+ int ndims;
+ nc_inq_varndims(ncid, varid, &ndims);
+ double minval = 0, maxval = 0;
+ size_t nvals = 1;
+ for ( int i = 0; i < ndims; ++i ) nvals *= count[i];
+ minmaxval(nvals, dp, &minval, &maxval);
+ // Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+ Message("name=%s type=%s minval=%f maxval=%f", name, cdf_var_type(xtype), minval, maxval);
}
if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
@@ -3999,7 +4141,20 @@ void cdf_put_vara_float(int ncid, int varid, const size_t start[],
int status = nc_put_vara_float(ncid, varid, start, count, fp);
if ( CDF_Debug || status != NC_NOERR )
- Message("ncid = %d varid = %d val0 = %f", ncid, varid, *fp);
+ {
+ char name[256];
+ nc_inq_varname(ncid, varid, name);
+ nc_type xtype;
+ nc_inq_vartype(ncid, varid, &xtype);
+ int ndims;
+ nc_inq_varndims(ncid, varid, &ndims);
+ double minval = 0, maxval = 0;
+ size_t nvals = 1;
+ for ( int i = 0; i < ndims; ++i ) nvals *= count[i];
+ minmaxvalf(nvals, fp, &minval, &maxval);
+ // Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+ Message("name=%s type=%s minval=%f maxval=%f", name, cdf_var_type(xtype), minval, maxval);
+ }
if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
}
@@ -4268,6 +4423,19 @@ void cdf_get_att_int(int ncid, int varid, const char *name, int *ip)
}
+void cdf_get_att_long(int ncid, int varid, const char *name, long *ip)
+{
+#if defined (HAVE_NETCDF4)
+ int status = nc_get_att_long(ncid, varid, name, ip);
+
+ if ( CDF_Debug || status != NC_NOERR )
+ Message("ncid = %d varid = %d att = %s val = %ld", ncid, varid, name, *ip);
+
+ if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+#endif
+}
+
+
void cdf_get_att_double(int ncid, int varid, const char *name, double *dp)
{
int status;
@@ -4336,224 +4504,16 @@ void cdf_inq_attid(int ncid, int varid, const char *name, int *attnump)
if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
}
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef CDI_CKSUM_H_
-#define CDI_CKSUM_H_
-
-#include <inttypes.h>
-
-uint32_t cdiCheckSum(int type, int count, const void *data);
-
-#endif
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#include <inttypes.h>
-#include <sys/types.h>
-
-void
-memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
-
-void
-memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
- size_t elem_size);
-
-uint32_t
-memcrc_finish(uint32_t *state, off_t total_size);
-
-uint32_t
-memcrc(const unsigned char *b, size_t n);
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifndef SERIALIZE_H
-#define SERIALIZE_H
-
-#include <string.h>
-
-#ifndef CDI_CKSUM_H_
-#endif
-#ifndef _ERROR_H
-#endif
-
-/*
- * Generic interfaces for (de-)marshalling
- */
-int serializeGetSize(int count, int datatype, void *context);
-void serializePack(const void *data, int count, int datatype,
- void *buf, int buf_size, int *position, void *context);
-void serializeUnpack(const void *buf, int buf_size, int *position,
- void *data, int count, int datatype, void *context);
-
-/*
- * (de-)marshalling function for common data structures
- */
-static inline int
-serializeStrTabGetPackSize(const char **strTab, int numStr,
- void *context)
-{
- xassert(numStr >= 0);
- int packBuffSize = 0;
- for (size_t i = 0; i < (size_t)numStr; ++i)
- {
- size_t len = strlen(strTab[i]);
- packBuffSize +=
- serializeGetSize(1, DATATYPE_INT, context)
- + serializeGetSize((int)len, DATATYPE_TXT, context);
- }
- packBuffSize +=
- serializeGetSize(1, DATATYPE_UINT32, context);
- return packBuffSize;
-}
-
-static inline void
-serializeStrTabPack(const char **strTab, int numStr,
- void *buf, int buf_size, int *position, void *context)
-{
- uint32_t d = 0;
- xassert(numStr >= 0);
- for (size_t i = 0; i < (size_t)numStr; ++i)
- {
- int len = (int)strlen(strTab[i]);
- serializePack(&len, 1, DATATYPE_INT,
- buf, buf_size, position, context);
- serializePack(strTab[i], len, DATATYPE_TXT,
- buf, buf_size, position, context);
- d ^= cdiCheckSum(DATATYPE_TXT, len, strTab[i]);
- }
- serializePack(&d, 1, DATATYPE_UINT32,
- buf, buf_size, position, context);
-}
-static inline void
-serializeStrTabUnpack(const void *buf, int buf_size, int *position,
- char **strTab, int numStr, void *context)
+#if defined (HAVE_NETCDF4)
+void cdf_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp)
{
- uint32_t d, d2 = 0;
- xassert(numStr >= 0);
- for (size_t i = 0; i < (size_t)numStr; ++i)
- {
- int len;
- serializeUnpack(buf, buf_size, position,
- &len, 1, DATATYPE_INT, context);
- serializeUnpack(buf, buf_size, position,
- strTab[i], len, DATATYPE_TXT, context);
- strTab[i][len] = '\0';
- d2 ^= cdiCheckSum(DATATYPE_TXT, len, strTab[i]);
- }
- serializeUnpack(buf, buf_size, position,
- &d, 1, DATATYPE_UINT32, context);
- xassert(d == d2);
+ int status = nc_def_var_chunking(ncid, varid, storage, chunksizesp);
+ if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
}
-
-/*
- * Interfaces for marshalling within a single memory domain
- */
-int serializeGetSizeInCore(int count, int datatype, void *context);
-void serializePackInCore(const void *data, int count, int datatype,
- void *buf, int buf_size, int *position, void *context);
-void serializeUnpackInCore(const void *buf, int buf_size, int *position,
- void *data, int count, int datatype, void *context);
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
#endif
-#include <inttypes.h>
-#include <sys/types.h>
-#include <stdlib.h>
-
-
-uint32_t cdiCheckSum(int type, int count, const void *buffer)
-{
- uint32_t s = 0U;
- xassert(count >= 0);
- size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
- memcrc_r_eswap(&s, (const unsigned char *)buffer, (size_t)count, elemSize);
- s = memcrc_finish(&s, (off_t)(elemSize * (size_t)count));
- return s;
-}
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-const char *cdiStringError(int cdiErrno)
-{
- static const char UnknownError[] = "Unknown Error";
- static const char _EUFTYPE[] = "Unsupported file type";
- static const char _ELIBNAVAIL[] = "Unsupported file type (library support not compiled in)";
- static const char _EUFSTRUCT[] = "Unsupported file structure";
- static const char _EUNC4[] = "Unsupported NetCDF4 structure";
- static const char _ELIMIT[] = "Internal limits exceeded";
-
- switch (cdiErrno) {
- case CDI_ESYSTEM:
- {
- const char *cp = strerror(errno);
- if ( cp == NULL ) break;
- return cp;
- }
- case CDI_EUFTYPE: return _EUFTYPE;
- case CDI_ELIBNAVAIL: return _ELIBNAVAIL;
- case CDI_EUFSTRUCT: return _EUFSTRUCT;
- case CDI_EUNC4: return _EUNC4;
- case CDI_ELIMIT: return _ELIMIT;
- }
-
- return UnknownError;
-}
-
/*
* Local Variables:
* c-file-style: "Java"
@@ -4618,134 +4578,373 @@ extern void memFree (void *ptr, const char *file, const char *functionname,
* require-trailing-newline: t
* End:
*/
-#ifndef _GRIBAPI_H
-#define _GRIBAPI_H
+#ifndef CDF_UTIL_H_
+#define CDF_UTIL_H_
-#ifdef HAVE_LIBGRIB_API
-#include <grib_api.h>
-#ifndef _ERROR_H
-#endif
-#endif
+#include <stdbool.h>
+
+void str_tolower(char *str);
+bool str_is_equal(const char *vstr, const char *cstr);
+
+int get_timeunit(size_t len, const char *ptu);
+
+bool is_time_units(const char *timeunits);
+bool is_timeaxis_units(const char *timeunits);
+
+bool is_height_units(const char *units);
+bool is_pressure_units(const char *units);
+bool is_DBL_axis(/*const char *units,*/ const char *longname);
+bool is_depth_axis(const char *stdname, const char *longname);
+bool is_height_axis(const char *stdname, const char *longname);
+
+bool is_lon_axis(const char *units, const char *stdname);
+bool is_lat_axis(const char *units, const char *stdname);
+
+bool is_x_axis(const char *units, const char *stdname);
+bool is_y_axis(const char *units, const char *stdname);
+
+void set_gridtype(const char *attstring, int *gridtype);
+void set_zaxistype(const char *attstring, int *zaxistype);
+void set_calendar(const char *attstring, int *calendar);
-#ifndef _CDI_INT_H
#endif
+#include <string.h>
+#include <ctype.h>
-#define GRIBAPI_MISSVAL -9.E33
-/* GRIB2 Level Types */
-#define GRIB2_LTYPE_SURFACE 1
-#define GRIB2_LTYPE_CLOUD_BASE 2
-#define GRIB2_LTYPE_CLOUD_TOP 3
-#define GRIB2_LTYPE_ISOTHERM0 4
-#define GRIB2_LTYPE_TOA 8
-#define GRIB2_LTYPE_SEA_BOTTOM 9
-#define GRIB2_LTYPE_ATMOSPHERE 10
-#define GRIB2_LTYPE_ISOBARIC 100
-#define GRIB2_LTYPE_MEANSEA 101
-#define GRIB2_LTYPE_ALTITUDE 102
-#define GRIB2_LTYPE_HEIGHT 103
-#define GRIB2_LTYPE_SIGMA 104
-#define GRIB2_LTYPE_HYBRID 105
-#define GRIB2_LTYPE_LANDDEPTH 106
-#define GRIB2_LTYPE_ISENTROPIC 107
-#define GRIB2_LTYPE_SNOW 114
-#define GRIB2_LTYPE_REFERENCE 150
-#define GRIB2_LTYPE_SEADEPTH 160 /* Depth Below Sea Level */
-#define GRIB2_LTYPE_LAKE_BOTTOM 162 /* Lake or River Bottom */
-#define GRIB2_LTYPE_SEDIMENT_BOTTOM 163 /* Bottom Of Sediment Layer */
-#define GRIB2_LTYPE_SEDIMENT_BOTTOM_TA 164 /* Bottom Of Thermally Active Sediment Layer */
-#define GRIB2_LTYPE_SEDIMENT_BOTTOM_TW 165 /* Bottom Of Sediment Layer Penetrated By Thermal Wave */
-#define GRIB2_LTYPE_MIX_LAYER 166 /* Mixing Layer */
+void str_tolower(char *str)
+{
+ if ( str )
+ for ( size_t i = 0; str[i]; ++i )
+ str[i] = (char)tolower((int)str[i]);
+}
-/* GRIB2 Data representation type (Grid Type) */
-#define GRIB2_GTYPE_LATLON 0 /* latitude/longitude */
-#define GRIB2_GTYPE_LATLON_ROT 1 /* rotated latitude/longitude */
-#define GRIB2_GTYPE_LATLON_STR 2 /* stretched latitude/longitude */
-#define GRIB2_GTYPE_LATLON_ROTSTR 3 /* rotated and stretched latitude/longitude */
-#define GRIB2_GTYPE_GAUSSIAN 40 /* gaussian grid */
-#define GRIB2_GTYPE_GAUSSIAN_ROT 41 /* rotated gaussian grid */
-#define GRIB2_GTYPE_GAUSSIAN_STR 42 /* stretched gaussian grid */
-#define GRIB2_GTYPE_GAUSSIAN_ROTSTR 43 /* rotated and stretched gaussian grid */
-#define GRIB2_GTYPE_LCC 30 /* Lambert conformal */
-#define GRIB2_GTYPE_SPECTRAL 50 /* spherical harmonics */
-#define GRIB2_GTYPE_GME 100 /* hexagonal GME grid */
-#define GRIB2_GTYPE_UNSTRUCTURED 101 /* General Unstructured Grid */
-const char *gribapiLibraryVersionString(void);
-void gribContainersNew(stream_t * streamptr);
-void gribContainersDelete(stream_t * streamptr);
+bool str_is_equal(const char *vstr, const char *cstr)
+{
+ bool is_equal = false;
+ size_t clen = (cstr != NULL) ? strlen(cstr) : 0;
-#ifdef HAVE_LIBGRIB_API
-static inline void *gribHandleNew(int editionNumber)
+ if ( vstr && *vstr ) is_equal = (memcmp(vstr, cstr, clen) == 0);
+
+ return is_equal;
+}
+
+int get_timeunit(size_t len, const char *ptu)
{
- void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
+ int timeunit = -1;
- if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
+ while ( isspace(*ptu) && len ) { ptu++; len--; }
- return gh;
+ if ( len > 2 )
+ {
+ if ( str_is_equal(ptu, "sec") ) timeunit = TUNIT_SECOND;
+ else if ( str_is_equal(ptu, "minute") ) timeunit = TUNIT_MINUTE;
+ else if ( str_is_equal(ptu, "hour") ) timeunit = TUNIT_HOUR;
+ else if ( str_is_equal(ptu, "day") ) timeunit = TUNIT_DAY;
+ else if ( str_is_equal(ptu, "month") ) timeunit = TUNIT_MONTH;
+ else if ( str_is_equal(ptu, "calendar_month") ) timeunit = TUNIT_MONTH;
+ else if ( str_is_equal(ptu, "year") ) timeunit = TUNIT_YEAR;
+ }
+ else if ( len == 1 && ptu[0] == 's' ) timeunit = TUNIT_SECOND;
+
+ return timeunit;
}
-static inline int my_grib_set_double(grib_handle* h, const char* key, double val)
+
+bool is_time_units(const char *timeunits)
{
- if ( cdiGribApiDebug )
- fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val);
+ while ( isspace(*timeunits) ) timeunits++;
- int ret_val = grib_set_double(h, key, val);
- if (ret_val != 0)
- fprintf(stderr, "!!! failed call to grib_set_double(\tgrib_handle* h, \"%s\", %f) !!!\n", key, val);
- return ret_val;
+ bool status = str_is_equal(timeunits, "sec")
+ || str_is_equal(timeunits, "minute")
+ || str_is_equal(timeunits, "hour")
+ || str_is_equal(timeunits, "day")
+ || str_is_equal(timeunits, "month")
+ || str_is_equal(timeunits, "calendar_month")
+ || str_is_equal(timeunits, "year");
+
+ return status;
}
-static inline int my_grib_set_long(grib_handle* h, const char* key, long val)
+
+bool is_timeaxis_units(const char *timeunits)
{
- if ( cdiGribApiDebug )
- fprintf(stderr, "grib_set_long( \tgrib_handle* h, \"%s\", %ld)\n", key, val);
+ bool status = false;
- int ret_val = grib_set_long(h, key, val);
- if (ret_val != 0)
- fprintf(stderr, "!!! failed call to grib_set_long( \tgrib_handle* h, \"%s\", %ld) !!!\n", key, val);
- return ret_val;
+ size_t len = strlen(timeunits);
+ char *tu = (char *) Malloc((len+1)*sizeof(char));
+ memcpy(tu, timeunits, (len+1) * sizeof(char));
+ char *ptu = tu;
+
+ for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
+
+ int timeunit = get_timeunit(len, ptu);
+ if ( timeunit != -1 )
+ {
+ while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+ if ( *ptu )
+ {
+ while ( isspace(*ptu) ) ptu++;
+
+ int timetype = str_is_equal(ptu, "as") ? TAXIS_ABSOLUTE :
+ str_is_equal(ptu, "since") ? TAXIS_RELATIVE : -1;
+
+ status = timetype != -1;
+ }
+ }
+
+ Free(tu);
+
+ return status;
}
-static inline int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t* length)
+
+bool is_height_units(const char *units)
{
- if ( cdiGribApiDebug )
- fprintf(stderr, "grib_set_string(\tgrib_handle* h, \"%s\", \"%s\")\n", key, val);
+ int u0 = units[0];
- int ret_val = grib_set_string(h, key, val, length);
- if (ret_val != 0)
- fprintf(stderr, "!!! grib_set_string(\tgrib_handle* h, \"%s\", \"%s\") !!!\n", key, val);
- return ret_val;
+ bool status
+ = (u0=='m' && (!units[1] || strncmp(units, "meter", 5) == 0))
+ || (!units[2] && units[1]=='m' && (u0=='c' || u0=='d' || u0=='k'));
+
+ return status;
}
-static inline void gribHandleDelete(void *gh)
+
+bool is_pressure_units(const char *units)
{
- grib_handle_delete((struct grib_handle *)gh);
+ bool status = false;
+
+ if ( strncmp(units, "millibar", 8) == 0 ||
+ strncmp(units, "mb", 2) == 0 ||
+ strncmp(units, "hectopas", 8) == 0 ||
+ strncmp(units, "hPa", 3) == 0 ||
+ strncmp(units, "Pa", 2) == 0 )
+ {
+ status = true;
+ }
+
+ return status;
}
-#else
-#define gribHandleNew(editionNumber) (NULL)
-#define gribHandleDelete(gh)
-#endif
-typedef struct {
- int init;
- void *gribHandle;
+
+bool is_DBL_axis(/*const char *units,*/ const char *longname)
+{
+ bool status = false;
+
+ if ( strcmp(longname, "depth below land") == 0 ||
+ strcmp(longname, "depth_below_land") == 0 ||
+ strcmp(longname, "levels below the surface") == 0 )
+ {
+ /*
+ if ( strcmp(ncvars[ncvarid].units, "cm") == 0 ||
+ strcmp(ncvars[ncvarid].units, "dm") == 0 ||
+ strcmp(ncvars[ncvarid].units, "m") == 0 )
+ */
+ status = true;
+ }
+
+ return status;
}
-gribContainer_t;
-#endif /* _GRIBAPI_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
+
+bool is_depth_axis(const char *stdname, const char *longname)
+{
+ bool status = false;
+
+ if ( strcmp(stdname, "depth") == 0 )
+ status = true;
+ else
+ if ( strcmp(longname, "depth_below_sea") == 0 ||
+ strcmp(longname, "depth below sea") == 0 )
+ {
+ status = true;
+ }
+
+ return status;
+}
+
+
+bool is_height_axis(const char *stdname, const char *longname)
+{
+ bool status = false;
+
+ if ( strcmp(stdname, "height") == 0 )
+ status = true;
+ else
+ if ( strcmp(longname, "height") == 0 ||
+ strcmp(longname, "height above the surface") == 0 )
+ {
+ status = true;
+ }
+
+ return status;
+}
+
+
+bool is_lon_axis(const char *units, const char *stdname)
+{
+ bool status = false;
+ char lc_units[16];
+
+ memcpy(lc_units, units, 15);
+ lc_units[15] = 0;
+ str_tolower(lc_units);
+
+ if ( (str_is_equal(lc_units, "degree") || str_is_equal(lc_units, "radian")) &&
+ (str_is_equal(stdname, "grid_longitude") || str_is_equal(stdname, "longitude")) )
+ {
+ status = true;
+ }
+ else if ( str_is_equal(lc_units, "degree")
+ && !str_is_equal(stdname, "grid_latitude")
+ && !str_is_equal(stdname, "latitude") )
+ {
+ int ioff = 6;
+ if ( lc_units[ioff] == 's' ) ioff++;
+ if ( lc_units[ioff] == '_' ) ioff++;
+ if ( lc_units[ioff] == 'e' ) status = true;
+ }
+
+ return status;
+}
+
+
+bool is_lat_axis(const char *units, const char *stdname)
+{
+ bool status = false;
+ char lc_units[16];
+
+ memcpy(lc_units, units, 15);
+ lc_units[15] = 0;
+ str_tolower(lc_units);
+
+ if ( (str_is_equal(lc_units, "degree") || str_is_equal(lc_units, "radian")) &&
+ (str_is_equal(stdname, "grid_latitude") || str_is_equal(stdname, "latitude")) )
+ {
+ status = true;
+ }
+ else if ( str_is_equal(lc_units, "degree")
+ && !str_is_equal(stdname, "grid_longitude")
+ && !str_is_equal(stdname, "longitude") )
+ {
+ int ioff = 6;
+ if ( lc_units[ioff] == 's' ) ioff++;
+ if ( lc_units[ioff] == '_' ) ioff++;
+ if ( lc_units[ioff] == 'n' || lc_units[ioff] == 's' ) status = true;
+ }
+
+ return status;
+}
+
+
+bool is_x_axis(const char *units, const char *stdname)
+{
+ (void)units;
+ return (strcmp(stdname, "projection_x_coordinate") == 0);
+}
+
+
+bool is_y_axis(const char *units, const char *stdname)
+{
+ (void)units;
+ return (strcmp(stdname, "projection_y_coordinate") == 0);
+}
+
+
+void set_gridtype(const char *attstring, int *gridtype)
+{
+ if ( strcmp(attstring, "gaussian reduced") == 0 )
+ *gridtype = GRID_GAUSSIAN_REDUCED;
+ else if ( strcmp(attstring, "gaussian") == 0 )
+ *gridtype = GRID_GAUSSIAN;
+ else if ( strncmp(attstring, "spectral", 8) == 0 )
+ *gridtype = GRID_SPECTRAL;
+ else if ( strncmp(attstring, "fourier", 7) == 0 )
+ *gridtype = GRID_FOURIER;
+ else if ( strcmp(attstring, "trajectory") == 0 )
+ *gridtype = GRID_TRAJECTORY;
+ else if ( strcmp(attstring, "generic") == 0 )
+ *gridtype = GRID_GENERIC;
+ else if ( strcmp(attstring, "cell") == 0 )
+ *gridtype = GRID_UNSTRUCTURED;
+ else if ( strcmp(attstring, "unstructured") == 0 )
+ *gridtype = GRID_UNSTRUCTURED;
+ else if ( strcmp(attstring, "curvilinear") == 0 )
+ *gridtype = GRID_CURVILINEAR;
+ else if ( strcmp(attstring, "characterxy") == 0 )
+ *gridtype = GRID_CHARXY;
+ else if ( strcmp(attstring, "sinusoidal") == 0 )
+ ;
+ else if ( strcmp(attstring, "laea") == 0 )
+ ;
+ else if ( strcmp(attstring, "lcc2") == 0 )
+ ;
+ else if ( strcmp(attstring, "linear") == 0 ) // ignore grid type linear
+ ;
+ else
+ {
+ static bool warn = true;
+ if ( warn )
+ {
+ warn = false;
+ Warning("NetCDF attribute grid_type='%s' unsupported!", attstring);
+ }
+ }
+}
+
+
+void set_zaxistype(const char *attstring, int *zaxistype)
+{
+ if ( strcmp(attstring, "toa") == 0 ) *zaxistype = ZAXIS_TOA;
+ else if ( strcmp(attstring, "cloudbase") == 0 ) *zaxistype = ZAXIS_CLOUD_BASE;
+ else if ( strcmp(attstring, "cloudtop") == 0 ) *zaxistype = ZAXIS_CLOUD_TOP;
+ else if ( strcmp(attstring, "isotherm0") == 0 ) *zaxistype = ZAXIS_ISOTHERM_ZERO;
+ else if ( strcmp(attstring, "seabottom") == 0 ) *zaxistype = ZAXIS_SEA_BOTTOM;
+ else if ( strcmp(attstring, "lakebottom") == 0 ) *zaxistype = ZAXIS_LAKE_BOTTOM;
+ else if ( strcmp(attstring, "sedimentbottom") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM;
+ else if ( strcmp(attstring, "sedimentbottomta") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;
+ else if ( strcmp(attstring, "sedimentbottomtw") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;
+ else if ( strcmp(attstring, "mixlayer") == 0 ) *zaxistype = ZAXIS_MIX_LAYER;
+ else if ( strcmp(attstring, "atmosphere") == 0 ) *zaxistype = ZAXIS_ATMOSPHERE;
+ else
+ {
+ static bool warn = true;
+ if ( warn )
+ {
+ warn = false;
+ Warning("NetCDF attribute level_type='%s' unsupported!", attstring);
+ }
+ }
+}
+
+
+void set_calendar(const char *attstring, int *calendar)
+{
+ if ( str_is_equal(attstring, "standard") )
+ *calendar = CALENDAR_STANDARD;
+ else if ( str_is_equal(attstring, "gregorian") )
+ *calendar = CALENDAR_GREGORIAN;
+ else if ( str_is_equal(attstring, "none") )
+ *calendar = CALENDAR_NONE;
+ else if ( str_is_equal(attstring, "proleptic") )
+ *calendar = CALENDAR_PROLEPTIC;
+ else if ( str_is_equal(attstring, "360") )
+ *calendar = CALENDAR_360DAYS;
+ else if ( str_is_equal(attstring, "365") ||
+ str_is_equal(attstring, "noleap") )
+ *calendar = CALENDAR_365DAYS;
+ else if ( str_is_equal(attstring, "366") ||
+ str_is_equal(attstring, "all_leap") )
+ *calendar = CALENDAR_366DAYS;
+ else
+ Warning("calendar >%s< unsupported!", attstring);
+}
#ifndef _STREAM_CDF_H
#define _STREAM_CDF_H
+
void cdfDefVars(stream_t *streamptr);
void cdfDefTimestep(stream_t *streamptr, int tsID);
int cdfInqTimestep(stream_t *streamptr, int tsID);
@@ -4759,21 +4958,27 @@ void cdfDefRecord(stream_t * streamptr);
void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void cdf_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss);
-void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
+void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID);
+
+void cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss);
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss);
-void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss);
-void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
+void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss);
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss);
-void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss);
-void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss);
+void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss);
void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss);
+ const int rect[][2], const void *data, size_t nmiss);
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level);
void cdfDefTime(stream_t* streamptr);
+void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor);
+
+int cdfDefDatatype(int datatype, int filetype);
+
#endif
/*
* Local Variables:
@@ -4784,870 +4989,810 @@ void cdfDefTime(stream_t* streamptr);
* require-trailing-newline: t
* End:
*/
-#ifndef _CGRIBEX_H
-#define _CGRIBEX_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#define GRIB_MISSVAL -9.E33
+#ifndef CDI_ATT_H
+#define CDI_ATT_H
-/* GRIB1 Level Types */
-#define GRIB1_LTYPE_SURFACE 1
-#define GRIB1_LTYPE_CLOUD_BASE 2
-#define GRIB1_LTYPE_CLOUD_TOP 3
-#define GRIB1_LTYPE_ISOTHERM0 4
-#define GRIB1_LTYPE_TOA 8
-#define GRIB1_LTYPE_SEA_BOTTOM 9
-#define GRIB1_LTYPE_ATMOSPHERE 10
-#define GRIB1_LTYPE_99 99
-#define GRIB1_LTYPE_ISOBARIC 100
-#define GRIB1_LTYPE_MEANSEA 102
-#define GRIB1_LTYPE_ALTITUDE 103
-#define GRIB1_LTYPE_HEIGHT 105
-#define GRIB1_LTYPE_SIGMA 107
-#define GRIB1_LTYPE_SIGMA_LAYER 108
-#define GRIB1_LTYPE_HYBRID 109
-#define GRIB1_LTYPE_HYBRID_LAYER 110
-#define GRIB1_LTYPE_LANDDEPTH 111
-#define GRIB1_LTYPE_LANDDEPTH_LAYER 112
-#define GRIB1_LTYPE_ISENTROPIC 113
-#define GRIB1_LTYPE_SEADEPTH 160 /* Depth Below Sea Level */
-#define GRIB1_LTYPE_LAKE_BOTTOM 162 /* Lake or River Bottom */
-#define GRIB1_LTYPE_SEDIMENT_BOTTOM 163 /* Bottom Of Sediment Layer */
-#define GRIB1_LTYPE_SEDIMENT_BOTTOM_TA 164 /* Bottom Of Thermally Active Sediment Layer */
-#define GRIB1_LTYPE_SEDIMENT_BOTTOM_TW 165 /* Bottom Of Sediment Layer Penetrated By Thermal Wave */
-#define GRIB1_LTYPE_MIX_LAYER 166 /* Mixing Layer */
-#define GRIB1_LTYPE_99_MARGIN 1000
+#ifdef HAVE_CONFIG_H
+#endif
-/* GRIB1 Data representation type (Grid Type) [Table 6] */
-#define GRIB1_GTYPE_LATLON 0 /* latitude/longitude */
-#define GRIB1_GTYPE_LATLON_ROT 10 /* rotated latitude/longitude */
-#define GRIB1_GTYPE_LATLON_STR 20 /* stretched latitude/longitude */
-#define GRIB1_GTYPE_LATLON_ROTSTR 30 /* rotated and stretched latitude/longitude */
-#define GRIB1_GTYPE_GAUSSIAN 4 /* gaussian grid */
-#define GRIB1_GTYPE_GAUSSIAN_ROT 14 /* rotated gaussian grid */
-#define GRIB1_GTYPE_GAUSSIAN_STR 24 /* stretched gaussian grid */
-#define GRIB1_GTYPE_GAUSSIAN_ROTSTR 34 /* rotated and stretched gaussian grid */
-#define GRIB1_GTYPE_LCC 3 /* Lambert conformal */
-#define GRIB1_GTYPE_SPECTRAL 50 /* spherical harmonics */
-#define GRIB1_GTYPE_GME 192 /* hexagonal GME grid */
+#ifndef _CDI_LIMITS_H
+#endif
/*
- * Macros for the indicator section ( Section 0 )
+ * CDI attribute
*/
-#define ISEC0_GRIB_Len (isec0[ 0]) /* Number of octets in the GRIB message */
-#define ISEC0_GRIB_Version (isec0[ 1]) /* GRIB edition number */
+typedef struct {
+ size_t xsz; /* amount of space at xvalue */
+ size_t namesz; /* size of name */
+ char *name; /* attribute name */
+ int indtype; /* internal data type of xvalue (INT, FLT or TXT) */
+ int exdtype; /* external data type */
+ /* indtype exdtype */
+ /* TXT TXT */
+ /* INT INT16, INT32 */
+ /* FLT FLT32, FLT64 */
+ size_t nelems; /* number of elements */
+ void *xvalue; /* the actual data */
+} cdi_att_t;
-/*
- * Macros for the product definition section ( Section 1 )
- */
-#define ISEC1_TABLE4_MINUTE 0
-#define ISEC1_TABLE4_HOUR 1
-#define ISEC1_TABLE4_DAY 2
-#define ISEC1_TABLE4_3HOURS 10
-#define ISEC1_TABLE4_6HOURS 11
-#define ISEC1_TABLE4_12HOURS 12
-#define ISEC1_TABLE4_QUARTER 13
-#define ISEC1_TABLE4_30MINUTES 14
+typedef struct {
+ size_t nalloc; /* number allocated >= nelems */
+ size_t nelems; /* length of the array */
+ cdi_att_t value[MAX_ATTRIBUTES];
+} cdi_atts_t;
-#define ISEC1_CodeTable (isec1[ 0]) /* Version number of code table */
-#define ISEC1_CenterID (isec1[ 1]) /* Identification of centre */
-#define ISEC1_ModelID (isec1[ 2]) /* Identification of model */
-#define ISEC1_GridDefinition (isec1[ 3]) /* Grid definition */
-#define ISEC1_Sec2Or3Flag (isec1[ 4]) /* Section 2 or 3 included */
-#define ISEC1_Parameter (isec1[ 5]) /* Parameter indicator */
-#define ISEC1_LevelType (isec1[ 6]) /* Type of level indicator */
-#define ISEC1_Level1 (isec1[ 7]) /* Level 1 */
-#define ISEC1_Level2 (isec1[ 8]) /* Level 2 */
-#define ISEC1_Year (isec1[ 9]) /* Year of century (YY) */
-#define ISEC1_Month (isec1[10]) /* Month (MM) */
-#define ISEC1_Day (isec1[11]) /* Day (DD) */
-#define ISEC1_Hour (isec1[12]) /* Hour (HH) */
-#define ISEC1_Minute (isec1[13]) /* Minute (MM) */
-#define ISEC1_TimeUnit (isec1[14]) /* Time unit indicator */
-#define ISEC1_TimePeriod1 (isec1[15]) /* P1 Time period */
-#define ISEC1_TimePeriod2 (isec1[16]) /* P2 Time period */
-#define ISEC1_TimeRange (isec1[17]) /* Time range indicator */
-#define ISEC1_AvgNum (isec1[18]) /* Number of products included in an average */
-#define ISEC1_AvgMiss (isec1[19]) /* Number of products missing from an average */
-#define ISEC1_Century (isec1[20]) /* Century */
-#define ISEC1_SubCenterID (isec1[21]) /* Subcenter identifier */
-#define ISEC1_DecScaleFactor (isec1[22]) /* Decimal scale factor */
-#define ISEC1_LocalFLag (isec1[23]) /* Flag field to indicate local use in isec1 */
+int cdiAttsGetSize(void *p, int varID, void *context);
-#define ISEC1_ECMWF_LocalExtension (isec1[36])
-#define ISEC1_ECMWF_Class (isec1[37])
+void cdiAttsPack(void *p, int varID, void *buf, int size, int *position, void *context);
+void cdiAttsUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context);
+
+#endif
/*
- * Macros for the grid definition section ( Section 2 )
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
*/
-#define ISEC2_GridType (isec2[ 0]) /* Data representation type */
+#ifndef _GRID_H
+#define _GRID_H
-/* Triangular grids */
+#include <stdbool.h>
-#define ISEC2_GME_NI2 (isec2[ 1]) /* Number of factor 2 in factorisation of Ni */
-#define ISEC2_GME_NI3 (isec2[ 2]) /* Number of factor 3 in factorisation of Ni */
-#define ISEC2_GME_ND (isec2[ 3]) /* Nubmer of diamonds */
-#define ISEC2_GME_NI (isec2[ 4]) /* Number of tri. subdiv. of the icosahedron */
-#define ISEC2_GME_AFlag (isec2[ 5]) /* Flag for orientation of diamonds (Table A) */
-#define ISEC2_GME_LatPP (isec2[ 6]) /* Latitude of pole point */
-#define ISEC2_GME_LonPP (isec2[ 7]) /* Longitude of pole point */
-#define ISEC2_GME_LonMPL (isec2[ 8]) /* Longitude of the first diamond */
-#define ISEC2_GME_BFlag (isec2[ 9]) /* Flag for storage sequence (Table B) */
-/* Spherical harmonic coeficients */
+extern double grid_missval;
+extern int (*proj_lonlat_to_lcc_func)();
+extern int (*proj_lcc_to_lonlat_func)();
-#define ISEC2_PentaJ (isec2[ 1]) /* J pentagonal resolution parameter */
-#define ISEC2_PentaK (isec2[ 2]) /* K pentagonal resolution parameter */
-#define ISEC2_PentaM (isec2[ 3]) /* M pentagonal resolution parameter */
-#define ISEC2_RepType (isec2[ 4]) /* Representation type */
-#define ISEC2_RepMode (isec2[ 5]) /* Representation mode */
+typedef unsigned char mask_t;
-/* Gaussian grids */
+typedef struct grid_t grid_t;
-#define ISEC2_NumLon (isec2[ 1]) /* Number of points along a parallel (Ni) */
-#define ISEC2_NumLat (isec2[ 2]) /* Number of points along a meridian (Nj) */
-#define ISEC2_FirstLat (isec2[ 3]) /* Latitude of the first grid point */
-#define ISEC2_FirstLon (isec2[ 4]) /* Longitude of the first grid point */
-#define ISEC2_ResFlag (isec2[ 5]) /* Resolution flag: 128 regular grid */
-#define ISEC2_LastLat (isec2[ 6]) /* Latitude of the last grid point */
-#define ISEC2_LastLon (isec2[ 7]) /* Longitude of the last grid point */
-#define ISEC2_LonIncr (isec2[ 8]) /* i direction increment */
-#define ISEC2_LatIncr (isec2[ 9]) /* j direction increment */
-#define ISEC2_NumPar (isec2[ 9]) /* Number of parallels between a pole and the E.*/
-#define ISEC2_ScanFlag (isec2[10]) /* Scanning mode flags */
-#define ISEC2_NumVCP (isec2[11]) /* Number of vertical coordinate parameters */
+struct gridVirtTable
+{
+ void (*destroy)(grid_t *gridptr);
+ grid_t *(*copy)(grid_t *gridptr);
+ void (*copyScalarFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
+ void (*copyArrayFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
+ void (*defXVals)(grid_t *gridptr, const double *xvals);
+ void (*defYVals)(grid_t *gridptr, const double *yvals);
+ void (*defMask)(grid_t *gridptr, const int *mask);
+ void (*defMaskGME)(grid_t *gridptr, const int *mask);
+ void (*defXBounds)(grid_t *gridptr, const double *xbounds);
+ void (*defYBounds)(grid_t *gridptr, const double *ybounds);
+ void (*defArea)(grid_t *gridptr, const double *area);
+ double (*inqXVal)(grid_t *gridptr, size_t index);
+ double (*inqYVal)(grid_t *gridptr, size_t index);
+ size_t (*inqXVals)(grid_t *gridptr, double *xvals);
+ size_t (*inqXCvals)(grid_t *gridptr, char **xcvals);
+ int (*inqXIsc)(grid_t *gridptr);
+ size_t (*inqYVals)(grid_t *gridptr, double *yvals);
+ size_t (*inqYCvals)(grid_t *gridptr, char **ycvals);
+ int (*inqYIsc)(grid_t *gridptr);
+ const double *(*inqXValsPtr)(grid_t *gridptr);
+ const char **(*inqXCvalsPtr)(grid_t *gridptr);
+ const double *(*inqYValsPtr)(grid_t *gridptr);
+ const char **(*inqYCvalsPtr)(grid_t *gridptr);
+ /* return if for both grids, all xval and all yval are equal */
+ bool (*compareXYFull)(grid_t *gridRef, grid_t *gridTest);
+ /* return if for both grids, x[0], y[0], x[size-1] and y[size-1] are
+ * respectively equal */
+ bool (*compareXYAO)(grid_t *gridRef, grid_t *gridTest);
+ void (*inqArea)(grid_t *gridptr, double *area);
+ const double *(*inqAreaPtr)(grid_t *gridptr);
+ int (*hasArea)(grid_t *gridptr);
+ size_t (*inqMask)(grid_t *gridptr, int *mask);
+ int (*inqMaskGME)(grid_t *gridptr, int *mask_gme);
+ size_t (*inqXBounds)(grid_t *gridptr, double *xbounds);
+ size_t (*inqYBounds)(grid_t *gridptr, double *ybounds);
+ const double *(*inqXBoundsPtr)(grid_t *gridptr);
+ const double *(*inqYBoundsPtr)(grid_t *gridptr);
+};
-/* Lambert */
-#define ISEC2_Lambert_Lov (isec2[ 6]) /* Orientation of the grid */
-#define ISEC2_Lambert_dx (isec2[ 8]) /* X-direction grid length */
-#define ISEC2_Lambert_dy (isec2[ 9]) /* Y-direction grid length */
-#define ISEC2_Lambert_ProjFlag (isec2[12]) /* Projection centre flag */
-#define ISEC2_Lambert_LatS1 (isec2[13]) /* First lat at which the secant cone cuts the sphere */
-#define ISEC2_Lambert_LatS2 (isec2[14]) /* Second lat at which the secant cone cuts the sphere */
-#define ISEC2_Lambert_LatSP (isec2[19]) /* Latitude of the southern pole */
-#define ISEC2_Lambert_LonSP (isec2[20]) /* Longitude of the southern pole */
+struct gridaxis_t {
+ char name[CDI_MAX_NAME];
+ char longname[CDI_MAX_NAME];
+ char units[CDI_MAX_NAME];
+ char dimname[CDI_MAX_NAME];
+ const char *stdname;
+ size_t size; // number of values
+ short flag; // 0: undefined 1:vals 2:first+inc
+ double first, last, inc;
+ double *vals;
+ int clength;
+ char **cvals;
+ double *bounds;
+};
+// GME Grid
+struct grid_gme_t {
+ int nd, ni, ni2, ni3; /* parameter for GRID_GME */
+};
-#define ISEC2_Reduced (isec2[16]) /* 0: regular, 1: reduced grid */
+struct grid_t {
+ char vdimname[CDI_MAX_NAME];
+ char mapname[CDI_MAX_NAME];
+ char mapping[CDI_MAX_NAME];
+ char *name;
+ int self;
+ size_t size;
+ int type; /* grid type */
+ int datatype; /* grid data type */
+ int proj; /* grid projection */
+ int projtype; /* grid projection type */
+ mask_t *mask;
+ mask_t *mask_gme;
+ double *area;
+ struct grid_gme_t gme;
+ int number, position; /* parameter for GRID_REFERENCE */
+ int trunc; /* parameter for GRID_SPECTEAL */
+ int nvertex;
+ char *reference;
+ unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference */
+ int *rowlon;
+ int nrowlon;
+ int np; /* number of parallels between a pole and the equator */
+ signed char isCyclic; /* three possible states:
+ * -1 if unknown,
+ * 0 if found not cyclic, or
+ * 1 for global cyclic grids
+ */
+ bool lcomplex;
+ bool hasdims;
+ bool uvRelativeToGrid; /* Some models deliver wind U,V relative to the grid-cell */
+ struct gridaxis_t x;
+ struct gridaxis_t y;
+ const struct gridVirtTable *vtable;
+ cdi_atts_t atts;
+ int scanningMode;
+ bool iScansNegatively, jScansPositively, jPointsAreConsecutive;
+ /* scanningMode = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
+ 64 = 128 * 0 + 64 * 1 + 32 * 0
+ 00 = 128 * 0 + 64 * 0 + 32 * 0
+ 96 = 128 * 0 + 64 * 1 + 32 * 1
+ Default / implicit scanning mode is 64:
+ i and j scan positively, i points are consecutive (row-major) */
+};
-#define ISEC2_RowLonPtr (&isec2[22])
-#define ISEC2_RowLon(i) (isec2[22+i]) /* Number of points along each parallel */
-/* */
+void grid_init(grid_t *gridptr);
+void cdiGridTypeInit(grid_t *gridptr, int gridtype, size_t size);
+void grid_free(grid_t *gridptr);
+grid_t *grid_to_pointer(int gridID);
+extern const struct gridVirtTable cdiGridVtable;
-#define ISEC2_LatSP (isec2[12]) /* Latitude of the southern pole of rotation */
-#define ISEC2_LonSP (isec2[13]) /* Longitude of the southern pole of rotation */
+unsigned cdiGridCount(void);
-#define FSEC2_RotAngle (fsec2[ 0]) /* Angle of rotation */
-#define FSEC2_StrFact (fsec2[ 1]) /* Stretching factor */
+void gridVerifyProj(int gridID);
-/*
- * Macros for the bit map section ( Section 3 )
- */
-#define ISEC3_PredefBitmap (isec3[ 0]) /* Predefined bitmap */
-#define ISEC3_MissVal (isec3[ 1]) /* Missing data value for integers */
-#define FSEC3_MissVal (fsec3[ 1]) /* Missing data value for floats */
-
-/*
- * Macros for the binary data section ( Section 4 )
- */
-#define ISEC4_NumValues (isec4[ 0]) /* Number of data values for encode/decode */
-#define ISEC4_NumBits (isec4[ 1]) /* Number of bits used for each encoded value */
-#define ISEC4_NumNonMissValues (isec4[20]) /* Number of non-missing values */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void gribFixZSE(int flag); /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
-void gribSetConst(int flag); /* 1: Don't pack constant fields on regular grids */
-void gribSetDebug(int debug); /* 1: Debugging */
-void gribSetRound(int round);
-void gribSetRefDP(double refval);
-void gribSetRefSP(float refval);
-void gribSetValueCheck(int vcheck);
-
-
-void gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
- float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, const char *hoper, int *kret);
-
-void gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
- double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, const char *hoper, int *kret);
-
-
-const char *cgribexLibraryVersion(void);
-
-void gribDebug(int debug);
-void gribSetCalendar(int calendar);
+const double *gridInqXvalsPtr(int gridID);
+const double *gridInqYvalsPtr(int gridID);
-void gribDateTime(int *isec1, int *date, int *time);
-int gribRefDate(int *isec1);
-int gribRefTime(int *isec1);
-int gribTimeIsFC(int *isec1);
+const char **gridInqXCvalsPtr(int gridID);
+const char **gridInqYCvalsPtr(int gridID);
-void gribPrintSec0(int *isec0);
-void gribPrintSec1(int *isec0, int *isec1);
-void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
-void gribPrintSec2SP(int *isec0, int *isec2, float *fsec2);
-void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
-void gribPrintSec3SP(int *isec0, int *isec3, float *fsec3);
-void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
-void gribPrintSec4SP(int *isec0, int *isec4, float *fsec4);
-void gribPrintSec4Wave(int *isec4);
+const double *gridInqXboundsPtr(int gridID);
+const double *gridInqYboundsPtr(int gridID);
+const double *gridInqAreaPtr(int gridID);
-void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
-void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
+const char *gridInqReferencePtr(int gridID);
-int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize);
+int gridGenerate(const grid_t *grid);
-int gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+//int gridIsEqual(int gridID1, int gridID2);
-int gribOpen(const char *filename, const char *mode);
-void gribClose(int fileID);
+void cdiGridGetIndexList(unsigned, int * );
-int gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
-int gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
-off_t gribGetPos(int fileID);
-int gribGetSize(int fileID);
-int gribCheckSeek(int fileID, long *offset, int *version);
-int gribFileSeek(int fileID, long *offset);
-int gribReadSize(int fileID);
-int gribVersion(unsigned char *buffer, size_t buffersize);
+void
+gridUnpack(char * unpackBuffer, int unpackBufferSize,
+ int * unpackBufferPos, int originNamespace, void *context,
+ int force_id);
-int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
+struct addIfNewRes
+{
+ int Id;
+ int isNew;
+};
-double calculate_pfactor_float(const float* spectralField, long fieldTruncation, long subsetTruncation);
-double calculate_pfactor_double(const double* spectralField, long fieldTruncation, long subsetTruncation);
+struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode);
+int gridVerifyGribParamLCC(double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
+ double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0);
-#if defined (__cplusplus)
-}
#endif
-
-#endif /* _CGRIBEX_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef CDF_LAZY_GRID_H_
+#define CDF_LAZY_GRID_H_
#if defined (HAVE_CONFIG_H)
#endif
-#include <stdarg.h>
-#include <ctype.h>
-
-#ifdef HAVE_LIBNETCDF
+#ifdef HAVE_MMAP
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#endif
-
-#if defined (HAVE_LIBCGRIBEX)
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
#endif
-int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
+#include <string.h>
-int cdiDefaultInstID = CDI_UNDEFID;
-int cdiDefaultModelID = CDI_UNDEFID;
-int cdiDefaultTableID = CDI_UNDEFID;
-//int cdiNcMissingValue = CDI_UNDEFID;
-int cdiNcChunksizehint = CDI_UNDEFID;
-int cdiChunkType = CHUNK_GRID;
-int cdiSplitLtype105 = CDI_UNDEFID;
-int cdiIgnoreAttCoordinates = FALSE;
-int cdiIgnoreValidRange = FALSE;
-int cdiSkipRecords = 0;
-int cdiConvention = CDI_CONVENTION_ECHAM;
-int cdiInventoryMode = 1;
-int CDI_Version_Info = 1;
-int CDI_cmor_mode = 0;
-size_t CDI_netcdf_hdr_pad = 0UL;
-bool CDI_netcdf_lazy_grid_load = false;
+struct cdfLazyGrid
+{
+ grid_t base;
+ const struct gridVirtTable *baseVtable;
+ struct cdfLazyGridIds {
+ int datasetNCId, varNCId;
+ } cellAreaGet, xBoundsGet, yBoundsGet;
+ struct xyValGet {
+ double scalefactor, addoffset;
+ size_t start[3], count[3], size, dimsize;
+ int datasetNCId, varNCId;
+ short ndims;
+ } xValsGet, yValsGet;
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_t loadSerialize;
+#endif
+};
-char *cdiPartabPath = NULL;
-int cdiPartabIntern = 1;
-double cdiDefaultMissval = -9.E33;
+extern double *cdfPendingLoad;
-static const char Filetypes[][9] = {
- "UNKNOWN",
- "GRIB",
- "GRIB2",
- "NetCDF",
- "NetCDF2",
- "NetCDF4",
- "NetCDF4c",
- "SERVICE",
- "EXTRA",
- "IEG",
- "HDF5",
-};
+void cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype);
+void cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype);
-int CDI_Debug = 0; /* If set to 1, debugging */
-int CDI_Recopt = 0;
+void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid);
-int cdiGribApiDebug = 0;
-int cdiDefaultLeveltype = -1;
-int cdiDataUnreduced = 0;
-int cdiSortName = 0;
-int cdiHaveMissval = 0;
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
+#ifdef HAVE_LIBNETCDF
-static long cdiGetenvInt(const char *envName)
-{
- char *envString;
- long envValue = -1;
- long fact = 1;
- envString = getenv(envName);
+static struct gridVirtTable cdfLazyGridVtable;
+double *cdfPendingLoad;
+#ifdef HAVE_LIBPTHREAD
+static pthread_once_t cdfLazyInitialized = PTHREAD_ONCE_INIT;
+#else
+static bool cdfLazyInitialized;
+#endif
- if ( envString )
- {
- int loop, len;
- len = (int) strlen(envString);
- for ( loop = 0; loop < len; loop++ )
- {
- if ( ! isdigit((int) envString[loop]) )
- {
- switch ( tolower((int) envString[loop]) )
- {
- case 'k': fact = 1024; break;
- case 'm': fact = 1048576; break;
- case 'g': fact = 1073741824; break;
- default:
- fact = 0;
- Message("Invalid number string in %s: %s", envName, envString);
- Warning("%s must comprise only digits [0-9].",envName);
- break;
- }
- break;
- }
- }
+#ifdef HAVE_LIBPTHREAD
+#define lock_lazy_load(plGrid) pthread_mutex_lock(&((plGrid)->loadSerialize))
+#define unlock_lazy_load(plGrid) pthread_mutex_unlock(&((plGrid)->loadSerialize))
+#define destroy_lazy_load_lock(plGrid) pthread_mutex_destroy(&((plGrid)->loadSerialize))
+#define init_lazy_load_lock(plGrid) pthread_mutex_init(&((plGrid)->loadSerialize), NULL)
+#else
+#define lock_lazy_load(plGrid)
+#define unlock_lazy_load(plGrid)
+#define destroy_lazy_load_lock(plGrid)
+#define init_lazy_load_lock(plGrid)
+#endif
- if ( fact ) envValue = fact*atol(envString);
- if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
- }
- return (envValue);
+void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid)
+{
+ if (lazyGrid->base.area == cdfPendingLoad) lazyGrid->base.area = NULL;
+ if (lazyGrid->base.x.vals == cdfPendingLoad) lazyGrid->base.x.vals = NULL;
+ if (lazyGrid->base.y.vals == cdfPendingLoad) lazyGrid->base.y.vals = NULL;
+ if (lazyGrid->base.x.bounds == cdfPendingLoad) lazyGrid->base.x.bounds = NULL;
+ if (lazyGrid->base.y.bounds == cdfPendingLoad) lazyGrid->base.y.bounds = NULL;
+ destroy_lazy_load_lock(lazyGrid);
}
-static void
-cdiPrintDefaults(void)
+static void cdfLazyGridDelete(grid_t *grid)
{
- fprintf(stderr, "default instID : %d\n"
- "default modelID : %d\n"
- "default tableID : %d\n"
- "default missval : %g\n", cdiDefaultInstID,
- cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ void (*baseDestroy)(grid_t *grid) = cdfGrid->baseVtable->destroy;
+ cdfLazyGridDestroy(cdfGrid);
+ baseDestroy(grid);
}
-void cdiPrintVersion(void)
+static void cdfLazyGridDestroyOnce(void)
{
- fprintf(stderr, " CDI library version : %s\n", cdiLibraryVersion());
-#if defined (HAVE_LIBCGRIBEX)
- fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
-#endif
-#if defined (HAVE_LIBGRIB_API)
- fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
-#endif
-#if defined (HAVE_LIBNETCDF)
- fprintf(stderr, " NetCDF library version : %s\n", cdfLibraryVersion());
-#endif
-#if defined (HAVE_NC4HDF5)
- fprintf(stderr, " HDF5 library version : %s\n", hdfLibraryVersion());
-#endif
-#if defined (HAVE_LIBSERVICE)
- fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
-#endif
-#if defined (HAVE_LIBEXTRA)
- fprintf(stderr, " EXTRA library version : %s\n", extLibraryVersion());
-#endif
-#if defined (HAVE_LIBIEG)
- fprintf(stderr, " IEG library version : %s\n", iegLibraryVersion());
+ /*
+#ifdef HAVE_MMAP
+ size_t pgSize = cdiGetPageSize(false);
+ munmap(cdfPendingLoad, pgSize);
#endif
- fprintf(stderr, " FILE library version : %s\n", fileLibraryVersion());
+ */
}
-void cdiDebug(int level)
+static void
+cdfLazyGridDefArea(grid_t *grid, const double *area)
{
- if ( level == 1 || (level & 2) ) CDI_Debug = 1;
-
- if ( CDI_Debug ) Message("debug level %d", level);
-
- if ( level == 1 || (level & 4) ) memDebug(1);
-
- if ( level == 1 || (level & 8) ) fileDebug(1);
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(cdfGrid);
+ if (grid->area == cdfPendingLoad) grid->area = NULL;
+ cdfGrid->cellAreaGet.datasetNCId = -1;
+ cdfGrid->cellAreaGet.varNCId = -1;
+ cdfGrid->baseVtable->defArea(grid, area);
+ unlock_lazy_load(cdfGrid);
+}
- if ( level == 1 || (level & 16) )
- {
-#if defined (HAVE_LIBCGRIBEX)
- gribSetDebug(1);
-#endif
-#if defined (HAVE_LIBNETCDF)
- cdfDebug(1);
-#endif
-#if defined (HAVE_LIBSERVICE)
- srvDebug(1);
-#endif
-#if defined (HAVE_LIBEXTRA)
- extDebug(1);
-#endif
-#if defined (HAVE_LIBIEG)
- iegDebug(1);
-#endif
- }
- if ( CDI_Debug )
+static const double *
+cdfLazyGridInqAreaPtr(grid_t *grid)
+{
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ if (grid->area == cdfPendingLoad)
{
- cdiPrintDefaults();
- cdiPrintDatatypes();
+ grid->area = (double *)Malloc((size_t)grid->size * sizeof(double));
+ cdf_get_var_double(lazyGrid->cellAreaGet.datasetNCId,
+ lazyGrid->cellAreaGet.varNCId, grid->area);
}
+ unlock_lazy_load(lazyGrid);
+ return lazyGrid->baseVtable->inqAreaPtr(grid);
}
-
-int cdiHaveFiletype(int filetype)
+static void
+cdfLazyGridInqArea(grid_t *grid, double *area)
{
- int status = 0;
+ grid->vtable->inqAreaPtr(grid);
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lazyGrid->baseVtable->inqArea(grid, area);
+}
- switch (filetype)
- {
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV: { status = 1; break; }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT: { status = 1; break; }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG: { status = 1; break; }
-#endif
-#if defined (HAVE_LIBGRIB)
-#if defined (HAVE_LIBGRIB_API) || defined (HAVE_LIBCGRIBEX)
- case FILETYPE_GRB: { status = 1; break; }
-#endif
-#if defined (HAVE_LIBGRIB_API)
- case FILETYPE_GRB2: { status = 1; break; }
-#endif
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC: { status = 1; break; }
-#if defined (HAVE_NETCDF2)
- case FILETYPE_NC2: { status = 1; break; }
-#endif
-#if defined (HAVE_NETCDF4)
- case FILETYPE_NC4: { status = 1; break; }
- case FILETYPE_NC4C: { status = 1; break; }
-#endif
-#endif
- default: { status = 0; break; }
- }
- return (status);
+static void
+cdfLazyLoadXYVals(struct xyValGet *valsGet, double **valsp)
+{
+ double *grid_vals = (double *)Malloc(valsGet->size * sizeof (double));
+ *valsp = grid_vals;
+ if ( valsGet->ndims == 3 )
+ cdf_get_vara_double(valsGet->datasetNCId, valsGet->varNCId,
+ valsGet->start, valsGet->count, grid_vals);
+ else
+ cdf_get_var_double(valsGet->datasetNCId, valsGet->varNCId, grid_vals);
+ cdf_scale_add(valsGet->size, grid_vals, valsGet->addoffset, valsGet->scalefactor);
}
-void cdiDefTableID(int tableID)
+static const double *
+cdfLazyGridInqXValsPtr(grid_t *grid)
{
- cdiDefaultTableID = tableID;
- int modelID = cdiDefaultModelID = tableInqModel(tableID);
- cdiDefaultInstID = modelInqInstitut(modelID);
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ if (grid->x.vals == cdfPendingLoad)
+ cdfLazyLoadXYVals(&lazyGrid->xValsGet, &grid->x.vals);
+ unlock_lazy_load(lazyGrid);
+ return lazyGrid->baseVtable->inqXValsPtr(grid);
}
-static
-void cdiSetChunk(const char *chunkAlgo)
+static const double *
+cdfLazyGridInqYValsPtr(grid_t *grid)
{
- //char *pch;
- //size_t len = strlen(chunkAlgo);
- int algo = -1;
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ if (grid->y.vals == cdfPendingLoad)
+ cdfLazyLoadXYVals(&lazyGrid->yValsGet, &grid->y.vals);
+ unlock_lazy_load(lazyGrid);
+ return lazyGrid->baseVtable->inqYValsPtr(grid);
+}
- if ( strcmp("auto", chunkAlgo) == 0 ) algo = CHUNK_AUTO;
- else if ( strcmp("grid", chunkAlgo) == 0 ) algo = CHUNK_GRID;
- else if ( strcmp("lines", chunkAlgo) == 0 ) algo = CHUNK_LINES;
- /*
- else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
+static double
+cdfLazyGridInqXYVal(grid_t *grid, size_t index,
+ const struct xyValGet *valsGet, double *vals,
+ const double *(*inqValsPtr)(grid_t *gridptr))
+{
+ size_t size = valsGet->size;
+ double v;
+ if ( vals == cdfPendingLoad )
{
- int ix, iy;
- ix = atoi(chunkAlgo);
- iy = atoi(pch+1);
- if ( ix > 0 && iy > 0 )
+ /* prevent full load if only first/last values get inspected */
+ if ( index == 0 || index == size - 1 )
{
- cdiChunkX = ix;
- cdiChunkY = iy;
- algo = CHUNK_USER;
+ size_t indexND[3];
+ if ( valsGet->ndims == 3 )
+ {
+ indexND[0] = 0;
+ indexND[1] = index / valsGet->count[2];
+ indexND[2] = index % valsGet->count[2];
+ }
+ else if ( valsGet->ndims == 2)
+ {
+ indexND[0] = index / (size_t)grid->x.size;
+ indexND[1] = index % (size_t)grid->x.size;
+ }
+ else
+ indexND[0] = index;
+ cdf_get_var1_double(valsGet->datasetNCId, valsGet->varNCId, indexND, &v);
}
else
- Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
+ {
+ const double *grid_vals = inqValsPtr(grid);
+ v = grid_vals[index];
+ }
}
- */
+ else if ( vals )
+ v = vals[index];
else
- Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
+ v = 0.0;
+ return v;
+}
- if ( algo != -1 )
- {
- cdiChunkType = algo;
- if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
- }
+static void
+cdfLazyGridDefXVals(grid_t *grid, const double *vals)
+{
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(cdfGrid);
+ if (grid->x.vals == cdfPendingLoad)
+ grid->x.vals = NULL;
+ cdfGrid->xValsGet.datasetNCId = -1;
+ cdfGrid->xValsGet.varNCId = -1;
+ cdfGrid->baseVtable->defXVals(grid, vals);
+ unlock_lazy_load(cdfGrid);
}
+static void
+cdfLazyGridDefYVals(grid_t *grid, const double *vals)
+{
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(cdfGrid);
+ if (grid->y.vals == cdfPendingLoad)
+ grid->y.vals = NULL;
+ cdfGrid->yValsGet.datasetNCId = -1;
+ cdfGrid->yValsGet.varNCId = -1;
+ cdfGrid->baseVtable->defYVals(grid, vals);
+ unlock_lazy_load(cdfGrid);
+}
-void cdiInitialize(void)
+static double
+cdfLazyGridInqXVal(grid_t *grid, size_t index)
{
- static int Init_CDI = FALSE;
- char *envstr;
- long value;
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ double rv = cdfLazyGridInqXYVal(grid, index, &lazyGrid->xValsGet,
+ grid->x.vals, grid->vtable->inqXValsPtr);
+ unlock_lazy_load(lazyGrid);
+ return rv;
+}
- if ( ! Init_CDI )
- {
- Init_CDI = TRUE;
+static double
+cdfLazyGridInqYVal(grid_t *grid, size_t index)
+{
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ double rv = cdfLazyGridInqXYVal(grid, index, &lazyGrid->yValsGet,
+ grid->y.vals, grid->vtable->inqYValsPtr);
+ unlock_lazy_load(lazyGrid);
+ return rv;
+}
-#if defined (HAVE_LIBCGRIBEX)
- gribFixZSE(1); // 1: Fix ZeroShiftError of simple packed spherical harmonics
- gribSetConst(1); // 1: Don't pack constant fields on regular grids
-#endif
+static bool
+cdfLazyXYValGetCompare(struct cdfLazyGrid *lazyGridRef,
+ struct cdfLazyGrid *lazyGridTest)
+{
+ struct xyValGet *valsGetXRef = &lazyGridRef->xValsGet,
+ *valsGetYRef = &lazyGridRef->yValsGet,
+ *valsGetXTest = &lazyGridTest->xValsGet,
+ *valsGetYTest = &lazyGridTest->yValsGet;
+ if (valsGetXRef->datasetNCId == -1
+ || valsGetXTest->datasetNCId == -1
+ || valsGetYRef->datasetNCId == -1
+ || valsGetYTest->datasetNCId == -1)
+ return lazyGridRef->baseVtable->compareXYFull(&lazyGridRef->base,
+ &lazyGridTest->base);
+ return valsGetXRef->datasetNCId != valsGetXTest->datasetNCId
+ || valsGetXRef->varNCId != valsGetXTest->varNCId
+ || valsGetYRef->datasetNCId != valsGetYTest->datasetNCId
+ || valsGetYRef->varNCId != valsGetYTest->varNCId;
+}
- value = cdiGetenvInt("CDI_DEBUG");
- if ( value >= 0 ) CDI_Debug = (int) value;
+static bool
+cdfLazyCompareXYFull(grid_t *gridRef, grid_t *gridTest)
+{
+ bool diff;
+ struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
+ if (gridTest->vtable == &cdfLazyGridVtable)
+ diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
+ else
+ diff = lazyGridRef->baseVtable->compareXYFull(gridRef, gridTest);
+ return diff;
+}
- value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
- if ( value >= 0 ) cdiGribApiDebug = (int) value;
+static bool
+cdfLazyCompareXYAO(grid_t *gridRef, grid_t *gridTest)
+{
+ bool diff;
+ struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
+ if (gridTest->vtable == &cdfLazyGridVtable)
+ diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
+ else
+ diff = lazyGridRef->baseVtable->compareXYAO(gridRef, gridTest);
+ return diff;
+}
- value = cdiGetenvInt("CDI_RECOPT");
- if ( value >= 0 ) CDI_Recopt = (int) value;
- value = cdiGetenvInt("CDI_REGULARGRID");
- if ( value >= 0 ) cdiDataUnreduced = (int) value;
-
- value = cdiGetenvInt("CDI_SORTNAME");
- if ( value >= 0 ) cdiSortName = (int) value;
-
- value = cdiGetenvInt("CDI_HAVE_MISSVAL");
- if ( value >= 0 ) cdiHaveMissval = (int) value;
-
- value = cdiGetenvInt("CDI_LEVELTYPE");
- if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
-
- value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
- if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
-
- envstr = getenv("CDI_MISSVAL");
- if ( envstr ) cdiDefaultMissval = atof(envstr);
- /*
- envstr = getenv("NC_MISSING_VALUE");
- if ( envstr ) cdiNcMissingValue = atoi(envstr);
- */
- envstr = getenv("NC_CHUNKSIZEHINT");
- if ( envstr ) cdiNcChunksizehint = atoi(envstr);
-
- envstr = getenv("CDI_CHUNK_ALGO");
- if ( envstr ) cdiSetChunk(envstr);
-
- envstr = getenv("SPLIT_LTYPE_105");
- if ( envstr ) cdiSplitLtype105 = atoi(envstr);
-
- envstr = getenv("IGNORE_ATT_COORDINATES");
- if ( envstr ) cdiIgnoreAttCoordinates = atoi(envstr);
-
- envstr = getenv("IGNORE_VALID_RANGE");
- if ( envstr ) cdiIgnoreValidRange = atoi(envstr);
-
- envstr = getenv("CDI_SKIP_RECORDS");
- if ( envstr )
- {
- cdiSkipRecords = atoi(envstr);
- cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
- }
-
- envstr = getenv("CDI_CONVENTION");
- if ( envstr )
- {
- if ( strcmp(envstr, "CF") == 0 || strcmp(envstr, "cf") == 0 )
- {
- cdiConvention = CDI_CONVENTION_CF;
- if ( CDI_Debug )
- Message("CDI convention was set to CF!");
- }
- }
-
- envstr = getenv("CDI_INVENTORY_MODE");
- if ( envstr )
- {
- if ( strncmp(envstr, "time", 4) == 0 )
- {
- cdiInventoryMode = 2;
- if ( CDI_Debug )
- Message("Inventory mode was set to timestep!");
- }
- }
-
- envstr = getenv("CDI_VERSION_INFO");
- if ( envstr )
- {
- int ival = atoi(envstr);
- if ( ival == 0 || ival == 1 )
- {
- CDI_Version_Info = ival;
- if ( CDI_Debug )
- Message("CDI_Version_Info = %s", envstr);
- }
- }
-
-
- envstr = getenv("CDI_CALENDAR");
- if ( envstr )
- {
- if ( strncmp(envstr, "standard", 8) == 0 )
- cdiDefaultCalendar = CALENDAR_STANDARD;
- else if ( strncmp(envstr, "proleptic", 9) == 0 )
- cdiDefaultCalendar = CALENDAR_PROLEPTIC;
- else if ( strncmp(envstr, "360days", 7) == 0 )
- cdiDefaultCalendar = CALENDAR_360DAYS;
- else if ( strncmp(envstr, "365days", 7) == 0 )
- cdiDefaultCalendar = CALENDAR_365DAYS;
- else if ( strncmp(envstr, "366days", 7) == 0 )
- cdiDefaultCalendar = CALENDAR_366DAYS;
- else if ( strncmp(envstr, "none", 4) == 0 )
- cdiDefaultCalendar = CALENDAR_NONE;
-
- if ( CDI_Debug )
- Message("Default calendar set to %s!", envstr);
- }
-#if defined (HAVE_LIBCGRIBEX)
- gribSetCalendar(cdiDefaultCalendar);
-#endif
-
- envstr = getenv("PARTAB_INTERN");
- if ( envstr ) cdiPartabIntern = atoi(envstr);
-
- envstr = getenv("PARTAB_PATH");
- if ( envstr ) cdiPartabPath = strdup(envstr);
+static const double *
+cdfLazyGridInqXBoundsPtr(grid_t *grid)
+{
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ if (grid->x.bounds == cdfPendingLoad)
+ {
+ grid->x.bounds = (double *)Malloc((size_t)grid->nvertex
+ * (size_t)grid->size * sizeof(double));
+ cdf_get_var_double(lazyGrid->xBoundsGet.datasetNCId,
+ lazyGrid->xBoundsGet.varNCId, grid->x.bounds);
}
+ unlock_lazy_load(lazyGrid);
+ return lazyGrid->baseVtable->inqXBoundsPtr(grid);
}
-
-const char *strfiletype(int filetype)
+static void
+cdfLazyGridDefXBounds(grid_t *grid, const double *xbounds)
{
- const char *name;
- int size = (int) (sizeof(Filetypes)/sizeof(char *));
-
- if ( filetype > 0 && filetype < size )
- name = Filetypes[filetype];
- else
- name = Filetypes[0];
-
- return (name);
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(cdfGrid);
+ if (grid->x.bounds == cdfPendingLoad)
+ grid->x.bounds = NULL;
+ cdfGrid->xBoundsGet.datasetNCId = -1;
+ cdfGrid->xBoundsGet.varNCId = -1;
+ cdfGrid->baseVtable->defXBounds(grid, xbounds);
+ unlock_lazy_load(cdfGrid);
}
-
-void cdiDefGlobal(const char *string, int val)
+static void
+cdfLazyGridDefYBounds(grid_t *grid, const double *ybounds)
{
- if ( strcmp(string, "REGULARGRID") == 0 ) cdiDataUnreduced = val;
- else if ( strcmp(string, "GRIBAPI_DEBUG") == 0 ) cdiGribApiDebug = val;
- else if ( strcmp(string, "SORTNAME") == 0 ) cdiSortName = val;
- else if ( strcmp(string, "HAVE_MISSVAL") == 0 ) cdiHaveMissval = val;
- else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
- else if ( strcmp(string, "CMOR_MODE") == 0 ) CDI_cmor_mode = val;
- else if ( strcmp(string, "NETCDF_HDR_PAD") == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
- else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
- CDI_netcdf_lazy_grid_load = (bool)val;
- else Warning("Unsupported global key: %s", string);
+ struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(cdfGrid);
+ if (grid->y.bounds == cdfPendingLoad)
+ grid->y.bounds = NULL;
+ cdfGrid->yBoundsGet.datasetNCId = -1;
+ cdfGrid->yBoundsGet.varNCId = -1;
+ cdfGrid->baseVtable->defYBounds(grid, ybounds);
+ unlock_lazy_load(cdfGrid);
}
-
-void cdiDefMissval(double missval)
+static const double *
+cdfLazyGridInqYBoundsPtr(grid_t *grid)
{
- cdiInitialize();
-
- cdiDefaultMissval = missval;
+ struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+ lock_lazy_load(lazyGrid);
+ if (grid->y.bounds == cdfPendingLoad)
+ {
+ grid->y.bounds = (double *)Malloc((size_t)grid->nvertex
+ * (size_t)grid->size * sizeof(double));
+ cdf_get_var_double(lazyGrid->yBoundsGet.datasetNCId,
+ lazyGrid->yBoundsGet.varNCId, grid->y.bounds);
+ }
+ unlock_lazy_load(lazyGrid);
+ return lazyGrid->baseVtable->inqYBoundsPtr(grid);
}
-
-double cdiInqMissval(void)
+static void
+cdfLazyGridCopyScalarFields(grid_t *gridptrOrig, grid_t *gridptrDup)
{
- cdiInitialize();
-
- return (cdiDefaultMissval);
+ struct cdfLazyGrid *lazyGridDup = (struct cdfLazyGrid *)gridptrDup,
+ *lazyGridOrig = (struct cdfLazyGrid *)gridptrOrig;
+ lazyGridOrig->baseVtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
+ lazyGridDup->baseVtable = lazyGridOrig->baseVtable;
+ lazyGridDup->cellAreaGet = lazyGridOrig->cellAreaGet;
+ lazyGridDup->xBoundsGet = lazyGridOrig->xBoundsGet;
+ lazyGridDup->yBoundsGet = lazyGridOrig->yBoundsGet;
+ lazyGridDup->xValsGet = lazyGridOrig->xValsGet;
+ lazyGridDup->yValsGet = lazyGridOrig->yValsGet;
+ init_lazy_load_lock(lazyGridDup);
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
+static void
+cdfLazyGridCopyArrayFields(grid_t *gridptrOrig, grid_t *gridptrDup)
+{
+ size_t nrowlon = (size_t)gridptrOrig->nrowlon;
+ size_t gridsize = (size_t)gridptrOrig->size;
+ int gridtype = gridptrOrig->type;
+ int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
+ if ( nrowlon )
+ {
+ gridptrDup->rowlon = (int *)Malloc(nrowlon * sizeof (int));
+ memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
+ }
-#if defined (HAVE_CONFIG_H)
-#endif
+ if ( gridptrOrig->x.vals != NULL && gridptrOrig->x.vals != cdfPendingLoad )
+ {
+ size_t size = irregular ? gridsize : (size_t)gridptrOrig->x.size;
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+ gridptrDup->x.vals = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->x.vals, gridptrOrig->x.vals, size * sizeof (double));
+ }
+ if ( gridptrOrig->y.vals != NULL && gridptrOrig->y.vals != cdfPendingLoad )
+ {
+ size_t size = irregular ? gridsize : (size_t)gridptrOrig->y.size;
-void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
-{
- unsigned uparam = (unsigned)param;
- unsigned upnum;
+ gridptrDup->y.vals = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->y.vals, gridptrOrig->y.vals, size * sizeof (double));
+ }
- *pdis = 0xff & uparam;
- *pcat = 0xff & uparam >> 8;
- upnum = 0xffff & uparam >> 16;
- if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
- *pnum = (int)upnum;
-}
+ if ( gridptrOrig->x.bounds != NULL && gridptrOrig->x.bounds != cdfPendingLoad )
+ {
+ size_t size = (irregular ? gridsize : (size_t)gridptrOrig->x.size)
+ * (size_t)gridptrOrig->nvertex;
+ gridptrDup->x.bounds = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->x.bounds, gridptrOrig->x.bounds, size * sizeof (double));
+ }
-int cdiEncodeParam(int pnum, int pcat, int pdis)
-{
- unsigned uparam, upnum;
+ if ( gridptrOrig->y.bounds != NULL && gridptrOrig->y.bounds != cdfPendingLoad )
+ {
+ size_t size = (irregular ? gridsize : (size_t)gridptrOrig->y.size)
+ * (size_t)gridptrOrig->nvertex;
- if ( pcat < 0 || pcat > 255 ) pcat = 255;
- if ( pdis < 0 || pdis > 255 ) pdis = 255;
+ gridptrDup->y.bounds = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->y.bounds, gridptrOrig->y.bounds, size * sizeof (double));
+ }
- upnum = (unsigned)pnum;
- if ( pnum < 0 ) upnum = (unsigned)(0x8000 - pnum);
+ {
+ if ( gridptrOrig->area != NULL && gridptrOrig->area != cdfPendingLoad )
+ {
+ size_t size = gridsize;
- uparam = upnum << 16 | (unsigned)(pcat << 8) | (unsigned)pdis;
+ gridptrDup->area = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->area, gridptrOrig->area, size * sizeof (double));
+ }
+ }
- return ((int)uparam);
-}
+ if ( gridptrOrig->mask != NULL )
+ {
+ size_t size = gridsize;
+ gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
+ memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
+ }
-void cdiDecodeDate(int date, int *year, int *month, int *day)
-{
+ if ( gridptrOrig->mask_gme != NULL )
+ {
+ size_t size = gridsize;
- int iyear = date / 10000;
- *year = iyear;
- int idate = abs(date - iyear * 10000),
- imonth = idate / 100;
- *month = imonth;
- *day = idate - imonth * 100;
+ gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
+ memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
+ }
}
-
-int cdiEncodeDate(int year, int month, int day)
+static grid_t *
+cdfLazyGridCopy(grid_t *gridptrOrig)
{
- int iyear = abs(year),
- date = iyear * 10000 + month * 100 + day;
- if ( year < 0 ) date = -date;
- return (date);
+ struct cdfLazyGrid *lazyGridDup
+ = (struct cdfLazyGrid *)Malloc(sizeof (*lazyGridDup));
+ gridptrOrig->vtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
+ gridptrOrig->vtable->copyArrayFields(gridptrOrig, &lazyGridDup->base);
+ return &lazyGridDup->base;
}
-
-void cdiDecodeTime(int time, int *hour, int *minute, int *second)
+static void
+cdfLazyGridInitOnce(void)
{
- int ihour = time / 10000,
- itime = time - ihour * 10000,
- iminute = itime / 100;
- *hour = ihour;
- *minute = iminute;
- *second = itime - iminute * 100;
+ cdfLazyGridVtable = cdiGridVtable;
+ cdfLazyGridVtable.destroy = cdfLazyGridDelete;
+ cdfLazyGridVtable.copy = cdfLazyGridCopy;
+ cdfLazyGridVtable.copyScalarFields = cdfLazyGridCopyScalarFields;
+ cdfLazyGridVtable.copyArrayFields = cdfLazyGridCopyArrayFields;
+ cdfLazyGridVtable.defArea = cdfLazyGridDefArea;
+ cdfLazyGridVtable.inqAreaPtr = cdfLazyGridInqAreaPtr;
+ cdfLazyGridVtable.inqArea = cdfLazyGridInqArea;
+ cdfLazyGridVtable.inqXValsPtr = cdfLazyGridInqXValsPtr;
+ cdfLazyGridVtable.inqYValsPtr = cdfLazyGridInqYValsPtr;
+ cdfLazyGridVtable.inqXVal = cdfLazyGridInqXVal;
+ cdfLazyGridVtable.inqYVal = cdfLazyGridInqYVal;
+ cdfLazyGridVtable.defXVals = cdfLazyGridDefXVals;
+ cdfLazyGridVtable.defYVals = cdfLazyGridDefYVals;
+ cdfLazyGridVtable.compareXYFull = cdfLazyCompareXYFull;
+ cdfLazyGridVtable.compareXYAO = cdfLazyCompareXYAO;
+ cdfLazyGridVtable.defXBounds = cdfLazyGridDefXBounds;
+ cdfLazyGridVtable.defYBounds = cdfLazyGridDefYBounds;
+ cdfLazyGridVtable.inqXBoundsPtr = cdfLazyGridInqXBoundsPtr;
+ cdfLazyGridVtable.inqYBoundsPtr = cdfLazyGridInqYBoundsPtr;
+ /* create inaccessible memory area, if possible, this serves as
+ * dummy value for pointers to data not yet loaded */
+ /*
+#ifdef HAVE_MMAP
+ {
+ size_t pgSize = cdiGetPageSize(false);
+ static const char devZero[] = "/dev/zero";
+ int fd = open(devZero, O_RDWR);
+ if (fd == -1)
+ SysError("Could not open %s to map anonymous memory", devZero);
+ void *cdfInvalid = mmap(NULL, pgSize, PROT_NONE, MAP_PRIVATE, fd, 0);
+ if (cdfInvalid == MAP_FAILED)
+ SysError("Could not mmap anonymous memory");
+ cdfPendingLoad = cdfInvalid;
+ int rc = close(fd);
+ if (rc == -1)
+ SysError("Could not close %s file handle %d after mapping anonymous"
+ " memory", devZero, fd);
+ }
+#else
+ */
+ cdfPendingLoad = (double *)&cdfPendingLoad;
+ //#endif
+ atexit(cdfLazyGridDestroyOnce);
+#ifndef HAVE_LIBPTHREAD
+ cdfLazyInitialized = true;
+#endif
}
-
-int cdiEncodeTime(int hour, int minute, int second)
+static void
+cdfBaseGridInit(grid_t *grid, int gridtype)
{
- int time = hour*10000 + minute*100 + second;
-
- return time;
+ grid_init(grid);
+ cdiGridTypeInit(grid, gridtype, 0);
}
-
-void cdiParamToString(int param, char *paramstr, int maxlen)
+static void
+cdfLazyGridInit(struct cdfLazyGrid *grid, int gridtype)
{
- int dis, cat, num;
- int len;
-
- cdiDecodeParam(param, &num, &cat, &dis);
-
- size_t umaxlen = maxlen >= 0 ? (unsigned)maxlen : 0U;
- if ( dis == 255 && (cat == 255 || cat == 0 ) )
- len = snprintf(paramstr, umaxlen, "%d", num);
- else if ( dis == 255 )
- len = snprintf(paramstr, umaxlen, "%d.%d", num, cat);
- else
- len = snprintf(paramstr, umaxlen, "%d.%d.%d", num, cat, dis);
-
- if ( len >= maxlen || len < 0)
- fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
+#ifdef HAVE_LIBPTHREAD
+ pthread_once(&cdfLazyInitialized, cdfLazyGridInitOnce);
+#else
+ if (cdfLazyInitialized) ; else cdfLazyGridInitOnce();
+#endif
+ cdfBaseGridInit(&grid->base, gridtype);
+ grid->baseVtable = grid->base.vtable;
+ grid->cellAreaGet.datasetNCId = -1;
+ grid->cellAreaGet.varNCId = -1;
+ grid->xValsGet.datasetNCId = -1;
+ grid->xValsGet.varNCId = -1;
+ grid->yValsGet.datasetNCId = -1;
+ grid->yValsGet.varNCId = -1;
+ grid->xBoundsGet.datasetNCId = -1;
+ grid->xBoundsGet.varNCId = -1;
+ grid->yBoundsGet.datasetNCId = -1;
+ grid->yBoundsGet.varNCId = -1;
+ grid->base.vtable = &cdfLazyGridVtable;
+ init_lazy_load_lock(grid);
}
-const char *cdiUnitNamePtr(int cdi_unit)
+void cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
{
- const char *cdiUnits[] = {
- /* 0 */ "undefined",
- /* 1 */ "Pa",
- /* 2 */ "hPa",
- /* 3 */ "mm",
- /* 4 */ "cm",
- /* 5 */ "dm",
- /* 6 */ "m",
- };
- enum { numUnits = (int) (sizeof(cdiUnits)/sizeof(char *)) };
- const char *name = ( cdi_unit > 0 && cdi_unit < numUnits ) ?
- cdiUnits[cdi_unit] : NULL;
- return name;
+ struct cdfLazyGrid *restrict grid = *gridpptr;
+ if (!grid)
+ *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (*grid));
+ cdfLazyGridInit(grid, gridtype);
}
-size_t
-cdiGetPageSize(bool largePageAlign)
+
+void cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
{
- long pagesize = -1L;
-#if HAVE_DECL__SC_LARGE_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE || HAVE_DECL__SC_PAGESIZE
- bool nameAssigned = false;
- int name;
-# if HAVE_DECL__SC_LARGE_PAGESIZE
- if (largePageAlign)
- {
- name = _SC_LARGE_PAGESIZE;
- nameAssigned = true;
- }
- else
-# else
- (void)largePageAlign;
-# endif
- {
-# if HAVE_DECL__SC_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE
- name =
-# if HAVE_DECL__SC_PAGESIZE
- _SC_PAGESIZE
-# elif HAVE_DECL__SC_PAGE_SIZE
- _SC_PAGE_SIZE
-# endif
- ;
- nameAssigned = true;
-# endif
- }
- if (nameAssigned)
- pagesize = sysconf(name);
-#endif
- if (pagesize == -1L)
- pagesize =
-#if HAVE_DECL_PAGESIZE
- PAGESIZE
-#elif HAVE_DECL_PAGE_SIZE
- PAGE_SIZE
-#else
- commonPageSize
-#endif
- ;
- return (size_t)pagesize;
+ struct cdfLazyGrid *restrict grid = *gridpptr;
+ if (!grid)
+ *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (grid_t));
+ cdfBaseGridInit((grid_t*)grid, gridtype);
}
+#endif
/*
* Local Variables:
@@ -5658,12585 +5803,10162 @@ cdiGetPageSize(bool largePageAlign)
* require-trailing-newline: t
* End:
*/
+#ifndef CDI_CKSUM_H_
+#define CDI_CKSUM_H_
-/* Automatically generated by m214003 at 2016-06-03, do not edit */
-
-/* CGRIBEXLIB_VERSION="1.7.5" */
+#include <inttypes.h>
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) || defined (__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Wsign-conversion"
-#pragma GCC diagnostic warning "-Wstrict-overflow"
-#endif
+uint32_t cdiCheckSum(int type, int count, const void *data);
-#ifdef _ARCH_PWR6
-#pragma options nostrict
#endif
-#if defined (HAVE_CONFIG_H)
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
#endif
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <sys/types.h>
#include <inttypes.h>
+#include <sys/types.h>
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+ size_t elem_size);
-#ifndef _TEMPLATES_H
-#define _TEMPLATES_H
-
-#define CAT(X,Y) X##_##Y
-#define TEMPLATE(X,Y) CAT(X,Y)
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size);
-#endif
-#ifndef GRIB_INT_H
-#define GRIB_INT_H
+uint32_t
+memcrc(const unsigned char *b, size_t n);
-#if defined (HAVE_CONFIG_H)
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
+#ifndef SERIALIZE_H
+#define SERIALIZE_H
+#include <string.h>
-#if ! defined (_CGRIBEX_H)
+#ifndef CDI_CKSUM_H_
#endif
-#if ! defined (_ERROR_H)
-#endif
-#if ! defined (_DTYPES_H)
-#endif
-
-#if ! defined (FALSE)
-# define FALSE 0
+#ifndef ERROR_H
#endif
-#if ! defined (TRUE)
-# define TRUE 1
-#endif
+/*
+ * Generic interfaces for (de-)marshalling
+ */
+int serializeGetSize(int count, int datatype, void *context);
+void serializePack(const void *data, int count, int datatype,
+ void *buf, int buf_size, int *position, void *context);
+void serializeUnpack(const void *buf, int buf_size, int *position,
+ void *data, int count, int datatype, void *context);
-#if ! defined (UCHAR)
-# define UCHAR unsigned char
-#endif
+/*
+ * (de-)marshalling function for common data structures
+ */
+static inline int
+serializeStrTabGetPackSize(const char **strTab, int numStr,
+ void *context)
+{
+ xassert(numStr >= 0);
+ int packBuffSize = 0;
+ for (size_t i = 0; i < (size_t)numStr; ++i)
+ {
+ size_t len = strlen(strTab[i]);
+ packBuffSize +=
+ serializeGetSize(1, CDI_DATATYPE_INT, context)
+ + serializeGetSize((int)len, CDI_DATATYPE_TXT, context);
+ }
+ packBuffSize +=
+ serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+ return packBuffSize;
+}
+static inline void
+serializeStrTabPack(const char **strTab, int numStr,
+ void *buf, int buf_size, int *position, void *context)
+{
+ uint32_t d = 0;
+ xassert(numStr >= 0);
+ for (size_t i = 0; i < (size_t)numStr; ++i)
+ {
+ int len = (int)strlen(strTab[i]);
+ serializePack(&len, 1, CDI_DATATYPE_INT,
+ buf, buf_size, position, context);
+ serializePack(strTab[i], len, CDI_DATATYPE_TXT,
+ buf, buf_size, position, context);
+ d ^= cdiCheckSum(CDI_DATATYPE_TXT, len, strTab[i]);
+ }
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ buf, buf_size, position, context);
+}
-#if defined (CRAY) || defined (SX) || defined (__uxpch__)
-# define VECTORCODE
-#endif
+static inline void
+serializeStrTabUnpack(const void *buf, int buf_size, int *position,
+ char **strTab, int numStr, void *context)
+{
+ uint32_t d, d2 = 0;
+ xassert(numStr >= 0);
+ for (size_t i = 0; i < (size_t)numStr; ++i)
+ {
+ int len;
+ serializeUnpack(buf, buf_size, position,
+ &len, 1, CDI_DATATYPE_INT, context);
+ serializeUnpack(buf, buf_size, position,
+ strTab[i], len, CDI_DATATYPE_TXT, context);
+ strTab[i][len] = '\0';
+ d2 ^= cdiCheckSum(CDI_DATATYPE_TXT, len, strTab[i]);
+ }
+ serializeUnpack(buf, buf_size, position,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(d == d2);
+}
+/*
+ * Interfaces for marshalling within a single memory domain
+ */
+int serializeGetSizeInCore(int count, int datatype, void *context);
+void serializePackInCore(const void *data, int count, int datatype,
+ void *buf, int buf_size, int *position, void *context);
+void serializeUnpackInCore(const void *buf, int buf_size, int *position,
+ void *data, int count, int datatype, void *context);
-#if defined (VECTORCODE)
-#if defined (INT32)
-# define GRIBPACK unsigned INT32
-# define PACK_GRIB packInt32
-# define UNPACK_GRIB unpackInt32
-#else
-# define GRIBPACK unsigned INT64
-# define PACK_GRIB packInt64
-# define UNPACK_GRIB unpackInt64
#endif
-#else
-# define GRIBPACK unsigned char
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
#endif
-#define U_BYTEORDER static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
-#define IS_BIGENDIAN() (u_byteorder.c[sizeof(long) - 1])
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdlib.h>
-#if defined (__xlC__) /* performance problems on IBM */
-#ifndef DBL_IS_NAN
-# define DBL_IS_NAN(x) ((x) != (x))
-#endif
-#else
-#ifndef DBL_IS_NAN
-#if defined (HAVE_DECL_ISNAN)
-# define DBL_IS_NAN(x) (isnan(x))
-#elif defined (FP_NAN)
-# define DBL_IS_NAN(x) (fpclassify(x) == FP_NAN)
-#else
-# define DBL_IS_NAN(x) ((x) != (x))
-#endif
-#endif
-#endif
-#ifndef IS_EQUAL
-# define IS_NOT_EQUAL(x,y) (x < y || y < x)
-# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
-#endif
+uint32_t cdiCheckSum(int type, int count, const void *buffer)
+{
+ uint32_t s = 0U;
+ xassert(count >= 0);
+ size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
+ memcrc_r_eswap(&s, (const unsigned char *)buffer, (size_t)count, elemSize);
+ s = memcrc_finish(&s, (off_t)(elemSize * (size_t)count));
+ return s;
+}
-/* dummy use of unused parameters to silence compiler warnings */
-#ifndef UNUSED
-# define UNUSED(x) (void)(x)
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
#endif
-#define JP23SET 0x7FFFFF /* 2**23 - 1 (---> 8388607) */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
-#define POW_2_M24 0.000000059604644775390625 /* pow(2.0, -24.0) */
+const char *cdiStringError(int cdiErrno)
+{
+ static const char UnknownError[] = "Unknown Error";
+ static const char _EISDIR[] = "Is a directory";
+ static const char _EISEMPTY[] = "File is empty";
+ static const char _EUFTYPE[] = "Unsupported file type";
+ static const char _ELIBNAVAIL[] = "Unsupported file type (library support not compiled in)";
+ static const char _EUFSTRUCT[] = "Unsupported file structure";
+ static const char _EUNC4[] = "Unsupported NetCDF4 structure";
+ static const char _EDIMSIZE[] = "Invalid dimension size";
+ static const char _ELIMIT[] = "Internal limits exceeded";
-#ifdef __cplusplus
-extern "C" {
-#endif
+ switch (cdiErrno) {
+ case CDI_ESYSTEM:
+ {
+ const char *cp = strerror(errno);
+ if ( cp == NULL ) break;
+ return cp;
+ }
+ case CDI_EISDIR: return _EISDIR;
+ case CDI_EISEMPTY: return _EISEMPTY;
+ case CDI_EUFTYPE: return _EUFTYPE;
+ case CDI_ELIBNAVAIL: return _ELIBNAVAIL;
+ case CDI_EUFSTRUCT: return _EUFSTRUCT;
+ case CDI_EUNC4: return _EUNC4;
+ case CDI_EDIMSIZE: return _EDIMSIZE;
+ case CDI_ELIMIT: return _ELIMIT;
+ }
-#define intpow2(x) (ldexp(1.0, (x)))
+ return UnknownError;
+}
-int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
-int correct_bdslen(int bdslen, long recsize, long gribpos);
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _GRIBAPI_H
+#define _GRIBAPI_H
-/* CDI converter routines */
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#ifndef ERROR_H
+#endif
+#endif
-/* param format: DDDCCCNNN */
+#ifndef _CDI_INT_H
+#endif
-void cdiDecodeParam(int param, int *dis, int *cat, int *num);
-int cdiEncodeParam(int dis, int cat, int num);
+#define GRIBAPI_MISSVAL -9.E33
-/* date format: YYYYMMDD */
-/* time format: hhmmss */
+/* GRIB2 Level Types */
+#define GRIB2_LTYPE_SURFACE 1
+#define GRIB2_LTYPE_CLOUD_BASE 2
+#define GRIB2_LTYPE_CLOUD_TOP 3
+#define GRIB2_LTYPE_ISOTHERM0 4
+#define GRIB2_LTYPE_TOA 8
+#define GRIB2_LTYPE_SEA_BOTTOM 9
+#define GRIB2_LTYPE_ATMOSPHERE 10
+#define GRIB2_LTYPE_ISOBARIC 100
+#define GRIB2_LTYPE_MEANSEA 101
+#define GRIB2_LTYPE_ALTITUDE 102
+#define GRIB2_LTYPE_HEIGHT 103
+#define GRIB2_LTYPE_SIGMA 104
+#define GRIB2_LTYPE_HYBRID 105
+#define GRIB2_LTYPE_LANDDEPTH 106
+#define GRIB2_LTYPE_ISENTROPIC 107
+#define GRIB2_LTYPE_SNOW 114
+#define GRIB2_LTYPE_REFERENCE 150
+#define GRIB2_LTYPE_SEADEPTH 160 /* Depth Below Sea Level */
+#define GRIB2_LTYPE_LAKE_BOTTOM 162 /* Lake or River Bottom */
+#define GRIB2_LTYPE_SEDIMENT_BOTTOM 163 /* Bottom Of Sediment Layer */
+#define GRIB2_LTYPE_SEDIMENT_BOTTOM_TA 164 /* Bottom Of Thermally Active Sediment Layer */
+#define GRIB2_LTYPE_SEDIMENT_BOTTOM_TW 165 /* Bottom Of Sediment Layer Penetrated By Thermal Wave */
+#define GRIB2_LTYPE_MIX_LAYER 166 /* Mixing Layer */
-void cdiDecodeDate(int date, int *year, int *month, int *day);
-int cdiEncodeDate(int year, int month, int day);
+/* GRIB2 Data representation type (Grid Type) */
+#define GRIB2_GTYPE_LATLON 0 /* latitude/longitude */
+#define GRIB2_GTYPE_LATLON_ROT 1 /* rotated latitude/longitude */
+#define GRIB2_GTYPE_LATLON_STR 2 /* stretched latitude/longitude */
+#define GRIB2_GTYPE_LATLON_ROTSTR 3 /* rotated and stretched latitude/longitude */
+#define GRIB2_GTYPE_GAUSSIAN 40 /* gaussian grid */
+#define GRIB2_GTYPE_GAUSSIAN_ROT 41 /* rotated gaussian grid */
+#define GRIB2_GTYPE_GAUSSIAN_STR 42 /* stretched gaussian grid */
+#define GRIB2_GTYPE_GAUSSIAN_ROTSTR 43 /* rotated and stretched gaussian grid */
+#define GRIB2_GTYPE_LCC 30 /* Lambert conformal */
+#define GRIB2_GTYPE_SPECTRAL 50 /* spherical harmonics */
+#define GRIB2_GTYPE_GME 100 /* hexagonal GME grid */
+#define GRIB2_GTYPE_UNSTRUCTURED 101 /* General Unstructured Grid */
-void cdiDecodeTime(int time, int *hour, int *minute, int *second);
-int cdiEncodeTime(int hour, int minute, int second);
+const char *gribapiLibraryVersionString(void);
+void gribContainersNew(stream_t * streamptr);
+void gribContainersDelete(stream_t * streamptr);
-/* CALENDAR types */
+#ifdef HAVE_LIBGRIB_API
+static inline void *gribHandleNew(int editionNumber)
+{
+ void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
-#define CALENDAR_STANDARD 0 /* don't change this value (used also in cgribexlib)! */
-#define CALENDAR_PROLEPTIC 1
-#define CALENDAR_360DAYS 2
-#define CALENDAR_365DAYS 3
-#define CALENDAR_366DAYS 4
-#define CALENDAR_NONE 5
+ if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
-extern FILE *grprsm;
+ return gh;
+}
-extern int CGRIBEX_Debug;
+static inline int my_grib_set_double(grib_handle* h, const char* key, double val)
+{
+ if ( cdiGribApiDebug )
+ fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val);
-void gprintf(const char *caller, const char *fmt, ...);
+ int ret_val = grib_set_double(h, key, val);
+ if (ret_val != 0)
+ fprintf(stderr, "!!! failed call to grib_set_double(\tgrib_handle* h, \"%s\", %f) !!!\n", key, val);
+ return ret_val;
+}
-void grsdef(void);
+static inline int my_grib_set_long(grib_handle* h, const char* key, long val)
+{
+ if ( cdiGribApiDebug )
+ fprintf(stderr, "grib_set_long( \tgrib_handle* h, \"%s\", %ld)\n", key, val);
-void prtbin(int kin, int knbit, int *kout, int *kerr);
-void confp3(double pval, int *kexp, int *kmant, int kbits, int kround);
-double decfp2(int kexp, int kmant);
-void ref2ibm(double *pref, int kbits);
+ int ret_val = grib_set_long(h, key, val);
+ if (ret_val != 0)
+ fprintf(stderr, "!!! failed call to grib_set_long( \tgrib_handle* h, \"%s\", %ld) !!!\n", key, val);
+ return ret_val;
+}
-void scale_complex_double(double *fpdata, int pcStart, int pcScale, int trunc, int inv);
-void scale_complex_float(float *fpdata, int pcStart, int pcScale, int trunc, int inv);
-void scatter_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
-void scatter_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
-void gather_complex_double(double *fpdata, size_t pcStart, size_t trunc, size_t nsp);
-void gather_complex_float(float *fpdata, size_t pcStart, size_t trunc, size_t nsp);
+static inline int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t* length)
+{
+ if ( cdiGribApiDebug )
+ fprintf(stderr, "grib_set_string(\tgrib_handle* h, \"%s\", \"%s\")\n", key, val);
-void scm0_double(double *pdl, double *pdr, double *pfl, double *pfr, int klg);
-int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
- double *ztemp, double msval, int *kret);
-int qu2reg3_double(double *pfield, int *kpoint, int klat, int klon,
- double msval, int *kret, int omisng, int operio, int oveggy);
-int qu2reg3_float(float *pfield, int *kpoint, int klat, int klon,
- float msval, int *kret, int omisng, int operio, int oveggy);
+ int ret_val = grib_set_string(h, key, val, length);
+ if (ret_val != 0)
+ fprintf(stderr, "!!! grib_set_string(\tgrib_handle* h, \"%s\", \"%s\") !!!\n", key, val);
+ return ret_val;
+}
-#if defined (INT32)
-long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc);
-#endif
-long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc);
-#if defined (INT32)
-long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc);
+static inline void gribHandleDelete(void *gh)
+{
+ grib_handle_delete((struct grib_handle *)gh);
+}
+#else
+#define gribHandleNew(editionNumber) (NULL)
+#define gribHandleDelete(gh)
#endif
-long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc);
-
-void grib_encode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
- double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int efunc, int *kret);
-void grib_encode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
- float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int efunc, int *kret);
-
-void grib_decode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
- double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int dfunc, int *kret);
-void grib_decode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
- float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int dfunc, int *kret);
+typedef struct {
+ bool init;
+ void *gribHandle;
+}
+gribContainer_t;
-int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
- unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
-int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
- unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
- unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
+#endif /* _GRIBAPI_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef CGRIBEX_H
+#define CGRIBEX_H
-#if defined (__cplusplus)
-}
-#endif
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/types.h>
-#endif /* GRIB_INT_H */
-#ifndef _GRIBDECODE_H
-#define _GRIBDECODE_H
+#define GRIB_MISSVAL -9.E33
-#define UNDEFINED 9.999e20
+/* GRIB1 Level Types */
+#define GRIB1_LTYPE_SURFACE 1
+#define GRIB1_LTYPE_CLOUD_BASE 2
+#define GRIB1_LTYPE_CLOUD_TOP 3
+#define GRIB1_LTYPE_ISOTHERM0 4
+#define GRIB1_LTYPE_TOA 8
+#define GRIB1_LTYPE_SEA_BOTTOM 9
+#define GRIB1_LTYPE_ATMOSPHERE 10
+#define GRIB1_LTYPE_99 99
+#define GRIB1_LTYPE_ISOBARIC 100
+#define GRIB1_LTYPE_ISOBARIC_PA 210
+#define GRIB1_LTYPE_MEANSEA 102
+#define GRIB1_LTYPE_ALTITUDE 103
+#define GRIB1_LTYPE_HEIGHT 105
+#define GRIB1_LTYPE_SIGMA 107
+#define GRIB1_LTYPE_SIGMA_LAYER 108
+#define GRIB1_LTYPE_HYBRID 109
+#define GRIB1_LTYPE_HYBRID_LAYER 110
+#define GRIB1_LTYPE_LANDDEPTH 111
+#define GRIB1_LTYPE_LANDDEPTH_LAYER 112
+#define GRIB1_LTYPE_ISENTROPIC 113
+#define GRIB1_LTYPE_SEADEPTH 160 /* Depth Below Sea Level */
+#define GRIB1_LTYPE_LAKE_BOTTOM 162 /* Lake or River Bottom */
+#define GRIB1_LTYPE_SEDIMENT_BOTTOM 163 /* Bottom Of Sediment Layer */
+#define GRIB1_LTYPE_SEDIMENT_BOTTOM_TA 164 /* Bottom Of Thermally Active Sediment Layer */
+#define GRIB1_LTYPE_SEDIMENT_BOTTOM_TW 165 /* Bottom Of Sediment Layer Penetrated By Thermal Wave */
+#define GRIB1_LTYPE_MIX_LAYER 166 /* Mixing Layer */
+/* GRIB1 Data representation type (Grid Type) [Table 6] */
+#define GRIB1_GTYPE_LATLON 0 /* latitude/longitude */
+#define GRIB1_GTYPE_LATLON_ROT 10 /* rotated latitude/longitude */
+#define GRIB1_GTYPE_LATLON_STR 20 /* stretched latitude/longitude */
+#define GRIB1_GTYPE_LATLON_ROTSTR 30 /* rotated and stretched latitude/longitude */
+#define GRIB1_GTYPE_GAUSSIAN 4 /* gaussian grid */
+#define GRIB1_GTYPE_GAUSSIAN_ROT 14 /* rotated gaussian grid */
+#define GRIB1_GTYPE_GAUSSIAN_STR 24 /* stretched gaussian grid */
+#define GRIB1_GTYPE_GAUSSIAN_ROTSTR 34 /* rotated and stretched gaussian grid */
+#define GRIB1_GTYPE_LCC 3 /* Lambert conformal */
+#define GRIB1_GTYPE_SPECTRAL 50 /* spherical harmonics */
+#define GRIB1_GTYPE_GME 192 /* hexagonal GME grid */
-#define GET_INT3(a,b,c) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
-#define GET_INT2(a,b) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 8) + b))
-#define GET_INT1(a) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (a&127))
+/*
+ * Macros for the indicator section ( Section 0 )
+ */
+#define ISEC0_GRIB_Len (isec0[ 0]) /* Number of octets in the GRIB message */
+#define ISEC0_GRIB_Version (isec0[ 1]) /* GRIB edition number */
-/* this requires a 32-bit default integer machine */
-#define GET_UINT4(a,b,c,d) ((int) ((a << 24) + (b << 16) + (c << 8) + (d)))
-#define GET_UINT3(a,b,c) ((int) ((a << 16) + (b << 8) + (c)))
-#define GET_UINT2(a,b) ((int) ((a << 8) + (b)))
-#define GET_UINT1(a) ((int) (a))
-#define BUDG_START(s) (s[0]=='B' && s[1]=='U' && s[2]=='D' && s[3]=='G')
-#define TIDE_START(s) (s[0]=='T' && s[1]=='I' && s[2]=='D' && s[3]=='E')
-#define GRIB_START(s) (s[0]=='G' && s[1]=='R' && s[2]=='I' && s[3]=='B')
-#define GRIB_FIN(s) (s[0]=='7' && s[1]=='7' && s[2]=='7' && s[3]=='7')
+/*
+ * Macros for the product definition section ( Section 1 )
+ */
+#define ISEC1_TABLE4_MINUTE 0
+#define ISEC1_TABLE4_HOUR 1
+#define ISEC1_TABLE4_DAY 2
+#define ISEC1_TABLE4_3HOURS 10
+#define ISEC1_TABLE4_6HOURS 11
+#define ISEC1_TABLE4_12HOURS 12
+#define ISEC1_TABLE4_QUARTER 13
+#define ISEC1_TABLE4_30MINUTES 14
-/* GRIB1 Section 0: Indicator Section (IS) */
-#define GRIB1_SECLEN(s) GET_INT3(s[ 4], s[ 5], s[ 6])
-#define GRIB_EDITION(s) GET_UINT1(s[ 7])
+#define ISEC1_CodeTable (isec1[ 0]) /* Version number of code table */
+#define ISEC1_CenterID (isec1[ 1]) /* Identification of centre */
+#define ISEC1_ModelID (isec1[ 2]) /* Identification of model */
+#define ISEC1_GridDefinition (isec1[ 3]) /* Grid definition */
+#define ISEC1_Sec2Or3Flag (isec1[ 4]) /* Section 2 or 3 included */
+#define ISEC1_Parameter (isec1[ 5]) /* Parameter indicator */
+#define ISEC1_LevelType (isec1[ 6]) /* Type of level indicator */
+#define ISEC1_Level1 (isec1[ 7]) /* Level 1 */
+#define ISEC1_Level2 (isec1[ 8]) /* Level 2 */
+#define ISEC1_Year (isec1[ 9]) /* Year of century (YY) */
+#define ISEC1_Month (isec1[10]) /* Month (MM) */
+#define ISEC1_Day (isec1[11]) /* Day (DD) */
+#define ISEC1_Hour (isec1[12]) /* Hour (HH) */
+#define ISEC1_Minute (isec1[13]) /* Minute (MM) */
+#define ISEC1_TimeUnit (isec1[14]) /* Time unit indicator */
+#define ISEC1_TimePeriod1 (isec1[15]) /* P1 Time period */
+#define ISEC1_TimePeriod2 (isec1[16]) /* P2 Time period */
+#define ISEC1_TimeRange (isec1[17]) /* Time range indicator */
+#define ISEC1_AvgNum (isec1[18]) /* Number of products included in an average */
+#define ISEC1_AvgMiss (isec1[19]) /* Number of products missing from an average */
+#define ISEC1_Century (isec1[20]) /* Century */
+#define ISEC1_SubCenterID (isec1[21]) /* Subcenter identifier */
+#define ISEC1_DecScaleFactor (isec1[22]) /* Decimal scale factor */
+#define ISEC1_LocalFLag (isec1[23]) /* Flag field to indicate local use in isec1 */
-/* GRIB1 Section 1: Product Definition Section (PDS) */
+#define ISEC1_ECMWF_LocalExtension (isec1[36])
+#define ISEC1_ECMWF_Class (isec1[37])
-#define PDS_Len GET_UINT3(pds[ 0], pds[ 1], pds[ 2])
-#define PDS_CodeTable GET_UINT1(pds[ 3])
-#define PDS_CenterID GET_UINT1(pds[ 4])
-#define PDS_ModelID GET_UINT1(pds[ 5])
-#define PDS_GridDefinition GET_UINT1(pds[ 6])
-#define PDS_Sec2Or3Flag GET_UINT1(pds[ 7])
-#define PDS_HAS_GDS ((pds[7] & 128) != 0)
-#define PDS_HAS_BMS ((pds[7] & 64) != 0)
-#define PDS_Parameter GET_UINT1(pds[ 8])
-#define PDS_LevelType GET_UINT1(pds[ 9])
-#define PDS_Level1 (pds[10])
-#define PDS_Level2 (pds[11])
-#define PDS_Level GET_UINT2(pds[10], pds[11])
-#define PDS_Year GET_INT1(pds[12])
-#define PDS_Month GET_UINT1(pds[13])
-#define PDS_Day GET_UINT1(pds[14])
-#define PDS_Hour GET_UINT1(pds[15])
-#define PDS_Minute GET_UINT1(pds[16])
-#define PDS_Date (PDS_Year*10000+PDS_Month*100+PDS_Day)
-#define PDS_Time (PDS_Hour*100+PDS_Minute)
-#define PDS_TimeUnit GET_UINT1(pds[17])
-#define PDS_TimePeriod1 GET_UINT1(pds[18])
-#define PDS_TimePeriod2 GET_UINT1(pds[19])
-#define PDS_TimeRange GET_UINT1(pds[20])
-#define PDS_AvgNum GET_UINT2(pds[21], pds[22])
-#define PDS_AvgMiss GET_UINT1(pds[23])
-#define PDS_Century GET_UINT1(pds[24])
-#define PDS_Subcenter GET_UINT1(pds[25])
-#define PDS_DecimalScale GET_INT2(pds[26],pds[27])
+/*
+ * Macros for the grid definition section ( Section 2 )
+ */
+#define ISEC2_GridType (isec2[ 0]) /* Data representation type */
-/* GRIB1 Section 2: Grid Description Section (GDS) */
+/* Triangular grids */
-#define GDS_Len ((gds) == NULL ? 0 : GET_UINT3(gds[ 0], gds[ 1], gds[ 2]))
-#define GDS_NV GET_UINT1(gds[ 3])
-#define GDS_PVPL GET_UINT1(gds[ 4])
-#define GDS_PV ((gds[3] == 0) ? -1 : (int) gds[4] - 1)
-#define GDS_PL ((gds[4] == 0xFF) ? -1 : (int) gds[3] * 4 + (int) gds[4] - 1)
-#define GDS_GridType GET_UINT1(gds[ 5])
+#define ISEC2_GME_NI2 (isec2[ 1]) /* Number of factor 2 in factorisation of Ni */
+#define ISEC2_GME_NI3 (isec2[ 2]) /* Number of factor 3 in factorisation of Ni */
+#define ISEC2_GME_ND (isec2[ 3]) /* Nubmer of diamonds */
+#define ISEC2_GME_NI (isec2[ 4]) /* Number of tri. subdiv. of the icosahedron */
+#define ISEC2_GME_AFlag (isec2[ 5]) /* Flag for orientation of diamonds (Table A) */
+#define ISEC2_GME_LatPP (isec2[ 6]) /* Latitude of pole point */
+#define ISEC2_GME_LonPP (isec2[ 7]) /* Longitude of pole point */
+#define ISEC2_GME_LonMPL (isec2[ 8]) /* Longitude of the first diamond */
+#define ISEC2_GME_BFlag (isec2[ 9]) /* Flag for storage sequence (Table B) */
+/* Spherical harmonic coeficients */
-/* GRIB1 Triangular grid of DWD */
-#define GDS_GME_NI2 GET_UINT2(gds[ 6], gds[ 7])
-#define GDS_GME_NI3 GET_UINT2(gds[ 8], gds[ 9])
-#define GDS_GME_ND GET_UINT3(gds[10], gds[11], gds[12])
-#define GDS_GME_NI GET_UINT3(gds[13], gds[14], gds[15])
-#define GDS_GME_AFlag GET_UINT1(gds[16])
-#define GDS_GME_LatPP GET_INT3(gds[17], gds[18], gds[19])
-#define GDS_GME_LonPP GET_INT3(gds[20], gds[21], gds[22])
-#define GDS_GME_LonMPL GET_INT3(gds[23], gds[24], gds[25])
-#define GDS_GME_BFlag GET_UINT1(gds[27])
+#define ISEC2_PentaJ (isec2[ 1]) /* J pentagonal resolution parameter */
+#define ISEC2_PentaK (isec2[ 2]) /* K pentagonal resolution parameter */
+#define ISEC2_PentaM (isec2[ 3]) /* M pentagonal resolution parameter */
+#define ISEC2_RepType (isec2[ 4]) /* Representation type */
+#define ISEC2_RepMode (isec2[ 5]) /* Representation mode */
-/* GRIB1 Spectral */
-#define GDS_PentaJ GET_UINT2(gds[ 6], gds[ 7])
-#define GDS_PentaK GET_UINT2(gds[ 8], gds[ 9])
-#define GDS_PentaM GET_UINT2(gds[10], gds[11])
-#define GDS_RepType GET_UINT1(gds[12])
-#define GDS_RepMode GET_UINT1(gds[13])
+/* Gaussian grids */
-/* GRIB1 Regular grid */
-#define GDS_NumLon GET_UINT2(gds[ 6], gds[ 7])
-#define GDS_NumLat GET_UINT2(gds[ 8], gds[ 9])
-#define GDS_FirstLat GET_INT3(gds[10], gds[11], gds[12])
-#define GDS_FirstLon GET_INT3(gds[13], gds[14], gds[15])
-#define GDS_ResFlag GET_UINT1(gds[16])
-#define GDS_LastLat GET_INT3(gds[17], gds[18], gds[19])
-#define GDS_LastLon GET_INT3(gds[20], gds[21], gds[22])
-#define GDS_LonIncr GET_UINT2(gds[23], gds[24])
-#define GDS_LatIncr GET_UINT2(gds[25], gds[26])
-#define GDS_NumPar GET_UINT2(gds[25], gds[26])
-#define GDS_ScanFlag GET_UINT1(gds[27])
-#define GDS_LatSP GET_INT3(gds[32], gds[33], gds[34])
-#define GDS_LonSP GET_INT3(gds[35], gds[36], gds[37])
-#define GDS_RotAngle (GET_Real(&(gds[38])))
+#define ISEC2_NumLon (isec2[ 1]) /* Number of points along a parallel (Ni) */
+#define ISEC2_NumLat (isec2[ 2]) /* Number of points along a meridian (Nj) */
+#define ISEC2_FirstLat (isec2[ 3]) /* Latitude of the first grid point */
+#define ISEC2_FirstLon (isec2[ 4]) /* Longitude of the first grid point */
+#define ISEC2_ResFlag (isec2[ 5]) /* Resolution flag: 128 regular grid */
+#define ISEC2_LastLat (isec2[ 6]) /* Latitude of the last grid point */
+#define ISEC2_LastLon (isec2[ 7]) /* Longitude of the last grid point */
+#define ISEC2_LonIncr (isec2[ 8]) /* i direction increment */
+#define ISEC2_LatIncr (isec2[ 9]) /* j direction increment */
+#define ISEC2_NumPar (isec2[ 9]) /* Number of parallels between a pole and the E.*/
+#define ISEC2_ScanFlag (isec2[10]) /* Scanning mode flags */
+#define ISEC2_NumVCP (isec2[11]) /* Number of vertical coordinate parameters */
-/* GRIB1 Lambert */
-#define GDS_Lambert_Lov GET_INT3(gds[17], gds[18], gds[19])
-#define GDS_Lambert_dx GET_INT3(gds[20], gds[21], gds[22])
-#define GDS_Lambert_dy GET_INT3(gds[23], gds[24], gds[25])
-#define GDS_Lambert_ProjFlag GET_UINT1(gds[26])
-#define GDS_Lambert_LatS1 GET_INT3(gds[28], gds[29], gds[30])
-#define GDS_Lambert_LatS2 GET_INT3(gds[31], gds[32], gds[33])
-#define GDS_Lambert_LatSP GET_INT3(gds[34], gds[35], gds[36])
-#define GDS_Lambert_LonSP GET_INT3(gds[37], gds[37], gds[37])
+/* Lambert */
+#define ISEC2_Lambert_Lov (isec2[ 6]) /* Orientation of the grid */
+#define ISEC2_Lambert_dx (isec2[ 8]) /* X-direction grid length */
+#define ISEC2_Lambert_dy (isec2[ 9]) /* Y-direction grid length */
+#define ISEC2_Lambert_ProjFlag (isec2[12]) /* Projection centre flag */
+#define ISEC2_Lambert_LatS1 (isec2[13]) /* First lat at which the secant cone cuts the sphere */
+#define ISEC2_Lambert_LatS2 (isec2[14]) /* Second lat at which the secant cone cuts the sphere */
+#define ISEC2_Lambert_LatSP (isec2[19]) /* Latitude of the southern pole */
+#define ISEC2_Lambert_LonSP (isec2[20]) /* Longitude of the southern pole */
-/* GRIB1 Section 3: Bit Map Section (BMS) */
-#define BMS_Len ((bms) == NULL ? 0 : (int) (bms[0]<<16)+(bms[1]<<8)+bms[2])
-#define BMS_UnusedBits (bms[3])
-#define BMS_Numeric
-#define BMS_Bitmap ((bms) == NULL ? NULL : (bms)+6)
-#define BMS_BitmapSize (((((bms[0]<<16)+(bms[1]<<8)+bms[2]) - 6)<<3) - bms[3])
+#define ISEC2_Reduced (isec2[16]) /* 0: regular, 1: reduced grid */
-/* GRIB1 Section 4: Binary Data Section (BDS) */
+#define ISEC2_RowLonPtr (&isec2[22])
+#define ISEC2_RowLon(i) (isec2[22+i]) /* Number of points along each parallel */
-#define BDS_Len ((int) ((bds[0]<<16)+(bds[1]<<8)+bds[2]))
-#define BDS_Flag (bds[3])
-#define BDS_BinScale GET_INT2(bds[ 4], bds[ 5])
-#define BDS_RefValue (decfp2((int)bds[ 6], GET_UINT3(bds[ 7], bds[ 8], bds[ 9])))
-#define BDS_NumBits ((int) bds[10])
-#define BDS_RealCoef (decfp2((int)bds[zoff+11], GET_UINT3(bds[zoff+12], bds[zoff+13], bds[zoff+14])))
-#define BDS_PackData ((int) ((bds[zoff+11]<<8) + bds[zoff+12]))
-#define BDS_Power GET_INT2(bds[zoff+13], bds[zoff+14])
-#define BDS_Z (bds[13])
+/* */
-/* GRIB1 Section 5: End Section (ES) */
+#define ISEC2_LatSP (isec2[12]) /* Latitude of the southern pole of rotation */
+#define ISEC2_LonSP (isec2[13]) /* Longitude of the southern pole of rotation */
-/* GRIB2 */
+#define FSEC2_RotAngle (fsec2[ 0]) /* Angle of rotation */
+#define FSEC2_StrFact (fsec2[ 1]) /* Stretching factor */
-#define GRIB2_SECLEN(section) (GET_UINT4(section[0], section[1], section[2], section[3]))
-#define GRIB2_SECNUM(section) (GET_UINT1(section[4]))
+/*
+ * Macros for the bit map section ( Section 3 )
+ */
+#define ISEC3_PredefBitmap (isec3[ 0]) /* Predefined bitmap */
+#define ISEC3_MissVal (isec3[ 1]) /* Missing data value for integers */
+#define FSEC3_MissVal (fsec3[ 1]) /* Missing data value for floats */
-#endif /* _GRIBDECODE_H */
-#ifndef _GRIB_ENCODE_H
-#define _GRIB_ENCODE_H
+/*
+ * Macros for the binary data section ( Section 4 )
+ */
+#define ISEC4_NumValues (isec4[ 0]) /* Number of data values for encode/decode */
+#define ISEC4_NumBits (isec4[ 1]) /* Number of bits used for each encoded value */
+#define ISEC4_NumNonMissValues (isec4[20]) /* Number of non-missing values */
-#include <limits.h>
-#define PutnZero(n) \
-{ \
- for ( size_t i = z >= 0 ? (size_t)z : 0; i < (size_t)(z+n); i++ ) lGrib[i] = 0; \
- z += n; \
-}
+#ifdef __cplusplus
+extern "C" {
+#endif
-#define Put1Byte(Value) (lGrib[z++] = (GRIBPACK)(Value))
-#define Put2Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
- (lGrib[z++] = (GRIBPACK)(Value)))
-#define Put3Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 16)), \
- (lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
- (lGrib[z++] = (GRIBPACK)(Value)))
-#define Put4Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 24)), \
- (lGrib[z++] = (GRIBPACK)((Value) >> 16)), \
- (lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
- (lGrib[z++] = (GRIBPACK)(Value)))
-#define Put1Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x80 - ival; Put1Byte(ival);}
-#define Put2Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x8000 - ival; Put2Byte(ival);}
-#define Put3Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x800000 - ival; Put3Byte(ival);}
+void gribFixZSE(int flag); /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
+void gribSetConst(int flag); /* 1: Don't pack constant fields on regular grids */
+void gribSetDebug(int debug); /* 1: Debugging */
+void gribSetRound(int round);
+void gribSetRefDP(double refval);
+void gribSetRefSP(float refval);
+void gribSetValueCheck(int vcheck);
-enum {
- BitsPerInt = (int) (sizeof(int) * CHAR_BIT),
-};
+void gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+ float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, const char *hoper, int *kret);
-#define Put1Real(Value) \
-{ \
- confp3(Value, &exponent, &mantissa, BitsPerInt, 1); \
- Put1Byte(exponent); \
- Put3Byte(mantissa); \
-}
+void gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+ double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, const char *hoper, int *kret);
-#endif /* _GRIB_ENCODE_H */
-#ifndef CODEC_COMMON_H
-#define CODEC_COMMON_H
-#define gribSwapByteOrder_uint16(ui16) ((uint16_t)((ui16<<8) | (ui16>>8)))
-#endif /* CODEC_COMMON_H */
-/*
-icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -qopenmp -DOMP_SIMD minmax_val.c
- result on hama2 (icc 16.0.0):
- float:
-minmax_val: fmin: -500000 fmax: 499999 time: 1.22s
-simd : fmin: -500000 fmax: 499999 time: 1.20s
- double:
-minmax_val: fmin: -500000 fmax: 499999 time: 2.86s
-orig : fmin: -500000 fmax: 499999 time: 2.74s
-simd : fmin: -500000 fmax: 499999 time: 2.70s
-avx : fmin: -500000 fmax: 499999 time: 2.99s
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD -Wa,-q minmax_val.c
- result on thunder5 (gcc 6.1.0):
-float:
-minmax_val: fmin: -500000 fmax: 499999 time: 8.25s
- simd : fmin: -500000 fmax: 499999 time: 1.24s
-double:
-minmax_val: fmin: -500000 fmax: 499999 time: 2.73s
- orig : fmin: -500000 fmax: 499999 time: 9.24s
- simd : fmin: -500000 fmax: 499999 time: 2.78s
- avx : fmin: -500000 fmax: 499999 time: 2.90s
+const char *cgribexLibraryVersion(void);
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL minmax_val.c
- result on bailung (gcc 4.8.2):
- orig : fmin: -500000 fmax: 499999 time: 4.82s
- sse2 : fmin: -500000 fmax: 499999 time: 4.83s
+void gribDebug(int debug);
+void gribSetCalendar(int calendar);
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD -Wa,-q minmax_val.c
- result on thunder5 (gcc 4.8.2):
- orig : fmin: -500000 fmax: 499999 time: 3.10s
- simd : fmin: -500000 fmax: 499999 time: 3.10s # omp simd in gcc 4.9
- avx : fmin: -500000 fmax: 499999 time: 2.84s
+void gribDateTime(int *isec1, int *date, int *time);
+int gribRefDate(int *isec1);
+int gribRefTime(int *isec1);
+bool gribTimeIsFC(int *isec1);
-icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
- result on thunder5 (icc 14.0.2):
- orig : fmin: -500000 fmax: 499999 time: 2.83s
- simd : fmin: -500000 fmax: 499999 time: 2.83s
- avx : fmin: -500000 fmax: 499999 time: 2.92s
+void gribPrintSec0(int *isec0);
+void gribPrintSec1(int *isec0, int *isec1);
+void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
+void gribPrintSec2SP(int *isec0, int *isec2, float *fsec2);
+void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
+void gribPrintSec3SP(int *isec0, int *isec3, float *fsec3);
+void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
+void gribPrintSec4SP(int *isec0, int *isec4, float *fsec4);
+void gribPrintSec4Wave(int *isec4);
-xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_MINMAXVAL minmax_val.c
- result on blizzard (xlc 12):
- orig : fmin: -500000 fmax: 499999 time: 7.26s
- pwr6u6 : fmin: -500000 fmax: 499999 time: 5.92s
-*/
-#if defined(_ARCH_PWR6)
-#pragma options nostrict
-#endif
+void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
+void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
-#include <stdlib.h>
+int gribGetZip(size_t recsize, unsigned char *gribbuffer, size_t *urecsize);
-//#undef _GET_X86_COUNTER
-//#undef _GET_IBM_COUNTER
-//#undef _GET_MACH_COUNTER
-//#undef _ARCH_PWR6
+int gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-#if defined(_GET_IBM_COUNTER)
-#include <libhpc.h>
-#elif defined(_GET_X86_COUNTER)
-#include <x86intrin.h>
-#elif defined(_GET_MACH_COUNTER)
-#include <mach/mach_time.h>
-#endif
+int gribOpen(const char *filename, const char *mode);
+void gribClose(int fileID);
-#if defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
-#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 4)
-#define GNUC_PUSH_POP
-#endif
-#endif
+int gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
+int gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
+off_t gribGetPos(int fileID);
+size_t gribGetSize(int fileID);
+int gribCheckSeek(int fileID, long *offset, int *version);
+int gribFileSeek(int fileID, long *offset);
+size_t gribReadSize(int fileID);
+int gribVersion(unsigned char *buffer, size_t buffersize);
-#ifndef DISABLE_SIMD
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#elif defined(__ICC) && (__ICC >= 1100)
-#elif defined(__clang__)
-#else
-#define DISABLE_SIMD
-#endif
-#endif
+int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
-#ifdef DISABLE_SIMD
-#define DISABLE_SIMD_MINMAXVAL
+double calculate_pfactor_float(const float* spectralField, long fieldTruncation, long subsetTruncation);
+double calculate_pfactor_double(const double* spectralField, long fieldTruncation, long subsetTruncation);
+
+
+#if defined (__cplusplus)
+}
#endif
-#if !defined(TEST_MINMAXVAL)
-#define DISABLE_SIMD_MINMAXVAL
+#endif /* CGRIBEX_H */
+
+#ifdef HAVE_CONFIG_H
#endif
-#ifdef DISABLE_SIMD_MINMAXVAL
-# if defined(ENABLE_AVX)
-# define _ENABLE_AVX
-# endif
-# if defined(ENABLE_SSE2)
-# define _ENABLE_SSE2
-# endif
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_LIBNETCDF
#endif
-#ifndef DISABLE_SIMD_MINMAXVAL
-# if defined(__AVX__)
-# define _ENABLE_AVX
-# endif
-# if defined(__SSE2__)
-# define _ENABLE_SSE2
-# endif
+#ifdef HAVE_LIBCGRIBEX
#endif
-#include <float.h>
-#include <stdint.h>
-#include <inttypes.h>
+int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
-#if defined(_ENABLE_AVX)
-#include <immintrin.h>
-#elif defined(_ENABLE_SSE2)
-#include <emmintrin.h>
-#endif
+int cdiDefaultInstID = CDI_UNDEFID;
+int cdiDefaultModelID = CDI_UNDEFID;
+int cdiDefaultTableID = CDI_UNDEFID;
+//int cdiNcMissingValue = CDI_UNDEFID;
+int cdiNcChunksizehint = CDI_UNDEFID;
+int cdiChunkType = CDI_CHUNK_GRID;
+int cdiSplitLtype105 = CDI_UNDEFID;
+bool cdiIgnoreAttCoordinates = false;
+bool cdiCoordinatesLonLat = false;
+bool cdiIgnoreValidRange = false;
+int cdiSkipRecords = 0;
+int cdiConvention = CDI_CONVENTION_ECHAM;
+int cdiInventoryMode = 1;
+int CDI_Version_Info = 1;
+int CDI_cmor_mode = 0;
+int CDI_reduce_dim = 0;
+size_t CDI_netcdf_hdr_pad = 0UL;
+bool CDI_netcdf_lazy_grid_load = false;
-#if defined(_ENABLE_AVX)
+char *cdiPartabPath = NULL;
+int cdiPartabIntern = 1;
-static
-void avx_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
-{
- double fmin[4], fmax[4];
- __m256d current_max, current_min, work;
+double cdiDefaultMissval = -9.E33;
- // load max and min values into all four slots of the YMM registers
- current_min = _mm256_set1_pd(*min);
- current_max = _mm256_set1_pd(*max);
+static const char Filetypes[][9] = {
+ "UNKNOWN",
+ "GRIB",
+ "GRIB2",
+ "NetCDF",
+ "NetCDF2",
+ "NetCDF4",
+ "NetCDF4c",
+ "NetCDF5",
+ "SERVICE",
+ "EXTRA",
+ "IEG",
+ "HDF5",
+};
- // Work input until "buf" reaches 32 byte alignment
- while ( ((unsigned long)buf) % 32 != 0 && nframes > 0) {
+int CDI_Debug = 0; /* If set to 1, debugging */
+int CDI_Recopt = 0;
- // Load the next double into the work buffer
- work = _mm256_set1_pd(*buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf++;
- nframes--;
- }
+int cdiGribApiDebug = 0;
+int cdiDefaultLeveltype = -1;
+int cdiDataUnreduced = 0;
+int cdiSortName = 0;
+int cdiSortParam = 0;
+int cdiHaveMissval = 0;
- while (nframes >= 16) {
- (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
+static long cdiGetenvInt(const char *envName)
+{
+ long envValue = -1;
- work = _mm256_load_pd(buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf += 4;
+ char *envString = getenv(envName);
+ if ( envString )
+ {
+ long fact = 1;
+ int len = (int) strlen(envString);
+ for ( int loop = 0; loop < len; loop++ )
+ {
+ if ( ! isdigit((int) envString[loop]) )
+ {
+ switch ( tolower((int) envString[loop]) )
+ {
+ case 'k': fact = 1024; break;
+ case 'm': fact = 1048576; break;
+ case 'g': fact = 1073741824; break;
+ default:
+ fact = 0;
+ Message("Invalid number string in %s: %s", envName, envString);
+ Warning("%s must comprise only digits [0-9].",envName);
+ break;
+ }
+ break;
+ }
+ }
- work = _mm256_load_pd(buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf += 4;
+ if ( fact ) envValue = fact*atol(envString);
- (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
+ if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
+ }
- work = _mm256_load_pd(buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf += 4;
+ return envValue;
+}
- work = _mm256_load_pd(buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf += 4;
- nframes -= 16;
- }
+static void
+cdiPrintDefaults(void)
+{
+ fprintf(stderr, "default instID : %d\n"
+ "default modelID : %d\n"
+ "default tableID : %d\n"
+ "default missval : %g\n", cdiDefaultInstID,
+ cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
+}
- // work through aligned buffers
- while (nframes >= 4) {
- work = _mm256_load_pd(buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf += 4;
- nframes -= 4;
- }
+void cdiPrintVersion(void)
+{
+ fprintf(stderr, " CDI library version : %s\n", cdiLibraryVersion());
+#ifdef HAVE_LIBCGRIBEX
+ fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
+#endif
+#ifdef HAVE_LIBGRIB_API
+ fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
+#endif
+#ifdef HAVE_LIBNETCDF
+ fprintf(stderr, " NetCDF library version : %s\n", cdfLibraryVersion());
+#endif
+#ifdef HAVE_NC4HDF5
+ fprintf(stderr, " HDF5 library version : %s\n", hdfLibraryVersion());
+#endif
+#ifdef HAVE_LIBSERVICE
+ fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
+#endif
+#ifdef HAVE_LIBEXTRA
+ fprintf(stderr, " EXTRA library version : %s\n", extLibraryVersion());
+#endif
+#ifdef HAVE_LIBIEG
+ fprintf(stderr, " IEG library version : %s\n", iegLibraryVersion());
+#endif
+ fprintf(stderr, " FILE library version : %s\n", fileLibraryVersion());
+}
- // work through the remainung values
- while ( nframes > 0) {
- work = _mm256_set1_pd(*buf);
- current_min = _mm256_min_pd(current_min, work);
- current_max = _mm256_max_pd(current_max, work);
- buf++;
- nframes--;
- }
+static void cdiPrintDatatypes(void)
+{
+#define XSTRING(x) #x
+#define STRING(x) XSTRING(x)
+ fprintf (stderr, "+-------------+-------+\n"
+ "| types | bytes |\n"
+ "+-------------+-------+\n"
+ "| void * | %3d |\n"
+ "+-------------+-------+\n"
+ "| char | %3d |\n"
+ "+-------------+-------+\n"
+ "| bool | %3d |\n"
+ "| short | %3d |\n"
+ "| int | %3d |\n"
+ "| long | %3d |\n"
+ "| long long | %3d |\n"
+ "| size_t | %3d |\n"
+ "| off_t | %3d |\n"
+ "+-------------+-------+\n"
+ "| float | %3d |\n"
+ "| double | %3d |\n"
+ "| long double | %3d |\n"
+ "+-------------+-------+\n\n"
+ "+-------------+-----------+\n"
+ "| INT32 | %-9s |\n"
+ "| INT64 | %-9s |\n"
+ "| FLT32 | %-9s |\n"
+ "| FLT64 | %-9s |\n"
+ "+-------------+-----------+\n"
+ "\n byte ordering is %s\n\n",
+ (int) sizeof(void *), (int) sizeof(char), (int) sizeof(bool),
+ (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
+ (int) sizeof(size_t), (int) sizeof(off_t),
+ (int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
+ STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
+ ((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
+ : ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
+ : "Unhandled endianness!")));
+#undef STRING
+#undef XSTRING
+}
- // find min & max value through shuffle tricks
- work = current_min;
- work = _mm256_shuffle_pd(work, work, 5);
- work = _mm256_min_pd (work, current_min);
- current_min = work;
- work = _mm256_permute2f128_pd(work, work, 1);
- work = _mm256_min_pd (work, current_min);
- _mm256_storeu_pd(fmin, work);
+void cdiDebug(int level)
+{
+ if ( level == 1 || (level & 2) ) CDI_Debug = 1;
- work = current_max;
- work = current_max;
- work = _mm256_shuffle_pd(work, work, 5);
- work = _mm256_max_pd (work, current_max);
- current_max = work;
- work = _mm256_permute2f128_pd(work, work, 1);
- work = _mm256_max_pd (work, current_max);
- _mm256_storeu_pd(fmax, work);
+ if ( CDI_Debug ) Message("debug level %d", level);
- *min = fmin[0];
- *max = fmax[0];
+ if ( level == 1 || (level & 4) ) memDebug(1);
- return;
+ if ( level == 1 || (level & 8) ) fileDebug(1);
+
+ if ( level == 1 || (level & 16) )
+ {
+#if defined (HAVE_LIBCGRIBEX)
+ gribSetDebug(1);
+#endif
+#if defined (HAVE_LIBNETCDF)
+ cdfDebug(1);
+#endif
+#if defined (HAVE_LIBSERVICE)
+ srvDebug(1);
+#endif
+#if defined (HAVE_LIBEXTRA)
+ extDebug(1);
+#endif
+#if defined (HAVE_LIBIEG)
+ iegDebug(1);
+#endif
+ }
+
+ if ( CDI_Debug )
+ {
+ cdiPrintDefaults();
+ cdiPrintDatatypes();
+ }
}
-#elif defined(_ENABLE_SSE2)
-static
-void sse2_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
+int cdiHaveFiletype(int filetype)
{
- __m128d current_max, current_min, work;
-
- // load starting max and min values into all slots of the XMM registers
- current_min = _mm_set1_pd(*min);
- current_max = _mm_set1_pd(*max);
-
- // work on input until buf reaches 16 byte alignment
- while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) {
-
- // load one double and replicate
- work = _mm_set1_pd(*buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf++;
- nframes--;
- }
-
- while (nframes >= 8) {
- // use 64 byte prefetch for double octetts
- // __builtin_prefetch(buf+64,0,0); // for GCC 4.3.2 +
-
- work = _mm_load_pd(buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf += 2;
- work = _mm_load_pd(buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf += 2;
- work = _mm_load_pd(buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf += 2;
- work = _mm_load_pd(buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf += 2;
- nframes -= 8;
- }
-
- // work through smaller chunks of aligned buffers without prefetching
- while (nframes >= 2) {
- work = _mm_load_pd(buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf += 2;
- nframes -= 2;
- }
-
- // work through the remaining value
- while ( nframes > 0) {
- // load the last double and replicate
- work = _mm_set1_pd(*buf);
- current_min = _mm_min_pd(current_min, work);
- current_max = _mm_max_pd(current_max, work);
- buf++;
- nframes--;
- }
+ int status = 0;
- // find final min and max value through shuffle tricks
- work = current_min;
- work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
- work = _mm_min_pd (work, current_min);
- _mm_store_sd(min, work);
- work = current_max;
- work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
- work = _mm_max_pd (work, current_max);
- _mm_store_sd(max, work);
+ switch (filetype)
+ {
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV: status = 1; break;
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT: status = 1; break;
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG: status = 1; break;
+#endif
+#ifdef HAVE_LIBGRIB
+#if defined (HAVE_LIBGRIB_API) || defined (HAVE_LIBCGRIBEX)
+ case CDI_FILETYPE_GRB: status = 1; break;
+#endif
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB2: status = 1; break;
+#endif
+#endif
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC: status = 1; break;
+#ifdef HAVE_NETCDF2
+ case CDI_FILETYPE_NC2: status = 1; break;
+#endif
+#ifdef HAVE_NETCDF4
+ case CDI_FILETYPE_NC4: status = 1; break;
+ case CDI_FILETYPE_NC4C: status = 1; break;
+#endif
+#ifdef HAVE_NETCDF5
+ case CDI_FILETYPE_NC5: status = 1; break;
+#endif
+#endif
+ default: status = 0; break;
+ }
- return;
+ return status;
}
-#endif // SIMD
-
-#if defined(_ARCH_PWR6)
-static
-void pwr6_minmax_val_double_unrolled6(const double *restrict data, size_t datasize, double *fmin, double *fmax)
+void cdiDefTableID(int tableID)
{
-#define __UNROLL_DEPTH_1 6
-
- // to allow pipelining we have to unroll
-
- {
- size_t i, j;
- size_t residual = datasize % __UNROLL_DEPTH_1;
- size_t ofs = datasize - residual;
- double register dmin[__UNROLL_DEPTH_1];
- double register dmax[__UNROLL_DEPTH_1];
-
- for ( j = 0; j < __UNROLL_DEPTH_1; j++)
- {
- dmin[j] = data[0];
- dmax[j] = data[0];
- }
-
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_1 )
- {
- for (j = 0; j < __UNROLL_DEPTH_1; j++)
- {
- dmin[j] = __fsel(dmin[j] - data[i+j], data[i+j], dmin[j]);
- dmax[j] = __fsel(data[i+j] - dmax[j], data[i+j], dmax[j]);
- }
- }
-
- for (j = 0; j < residual; j++)
- {
- dmin[j] = __fsel(dmin[j] - data[ofs+j], data[ofs+j], dmin[j]);
- dmax[j] = __fsel(data[ofs+j] - dmax[j], data[ofs+j], dmax[j]);
- }
-
- for ( j = 0; j < __UNROLL_DEPTH_1; j++)
- {
- *fmin = __fsel(*fmin - dmin[j], dmin[j], *fmin);
- *fmax = __fsel(dmax[j] - *fmax, dmax[j], *fmax);
- }
- }
-#undef __UNROLL_DEPTH_1
+ cdiDefaultTableID = tableID;
+ int modelID = cdiDefaultModelID = tableInqModel(tableID);
+ cdiDefaultInstID = modelInqInstitut(modelID);
}
-#endif
-
-#if defined(TEST_MINMAXVAL) && defined(__GNUC__)
-static
-void minmax_val_double_orig(const double *restrict data, size_t datasize, double *fmin, double *fmax) __attribute__ ((noinline));
-static
-void minmax_val_double_simd(const double *restrict data, size_t datasize, double *fmin, double *fmax) __attribute__ ((noinline));
-static
-void minmax_val_float(const float *restrict data, long datasize, float *fmin, float *fmax) __attribute__ ((noinline));
-static
-void minmax_val_float_simd(const float *restrict data, size_t datasize, float *fmin, float *fmax) __attribute__ ((noinline));
-#endif
-#if defined(GNUC_PUSH_POP)
-#pragma GCC push_options
-#pragma GCC optimize ("O3", "fast-math")
-#endif
static
-void minmax_val_double_orig(const double *restrict data, size_t datasize, double *fmin, double *fmax)
+void cdiSetChunk(const char *chunkAlgo)
{
- double dmin = *fmin, dmax = *fmax;
+ //char *pch;
+ //size_t len = strlen(chunkAlgo);
+ int algo = -1;
-#if defined(CRAY)
-#pragma _CRI ivdep
-#elif defined(SX)
-#pragma vdir nodep
-#elif defined(__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( size_t i = 0; i < datasize; ++i )
+ if ( strcmp("auto", chunkAlgo) == 0 ) algo = CDI_CHUNK_AUTO;
+ else if ( strcmp("grid", chunkAlgo) == 0 ) algo = CDI_CHUNK_GRID;
+ else if ( strcmp("lines", chunkAlgo) == 0 ) algo = CDI_CHUNK_LINES;
+ /*
+ else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
{
- dmin = dmin < data[i] ? dmin : data[i];
- dmax = dmax > data[i] ? dmax : data[i];
+ int ix, iy;
+ ix = atoi(chunkAlgo);
+ iy = atoi(pch+1);
+ if ( ix > 0 && iy > 0 )
+ {
+ cdiChunkX = ix;
+ cdiChunkY = iy;
+ algo = CHUNK_USER;
+ }
+ else
+ Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
}
+ */
+ else
+ Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
- *fmin = dmin;
- *fmax = dmax;
+ if ( algo != -1 )
+ {
+ cdiChunkType = algo;
+ if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
+ }
}
-static
-void minmax_val_float(const float *restrict data, long idatasize, float *fmin, float *fmax)
+
+void cdiInitialize(void)
{
- size_t datasize = (size_t)idatasize;
- float dmin = *fmin, dmax = *fmax;
+ static bool Init_CDI = false;
-#if defined(CRAY)
-#pragma _CRI ivdep
-#elif defined(SX)
-#pragma vdir nodep
-#elif defined(__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( size_t i = 0; i < datasize; ++i )
+ if ( ! Init_CDI )
{
- dmin = dmin < data[i] ? dmin : data[i];
- dmax = dmax > data[i] ? dmax : data[i];
- }
+ Init_CDI = true;
+ char *envstr;
+ long value;
- *fmin = dmin;
- *fmax = dmax;
-}
-#if defined(GNUC_PUSH_POP)
-#pragma GCC pop_options
+#ifdef HAVE_LIBCGRIBEX
+ gribFixZSE(1); // 1: Fix ZeroShiftError of simple packed spherical harmonics
+ gribSetConst(1); // 1: Don't pack constant fields on regular grids
#endif
-// TEST
-#if defined(OMP_SIMD)
+ value = cdiGetenvInt("CDI_DEBUG");
+ if ( value >= 0 ) CDI_Debug = (int) value;
-#if defined(GNUC_PUSH_POP)
-#pragma GCC push_options
-#pragma GCC optimize ("O3", "fast-math")
-#endif
-static
-void minmax_val_double_simd(const double *restrict data, size_t datasize, double *fmin, double *fmax)
-{
- double dmin = *fmin, dmax = *fmax;
+ value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
+ if ( value >= 0 ) cdiGribApiDebug = (int) value;
-#if defined(_OPENMP)
-#pragma omp simd reduction(min:dmin) reduction(max:dmax)
-#endif
- for ( size_t i = 0; i < datasize; ++i )
- {
- dmin = dmin < data[i] ? dmin : data[i];
- dmax = dmax > data[i] ? dmax : data[i];
- }
+ value = cdiGetenvInt("CDI_RECOPT");
+ if ( value >= 0 ) CDI_Recopt = (int) value;
- *fmin = dmin;
- *fmax = dmax;
-}
-static
-void minmax_val_float_simd(const float *restrict data, size_t datasize, float *fmin, float *fmax)
-{
- float dmin = *fmin, dmax = *fmax;
+ value = cdiGetenvInt("CDI_REGULARGRID");
+ if ( value >= 0 ) cdiDataUnreduced = (int) value;
-#if defined(_OPENMP)
-#pragma omp simd reduction(min:dmin) reduction(max:dmax)
-#endif
- for ( size_t i = 0; i < datasize; ++i )
- {
- dmin = dmin < data[i] ? dmin : data[i];
- dmax = dmax > data[i] ? dmax : data[i];
- }
+ value = cdiGetenvInt("CDI_SORTNAME");
+ if ( value >= 0 ) cdiSortName = (int) value;
- *fmin = dmin;
- *fmax = dmax;
-}
-#if defined(GNUC_PUSH_POP)
-#pragma GCC pop_options
-#endif
-#endif
+ value = cdiGetenvInt("CDI_SORTPARAM");
+ if ( value >= 0 ) cdiSortParam = (int) value;
-static
-void minmax_val_double(const double *restrict data, long idatasize, double *fmin, double *fmax)
-{
-#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
- uint64_t start_minmax, end_minmax;
-#endif
- size_t datasize = (size_t)idatasize;
+ value = cdiGetenvInt("CDI_HAVE_MISSVAL");
+ if ( value >= 0 ) cdiHaveMissval = (int) value;
- if ( idatasize >= 1 ) ; else return;
+ value = cdiGetenvInt("CDI_LEVELTYPE");
+ if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
-#if defined(_GET_X86_COUNTER)
- start_minmax = _rdtsc();
-#endif
-#if defined(_GET_MACH_COUNTER)
- start_minmax = mach_absolute_time();
-#endif
+ value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
+ if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
-#if defined(_ENABLE_AVX)
+ envstr = getenv("CDI_MISSVAL");
+ if ( envstr ) cdiDefaultMissval = atof(envstr);
+ /*
+ envstr = getenv("NC_MISSING_VALUE");
+ if ( envstr ) cdiNcMissingValue = atoi(envstr);
+ */
+ envstr = getenv("NC_CHUNKSIZEHINT");
+ if ( envstr ) cdiNcChunksizehint = atoi(envstr);
- avx_minmax_val_double(data, datasize, fmin, fmax);
+ envstr = getenv("CDI_CHUNK_ALGO");
+ if ( envstr ) cdiSetChunk(envstr);
-#elif defined(_ENABLE_SSE2)
+ envstr = getenv("SPLIT_LTYPE_105");
+ if ( envstr ) cdiSplitLtype105 = atoi(envstr);
- sse2_minmax_val_double(data, datasize, fmin, fmax);
+ envstr = getenv("IGNORE_ATT_COORDINATES");
+ if ( envstr ) cdiIgnoreAttCoordinates = atoi(envstr) > 0;
-#else
+ envstr = getenv("CDI_COORDINATES_LONLAT");
+ if ( envstr ) cdiCoordinatesLonLat = atoi(envstr) > 0;
-#if defined(_ARCH_PWR6)
-#define __UNROLL_DEPTH_1 6
+ envstr = getenv("IGNORE_VALID_RANGE");
+ if ( envstr ) cdiIgnoreValidRange = atoi(envstr) > 0;
- // to allow pipelining we have to unroll
+ envstr = getenv("CDI_SKIP_RECORDS");
+ if ( envstr )
+ {
+ cdiSkipRecords = atoi(envstr);
+ cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
+ }
-#if defined(_GET_IBM_COUNTER)
- hpmStart(1, "minmax fsel");
-#endif
+ envstr = getenv("CDI_CONVENTION");
+ if ( envstr )
+ {
+ if ( strcmp(envstr, "CF") == 0 || strcmp(envstr, "cf") == 0 )
+ {
+ cdiConvention = CDI_CONVENTION_CF;
+ if ( CDI_Debug )
+ Message("CDI convention was set to CF!");
+ }
+ }
- pwr6_minmax_val_double_unrolled6(data, datasize, fmin, fmax);
+ envstr = getenv("CDI_INVENTORY_MODE");
+ if ( envstr )
+ {
+ if ( strncmp(envstr, "time", 4) == 0 )
+ {
+ cdiInventoryMode = 2;
+ if ( CDI_Debug )
+ Message("Inventory mode was set to timestep!");
+ }
+ }
-#if defined(_GET_IBM_COUNTER)
- hpmStop(1);
-#endif
+ envstr = getenv("CDI_VERSION_INFO");
+ if ( envstr )
+ {
+ int ival = atoi(envstr);
+ if ( ival == 0 || ival == 1 )
+ {
+ CDI_Version_Info = ival;
+ if ( CDI_Debug )
+ Message("CDI_Version_Info = %s", envstr);
+ }
+ }
-#undef __UNROLL_DEPTH_1
-#else // original loop
+ envstr = getenv("CDI_CALENDAR");
+ if ( envstr )
+ {
+ if ( strncmp(envstr, "standard", 8) == 0 )
+ cdiDefaultCalendar = CALENDAR_STANDARD;
+ else if ( strncmp(envstr, "gregorian", 9) == 0 )
+ cdiDefaultCalendar = CALENDAR_GREGORIAN;
+ else if ( strncmp(envstr, "proleptic", 9) == 0 )
+ cdiDefaultCalendar = CALENDAR_PROLEPTIC;
+ else if ( strncmp(envstr, "360days", 7) == 0 )
+ cdiDefaultCalendar = CALENDAR_360DAYS;
+ else if ( strncmp(envstr, "365days", 7) == 0 )
+ cdiDefaultCalendar = CALENDAR_365DAYS;
+ else if ( strncmp(envstr, "366days", 7) == 0 )
+ cdiDefaultCalendar = CALENDAR_366DAYS;
+ else if ( strncmp(envstr, "none", 4) == 0 )
+ cdiDefaultCalendar = CALENDAR_NONE;
-#if defined(_GET_IBM_COUNTER)
- hpmStart(1, "minmax base");
+ if ( CDI_Debug )
+ Message("Default calendar set to %s!", envstr);
+ }
+#ifdef HAVE_LIBCGRIBEX
+ gribSetCalendar(cdiDefaultCalendar);
#endif
- minmax_val_double_orig(data, datasize, fmin, fmax);
+ envstr = getenv("PARTAB_INTERN");
+ if ( envstr ) cdiPartabIntern = atoi(envstr);
-#if defined(_GET_IBM_COUNTER)
- hpmStop(1);
-#endif
+ envstr = getenv("PARTAB_PATH");
+ if ( envstr ) cdiPartabPath = strdup(envstr);
+ }
+}
-#endif // _ARCH_PWR6 && original loop
-#endif // SIMD
-#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
-#if defined(_GET_X86_COUNTER)
- end_minmax = _rdtsc();
-#endif
-#if defined(_GET_MACH_COUNTER)
- end_minmax = mach_absolute_time();
-#endif
-#if defined(_ENABLE_AVX)
- printf("AVX minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
- fprintf (stderr, "AVX min: %lf max: %lf\n", *fmin, *fmax);
-#elif defined(_ENABLE_SSE2)
- printf("SSE2 minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
- fprintf (stderr, "SSE2 min: %lf max: %lf\n", *fmin, *fmax);
-#else
- printf("loop minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
- fprintf (stderr, "loop min: %lf max: %lf\n", *fmin, *fmax);
-#endif
-#endif
+const char *strfiletype(int filetype)
+{
+ int size = (int) (sizeof(Filetypes)/sizeof(char *));
+ const char *name = (filetype > 0 && filetype < size) ? Filetypes[filetype] : Filetypes[0];
- return;
+ return name;
}
-#if defined(TEST_MINMAXVAL)
-#include <stdio.h>
-#include <sys/time.h>
+void cdiDefGlobal(const char *string, int val)
+{
+ if ( strcmp(string, "REGULARGRID") == 0 ) cdiDataUnreduced = val;
+ else if ( strcmp(string, "GRIBAPI_DEBUG") == 0 ) cdiGribApiDebug = val;
+ else if ( strcmp(string, "SORTNAME") == 0 ) cdiSortName = val;
+ else if ( strcmp(string, "SORTPARAM") == 0 ) cdiSortParam = val;
+ else if ( strcmp(string, "HAVE_MISSVAL") == 0 ) cdiHaveMissval = val;
+ else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
+ else if ( strcmp(string, "CMOR_MODE") == 0 ) CDI_cmor_mode = val;
+ else if ( strcmp(string, "REDUCE_DIM") == 0 ) CDI_reduce_dim = val;
+ else if ( strcmp(string, "NETCDF_HDR_PAD") == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
+ else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
+ CDI_netcdf_lazy_grid_load = (bool)val;
+ else Warning("Unsupported global key: %s", string);
+}
-static
-double dtime()
+
+void cdiDefMissval(double missval)
{
- double tseconds = 0.0;
- struct timeval mytime;
- gettimeofday(&mytime, NULL);
- tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
- return (tseconds);
+ cdiInitialize();
+
+ cdiDefaultMissval = missval;
}
-#define NRUN 10000
-int main(void)
+double cdiInqMissval(void)
{
- long datasize = 1000000;
- double t_begin, t_end;
+ cdiInitialize();
-#if defined(_OPENMP)
- printf("_OPENMP=%d\n", _OPENMP);
-#endif
+ return cdiDefaultMissval;
+}
-#if defined(__ICC)
- printf("icc\n");
-#elif defined(__clang__)
- printf("clang\n");
-#elif defined(__GNUC__)
- printf("gcc\n");
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+
+#if defined (HAVE_CONFIG_H)
#endif
- {
- float fmin, fmax;
- float *data_sp = (float*) malloc(datasize*sizeof(float));
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
- for ( long i = 0; i < datasize/2; i++ ) data_sp[i] = (float) (i);
- for ( long i = datasize/2; i < datasize; i++ ) data_sp[i] = (float) (-datasize + i);
- printf("float:\n");
+void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
+{
+ unsigned uparam = (unsigned)param;
+ unsigned upnum;
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_sp[0];
- minmax_val_float(data_sp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("minmax_val: fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+ *pdis = 0xff & uparam;
+ *pcat = 0xff & uparam >> 8;
+ upnum = 0xffff & uparam >> 16;
+ if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
+ *pnum = (int)upnum;
+}
-#if defined(OMP_SIMD)
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_sp[0];
- minmax_val_float_simd(data_sp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("simd : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
- free(data_sp);
- }
+int cdiEncodeParam(int pnum, int pcat, int pdis)
+{
+ unsigned uparam, upnum;
- {
- double fmin, fmax;
- double *data_dp = (double*) malloc(datasize*sizeof(double));
+ if ( pcat < 0 || pcat > 255 ) pcat = 255;
+ if ( pdis < 0 || pdis > 255 ) pdis = 255;
- // for ( long i = datasize-1; i >= 0; i-- ) data[i] = (double) (-datasize/2 + i);
- for ( long i = 0; i < datasize/2; i++ ) data_dp[i] = (double) (i);
- for ( long i = datasize/2; i < datasize; i++ ) data_dp[i] = (double) (-datasize + i);
+ upnum = (unsigned)pnum;
+ if ( pnum < 0 ) upnum = (unsigned)(0x8000 - pnum);
- printf("double:\n");
+ uparam = upnum << 16 | (unsigned)(pcat << 8) | (unsigned)pdis;
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- minmax_val_double(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("minmax_val: fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+ return ((int)uparam);
+}
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- minmax_val_double_orig(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("orig : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#if defined(OMP_SIMD)
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- minmax_val_double_simd(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("simd : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
+void cdiDecodeDate(int date, int *year, int *month, int *day)
+{
-#if defined(_ENABLE_AVX)
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- avx_minmax_val_double(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("avx : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#elif defined(_ENABLE_SSE2)
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- sse2_minmax_val_double(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("sse2 : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
-#if defined(_ARCH_PWR6)
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- fmin = fmax = data_dp[0];
- pwr6_minmax_val_double_unrolled6(data_dp, datasize, &fmin, &fmax);
- }
- t_end = dtime();
- printf("pwr6u6 : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
- free(data_dp);
- }
+ int iyear = date / 10000;
+ *year = iyear;
+ int idate = abs(date - iyear * 10000),
+ imonth = idate / 100;
+ *month = imonth;
+ *day = idate - imonth * 100;
+}
- return (0);
+
+int cdiEncodeDate(int year, int month, int day)
+{
+ int iyear = abs(year),
+ date = iyear * 10000 + month * 100 + day;
+ if ( year < 0 ) date = -date;
+ return (date);
}
-#endif // TEST_MINMAXVAL
-#undef DISABLE_SIMD_MINMAXVAL
-#undef _ENABLE_AVX
-#undef _ENABLE_SSE2
-#undef GNUC_PUSH_POP
-/*
-### new version with gribSwapByteOrder_uint16()
-icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_ENCODE encode_array.c
- result on hama2 (icc 16.0.2):
- float:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 1.8731s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.0898s
- double:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.68089s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.30798s
- avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.23864s
-gcc -g -Wall -O3 -march=native -Wa,-q -std=c99 -DTEST_ENCODE encode_array.c
- result on hama2 (gcc 6.1.0):
-float:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.22871s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.30281s
-double:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.2669s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.81643s
- avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.98415s
+void cdiDecodeTime(int time, int *hour, int *minute, int *second)
+{
+ int ihour = time / 10000,
+ itime = time - ihour * 10000,
+ iminute = itime / 100;
+ *hour = ihour;
+ *minute = iminute;
+ *second = itime - iminute * 100;
+}
-###
-icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_ENCODE encode_array.c
- result on hama2 (icc 16.0.0):
- float:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 9.10691s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 8.63584s
- double:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 13.5768s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 9.17742s
- avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.9488s
-gcc -g -Wall -O3 -std=c99 -DTEST_ENCODE encode_array.c
- result on hama2 (gcc 5.2.0):
- float:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 5.32775s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 7.87125s
- double:
- orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 7.85873s
-unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 12.9979s
+int cdiEncodeTime(int hour, int minute, int second)
+{
+ int time = hour*10000 + minute*100 + second;
-###
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
- result on bailung (gcc 4.7):
- orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 8.4166s
- sse41 : val1: 1 val2: 1 val3: 2 valn: 66 time: 7.1522s
+ return time;
+}
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
- result on thunder5 (gcc 4.7):
- orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 6.21976s
- avx : val1: 1 val2: 1 val3: 2 valn: 66 time: 4.54485s
-icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_ENCODE encode_array.c
- result on thunder5 (icc 13.2):
- orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 14.6279s
- avx : val1: 1 val2: 1 val3: 2 valn: 66 time: 4.9776s
+void cdiParamToString(int param, char *paramstr, int maxlen)
+{
+ int dis, cat, num;
+ int len;
-xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_ENCODE encode_array.c
- result on blizzard (xlc 12):
- orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 132.25s
- unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 27.202s
- orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 106.627s // without -qhot
- unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 39.929s // without -qhot
-*/
-#ifdef _ARCH_PWR6
-#pragma options nostrict
-#endif
+ cdiDecodeParam(param, &num, &cat, &dis);
-#ifdef TEST_ENCODE
-#include <stdio.h>
-#include <stdlib.h>
-#define GRIBPACK unsigned char
-#define IS_BIGENDIAN() (u_byteorder.c[sizeof(long) - 1])
-#define U_BYTEORDER static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
-#define Error(x,y)
-#endif
+ size_t umaxlen = maxlen >= 0 ? (unsigned)maxlen : 0U;
+ if ( dis == 255 && (cat == 255 || cat == 0 ) )
+ len = snprintf(paramstr, umaxlen, "%d", num);
+ else if ( dis == 255 )
+ len = snprintf(paramstr, umaxlen, "%d.%d", num, cat);
+ else
+ len = snprintf(paramstr, umaxlen, "%d.%d.%d", num, cat, dis);
-//#undef _GET_X86_COUNTER
-//#undef _GET_MACH_COUNTER
-//#undef _GET_IBM_COUNTER
-//#undef _ARCH_PWR6
+ if ( len >= maxlen || len < 0)
+ fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
+}
-#if defined _GET_IBM_COUNTER
-#include <libhpc.h>
-#elif defined _GET_X86_COUNTER
-#include <x86intrin.h>
-#elif defined _GET_MACH_COUNTER
-#include <mach/mach_time.h>
-#endif
-#include <stdint.h>
+const char *cdiUnitNamePtr(int cdi_unit)
+{
+ const char *cdiUnits[] = {
+ /* 0 */ "undefined",
+ /* 1 */ "Pa",
+ /* 2 */ "hPa",
+ /* 3 */ "mm",
+ /* 4 */ "cm",
+ /* 5 */ "dm",
+ /* 6 */ "m",
+ };
+ enum { numUnits = (int) (sizeof(cdiUnits)/sizeof(char *)) };
+ const char *name = ( cdi_unit > 0 && cdi_unit < numUnits ) ?
+ cdiUnits[cdi_unit] : NULL;
+ return name;
+}
-#ifndef DISABLE_SIMD
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#elif defined(__ICC) && (__ICC >= 1100)
-#elif defined(__clang__)
-#else
-#define DISABLE_SIMD
+size_t
+cdiGetPageSize(bool largePageAlign)
+{
+ long pagesize = -1L;
+#if HAVE_DECL__SC_LARGE_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE || HAVE_DECL__SC_PAGESIZE
+ bool nameAssigned = false;
+ int name;
+# if HAVE_DECL__SC_LARGE_PAGESIZE
+ if (largePageAlign)
+ {
+ name = _SC_LARGE_PAGESIZE;
+ nameAssigned = true;
+ }
+ else
+# else
+ (void)largePageAlign;
+# endif
+ {
+# if HAVE_DECL__SC_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE
+ name =
+# if HAVE_DECL__SC_PAGESIZE
+ _SC_PAGESIZE
+# elif HAVE_DECL__SC_PAGE_SIZE
+ _SC_PAGE_SIZE
+# endif
+ ;
+ nameAssigned = true;
+# endif
+ }
+ if (nameAssigned)
+ pagesize = sysconf(name);
#endif
+ if (pagesize == -1L)
+ pagesize =
+#if HAVE_DECL_PAGESIZE
+ PAGESIZE
+#elif HAVE_DECL_PAGE_SIZE
+ PAGE_SIZE
+#else
+ commonPageSize
#endif
+ ;
+ return (size_t)pagesize;
+}
-#ifdef DISABLE_SIMD
-#define DISABLE_SIMD_ENCODE
-#endif
-//#define DISABLE_SIMD_ENCODE
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
-#ifdef DISABLE_SIMD_ENCODE
-# ifdef ENABLE_AVX
-# define _ENABLE_AVX
-# endif
-# ifdef ENABLE_SSE4_1
-# define _ENABLE_SSE4_1
-# endif
+/* Automatically generated by m214003 at 2017-09-29, do not edit */
+
+/* CGRIBEXLIB_VERSION="1.9.0" */
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) || defined (__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic warning "-Wstrict-overflow"
#endif
-#ifndef DISABLE_SIMD_ENCODE
-# ifdef __AVX__
-# define _ENABLE_AVX
-# endif
-# ifdef __SSE4_1__
-# define _ENABLE_SSE4_1
-# endif
+#ifdef _ARCH_PWR6
+#pragma options nostrict
#endif
-#if defined _ENABLE_AVX
-#include <immintrin.h>
-#elif defined _ENABLE_SSE4_1
-#include <smmintrin.h>
+#if defined (HAVE_CONFIG_H)
#endif
-#if defined _ENABLE_AVX
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <inttypes.h>
-static
-void avx_encode_array_2byte_double(size_t datasize,
- unsigned char * restrict lGrib,
- const double * restrict data,
- double zref, double factor, size_t *gz)
-{
- size_t i, j, residual;
- const double *dval = data;
- __m128i *sgrib = (__m128i *) (lGrib+(*gz));
- const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
- const __m256d c0 = _mm256_set1_pd(zref);
- const __m256d c1 = _mm256_set1_pd(factor);
- const __m256d c2 = _mm256_set1_pd(0.5);
-
- __m256d d0, d3, d2, d1;
- __m128i i0, i1, i2, i3;
- __m128i s0, s1;
+#ifndef CGRIBEX_TEMPLATES_H
+#define CGRIBEX_TEMPLATES_H
- residual = datasize % 16;
+#define CAT(X,Y) X##_##Y
+#define TEMPLATE(X,Y) CAT(X,Y)
- for (i = 0; i < (datasize-residual); i += 16)
- {
- (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
- //_____________________________________________________________________________
+#endif
+#ifndef GRIB_INT_H
+#define GRIB_INT_H
- d0 = _mm256_loadu_pd (dval);
- d0 = _mm256_sub_pd (d0, c0);
- d0 = _mm256_mul_pd (d0, c1);
- d0 = _mm256_add_pd (d0, c2);
+#if defined (HAVE_CONFIG_H)
+#endif
- i0 = _mm256_cvttpd_epi32 (d0);
-
- //_____________________________________________________________________________
-
- d1 = _mm256_loadu_pd (dval+4);
- d1 = _mm256_sub_pd (d1, c0);
- d1 = _mm256_mul_pd (d1, c1);
- d1 = _mm256_add_pd (d1, c2);
-
- i1 = _mm256_cvttpd_epi32 (d1);
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
+#include <float.h>
- //_____________________________________________________________________________
- s0 = _mm_packus_epi32(i0, i1);
- s0 = _mm_shuffle_epi8 (s0, swap);
- (void) _mm_storeu_si128 (sgrib, s0);
+#if ! defined (CGRIBEX_H)
+#endif
+#if ! defined (ERROR_H)
+#endif
+#if ! defined (DTYPES_H)
+#endif
- //_____________________________________________________________________________
- (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
+#if ! defined (UCHAR)
+#define UCHAR unsigned char
+#endif
- //_____________________________________________________________________________
-
- d2 = _mm256_loadu_pd (dval+8);
- d2 = _mm256_sub_pd (d2, c0);
- d2 = _mm256_mul_pd (d2, c1);
- d2 = _mm256_add_pd (d2, c2);
-
- i2 = _mm256_cvttpd_epi32 (d2);
- //_____________________________________________________________________________
-
- d3 = _mm256_loadu_pd (dval+12);
- d3 = _mm256_sub_pd (d3, c0);
- d3 = _mm256_mul_pd (d3, c1);
- d3 = _mm256_add_pd (d3, c2);
-
- i3 = _mm256_cvttpd_epi32 (d3);
+#if defined (CRAY) || defined (SX) || defined (__uxpch__)
+#define VECTORCODE
+#endif
- //_____________________________________________________________________________
- s1 = _mm_packus_epi32(i2, i3);
- s1 = _mm_shuffle_epi8 (s1, swap);
- (void) _mm_storeu_si128 (sgrib+1, s1);
+#if defined (VECTORCODE)
+#if defined (INT32)
+# define GRIBPACK unsigned INT32
+# define PACK_GRIB packInt32
+# define UNPACK_GRIB unpackInt32
+#else
+# define GRIBPACK unsigned INT64
+# define PACK_GRIB packInt64
+# define UNPACK_GRIB unpackInt64
+#endif
+#else
+# define GRIBPACK unsigned char
+#endif
- //_____________________________________________________________________________
-
- dval += 16;
- sgrib += 2;
- }
+#define U_BYTEORDER static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
+#define IS_BIGENDIAN() (u_byteorder.c[sizeof(long) - 1])
- if (i != datasize)
- {
- uint16_t ui16;
- for ( j = i; j < datasize; j++ )
- {
- ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
- lGrib[*gz+2*j ] = ui16 >> 8;
- lGrib[*gz+2*j+1] = ui16;
- }
- }
-
- *gz += 2*datasize;
+#if defined (__xlC__) /* performance problems on IBM */
+#ifndef DBL_IS_NAN
+# define DBL_IS_NAN(x) ((x) != (x))
+#endif
+#else
+#ifndef DBL_IS_NAN
+#if defined (HAVE_DECL_ISNAN)
+# define DBL_IS_NAN(x) (isnan(x))
+#elif defined (FP_NAN)
+# define DBL_IS_NAN(x) (fpclassify(x) == FP_NAN)
+#else
+# define DBL_IS_NAN(x) ((x) != (x))
+#endif
+#endif
+#endif
- return;
-}
+#ifndef IS_EQUAL
+# define IS_NOT_EQUAL(x,y) (x < y || y < x)
+# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
+#endif
-#define grib_encode_array_2byte_double avx_encode_array_2byte_double
+/* dummy use of unused parameters to silence compiler warnings */
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
-#elif defined _ENABLE_SSE4_1
+#define JP24SET 0xFFFFFF /* 2**24 (---> 16777215) */
+#define JP23SET 0x7FFFFF /* 2**23 - 1 (---> 8388607) */
-static
-void sse41_encode_array_2byte_double(size_t datasize,
- unsigned char * restrict lGrib,
- const double * restrict data,
- double zref, double factor, size_t *gz)
-{
- size_t i, j, residual;
- const double *dval = data;
- __m128i *sgrib = (__m128i *) (lGrib+(*gz));
+#define POW_2_M24 0.000000059604644775390625 /* pow(2.0, -24.0) */
- const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+#ifdef __cplusplus
+extern "C" {
+#endif
- const __m128d c0 = _mm_set1_pd(zref);
- const __m128d c1 = _mm_set1_pd(factor);
- const __m128d c2 = _mm_set1_pd(0.5);
-
- __m128d d0, d4, d3, d2, d1;
- __m128i i0, i1, i2, i3, i4;
- __m128i s0, s1;
+#define intpow2(x) (ldexp(1.0, (x)))
- residual = datasize % 16;
+unsigned correct_bdslen(unsigned bdslen, long recsize, long gribpos);
- for (i = 0; i < (datasize-residual); i += 16)
- {
- (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
- //_____________________________________________________________________________
+/* CDI converter routines */
- d0 = _mm_loadu_pd (dval);
- d0 = _mm_sub_pd (d0, c0);
- d0 = _mm_mul_pd (d0, c1);
- d0 = _mm_add_pd (d0, c2);
-
- d4 = _mm_loadu_pd (dval+2);
- d4 = _mm_sub_pd (d4, c0);
- d4 = _mm_mul_pd (d4, c1);
- d4 = _mm_add_pd (d4, c2);
+/* param format: DDDCCCNNN */
- i0 = _mm_cvttpd_epi32 (d0);
- i4 = _mm_cvttpd_epi32 (d4);
- i0 = _mm_unpacklo_epi64 (i0, i4);
+void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis);
+int cdiEncodeParam(int pnum, int pcat, int pdis);
- //_____________________________________________________________________________
-
- d1 = _mm_loadu_pd (dval+4);
- d1 = _mm_sub_pd (d1, c0);
- d1 = _mm_mul_pd (d1, c1);
- d1 = _mm_add_pd (d1, c2);
-
- d4 = _mm_loadu_pd (dval+6);
- d4 = _mm_sub_pd (d4, c0);
- d4 = _mm_mul_pd (d4, c1);
- d4 = _mm_add_pd (d4, c2);
-
- i1 = _mm_cvttpd_epi32 (d1);
- i4 = _mm_cvttpd_epi32 (d4);
- i1 = _mm_unpacklo_epi64 (i1, i4);
+/* date format: YYYYMMDD */
+/* time format: hhmmss */
- //_____________________________________________________________________________
+void cdiDecodeDate(int date, int *year, int *month, int *day);
+int cdiEncodeDate(int year, int month, int day);
- s0 = _mm_packus_epi32(i0, i1);
- s0 = _mm_shuffle_epi8 (s0, swap);
- (void) _mm_storeu_si128 (sgrib, s0);
+void cdiDecodeTime(int time, int *hour, int *minute, int *second);
+int cdiEncodeTime(int hour, int minute, int second);
- //_____________________________________________________________________________
+/* CALENDAR types */
- (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
-
- //_____________________________________________________________________________
-
- d2 = _mm_loadu_pd (dval+8);
- d2 = _mm_sub_pd (d2, c0);
- d2 = _mm_mul_pd (d2, c1);
- d2 = _mm_add_pd (d2, c2);
-
- d4 = _mm_loadu_pd (dval+10);
- d4 = _mm_sub_pd (d4, c0);
- d4 = _mm_mul_pd (d4, c1);
- d4 = _mm_add_pd (d4, c2);
-
- i2 = _mm_cvttpd_epi32 (d2);
- i4 = _mm_cvttpd_epi32 (d4);
- i2 = _mm_unpacklo_epi64 (i2, i4);
-
- //_____________________________________________________________________________
-
- d3 = _mm_loadu_pd (dval+12);
- d3 = _mm_sub_pd (d3, c0);
- d3 = _mm_mul_pd (d3, c1);
- d3 = _mm_add_pd (d3, c2);
-
- d4 = _mm_loadu_pd (dval+14);
- d4 = _mm_sub_pd (d4, c0);
- d4 = _mm_mul_pd (d4, c1);
- d4 = _mm_add_pd (d4, c2);
-
- i3 = _mm_cvttpd_epi32 (d3);
- i4 = _mm_cvttpd_epi32 (d4);
- i3 = _mm_unpacklo_epi64 (i3, i4);
-
- //_____________________________________________________________________________
-
- s1 = _mm_packus_epi32(i2, i3);
- s1 = _mm_shuffle_epi8 (s1, swap);
- (void) _mm_storeu_si128 (sgrib+1, s1);
-
- //_____________________________________________________________________________
-
- dval += 16;
- sgrib += 2;
- }
-
- if (i != datasize)
- {
- uint16_t ui16;
- for ( j = i; j < datasize; j++ )
- {
- ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
- lGrib[*gz+2*j ] = ui16 >> 8;
- lGrib[*gz+2*j+1] = ui16;
- }
- }
-
- *gz += 2*datasize;
-
- return;
-}
+#define CALENDAR_STANDARD 0 /* don't change this value (used also in cgribexlib)! */
+#define CALENDAR_GREGORIAN 1
+#define CALENDAR_PROLEPTIC 2
+#define CALENDAR_360DAYS 3
+#define CALENDAR_365DAYS 4
+#define CALENDAR_366DAYS 5
+#define CALENDAR_NONE 6
-#define grib_encode_array_2byte_double sse41_encode_array_2byte_double
+extern FILE *grprsm;
-#else
+extern int CGRIBEX_Debug;
-#define grib_encode_array_2byte_double encode_array_2byte_double
+void gprintf(const char *caller, const char *fmt, ...);
-#endif // SIMD variants
+void grsdef(void);
+void prtbin(int kin, int knbit, int *kout, int *kerr);
+void confp3(double pval, int *kexp, int *kmant, int kbits, int kround);
+double decfp2(int kexp, int kmant);
+void ref2ibm(double *pref, int kbits);
-#ifdef TEST_ENCODE
+void scale_complex_double(double *fpdata, int pcStart, int pcScale, int trunc, int inv);
+void scale_complex_float(float *fpdata, int pcStart, int pcScale, int trunc, int inv);
+void scatter_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
+void scatter_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
+void gather_complex_double(double *fpdata, size_t pcStart, size_t trunc, size_t nsp);
+void gather_complex_float(float *fpdata, size_t pcStart, size_t trunc, size_t nsp);
-#define CAT(X,Y) X##_##Y
-#define TEMPLATE(X,Y) CAT(X,Y)
+void scm0_double(double *pdl, double *pdr, double *pfl, double *pfr, int klg);
+int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
+ double *ztemp, double msval, int *kret);
+int qu2reg3_double(double *pfield, int *kpoint, int klat, int klon,
+ double msval, int *kret, int omisng, int operio, int oveggy);
+int qu2reg3_float(float *pfield, int *kpoint, int klat, int klon,
+ float msval, int *kret, int omisng, int operio, int oveggy);
-#ifdef T
-#undef T
+#if defined (INT32)
+long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc);
#endif
-#define T double
-
-#ifdef T
-#undef T
+long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc);
+#if defined (INT32)
+long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc);
#endif
-#define T float
+long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc);
+void grib_encode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+ double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int efunc, int *kret);
+void grib_encode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+ float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int efunc, int *kret);
-#include <sys/time.h>
+void grib_decode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+ double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int dfunc, int *kret);
+void grib_decode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+ float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int dfunc, int *kret);
-static
-double dtime()
-{
- double tseconds = 0.0;
- struct timeval mytime;
- gettimeofday(&mytime, NULL);
- tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
- return (tseconds);
-}
-#define NRUN 10000
+int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
+ unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
+int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
+ unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
+ unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
-static
-void pout(char *name, int s, unsigned char *lgrib, long datasize, double tt)
-{
- printf("%8s: val1: %d val2: %d val3: %d valn: %d time: %gs\n",
- name, (int) lgrib[s*1+1], (int) lgrib[s*2+1], (int) lgrib[s*3+1], (int) lgrib[2*datasize-1], tt);
+#if defined (__cplusplus)
}
+#endif
-int main(void)
-{
- long datasize = 1000000;
- double t_begin, t_end;
+#endif /* GRIB_INT_H */
+#ifndef GRIBDECODE_H
+#define GRIBDECODE_H
- float *dataf = (float*) malloc(datasize*sizeof(float));
- double *data = (double*) malloc(datasize*sizeof(double));
- unsigned char *lgrib = (unsigned char*) malloc(2*datasize*sizeof(unsigned char));
+#define UNDEFINED 9.999e20
- for ( long i = 0; i < datasize; ++i ) dataf[i] = (float) (-datasize/2 + i);
- for ( long i = 0; i < datasize; ++i ) data[i] = (double) (-datasize/2 + i);
- int PackStart = 0;
- int nbpv = 16;
- double zref = data[0];
- size_t z;
- double factor = 0.00390625;
- int s = 256;
+#define GET_INT3(a,b,c) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
+#define GET_INT2(a,b) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 8) + b))
+#define GET_INT1(a) ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (a&127))
- if ( 0 )
- {
- encode_array_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
- encode_array_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
- }
+/* this requires a 32-bit default integer machine */
+#define GET_UINT4(a,b,c,d) ((unsigned) ((a << 24) + (b << 16) + (c << 8) + (d)))
+#define GET_UINT3(a,b,c) ((unsigned) ((a << 16) + (b << 8) + (c)))
+#define GET_UINT2(a,b) ((unsigned) ((a << 8) + (b)))
+#define GET_UINT1(a) ((unsigned) (a))
-#if defined(__ICC)
- printf("icc\n");
-#elif defined(__clang__)
- printf("clang\n");
-#elif defined(__GNUC__)
- printf("gcc\n");
-#endif
+#define BUDG_START(s) (s[0]=='B' && s[1]=='U' && s[2]=='D' && s[3]=='G')
+#define TIDE_START(s) (s[0]=='T' && s[1]=='I' && s[2]=='D' && s[3]=='E')
+#define GRIB_START(s) (s[0]=='G' && s[1]=='R' && s[2]=='I' && s[3]=='B')
+#define GRIB_FIN(s) (s[0]=='7' && s[1]=='7' && s[2]=='7' && s[3]=='7')
- printf("float:\n");
+/* GRIB1 Section 0: Indicator Section (IS) */
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- encode_array_2byte_float(datasize, lgrib, dataf, (float)zref, (float)factor, &z);
- }
- t_end = dtime();
- pout("orig", s, lgrib, datasize, t_end-t_begin);
+#define GRIB1_SECLEN(s) GET_UINT3(s[ 4], s[ 5], s[ 6])
+#define GRIB_EDITION(s) GET_UINT1(s[ 7])
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- encode_array_unrolled_float(nbpv, PackStart, datasize, lgrib, dataf, (float)zref, (float)factor, &z);
- }
- t_end = dtime();
- pout("unrolled", s, lgrib, datasize, t_end-t_begin);
+/* GRIB1 Section 1: Product Definition Section (PDS) */
- printf("double:\n");
+#define PDS_Len GET_UINT3(pds[ 0], pds[ 1], pds[ 2])
+#define PDS_CodeTable GET_UINT1(pds[ 3])
+#define PDS_CenterID GET_UINT1(pds[ 4])
+#define PDS_ModelID GET_UINT1(pds[ 5])
+#define PDS_GridDefinition GET_UINT1(pds[ 6])
+#define PDS_Sec2Or3Flag GET_UINT1(pds[ 7])
+#define PDS_HAS_GDS ((pds[7] & 128) != 0)
+#define PDS_HAS_BMS ((pds[7] & 64) != 0)
+#define PDS_Parameter GET_UINT1(pds[ 8])
+#define PDS_LevelType GET_UINT1(pds[ 9])
+#define PDS_Level1 (pds[10])
+#define PDS_Level2 (pds[11])
+#define PDS_Level GET_UINT2(pds[10], pds[11])
+#define PDS_Year GET_INT1(pds[12])
+#define PDS_Month GET_UINT1(pds[13])
+#define PDS_Day GET_UINT1(pds[14])
+#define PDS_Hour GET_UINT1(pds[15])
+#define PDS_Minute GET_UINT1(pds[16])
+#define PDS_Date (PDS_Year*10000+PDS_Month*100+PDS_Day)
+#define PDS_Time (PDS_Hour*100+PDS_Minute)
+#define PDS_TimeUnit GET_UINT1(pds[17])
+#define PDS_TimePeriod1 GET_UINT1(pds[18])
+#define PDS_TimePeriod2 GET_UINT1(pds[19])
+#define PDS_TimeRange GET_UINT1(pds[20])
+#define PDS_AvgNum GET_UINT2(pds[21], pds[22])
+#define PDS_AvgMiss GET_UINT1(pds[23])
+#define PDS_Century GET_UINT1(pds[24])
+#define PDS_Subcenter GET_UINT1(pds[25])
+#define PDS_DecimalScale GET_INT2(pds[26],pds[27])
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
- }
- t_end = dtime();
- pout("orig", s, lgrib, datasize, t_end-t_begin);
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- encode_array_unrolled_double(nbpv, PackStart, datasize, lgrib, data, zref, factor, &z);
- }
- t_end = dtime();
- pout("unrolled", s, lgrib, datasize, t_end-t_begin);
+/* GRIB1 Section 2: Grid Description Section (GDS) */
-#if defined _ENABLE_AVX
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- avx_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
- }
- t_end = dtime();
- pout("avx", s, lgrib, datasize, t_end-t_begin);
-#elif defined _ENABLE_SSE4_1
- t_begin = dtime();
- for ( int i = 0; i < NRUN; ++i )
- {
- z = 0;
- sse41_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
- }
- t_end = dtime();
- pout("sse41", s, lgrib, datasize, t_end-t_begin);
-#endif
+#define GDS_Len ((gds) == NULL ? 0 : GET_UINT3(gds[0], gds[1], gds[2]))
+#define GDS_NV GET_UINT1(gds[ 3])
+#define GDS_PVPL GET_UINT1(gds[ 4])
+#define GDS_PV ((gds[3] == 0) ? -1 : (int) gds[4] - 1)
+#define GDS_PL ((gds[4] == 0xFF) ? -1 : (int) gds[3] * 4 + (int) gds[4] - 1)
+#define GDS_GridType GET_UINT1(gds[ 5])
- return 0;
-}
-#endif // TEST_ENCODE
-#undef DISABLE_SIMD_ENCODE
-#undef _ENABLE_AVX
-#undef _ENABLE_SSE4_1
+/* GRIB1 Triangular grid of DWD */
+#define GDS_GME_NI2 GET_UINT2(gds[ 6], gds[ 7])
+#define GDS_GME_NI3 GET_UINT2(gds[ 8], gds[ 9])
+#define GDS_GME_ND GET_UINT3(gds[10], gds[11], gds[12])
+#define GDS_GME_NI GET_UINT3(gds[13], gds[14], gds[15])
+#define GDS_GME_AFlag GET_UINT1(gds[16])
+#define GDS_GME_LatPP GET_INT3(gds[17], gds[18], gds[19])
+#define GDS_GME_LonPP GET_INT3(gds[20], gds[21], gds[22])
+#define GDS_GME_LonMPL GET_INT3(gds[23], gds[24], gds[25])
+#define GDS_GME_BFlag GET_UINT1(gds[27])
+/* GRIB1 Spectral */
+#define GDS_PentaJ GET_UINT2(gds[ 6], gds[ 7])
+#define GDS_PentaK GET_UINT2(gds[ 8], gds[ 9])
+#define GDS_PentaM GET_UINT2(gds[10], gds[11])
+#define GDS_RepType GET_UINT1(gds[12])
+#define GDS_RepMode GET_UINT1(gds[13])
-void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
-{
- /*
+/* GRIB1 Regular grid */
+#define GDS_NumLon GET_UINT2(gds[ 6], gds[ 7])
+#define GDS_NumLat GET_UINT2(gds[ 8], gds[ 9])
+#define GDS_FirstLat GET_INT3(gds[10], gds[11], gds[12])
+#define GDS_FirstLon GET_INT3(gds[13], gds[14], gds[15])
+#define GDS_ResFlag GET_UINT1(gds[16])
+#define GDS_LastLat GET_INT3(gds[17], gds[18], gds[19])
+#define GDS_LastLon GET_INT3(gds[20], gds[21], gds[22])
+#define GDS_LonIncr GET_UINT2(gds[23], gds[24])
+#define GDS_LatIncr GET_UINT2(gds[25], gds[26])
+#define GDS_NumPar GET_UINT2(gds[25], gds[26])
+#define GDS_ScanFlag GET_UINT1(gds[27])
+#define GDS_LatSP GET_INT3(gds[32], gds[33], gds[34])
+#define GDS_LonSP GET_INT3(gds[35], gds[36], gds[37])
+#define GDS_RotAngle (GET_Real(&(gds[38])))
- Purpose:
- --------
+/* GRIB1 Lambert */
+#define GDS_Lambert_Lov GET_INT3(gds[17], gds[18], gds[19])
+#define GDS_Lambert_dx GET_INT3(gds[20], gds[21], gds[22])
+#define GDS_Lambert_dy GET_INT3(gds[23], gds[24], gds[25])
+#define GDS_Lambert_ProjFlag GET_UINT1(gds[26])
+#define GDS_Lambert_LatS1 GET_INT3(gds[28], gds[29], gds[30])
+#define GDS_Lambert_LatS2 GET_INT3(gds[31], gds[32], gds[33])
+#define GDS_Lambert_LatSP GET_INT3(gds[34], gds[35], gds[36])
+#define GDS_Lambert_LonSP GET_INT3(gds[37], gds[37], gds[37])
- Convert floating point number from machine
- representation to GRIB representation.
+/* GRIB1 Section 3: Bit Map Section (BMS) */
- Input Parameters:
- -----------------
+#define BMS_Len ((bms) == NULL ? 0 : GET_UINT3(bms[0], bms[1], bms[2]))
+#define BMS_UnusedBits (bms[3])
+#define BMS_Numeric
+#define BMS_Bitmap ((bms) == NULL ? NULL : (bms)+6)
+#define BMS_BitmapSize (((((bms[0]<<16)+(bms[1]<<8)+bms[2]) - 6)<<3) - bms[3])
- pval - Floating point number to be converted.
- kbits - Number of bits in computer word.
- kround - Conversion type.
- 0 , Closest number in GRIB format less than
- original number.
- 1 , Closest number in GRIB format to the
- original number (equal to, greater than or
- less than original number).
+/* GRIB1 Section 4: Binary Data Section (BDS) */
- Output Parameters:
- ------------------
+#define BDS_Len GET_UINT3(bds[0], bds[1], bds[2])
+#define BDS_Flag (bds[3])
+#define BDS_BinScale GET_INT2(bds[ 4], bds[ 5])
+#define BDS_RefValue (decfp2((int)bds[ 6], GET_UINT3(bds[7], bds[8], bds[9])))
+#define BDS_NumBits ((int) bds[10])
+#define BDS_RealCoef (decfp2((int)bds[zoff+11], GET_UINT3(bds[zoff+12], bds[zoff+13], bds[zoff+14])))
+#define BDS_PackData ((int) ((bds[zoff+11]<<8) + bds[zoff+12]))
+#define BDS_Power GET_INT2(bds[zoff+13], bds[zoff+14])
+#define BDS_Z (bds[13])
- kexp - 8 Bit signed exponent.
- kmant - 24 Bit mantissa.
+/* GRIB1 Section 5: End Section (ES) */
- Method:
- -------
+/* GRIB2 */
- Floating point number represented as 8 bit signed
- exponent and 24 bit mantissa in integer values.
+#define GRIB2_SECLEN(section) (GET_UINT4(section[0], section[1], section[2], section[3]))
+#define GRIB2_SECNUM(section) (GET_UINT1(section[4]))
- Externals.
- ----------
+#endif /* GRIBDECODE_H */
+#ifndef CGRIBEX_GRIB_ENCODE_H
+#define CGRIBEX_GRIB_ENCODE_H
- decfp2 - Decode from IBM floating point format.
+#include <limits.h>
- Reference:
- ----------
+#define PutnZero(n) \
+{ \
+ for ( size_t i = z >= 0 ? (size_t)z : 0; i < (size_t)(z+n); i++ ) lGrib[i] = 0; \
+ z += n; \
+}
- WMO Manual on Codes re GRIB representation.
+#define Put1Byte(Value) (lGrib[z++] = (GRIBPACK)(Value))
+#define Put2Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
+ (lGrib[z++] = (GRIBPACK)(Value)))
+#define Put3Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 16)), \
+ (lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
+ (lGrib[z++] = (GRIBPACK)(Value)))
+#define Put4Byte(Value) ((lGrib[z++] = (GRIBPACK)((Value) >> 24)), \
+ (lGrib[z++] = (GRIBPACK)((Value) >> 16)), \
+ (lGrib[z++] = (GRIBPACK)((Value) >> 8)), \
+ (lGrib[z++] = (GRIBPACK)(Value)))
- Comments:
- ---------
+#define Put1Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x80 - ival; Put1Byte(ival);}
+#define Put2Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x8000 - ival; Put2Byte(ival);}
+#define Put3Int(Value) {ival = Value; if ( ival < 0 ) ival = 0x800000 - ival; Put3Byte(ival);}
- Routine aborts if an invalid conversion type parameter
- is used or if a 24 bit mantissa is not produced.
+enum {
+ BitsPerInt = (int) (sizeof(int) * CHAR_BIT),
+};
- Author:
- -------
-
- John Hennessy ECMWF 18.06.91
- Modifications:
- --------------
+#define Put1Real(Value) \
+{ \
+ confp3(Value, &exponent, &mantissa, BitsPerInt, 1); \
+ Put1Byte(exponent); \
+ Put3Byte(mantissa); \
+}
- Uwe Schulzweida MPIfM 01/04/2001
+#endif /* CGRIBEX_GRIB_ENCODE_H */
+#ifndef CODEC_COMMON_H
+#define CODEC_COMMON_H
+#define gribSwapByteOrder_uint16(ui16) ((uint16_t)((ui16<<8) | (ui16>>8)))
+#endif /* CODEC_COMMON_H */
+/*
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -qopenmp -DOMP_SIMD minmax_val.c
+ result on hama2 (icc 16.0.0):
+ float:
+minmax_val: fmin: -500000 fmax: 499999 time: 1.22s
+simd : fmin: -500000 fmax: 499999 time: 1.20s
+ double:
+minmax_val: fmin: -500000 fmax: 499999 time: 2.86s
+orig : fmin: -500000 fmax: 499999 time: 2.74s
+simd : fmin: -500000 fmax: 499999 time: 2.70s
+avx : fmin: -500000 fmax: 499999 time: 2.99s
- Convert to C from EMOS library version 130
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD -Wa,-q minmax_val.c
+ result on thunder5 (gcc 6.1.0):
+float:
+minmax_val: fmin: -500000 fmax: 499999 time: 8.25s
+ simd : fmin: -500000 fmax: 499999 time: 1.24s
+double:
+minmax_val: fmin: -500000 fmax: 499999 time: 2.73s
+ orig : fmin: -500000 fmax: 499999 time: 9.24s
+ simd : fmin: -500000 fmax: 499999 time: 2.78s
+ avx : fmin: -500000 fmax: 499999 time: 2.90s
- Uwe Schulzweida MPIfM 02/08/2002
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL minmax_val.c
+ result on bailung (gcc 4.8.2):
+ orig : fmin: -500000 fmax: 499999 time: 4.82s
+ sse2 : fmin: -500000 fmax: 499999 time: 4.83s
- - speed up by factor 1.6 on NEC SX6
- - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
- */
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD -Wa,-q minmax_val.c
+ result on thunder5 (gcc 4.8.2):
+ orig : fmin: -500000 fmax: 499999 time: 3.10s
+ simd : fmin: -500000 fmax: 499999 time: 3.10s # omp simd in gcc 4.9
+ avx : fmin: -500000 fmax: 499999 time: 2.84s
- // extern int CGRIBEX_Debug;
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
+ result on thunder5 (icc 14.0.2):
+ orig : fmin: -500000 fmax: 499999 time: 2.83s
+ simd : fmin: -500000 fmax: 499999 time: 2.83s
+ avx : fmin: -500000 fmax: 499999 time: 2.92s
- /* ----------------------------------------------------------------- */
- /* Section 1 . Initialise */
- /* ----------------------------------------------------------------- */
+xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_MINMAXVAL minmax_val.c
+ result on blizzard (xlc 12):
+ orig : fmin: -500000 fmax: 499999 time: 7.26s
+ pwr6u6 : fmin: -500000 fmax: 499999 time: 5.92s
+*/
+#if defined(_ARCH_PWR6)
+#pragma options nostrict
+#endif
- /* Check conversion type parameter. */
+#include <stdlib.h>
- int iround = kround;
- if ( iround != 0 && iround != 1 )
- {
- Error("Invalid conversion type = %d", iround);
+//#undef _GET_X86_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _ARCH_PWR6
- /* If not aborting, arbitrarily set rounding to 'up'. */
- iround = 1;
- }
+#if defined(_GET_IBM_COUNTER)
+#include <libhpc.h>
+#elif defined(_GET_X86_COUNTER)
+#include <x86intrin.h>
+#elif defined(_GET_MACH_COUNTER)
+#include <mach/mach_time.h>
+#endif
- /* ----------------------------------------------------------------- */
- /* Section 2 . Convert value of zero. */
- /* ----------------------------------------------------------------- */
+#if defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
+#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 4)
+#define GNUC_PUSH_POP
+#endif
+#endif
- if ( ! (fabs(pval) > 0))
- {
- *kexp = 0;
- *kmant = 0;
- // iexp = 0;
- // isign = 0;
- goto LABEL900;
- }
+#ifndef DISABLE_SIMD
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#elif defined(__ICC) && (__ICC >= 1100)
+#elif defined(__clang__)
+#else
+#define DISABLE_SIMD
+#endif
+#endif
- /* ----------------------------------------------------------------- */
- /* Section 3 . Convert other values. */
- /* ----------------------------------------------------------------- */
- {
- double zeps = kbits != 32 ? 1.0e-12 : 1.0e-8;
- double zref = pval;
+#ifdef DISABLE_SIMD
+#define DISABLE_SIMD_MINMAXVAL
+#endif
- /* Sign of value. */
+#if !defined(TEST_MINMAXVAL)
+#define DISABLE_SIMD_MINMAXVAL
+#endif
- int isign = zref >= 0.0 ? 0 : 128;
- zref = fabs(zref);
-
- /* Exponent. */
-
- int iexp = (int) (log(zref)/log(16.0) + 65.0 + zeps);
+#ifdef DISABLE_SIMD_MINMAXVAL
+# if defined(ENABLE_AVX)
+# define _ENABLE_AVX
+# endif
+# if defined(ENABLE_SSE2)
+# define _ENABLE_SSE2
+# endif
+#endif
- /* only ANSI C99 has log2 */
- /* iexp = (int) (log2(zref) * 0.25 + 65.0 + zeps); */
+#ifndef DISABLE_SIMD_MINMAXVAL
+# if defined(__AVX__)
+# define _ENABLE_AVX
+# endif
+# if defined(__SSE2__)
+# define _ENABLE_SSE2
+# endif
+#endif
- if ( iexp < 0 ) iexp = 0;
- if ( iexp > 127 ) iexp = 127;
+#include <float.h>
+#include <stdint.h>
+#include <inttypes.h>
- double rpowref;
- /*
- rpowref = zref / pow(16.0, (double)(iexp - 70));
- */
+#if defined(_ENABLE_AVX)
+#include <immintrin.h>
+#elif defined(_ENABLE_SSE2)
+#include <emmintrin.h>
+#endif
- rpowref = ldexp(zref, 4 * -(iexp - 70));
- /* Mantissa. */
+#if defined(_ENABLE_AVX)
- if ( iround == 0 )
- {
- /* Closest number in GRIB format less than original number. */
- /* Truncate for positive numbers. */
- /* Round up for negative numbers. */
+static
+void avx_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
+{
+ double fmin[4], fmax[4];
+ __m256d current_max, current_min, work;
- if ( isign == 0 )
- *kmant = (int)rpowref;
- else
- *kmant = (int)lround(rpowref + 0.5);
- }
- else
- {
- /* Closest number in GRIB format to the original number */
- /* (equal to, greater than or less than original number). */
+ // load max and min values into all four slots of the YMM registers
+ current_min = _mm256_set1_pd(*min);
+ current_max = _mm256_set1_pd(*max);
- *kmant = (int)lround(rpowref);
- }
+ // Work input until "buf" reaches 32 byte alignment
+ while ( ((unsigned long)buf) % 32 != 0 && nframes > 0) {
- /* Check that mantissa value does not exceed 24 bits. */
- /* If it does, adjust the exponent upwards and recalculate */
- /* the mantissa. */
- /* 16777215 = 2**24 - 1 */
+ // Load the next double into the work buffer
+ work = _mm256_set1_pd(*buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf++;
+ nframes--;
+ }
- if ( *kmant > 16777215 )
- {
+ while (nframes >= 16) {
- LABEL350:
+ (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
- ++iexp;
+ work = _mm256_load_pd(buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf += 4;
- /* Check for exponent overflow during adjustment */
+ work = _mm256_load_pd(buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf += 4;
- if ( iexp > 127 )
- {
- Message("Exponent overflow");
- Message("Original number = %30.20f", pval);
- Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
- isign, iexp, *kmant);
+ (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
- Error("Exponent overflow");
+ work = _mm256_load_pd(buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf += 4;
- /* If not aborting, arbitrarily set value to zero */
+ work = _mm256_load_pd(buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf += 4;
+ nframes -= 16;
+ }
- Message("Value arbitrarily set to zero.");
- *kexp = 0;
- *kmant = 0;
- // iexp = 0;
- // isign = 0;
- goto LABEL900;
- }
+ // work through aligned buffers
+ while (nframes >= 4) {
+ work = _mm256_load_pd(buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf += 4;
+ nframes -= 4;
+ }
- rpowref = ldexp(zref, 4 * -(iexp - 70));
+ // work through the remainung values
+ while ( nframes > 0) {
+ work = _mm256_set1_pd(*buf);
+ current_min = _mm256_min_pd(current_min, work);
+ current_max = _mm256_max_pd(current_max, work);
+ buf++;
+ nframes--;
+ }
- if ( iround == 0 )
- {
- /* Closest number in GRIB format less than original number. */
- /* Truncate for positive numbers. */
- /* Round up for negative numbers. */
+ // find min & max value through shuffle tricks
- if ( isign == 0 )
- *kmant = (int)rpowref;
- else
- *kmant = (int)lround(rpowref + 0.5);
- }
- else
- {
- /* Closest number in GRIB format to the original number */
- /* (equal to, greater or less than original number). */
+ work = current_min;
+ work = _mm256_shuffle_pd(work, work, 5);
+ work = _mm256_min_pd (work, current_min);
+ current_min = work;
+ work = _mm256_permute2f128_pd(work, work, 1);
+ work = _mm256_min_pd (work, current_min);
+ _mm256_storeu_pd(fmin, work);
- *kmant = (int)lround(rpowref);
- }
+ work = current_max;
+ work = current_max;
+ work = _mm256_shuffle_pd(work, work, 5);
+ work = _mm256_max_pd (work, current_max);
+ current_max = work;
+ work = _mm256_permute2f128_pd(work, work, 1);
+ work = _mm256_max_pd (work, current_max);
+ _mm256_storeu_pd(fmax, work);
- /* Repeat calculation (with modified exponent) if still have */
- /* mantissa overflow. */
+ *min = fmin[0];
+ *max = fmax[0];
- if ( *kmant > 16777215 ) goto LABEL350;
- }
+ return;
+}
- /* Add sign bit to exponent. */
+#elif defined(_ENABLE_SSE2)
- *kexp = iexp + isign;
+static
+void sse2_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
+{
+ __m128d current_max, current_min, work;
+
+ // load starting max and min values into all slots of the XMM registers
+ current_min = _mm_set1_pd(*min);
+ current_max = _mm_set1_pd(*max);
+
+ // work on input until buf reaches 16 byte alignment
+ while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) {
+
+ // load one double and replicate
+ work = _mm_set1_pd(*buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf++;
+ nframes--;
}
+
+ while (nframes >= 8) {
+ // use 64 byte prefetch for double octetts
+ // __builtin_prefetch(buf+64,0,0); // for GCC 4.3.2 +
- /* ----------------------------------------------------------------- */
- /* Section 9. Return */
- /* ----------------------------------------------------------------- */
+ work = _mm_load_pd(buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf += 2;
+ work = _mm_load_pd(buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf += 2;
+ work = _mm_load_pd(buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf += 2;
+ work = _mm_load_pd(buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf += 2;
+ nframes -= 8;
+ }
-LABEL900:
- /*
- if ( CGRIBEX_Debug )
- {
- double zval;
+ // work through smaller chunks of aligned buffers without prefetching
+ while (nframes >= 2) {
+ work = _mm_load_pd(buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf += 2;
+ nframes -= 2;
+ }
- Message("Conversion type parameter = %4d", kround);
- Message("Original number = %30.20f", pval);
+ // work through the remaining value
+ while ( nframes > 0) {
+ // load the last double and replicate
+ work = _mm_set1_pd(*buf);
+ current_min = _mm_min_pd(current_min, work);
+ current_max = _mm_max_pd(current_max, work);
+ buf++;
+ nframes--;
+ }
- zval = decfp2(*kexp, *kmant);
+ // find final min and max value through shuffle tricks
+ work = current_min;
+ work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
+ work = _mm_min_pd (work, current_min);
+ _mm_store_sd(min, work);
+ work = current_max;
+ work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
+ work = _mm_max_pd (work, current_max);
+ _mm_store_sd(max, work);
- Message("Converted to %30.20f", zval);
- Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
- }
- */
return;
-} /* confp3 */
-#include <math.h>
+}
+#endif // SIMD
-double decfp2(int kexp, int kmant)
+#if defined(_ARCH_PWR6)
+static
+void pwr6_minmax_val_double_unrolled6(const double *restrict data, size_t datasize, double *fmin, double *fmax)
{
- /*
+#define __UNROLL_DEPTH_1 6
- Purpose:
- --------
+ // to allow pipelining we have to unroll
- Convert GRIB representation of a floating point
- number to machine representation.
+ {
+ size_t i, j;
+ size_t residual = datasize % __UNROLL_DEPTH_1;
+ size_t ofs = datasize - residual;
+ double register dmin[__UNROLL_DEPTH_1];
+ double register dmax[__UNROLL_DEPTH_1];
- Input Parameters:
- -----------------
+ for ( j = 0; j < __UNROLL_DEPTH_1; j++)
+ {
+ dmin[j] = data[0];
+ dmax[j] = data[0];
+ }
+
+ for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_1 )
+ {
+ for (j = 0; j < __UNROLL_DEPTH_1; j++)
+ {
+ dmin[j] = __fsel(dmin[j] - data[i+j], data[i+j], dmin[j]);
+ dmax[j] = __fsel(data[i+j] - dmax[j], data[i+j], dmax[j]);
+ }
+ }
- kexp - 8 Bit signed exponent.
- kmant - 24 Bit mantissa.
+ for (j = 0; j < residual; j++)
+ {
+ dmin[j] = __fsel(dmin[j] - data[ofs+j], data[ofs+j], dmin[j]);
+ dmax[j] = __fsel(data[ofs+j] - dmax[j], data[ofs+j], dmax[j]);
+ }
- Output Parameters:
- ------------------
+ for ( j = 0; j < __UNROLL_DEPTH_1; j++)
+ {
+ *fmin = __fsel(*fmin - dmin[j], dmin[j], *fmin);
+ *fmax = __fsel(dmax[j] - *fmax, dmax[j], *fmax);
+ }
+ }
+#undef __UNROLL_DEPTH_1
+}
+#endif
- Return value - Floating point number represented
- by kexp and kmant.
+#if defined(TEST_MINMAXVAL) && defined(__GNUC__)
+static
+void minmax_val_double_orig(const double *restrict data, size_t datasize, double *fmin, double *fmax) __attribute__ ((noinline));
+static
+void minmax_val_double_simd(const double *restrict data, size_t datasize, double *fmin, double *fmax) __attribute__ ((noinline));
+static
+void minmax_val_float(const float *restrict data, long datasize, float *fmin, float *fmax) __attribute__ ((noinline));
+static
+void minmax_val_float_simd(const float *restrict data, size_t datasize, float *fmin, float *fmax) __attribute__ ((noinline));
+#endif
- Method:
- -------
+#if defined(GNUC_PUSH_POP)
+#pragma GCC push_options
+#pragma GCC optimize ("O3", "fast-math")
+#endif
+static
+void minmax_val_double_orig(const double *restrict data, size_t datasize, double *fmin, double *fmax)
+{
+ double dmin = *fmin, dmax = *fmax;
- Floating point number represented as 8 bit exponent
- and 24 bit mantissa in integer values converted to
- machine floating point format.
+#if defined(CRAY)
+#pragma _CRI ivdep
+#elif defined(SX)
+#pragma vdir nodep
+#elif defined(__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( size_t i = 0; i < datasize; ++i )
+ {
+ dmin = dmin < data[i] ? dmin : data[i];
+ dmax = dmax > data[i] ? dmax : data[i];
+ }
- Externals:
- ----------
+ *fmin = dmin;
+ *fmax = dmax;
+}
- None.
+static
+void minmax_val_float(const float *restrict data, long idatasize, float *fmin, float *fmax)
+{
+ size_t datasize = (size_t)idatasize;
+ float dmin = *fmin, dmax = *fmax;
- Reference:
- ----------
+#if defined(CRAY)
+#pragma _CRI ivdep
+#elif defined(SX)
+#pragma vdir nodep
+#elif defined(__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( size_t i = 0; i < datasize; ++i )
+ {
+ dmin = dmin < data[i] ? dmin : data[i];
+ dmax = dmax > data[i] ? dmax : data[i];
+ }
- WMO Manual on Codes re GRIB representation.
+ *fmin = dmin;
+ *fmax = dmax;
+}
+#if defined(GNUC_PUSH_POP)
+#pragma GCC pop_options
+#endif
- Comments:
- ---------
+// TEST
+#if defined(OMP_SIMD)
- Rewritten from DECFP, to conform to programming standards.
- Sign bit on 0 value now ignored, if present.
- If using 32 bit reals, check power of 16 is not so small as to
- cause overflows (underflows!); this causes warning to be given
- on Fujitsus.
+#if defined(GNUC_PUSH_POP)
+#pragma GCC push_options
+#pragma GCC optimize ("O3", "fast-math")
+#endif
+static
+void minmax_val_double_simd(const double *restrict data, size_t datasize, double *fmin, double *fmax)
+{
+ double dmin = *fmin, dmax = *fmax;
- Author:
- -------
+#if defined(_OPENMP)
+#pragma omp simd reduction(min:dmin) reduction(max:dmax)
+#endif
+ for ( size_t i = 0; i < datasize; ++i )
+ {
+ dmin = dmin < data[i] ? dmin : data[i];
+ dmax = dmax > data[i] ? dmax : data[i];
+ }
- John Hennessy ECMWF 18.06.91
+ *fmin = dmin;
+ *fmax = dmax;
+}
+static
+void minmax_val_float_simd(const float *restrict data, size_t datasize, float *fmin, float *fmax)
+{
+ float dmin = *fmin, dmax = *fmax;
- Modifications:
- --------------
+#if defined(_OPENMP)
+#pragma omp simd reduction(min:dmin) reduction(max:dmax)
+#endif
+ for ( size_t i = 0; i < datasize; ++i )
+ {
+ dmin = dmin < data[i] ? dmin : data[i];
+ dmax = dmax > data[i] ? dmax : data[i];
+ }
- Uwe Schulzweida MPIfM 01/04/2001
+ *fmin = dmin;
+ *fmax = dmax;
+}
+#if defined(GNUC_PUSH_POP)
+#pragma GCC pop_options
+#endif
+#endif
- - Convert to C from EMOS library version 130
+static
+void minmax_val_double(const double *restrict data, long idatasize, double *fmin, double *fmax)
+{
+#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
+ uint64_t start_minmax, end_minmax;
+#endif
+ size_t datasize = (size_t)idatasize;
- Uwe Schulzweida MPIfM 02/08/2002
+ if ( idatasize >= 1 ) ; else return;
- - speed up by factor 2 on NEC SX6
- - replace pow(2.0, -24.0) by constant POW_2_M24
- - replace pow(16.0, (double)(iexp - 64)) by pow16m64tab[iexp]
- */
+#if defined(_GET_X86_COUNTER)
+ start_minmax = _rdtsc();
+#endif
+#if defined(_GET_MACH_COUNTER)
+ start_minmax = mach_absolute_time();
+#endif
- double pval;
- //extern int CGRIBEX_Debug;
- /* ----------------------------------------------------------------- */
- /* Section 1 . Convert value of 0.0. Ignore sign bit. */
- /* ----------------------------------------------------------------- */
+#if defined(_ENABLE_AVX)
- //if ( CGRIBEX_Debug ) Message("KEXP = %d KMANT = %d", kexp, kmant);
- /*
- if ( (kexp == 128 || kexp == 0) && kmant == 0 )
- */
- if ( (kexp == 128) || (kexp == 0) || (kexp == 255) )
- {
- pval = 0.0;
- goto LABEL900;
- }
+ avx_minmax_val_double(data, datasize, fmin, fmax);
- /* ----------------------------------------------------------------- */
- /* Section 2 . Convert other values. */
- /* ----------------------------------------------------------------- */
+#elif defined(_ENABLE_SSE2)
- /* Sign of value. */
+ sse2_minmax_val_double(data, datasize, fmin, fmax);
- int iexp = kexp,
- isign = (iexp < 128) * 2 - 1;
+#else
- iexp -= iexp < 128 ? 0 : 128;
+#if defined(_ARCH_PWR6)
+#define __UNROLL_DEPTH_1 6
- /* Decode value. */
+ // to allow pipelining we have to unroll
- /* pval = isign * pow(2.0, -24.0) * kmant * pow(16.0, (double)(iexp - 64)); */
+#if defined(_GET_IBM_COUNTER)
+ hpmStart(1, "minmax fsel");
+#endif
- iexp -= 64;
+ pwr6_minmax_val_double_unrolled6(data, datasize, fmin, fmax);
- pval = ldexp(1.0, 4 * iexp) * isign * POW_2_M24 * kmant;
+#if defined(_GET_IBM_COUNTER)
+ hpmStop(1);
+#endif
- /* ----------------------------------------------------------------- */
- /* Section 9. Return to calling routine. */
- /* ----------------------------------------------------------------- */
+#undef __UNROLL_DEPTH_1
-LABEL900:
+#else // original loop
- //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
+#if defined(_GET_IBM_COUNTER)
+ hpmStart(1, "minmax base");
+#endif
- return (pval);
-} /* decfp2 */
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdarg.h>
+ minmax_val_double_orig(data, datasize, fmin, fmax);
+#if defined(_GET_IBM_COUNTER)
+ hpmStop(1);
+#endif
+#endif // _ARCH_PWR6 && original loop
+#endif // SIMD
-int gribRefDate(int *isec1)
-{
- int date, ryear, rmonth, rday;
- int century;
-
- century = ISEC1_Century;
- if ( century < 0 ) century = -century;
- century -= 1;
-
- ryear = ISEC1_Year;
-
- /* if ( century != 0 ) */
- {
- if ( ryear == 100 )
- {
- ryear = 0;
- century += 1;
- }
+#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
+#if defined(_GET_X86_COUNTER)
+ end_minmax = _rdtsc();
+#endif
+#if defined(_GET_MACH_COUNTER)
+ end_minmax = mach_absolute_time();
+#endif
+#if defined(_ENABLE_AVX)
+ printf("AVX minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+ fprintf (stderr, "AVX min: %lf max: %lf\n", *fmin, *fmax);
+#elif defined(_ENABLE_SSE2)
+ printf("SSE2 minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+ fprintf (stderr, "SSE2 min: %lf max: %lf\n", *fmin, *fmax);
+#else
+ printf("loop minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+ fprintf (stderr, "loop min: %lf max: %lf\n", *fmin, *fmax);
+#endif
+#endif
- if ( ryear != 255 )
- {
- ryear = century*100 + ryear;
- if ( ISEC1_Century < 0 ) ryear = -ryear;
- }
- else
- ryear = 1;
- }
+ return;
+}
- rmonth = ISEC1_Month;
- rday = ISEC1_Day;
+#if defined(TEST_MINMAXVAL)
- date = cdiEncodeDate(ryear, rmonth, rday);
+#include <stdio.h>
+#include <sys/time.h>
- return (date) ;
+static
+double dtime()
+{
+ double tseconds = 0.0;
+ struct timeval mytime;
+ gettimeofday(&mytime, NULL);
+ tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
+ return (tseconds);
}
+#define NRUN 10000
-int gribRefTime(int *isec1)
+int main(void)
{
- int time, rhour, rminute;
+ long datasize = 1000000;
+ double t_begin, t_end;
- rhour = ISEC1_Hour;
- rminute = ISEC1_Minute;
+#if defined(_OPENMP)
+ printf("_OPENMP=%d\n", _OPENMP);
+#endif
- time = cdiEncodeTime(rhour, rminute, 0);
+#if defined(__ICC)
+ printf("icc\n");
+#elif defined(__clang__)
+ printf("clang\n");
+#elif defined(__GNUC__)
+ printf("gcc\n");
+#endif
- return (time) ;
-}
+ {
+ float fmin, fmax;
+ float *data_sp = (float*) malloc(datasize*sizeof(float));
+ for ( long i = 0; i < datasize/2; i++ ) data_sp[i] = (float) (i);
+ for ( long i = datasize/2; i < datasize; i++ ) data_sp[i] = (float) (-datasize + i);
-int gribTimeIsFC(int *isec1)
-{
- int isFC = FALSE;
- int time_period;
+ printf("float:\n");
- if ( ISEC1_TimeRange == 10 )
- time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
- else
- time_period = ISEC1_TimePeriod1;
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_sp[0];
+ minmax_val_float(data_sp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("minmax_val: fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
- if ( time_period > 0 && ISEC1_Day > 0 )
- {
- if ( ISEC1_TimeRange == 0 || ISEC1_TimeRange == 10 ) isFC = TRUE;
- }
+#if defined(OMP_SIMD)
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_sp[0];
+ minmax_val_float_simd(data_sp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("simd : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
- return (isFC);
-}
+ free(data_sp);
+ }
+ {
+ double fmin, fmax;
+ double *data_dp = (double*) malloc(datasize*sizeof(double));
-void gribDateTime(int *isec1, int *date, int *time)
-{
- static int lprint = TRUE;
- int julday, secofday;
- int64_t addsec = 0;
- int64_t time_period = 0;
- extern int grib_calendar;
+ // for ( long i = datasize-1; i >= 0; i-- ) data[i] = (double) (-datasize/2 + i);
+ for ( long i = 0; i < datasize/2; i++ ) data_dp[i] = (double) (i);
+ for ( long i = datasize/2; i < datasize; i++ ) data_dp[i] = (double) (-datasize + i);
- int century = ISEC1_Century;
- int ryear = ISEC1_Year;
+ printf("double:\n");
- if ( century == -255 && ryear == 127 )
- {
- century = 0;
- ryear = 0;
- }
- else
- {
- if ( century < 0 ) century = -century;
- century -= 1;
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_dp[0];
+ minmax_val_double(data_dp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("minmax_val: fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
- /* if ( century != 0 ) */
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
{
- if ( ryear == 100 )
- {
- ryear = 0;
- century += 1;
- }
+ fmin = fmax = data_dp[0];
+ minmax_val_double_orig(data_dp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("orig : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
- if ( ryear != 255 )
- {
- ryear = century*100 + ryear;
- if ( ISEC1_Century < 0 ) ryear = -ryear;
- }
- else
- ryear = 1;
+#if defined(OMP_SIMD)
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_dp[0];
+ minmax_val_double_simd(data_dp, datasize, &fmin, &fmax);
}
- }
+ t_end = dtime();
+ printf("simd : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
- int rmonth = ISEC1_Month;
- int rday = ISEC1_Day;
+#if defined(_ENABLE_AVX)
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_dp[0];
+ avx_minmax_val_double(data_dp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("avx : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#elif defined(_ENABLE_SSE2)
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_dp[0];
+ sse2_minmax_val_double(data_dp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("sse2 : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
+#if defined(_ARCH_PWR6)
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ fmin = fmax = data_dp[0];
+ pwr6_minmax_val_double_unrolled6(data_dp, datasize, &fmin, &fmax);
+ }
+ t_end = dtime();
+ printf("pwr6u6 : fmin: %ld fmax: %ld time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
+ free(data_dp);
+ }
- int rhour = ISEC1_Hour;
- int rminute = ISEC1_Minute;
- int second = 0;
+ return (0);
+}
+#endif // TEST_MINMAXVAL
- /* printf("ref %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute); */
+#undef DISABLE_SIMD_MINMAXVAL
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE2
+#undef GNUC_PUSH_POP
+/*
+### new version with gribSwapByteOrder_uint16()
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_ENCODE encode_array.c
+ result on hama2 (icc 16.0.2):
+ float:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 1.8731s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.0898s
+ double:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.68089s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.30798s
+ avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.23864s
- if ( ISEC1_TimeRange == 10 )
- time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
- else if ( ISEC1_TimeRange >=2 && ISEC1_TimeRange <= 5 )
- time_period = ISEC1_TimePeriod2;
- else if ( ISEC1_TimeRange == 0 )
- time_period = ISEC1_TimePeriod1;
+gcc -g -Wall -O3 -march=native -Wa,-q -std=c99 -DTEST_ENCODE encode_array.c
+ result on hama2 (gcc 6.1.0):
+float:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.22871s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 2.30281s
+double:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.2669s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 4.81643s
+ avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.98415s
- if ( time_period > 0 && rday > 0 )
- {
- encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, second, &julday, &secofday);
+###
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_ENCODE encode_array.c
+ result on hama2 (icc 16.0.0):
+ float:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 9.10691s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 8.63584s
+ double:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 13.5768s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 9.17742s
+ avx: val1: 1 val2: 1 val3: 2 valn: 66 time: 3.9488s
- addsec = 0;
- switch ( ISEC1_TimeUnit )
- {
- case ISEC1_TABLE4_MINUTE: addsec = 60 * time_period; break;
- case ISEC1_TABLE4_QUARTER: addsec = 900 * time_period; break;
- case ISEC1_TABLE4_30MINUTES: addsec = 1800 * time_period; break;
- case ISEC1_TABLE4_HOUR: addsec = 3600 * time_period; break;
- case ISEC1_TABLE4_3HOURS: addsec = 10800 * time_period; break;
- case ISEC1_TABLE4_6HOURS: addsec = 21600 * time_period; break;
- case ISEC1_TABLE4_12HOURS: addsec = 43200 * time_period; break;
- case ISEC1_TABLE4_DAY: addsec = 86400 * time_period; break;
- default:
- if ( lprint )
- {
- gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
- lprint = FALSE;
- }
- break;
- }
+gcc -g -Wall -O3 -std=c99 -DTEST_ENCODE encode_array.c
+ result on hama2 (gcc 5.2.0):
+ float:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 5.32775s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 7.87125s
+ double:
+ orig: val1: 1 val2: 1 val3: 2 valn: 66 time: 7.85873s
+unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 12.9979s
- julday_add_seconds(addsec, &julday, &secofday);
+###
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
+ result on bailung (gcc 4.7):
+ orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 8.4166s
+ sse41 : val1: 1 val2: 1 val3: 2 valn: 66 time: 7.1522s
- decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &second);
- }
- /*
- printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
- */
- *date = cdiEncodeDate(ryear, rmonth, rday);
- *time = cdiEncodeTime(rhour, rminute, 0);
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
+ result on thunder5 (gcc 4.7):
+ orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 6.21976s
+ avx : val1: 1 val2: 1 val3: 2 valn: 66 time: 4.54485s
- return;
-}
+icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_ENCODE encode_array.c
+ result on thunder5 (icc 13.2):
+ orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 14.6279s
+ avx : val1: 1 val2: 1 val3: 2 valn: 66 time: 4.9776s
+xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_ENCODE encode_array.c
+ result on blizzard (xlc 12):
+ orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 132.25s
+ unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 27.202s
+ orig : val1: 1 val2: 1 val3: 2 valn: 66 time: 106.627s // without -qhot
+ unrolled: val1: 1 val2: 1 val3: 2 valn: 66 time: 39.929s // without -qhot
+*/
+#ifdef _ARCH_PWR6
+#pragma options nostrict
+#endif
-void gprintf(const char *caller, const char *fmt, ...)
-{
- va_list args;
+#ifdef TEST_ENCODE
+#include <stdio.h>
+#include <stdlib.h>
+#define GRIBPACK unsigned char
+#define IS_BIGENDIAN() (u_byteorder.c[sizeof(long) - 1])
+#define U_BYTEORDER static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
+#define Error(x,y)
+#endif
- if ( grprsm == NULL ) Error("GRIBEX initialization missing!");
-
- va_start(args, fmt);
+//#undef _GET_X86_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _ARCH_PWR6
- fprintf(grprsm, "%-18s : ", caller);
- vfprintf(grprsm, fmt, args);
- fprintf(grprsm, "\n");
+#if defined _GET_IBM_COUNTER
+#include <libhpc.h>
+#elif defined _GET_X86_COUNTER
+#include <x86intrin.h>
+#elif defined _GET_MACH_COUNTER
+#include <mach/mach_time.h>
+#endif
- va_end(args);
-}
+#include <stdint.h>
+#include <math.h>
+#ifndef DISABLE_SIMD
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#elif defined(__ICC) && (__ICC >= 1100)
+#elif defined(__clang__)
+#else
+#define DISABLE_SIMD
+#endif
+#endif
-void
-gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
- double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, const char *hoper, int *kret)
-{
- int yfunc = *hoper;
+#ifdef DISABLE_SIMD
+#define DISABLE_SIMD_ENCODE
+#endif
- if ( yfunc == 'C' )
- {
- grib_encode_double(isec0, isec1, isec2, fsec2, isec3,
- fsec3, isec4, fsec4, klenp, kgrib,
- kleng, kword, yfunc, kret);
- }
- else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
- {
- grib_decode_double(isec0, isec1, isec2, fsec2, isec3,
- fsec3, isec4, fsec4, klenp, kgrib,
- kleng, kword, yfunc, kret);
- }
- else if ( yfunc == 'V' )
- {
- fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
- }
- else
- {
- Error("oper %c unsupported!", yfunc);
- *kret=-9;
- }
-}
+//#define DISABLE_SIMD_ENCODE
+#ifdef DISABLE_SIMD_ENCODE
+# ifdef ENABLE_AVX
+# define _ENABLE_AVX
+# endif
+# ifdef ENABLE_SSE4_1
+# define _ENABLE_SSE4_1
+# endif
+#endif
-void
-gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
- float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, const char *hoper, int *kret)
-{
- int yfunc = *hoper;
+#ifndef DISABLE_SIMD_ENCODE
+# ifdef __AVX__
+# define _ENABLE_AVX
+# endif
+# ifdef __SSE4_1__
+# define _ENABLE_SSE4_1
+# endif
+#endif
- if ( yfunc == 'C' )
- {
- grib_encode_float(isec0, isec1, isec2, fsec2, isec3,
- fsec3, isec4, fsec4, klenp, kgrib,
- kleng, kword, yfunc, kret);
- }
- else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
- {
- grib_decode_float(isec0, isec1, isec2, fsec2, isec3,
- fsec3, isec4, fsec4, klenp, kgrib,
- kleng, kword, yfunc, kret);
- }
- else if ( yfunc == 'V' )
- {
- fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
- }
- else
- {
- Error("oper %c unsupported!", yfunc);
- *kret=-9;
- }
-}
+#if defined _ENABLE_AVX
+#include <immintrin.h>
+#elif defined _ENABLE_SSE4_1
+#include <smmintrin.h>
+#endif
-int CGRIBEX_Fix_ZSE = 0; /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
-int CGRIBEX_Const = 0; /* 1: Don't pack constant fields on regular grids */
-int CGRIBEX_Debug = 0; /* 1: Debugging */
+#if defined _ENABLE_AVX
-void gribSetDebug(int debug)
+static
+void avx_encode_array_2byte_double(size_t datasize,
+ unsigned char * restrict lGrib,
+ const double * restrict data,
+ double zref, double factor, size_t *gz)
{
- CGRIBEX_Debug = debug;
-
- if ( CGRIBEX_Debug )
- Message("debug level %d", debug);
-}
+ size_t i, j, residual;
+ const double *dval = data;
+ __m128i *sgrib = (__m128i *) (lGrib+(*gz));
+ const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
-void gribFixZSE(int flag)
-{
- CGRIBEX_Fix_ZSE = flag;
+ const __m256d c0 = _mm256_set1_pd(zref);
+ const __m256d c1 = _mm256_set1_pd(factor);
+ const __m256d c2 = _mm256_set1_pd(0.5);
+
+ __m256d d0, d3, d2, d1;
+ __m128i i0, i1, i2, i3;
+ __m128i s0, s1;
- if ( CGRIBEX_Debug )
- Message("Fix ZeroShiftError set to %d", flag);
-}
+ residual = datasize % 16;
+ for (i = 0; i < (datasize-residual); i += 16)
+ {
+ (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
+ //_____________________________________________________________________________
-void gribSetConst(int flag)
-{
- CGRIBEX_Const = flag;
+ d0 = _mm256_loadu_pd (dval);
+ d0 = _mm256_sub_pd (d0, c0);
+ d0 = _mm256_mul_pd (d0, c1);
+ d0 = _mm256_add_pd (d0, c2);
- if ( CGRIBEX_Debug )
- Message("Const set to %d", flag);
-}
+ i0 = _mm256_cvttpd_epi32 (d0);
+
+ //_____________________________________________________________________________
+
+ d1 = _mm256_loadu_pd (dval+4);
+ d1 = _mm256_sub_pd (d1, c0);
+ d1 = _mm256_mul_pd (d1, c1);
+ d1 = _mm256_add_pd (d1, c2);
+
+ i1 = _mm256_cvttpd_epi32 (d1);
+ //_____________________________________________________________________________
-void gribSetRound(int round)
-{
- UNUSED(round);
-}
+ s0 = _mm_packus_epi32(i0, i1);
+ s0 = _mm_shuffle_epi8 (s0, swap);
+ (void) _mm_storeu_si128 (sgrib, s0);
+ //_____________________________________________________________________________
-void gribSetRefDP(double refval)
-{
- UNUSED(refval);
-}
+ (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
+ //_____________________________________________________________________________
+
+ d2 = _mm256_loadu_pd (dval+8);
+ d2 = _mm256_sub_pd (d2, c0);
+ d2 = _mm256_mul_pd (d2, c1);
+ d2 = _mm256_add_pd (d2, c2);
+
+ i2 = _mm256_cvttpd_epi32 (d2);
-void gribSetRefSP(float refval)
-{
- gribSetRefDP((double) refval);
-}
+ //_____________________________________________________________________________
+
+ d3 = _mm256_loadu_pd (dval+12);
+ d3 = _mm256_sub_pd (d3, c0);
+ d3 = _mm256_mul_pd (d3, c1);
+ d3 = _mm256_add_pd (d3, c2);
+
+ i3 = _mm256_cvttpd_epi32 (d3);
+ //_____________________________________________________________________________
-void gribSetValueCheck(int vcheck)
-{
- UNUSED(vcheck);
+ s1 = _mm_packus_epi32(i2, i3);
+ s1 = _mm_shuffle_epi8 (s1, swap);
+ (void) _mm_storeu_si128 (sgrib+1, s1);
+
+ //_____________________________________________________________________________
+
+ dval += 16;
+ sgrib += 2;
+ }
+
+ if (i != datasize)
+ {
+ uint16_t ui16;
+ for ( j = i; j < datasize; j++ )
+ {
+ ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
+ lGrib[*gz+2*j ] = ui16 >> 8;
+ lGrib[*gz+2*j+1] = ui16;
+ }
+ }
+
+ *gz += 2*datasize;
+
+ return;
}
-#include <string.h>
-#include <math.h>
+#define grib_encode_array_2byte_double avx_encode_array_2byte_double
+#elif defined _ENABLE_SSE4_1
-void gribPrintSec0(int *isec0)
+static
+void sse41_encode_array_2byte_double(size_t datasize,
+ unsigned char * restrict lGrib,
+ const double * restrict data,
+ double zref, double factor, size_t *gz)
{
- /*
+ size_t i, j, residual;
+ const double *dval = data;
+ __m128i *sgrib = (__m128i *) (lGrib+(*gz));
- Print the information in the Indicator
- Section (Section 0) of decoded GRIB data.
+ const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
- Input Parameters:
+ const __m128d c0 = _mm_set1_pd(zref);
+ const __m128d c1 = _mm_set1_pd(factor);
+ const __m128d c2 = _mm_set1_pd(0.5);
+
+ __m128d d0, d4, d3, d2, d1;
+ __m128i i0, i1, i2, i3, i4;
+ __m128i s0, s1;
- isec0 - Array of decoded integers from Section 0
+ residual = datasize % 16;
+
+ for (i = 0; i < (datasize-residual); i += 16)
+ {
+ (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
+ //_____________________________________________________________________________
+ d0 = _mm_loadu_pd (dval);
+ d0 = _mm_sub_pd (d0, c0);
+ d0 = _mm_mul_pd (d0, c1);
+ d0 = _mm_add_pd (d0, c2);
+
+ d4 = _mm_loadu_pd (dval+2);
+ d4 = _mm_sub_pd (d4, c0);
+ d4 = _mm_mul_pd (d4, c1);
+ d4 = _mm_add_pd (d4, c2);
- Converted from EMOS routine GRPRS0.
+ i0 = _mm_cvttpd_epi32 (d0);
+ i4 = _mm_cvttpd_epi32 (d4);
+ i0 = _mm_unpacklo_epi64 (i0, i4);
- Uwe Schulzweida MPIfM 01/04/2001
+ //_____________________________________________________________________________
+
+ d1 = _mm_loadu_pd (dval+4);
+ d1 = _mm_sub_pd (d1, c0);
+ d1 = _mm_mul_pd (d1, c1);
+ d1 = _mm_add_pd (d1, c2);
+
+ d4 = _mm_loadu_pd (dval+6);
+ d4 = _mm_sub_pd (d4, c0);
+ d4 = _mm_mul_pd (d4, c1);
+ d4 = _mm_add_pd (d4, c2);
+
+ i1 = _mm_cvttpd_epi32 (d1);
+ i4 = _mm_cvttpd_epi32 (d4);
+ i1 = _mm_unpacklo_epi64 (i1, i4);
- */
+ //_____________________________________________________________________________
- grsdef();
+ s0 = _mm_packus_epi32(i0, i1);
+ s0 = _mm_shuffle_epi8 (s0, swap);
+ (void) _mm_storeu_si128 (sgrib, s0);
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Section 0 - Indicator Section. \n");
- fprintf(grprsm, " -------------------------------------\n");
- fprintf(grprsm, " Length of GRIB message (octets). %9d\n", ISEC0_GRIB_Len);
- fprintf(grprsm, " GRIB Edition Number. %9d\n", ISEC0_GRIB_Version);
+ //_____________________________________________________________________________
+
+ (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
+
+ //_____________________________________________________________________________
+
+ d2 = _mm_loadu_pd (dval+8);
+ d2 = _mm_sub_pd (d2, c0);
+ d2 = _mm_mul_pd (d2, c1);
+ d2 = _mm_add_pd (d2, c2);
+
+ d4 = _mm_loadu_pd (dval+10);
+ d4 = _mm_sub_pd (d4, c0);
+ d4 = _mm_mul_pd (d4, c1);
+ d4 = _mm_add_pd (d4, c2);
+
+ i2 = _mm_cvttpd_epi32 (d2);
+ i4 = _mm_cvttpd_epi32 (d4);
+ i2 = _mm_unpacklo_epi64 (i2, i4);
+
+ //_____________________________________________________________________________
+
+ d3 = _mm_loadu_pd (dval+12);
+ d3 = _mm_sub_pd (d3, c0);
+ d3 = _mm_mul_pd (d3, c1);
+ d3 = _mm_add_pd (d3, c2);
+
+ d4 = _mm_loadu_pd (dval+14);
+ d4 = _mm_sub_pd (d4, c0);
+ d4 = _mm_mul_pd (d4, c1);
+ d4 = _mm_add_pd (d4, c2);
+
+ i3 = _mm_cvttpd_epi32 (d3);
+ i4 = _mm_cvttpd_epi32 (d4);
+ i3 = _mm_unpacklo_epi64 (i3, i4);
+
+ //_____________________________________________________________________________
+
+ s1 = _mm_packus_epi32(i2, i3);
+ s1 = _mm_shuffle_epi8 (s1, swap);
+ (void) _mm_storeu_si128 (sgrib+1, s1);
+
+ //_____________________________________________________________________________
+
+ dval += 16;
+ sgrib += 2;
+ }
+
+ if (i != datasize)
+ {
+ uint16_t ui16;
+ for ( j = i; j < datasize; j++ )
+ {
+ ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
+ lGrib[*gz+2*j ] = ui16 >> 8;
+ lGrib[*gz+2*j+1] = ui16;
+ }
+ }
+
+ *gz += 2*datasize;
+
+ return;
}
-void gribPrintSec1(int *isec0, int *isec1)
-{
- /*
+#define grib_encode_array_2byte_double sse41_encode_array_2byte_double
- Print the information in the Product Definition
- Section (Section 1) of decoded GRIB data.
+#else
- Input Parameters:
+#define grib_encode_array_2byte_double encode_array_2byte_double
- isec0 - Array of decoded integers from Section 0
+#endif // SIMD variants
- isec1 - Array of decoded integers from Section 1
- Comments:
+#ifdef TEST_ENCODE
- When decoding data from Experimental Edition or Edition 0,
- routine GRIBEX adds the additional fields available in
- Edition 1.
+#define CAT(X,Y) X##_##Y
+#define TEMPLATE(X,Y) CAT(X,Y)
+#ifdef T
+#undef T
+#endif
+#define T double
- Converted from EMOS routine GRPRS1.
+#ifdef T
+#undef T
+#endif
+#define T float
- Uwe Schulzweida MPIfM 01/04/2001
- */
+#include <sys/time.h>
- int iprev, icurr, ioffset;
- int ibit, ierr, iout, iyear;
- int jloop, jiloop;
- float value;
+static
+double dtime()
+{
+ double tseconds = 0.0;
+ struct timeval mytime;
+ gettimeofday(&mytime, NULL);
+ tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
+ return (tseconds);
+}
- char hversion[9];
- /*
- char hfirst[121], hsecond[121], hthird[121], hfourth[121];
- */
+#define NRUN 10000
- grsdef();
+static
+void pout(char *name, int s, unsigned char *lgrib, long datasize, double tt)
+{
+ printf("%8s: val1: %d val2: %d val3: %d valn: %d time: %gs\n",
+ name, (int) lgrib[s*1+1], (int) lgrib[s*2+1], (int) lgrib[s*3+1], (int) lgrib[2*datasize-1], tt);
+}
- /*
- -----------------------------------------------------------------
- Section 0 . Print required information.
- -----------------------------------------------------------------
- */
+int main(void)
+{
+ long datasize = 1000000;
+ double t_begin, t_end;
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Section 1 - Product Definition Section.\n");
- fprintf(grprsm, " ---------------------------------------\n");
+ float *dataf = (float*) malloc(datasize*sizeof(float));
+ double *data = (double*) malloc(datasize*sizeof(double));
+ unsigned char *lgrib = (unsigned char*) malloc(2*datasize*sizeof(unsigned char));
- fprintf(grprsm, " Code Table 2 Version Number. %9d\n", isec1[0]);
- fprintf(grprsm, " Originating centre identifier. %9d\n", isec1[1]);
- fprintf(grprsm, " Model identification. %9d\n", isec1[2]);
- fprintf(grprsm, " Grid definition. %9d\n", isec1[3]);
+ for ( long i = 0; i < datasize; ++i ) dataf[i] = (float) (-datasize/2 + i);
+ for ( long i = 0; i < datasize; ++i ) data[i] = (double) (-datasize/2 + i);
- ibit = 8;
- prtbin(isec1[4], ibit, &iout, &ierr);
- fprintf(grprsm, " Flag (Code Table 1) %8.8d\n", iout);
- fprintf(grprsm, " Parameter identifier (Code Table 2). %9d\n", isec1[5]);
+ int PackStart = 0;
+ int nbpv = 16;
+ double zref = data[0];
+ size_t z;
+ double factor = 0.00390625;
+ int s = 256;
- /*
- IERR = CHKTAB2(ISEC1,HFIRST,HSECOND,HTHIRD,HFOURTH)
- IF( IERR .EQ. 0 ) THEN
- DO JLOOP = 121, 1, -1
- IF( HSECOND(JLOOP:JLOOP).NE.' ' ) THEN
- IOFFSET = JLOOP
- GOTO 110
- ENDIF
- ENDDO
- GOTO 120
- 110 CONTINUE
- WRITE(*,'(2H ",A,1H")') HSECOND(1:IOFFSET)
- 120 CONTINUE
- ENDIF
- */
+ if ( 0 )
+ {
+ encode_array_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
+ encode_array_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
+ }
- if ( isec1[5] != 127 )
+#if defined(__ICC)
+ printf("icc\n");
+#elif defined(__clang__)
+ printf("clang\n");
+#elif defined(__GNUC__)
+ printf("gcc\n");
+#endif
+
+ printf("float:\n");
+
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
{
- fprintf(grprsm, " Type of level (Code Table 3). %9d\n", isec1[6]);
- fprintf(grprsm, " Value 1 of level (Code Table 3). %9d\n", isec1[7]);
- fprintf(grprsm, " Value 2 of level (Code Table 3). %9d\n", isec1[8]);
+ z = 0;
+ encode_array_2byte_float(datasize, lgrib, dataf, (float)zref, (float)factor, &z);
}
- else
+ t_end = dtime();
+ pout("orig", s, lgrib, datasize, t_end-t_begin);
+
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
{
- fprintf(grprsm, " Satellite identifier. %9d\n", isec1[6]);
- fprintf(grprsm, " Spectral band. %9d\n", isec1[7]);
+ z = 0;
+ encode_array_unrolled_float(nbpv, PackStart, datasize, lgrib, dataf, (float)zref, (float)factor, &z);
}
+ t_end = dtime();
+ pout("unrolled", s, lgrib, datasize, t_end-t_begin);
- iyear = isec1[9];
- if ( iyear != 255 )
+ printf("double:\n");
+
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
{
- int date, time;
- /* iyear = ((isec1[20]-1)*100 + isec1[9]); */
- gribDateTime(isec1, &date, &time);
- iyear = date/10000;
- fprintf(grprsm, " Year of reference time of data. %9d (%4d)\n", isec1[9], iyear);
+ z = 0;
+ encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
}
- else
+ t_end = dtime();
+ pout("orig", s, lgrib, datasize, t_end-t_begin);
+
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
{
- fprintf(grprsm, " Year of reference time of data MISSING (=255)\n");
+ z = 0;
+ encode_array_unrolled_double(nbpv, PackStart, datasize, lgrib, data, zref, factor, &z);
}
+ t_end = dtime();
+ pout("unrolled", s, lgrib, datasize, t_end-t_begin);
- fprintf(grprsm, " Month of reference time of data. %9d\n", isec1[10]);
- fprintf(grprsm, " Day of reference time of data. %9d\n", isec1[11]);
- fprintf(grprsm, " Hour of reference time of data. %9d\n", isec1[12]);
- fprintf(grprsm, " Minute of reference time of data. %9d\n", isec1[13]);
- fprintf(grprsm, " Time unit (Code Table 4). %9d\n", isec1[14]);
- fprintf(grprsm, " Time range one. %9d\n", isec1[15]);
- fprintf(grprsm, " Time range two. %9d\n", isec1[16]);
- fprintf(grprsm, " Time range indicator (Code Table 5) %9d\n", isec1[17]);
- fprintf(grprsm, " Number averaged. %9d\n", isec1[18]);
- fprintf(grprsm, " Number missing from average. %9d\n", isec1[19]);
- /*
- All ECMWF data in GRIB Editions before Edition 1 is decoded
- as 20th century data. Other centres are decoded as missing.
- */
- if ( isec0[1] < 1 && isec1[1] != 98 )
- fprintf(grprsm, " Century of reference time of data. Not given\n");
- else
- fprintf(grprsm, " Century of reference time of data. %9d\n", isec1[20]);
+#if defined _ENABLE_AVX
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ z = 0;
+ avx_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
+ }
+ t_end = dtime();
+ pout("avx", s, lgrib, datasize, t_end-t_begin);
+#elif defined _ENABLE_SSE4_1
+ t_begin = dtime();
+ for ( int i = 0; i < NRUN; ++i )
+ {
+ z = 0;
+ sse41_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
+ }
+ t_end = dtime();
+ pout("sse41", s, lgrib, datasize, t_end-t_begin);
+#endif
- /* Print sub-centre */
- fprintf(grprsm, " Sub-centre identifier. %9d\n", ISEC1_SubCenterID);
+ return 0;
+}
+#endif // TEST_ENCODE
- /* Decimal scale factor */
- fprintf(grprsm, " Units decimal scaling factor. %9d\n", isec1[22]);
+#undef DISABLE_SIMD_ENCODE
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE4_1
+
+void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
+{
/*
- -----------------------------------------------------------------
- Section 1 . Print local DWD information.
- -----------------------------------------------------------------
- */
- if ( (ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250) &&
- (isec1[36] == 253 || isec1[36] == 254) )
- {
- fprintf(grprsm, " DWD local usage identifier. %9d\n", isec1[36]);
- if ( isec1[36] == 253 )
- fprintf(grprsm, " (Database labelling and ensemble forecast)\n");
- if ( isec1[36] == 254 )
- fprintf(grprsm, " (Database labelling)\n");
- fprintf(grprsm, " Year of database entry %3d (%4d)\n", isec1[43], 1900+isec1[43]);
- fprintf(grprsm, " Month of database entry %3d\n", isec1[44]);
- fprintf(grprsm, " Day of database entry %3d\n", isec1[45]);
- fprintf(grprsm, " Hour of database entry %3d\n", isec1[46]);
- fprintf(grprsm, " Minute of database entry %3d\n", isec1[47]);
- fprintf(grprsm, " DWD experiment number %9d\n",isec1[48]);
- fprintf(grprsm, " DWD run type %9d\n",isec1[49]);
- if ( isec1[36] == 253 )
- {
- fprintf(grprsm, " User id %9d\n",isec1[50]);
- fprintf(grprsm, " Experiment identifier %9d\n",isec1[51]);
- fprintf(grprsm, " Ensemble identification type %9d\n",isec1[52]);
- fprintf(grprsm, " Number of ensemble members %9d\n",isec1[53]);
- fprintf(grprsm, " Actual number of ensemble member %9d\n",isec1[54]);
- fprintf(grprsm, " Model version %2d.%2.2d\n",isec1[55],isec1[56]);
- }
- }
+ Purpose:
+ --------
- /*
- -----------------------------------------------------------------
- Section 2 . Print local ECMWF information.
- -----------------------------------------------------------------
- */
- /*
- Regular MARS labelling, or reformatted Washington EPS products.
- */
- if ( (ISEC1_CenterID == 98 && ISEC1_LocalFLag == 1) ||
- (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag == 1) ||
- (ISEC1_CenterID == 7 && ISEC1_SubCenterID == 98) )
- {
- /* Parameters common to all definitions. */
+ Convert floating point number from machine
+ representation to GRIB representation.
- fprintf(grprsm, " ECMWF local usage identifier. %9d\n", isec1[36]);
- if ( isec1[36] == 1 )
- fprintf(grprsm, " (Mars labelling or ensemble forecast)\n");
- if ( isec1[36] == 2 )
- fprintf(grprsm, " (Cluster means and standard deviations)\n");
- if ( isec1[36] == 3 )
- fprintf(grprsm, " (Satellite image data)\n");
- if ( isec1[36] == 4 )
- fprintf(grprsm, " (Ocean model data)\n");
- if ( isec1[36] == 5 )
- fprintf(grprsm, " (Forecast probability data)\n");
- if ( isec1[36] == 6 )
- fprintf(grprsm, " (Surface temperature data)\n");
- if ( isec1[36] == 7 )
- fprintf(grprsm, " (Sensitivity data)\n");
- if ( isec1[36] == 8 )
- fprintf(grprsm, " (ECMWF re-analysis data)\n");
- if ( isec1[36] == 9 )
- fprintf(grprsm, " (Singular vectors and ensemble perturbations)\n");
- if ( isec1[36] == 10 )
- fprintf(grprsm, " (EPS tubes)\n");
- if ( isec1[36] == 11 )
- fprintf(grprsm, " (Supplementary data used by analysis)\n");
- if ( isec1[36] == 13 )
- fprintf(grprsm, " (Wave 2D spectra direction and frequency)\n");
+ Input Parameters:
+ -----------------
- fprintf(grprsm, " Class. %9d\n", isec1[37]);
- fprintf(grprsm, " Type. %9d\n", isec1[38]);
- fprintf(grprsm, " Stream. %9d\n", isec1[39]);
- sprintf(hversion, "%4s", (char*)&isec1[40]); hversion[4] = 0;
- fprintf(grprsm, " Version number or Experiment identifier. %4s\n", hversion);
- /*
- ECMWF Local definition 1.
- (MARS labelling or ensemble forecast data)
- */
- if ( isec1[36] == 1 )
- {
- fprintf(grprsm, " Forecast number. %9d\n", isec1[41]);
- if ( isec1[39] != 1090 )
- fprintf(grprsm, " Total number of forecasts. %9d\n", isec1[42]);
+ pval - Floating point number to be converted.
+ kbits - Number of bits in computer word.
+ kround - Conversion type.
+ 0 , Closest number in GRIB format less than
+ original number.
+ 1 , Closest number in GRIB format to the
+ original number (equal to, greater than or
+ less than original number).
- return;
- }
- /*
- ECMWF Local definition 2.
- (Cluster means and standard deviations)
- */
- if ( isec1[36] == 2 )
- {
- fprintf(grprsm, " Cluster number. %9d\n", isec1[41]);
- fprintf(grprsm, " Total number of clusters. %9d\n", isec1[42]);
- fprintf(grprsm, " Clustering method. %9d\n", isec1[43]);
- fprintf(grprsm, " Start time step when clustering. %9d\n", isec1[44]);
- fprintf(grprsm, " End time step when clustering. %9d\n", isec1[45]);
- fprintf(grprsm, " Northern latitude of domain. %9d\n", isec1[46]);
- fprintf(grprsm, " Western longitude of domain. %9d\n", isec1[47]);
- fprintf(grprsm, " Southern latitude of domain. %9d\n", isec1[48]);
- fprintf(grprsm, " Eastern longitude of domain. %9d\n", isec1[49]);
- fprintf(grprsm, " Operational forecast in cluster %9d\n", isec1[50]);
- fprintf(grprsm, " Control forecast in cluster %9d\n", isec1[51]);
- fprintf(grprsm, " Number of forecasts in cluster. %9d\n", isec1[52]);
+ Output Parameters:
+ ------------------
- for (jloop = 0; jloop < isec1[52]; jloop++)
- fprintf(grprsm, " Forecast number %9d\n", isec1[jloop+53]);
+ kexp - 8 Bit signed exponent.
+ kmant - 24 Bit mantissa.
- return;
- }
- /*
- ECMWF Local definition 3.
- (Satellite image data)
- */
- if ( isec1[36] == 3 )
- {
- fprintf(grprsm, " Satellite spectral band. %9d\n", isec1[41]);
- fprintf(grprsm, " Function code. %9d\n", isec1[42]);
- return;
- }
- /*
- ECMWF Local definition 4.
- (Ocean model data)
- */
- if ( isec1[36] == 4 )
- {
- fprintf(grprsm, " Satellite spectral band. %9d\n", isec1[41]);
- if ( isec1[39] != 1090 )
- fprintf(grprsm, " Function code. %9d\n", isec1[42]);
- fprintf(grprsm, " Coordinate structure definition.\n");
- fprintf(grprsm, " Fundamental spatial reference system.%9d\n", isec1[43]);
- fprintf(grprsm, " Fundamental time reference. %9d\n", isec1[44]);
- fprintf(grprsm, " Space unit flag. %9d\n", isec1[45]);
- fprintf(grprsm, " Vertical coordinate definition. %9d\n", isec1[46]);
- fprintf(grprsm, " Horizontal coordinate definition. %9d\n", isec1[47]);
- fprintf(grprsm, " Time unit flag. %9d\n", isec1[48]);
- fprintf(grprsm, " Time coordinate definition. %9d\n", isec1[49]);
- fprintf(grprsm, " Position definition. \n");
- fprintf(grprsm, " Mixed coordinate field flag. %9d\n", isec1[50]);
- fprintf(grprsm, " Coordinate 1 flag. %9d\n", isec1[51]);
- fprintf(grprsm, " Averaging flag. %9d\n", isec1[52]);
- fprintf(grprsm, " Position of level 1. %9d\n", isec1[53]);
- fprintf(grprsm, " Position of level 2. %9d\n", isec1[54]);
- fprintf(grprsm, " Coordinate 2 flag. %9d\n", isec1[55]);
- fprintf(grprsm, " Averaging flag. %9d\n", isec1[56]);
- fprintf(grprsm, " Position of level 1. %9d\n", isec1[57]);
- fprintf(grprsm, " Position of level 2. %9d\n", isec1[58]);
- fprintf(grprsm, " Grid Definition.\n");
- fprintf(grprsm, " Coordinate 3 flag (x-axis) %9d\n", isec1[59]);
- fprintf(grprsm, " Coordinate 4 flag (y-axis) %9d\n", isec1[60]);
- fprintf(grprsm, " Coordinate 4 of first grid point. %9d\n", isec1[61]);
- fprintf(grprsm, " Coordinate 3 of first grid point. %9d\n", isec1[62]);
- fprintf(grprsm, " Coordinate 4 of last grid point. %9d\n", isec1[63]);
- fprintf(grprsm, " Coordinate 3 of last grid point. %9d\n", isec1[64]);
- fprintf(grprsm, " i - increment. %9d\n", isec1[65]);
- fprintf(grprsm, " j - increment. %9d\n", isec1[66]);
- fprintf(grprsm, " Flag for irregular grid coordinates. %9d\n", isec1[67]);
- fprintf(grprsm, " Flag for normal or staggered grids. %9d\n", isec1[68]);
- fprintf(grprsm, " Further information.\n");
- fprintf(grprsm, " Further information flag. %9d\n", isec1[69]);
- fprintf(grprsm, " Auxiliary information.\n");
- fprintf(grprsm, " No. entries in horizontal coordinate %9d\n", isec1[70]);
- fprintf(grprsm, " No. entries in mixed coordinate defn.%9d\n", isec1[71]);
- fprintf(grprsm, " No. entries in grid coordinate list. %9d\n", isec1[72]);
- fprintf(grprsm, " No. entries in auxiliary array. %9d\n", isec1[73]);
- /*
- Horizontal coordinate supplement.
- */
- fprintf(grprsm, " Horizontal coordinate supplement.\n");
- if ( isec1[70] == 0 )
- {
- fprintf(grprsm, "(None).\n");
- }
- else
- {
- fprintf(grprsm, "Number of items = %d\n", isec1[70]);
- for (jloop = 0; jloop < isec1[70]; jloop++)
- fprintf(grprsm, " %12d\n", isec1[74+jloop]);
- }
- /*
- Mixed coordinate definition.
- */
- fprintf(grprsm, " Mixed coordinate definition.\n");
- if ( isec1[71] == 0 )
- {
- fprintf(grprsm, "(None).\n");
- }
- else
- {
- fprintf(grprsm, "Number of items = %d\n", isec1[71]);
- ioffset = 74 + isec1[70];
- for (jloop = 0; jloop < isec1[71]; jloop++)
- fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
- }
- /*
- Grid coordinate list.
- */
- fprintf(grprsm, " Grid coordinate list. \n");
- if ( isec1[72] == 0 )
- {
- fprintf(grprsm, "(None).\n");
- }
- else
- {
- fprintf(grprsm, "Number of items = %d\n", isec1[72]);
- ioffset = 74 + isec1[70] + isec1[71];
- for (jloop = 0; jloop < isec1[72]; jloop++)
- fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
- }
- /*
- Auxiliary array.
- */
- fprintf(grprsm, " Auxiliary array. \n");
- if ( isec1[73] == 0 )
- {
- fprintf(grprsm, "(None).\n");
- }
- else
- {
- fprintf(grprsm, "Number of items = %d\n", isec1[73]);
- ioffset = 74 + isec1[70] + isec1[71] + isec1[72];
- for (jloop = 0; jloop < isec1[73]; jloop++)
- fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
- }
- /*
- Post-auxiliary array.
- */
- fprintf(grprsm, " Post-auxiliary array. \n");
- ioffset = 74 + isec1[70] + isec1[71] + isec1[72] + isec1[73];
- if ( isec1[ioffset] == 0 )
- {
- fprintf(grprsm, "(None).\n");
- }
- else
- {
- fprintf(grprsm, "Number of items = %d\n", isec1[ioffset]);
- for (jloop = 1; jloop < isec1[ioffset]; jloop++)
- fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
- }
-
- return;
- }
- /*
- ECMWF Local definition 5.
- (Forecast probability data)
- */
- if ( isec1[36] == 5 )
- {
- fprintf(grprsm, " Forecast probability number %9d\n", isec1[41]);
- fprintf(grprsm, " Total number of forecast probabilities %7d\n", isec1[42]);
- fprintf(grprsm, " Threshold units decimal scale factor %9d\n", isec1[43]);
- fprintf(grprsm, " Threshold indicator(1=lower,2=upper,3=both) %2d\n", isec1[44]);
- if ( isec1[44] != 2 )
- fprintf(grprsm, " Lower threshold value %9d\n", isec1[45]);
- if ( isec1[44] != 1 )
- fprintf(grprsm, " Upper threshold value %9d\n", isec1[46]);
- return;
- }
- /*
- ECMWF Local definition 6.
- (Surface temperature data)
- */
- if ( isec1[36] == 6 )
- {
- iyear = isec1[43];
- if ( iyear > 100 )
- {
- if ( iyear < 19000000 ) iyear = iyear + 19000000;
- fprintf(grprsm, " Date of SST field used %9d\n", iyear);
- }
- else
- fprintf(grprsm, "Date of SST field used Not given\n");
- }
- if ( isec1[44] == 0 )
- fprintf(grprsm, " Type of SST field (= climatology) %9d\n", isec1[44]);
- if ( isec1[44] == 1 )
- fprintf(grprsm, " Type of SST field (= 1/1 degree) %9d\n", isec1[44]);
- if ( isec1[44] == 2 )
- fprintf(grprsm, " Type of SST field (= 2/2 degree) %9d\n", isec1[44]);
-
- fprintf(grprsm, " Number of ICE fields used: %9d\n", isec1[45]);
-
- for (jloop = 1; jloop <= isec1[45]; jloop++)
- {
- iyear = isec1[44+(jloop*2)];
- if ( iyear > 100 )
- {
- if ( iyear < 19000000 ) iyear = iyear + 19000000;
- fprintf(grprsm, " Date of ICE field%3d %9d\n", jloop, iyear);
- fprintf(grprsm, " Satellite number (ICE field%3d) %9d\n", jloop,
- isec1[45+(jloop*2)]);
- }
- else
- fprintf(grprsm, "Date of SST field used Not given\n");
- }
- /*
- ECMWF Local definition 7.
- (Sensitivity data)
- */
- if ( isec1[36] == 7 )
- {
- if ( isec1[38] == 51 )
- fprintf(grprsm, " Forecast number %9d\n", isec1[41]);
- if ( isec1[38] != 51 )
- fprintf(grprsm, " Iteration number %9d\n", isec1[41]);
- if ( isec1[38] != 52 )
- fprintf(grprsm, " Total number of diagnostics %9d\n", isec1[42]);
- if ( isec1[38] == 52 )
- fprintf(grprsm, " No.interations in diag. minimisation %9d\n", isec1[42]);
- fprintf(grprsm, " Domain(0=Global,1=Europe,2=N.Hem.,3=S.Hem.) %2d\n", isec1[43]);
- fprintf(grprsm, " Diagnostic number %9d\n", isec1[44]);
- }
- /*
- ECMWF Local definition 8.
- (ECMWF re-analysis data)
- */
- if ( isec1[36] == 8 )
- {
- if ( (isec1[39] == 1043) ||
- (isec1[39] == 1070) ||
- (isec1[39] == 1071) )
- {
- fprintf(grprsm, " Interval between reference times %9d\n", isec1[41]);
- for (jloop = 43; jloop <= 54; jloop++)
- {
- jiloop = jloop + 8;
- fprintf(grprsm, " ERA section 1 octet %2d. %9d\n",
- jiloop, isec1[jloop-1]);
- }
- }
- else
- {
- for (jloop = 42; jloop <= 54; jloop++)
- {
- jiloop = jloop + 8;
- fprintf(grprsm, " ERA section 1 octet %2d. %9d\n",
- jiloop, isec1[jloop-1]);
- }
- }
- return;
- }
-
- if ( isec1[38] > 4 && isec1[38] < 9 )
- {
- fprintf(grprsm, " Simulation number. %9d\n", isec1[41]);
- fprintf(grprsm, " Total number of simulations. %9d\n", isec1[42]);
- }
- /*
- ECMWF Local definition 9.
- (Singular vectors and ensemble perturbations)
- */
- if ( isec1[36] == 9 )
- {
- if ( isec1[38] == 60 )
- fprintf(grprsm, " Perturbed ensemble forecast number %9d\n", isec1[41]);
- if ( isec1[38] == 61 )
- fprintf(grprsm, " Initial state perturbation number %9d\n", isec1[41]);
- if ( isec1[38] == 62 )
- fprintf(grprsm, " Singular vector number %9d\n", isec1[41]);
- if ( isec1[38] == 62 )
- {
- fprintf(grprsm, " Number of iterations %9d\n", isec1[42]);
- fprintf(grprsm, " Number of singular vectors computed %9d\n", isec1[43]);
- fprintf(grprsm, " Norm used at initial time %9d\n", isec1[44]);
- fprintf(grprsm, " Norm used at final time %9d\n", isec1[45]);
- fprintf(grprsm, " Multiplication factor %9d\n", isec1[46]);
- fprintf(grprsm, " Latitude of north-west corner %9d\n", isec1[47]);
- fprintf(grprsm, " Longitude of north-west corner %9d\n", isec1[48]);
- fprintf(grprsm, " Latitude of south-east corner %9d\n", isec1[49]);
- fprintf(grprsm, " Longitude of south-east corner %9d\n", isec1[50]);
- fprintf(grprsm, " Accuracy %9d\n", isec1[51]);
- fprintf(grprsm, " Number of singular vectors evolved %9d\n", isec1[52]);
- fprintf(grprsm, " Ritz number one %9d\n", isec1[53]);
- fprintf(grprsm, " Ritz number two %9d\n", isec1[54]);
- }
- }
- /*
- ECMWF Local definition 10.
- (EPS tubes)
- */
- if ( isec1[36] == 10 )
- {
- fprintf(grprsm, " Tube number %9d\n", isec1[41]);
- fprintf(grprsm, " Total number of tubes %9d\n", isec1[42]);
- fprintf(grprsm, " Central cluster definition %9d\n", isec1[43]);
- fprintf(grprsm, " Parameter %9d\n", isec1[44]);
- fprintf(grprsm, " Type of level %9d\n", isec1[45]);
- fprintf(grprsm, " Northern latitude of domain of tubing%9d\n", isec1[46]);
- fprintf(grprsm, " Western longitude of domain of tubing%9d\n", isec1[47]);
- fprintf(grprsm, " Southern latitude of domain of tubing%9d\n", isec1[48]);
- fprintf(grprsm, " Eastern longitude of domain of tubing%9d\n", isec1[49]);
- fprintf(grprsm, " Tube number of operational forecast %9d\n", isec1[50]);
- fprintf(grprsm, " Tube number of control forecast %9d\n", isec1[51]);
- fprintf(grprsm, " Height/pressure of level %9d\n", isec1[52]);
- fprintf(grprsm, " Reference step %9d\n", isec1[53]);
- fprintf(grprsm, " Radius of central cluster %9d\n", isec1[54]);
- fprintf(grprsm, " Ensemble standard deviation %9d\n", isec1[55]);
- fprintf(grprsm, " Dist.of tube extreme to ensemble mean%9d\n", isec1[56]);
- fprintf(grprsm, " Number of forecasts in the tube %9d\n", isec1[57]);
-
- fprintf(grprsm, " List of ensemble forecast numbers:\n");
- for (jloop = 1; jloop <= isec1[57]; jloop++)
- fprintf(grprsm, " %9d\n", isec1[57+jloop]);
- }
- /*
- ECMWF Local definition 11.
- (Supplementary data used by the analysis)
- */
- if ( isec1[36] == 11 )
- {
- fprintf(grprsm, " Details of analysis which used the supplementary data:\n");
- fprintf(grprsm, " Class %9d\n", isec1[41]);
- fprintf(grprsm, " Type %9d\n", isec1[42]);
- fprintf(grprsm, " Stream %9d\n", isec1[43]);
- /*
- sprintf(hversion, "%8d", isec1[44]);
- fprintf(grprsm, " Version number/experiment identifier: %4s\n", &hversion[4]);
- */
- iyear = isec1[45];
- if ( iyear > 50 )
- iyear = iyear + 1900;
- else
- iyear = iyear + 2000;
-
- fprintf(grprsm, " Year %9d\n", iyear);
- fprintf(grprsm, " Month %9d\n", isec1[46]);
- fprintf(grprsm, " Day %9d\n", isec1[47]);
- fprintf(grprsm, " Hour %9d\n", isec1[48]);
- fprintf(grprsm, " Minute %9d\n", isec1[49]);
- fprintf(grprsm, " Century %9d\n", isec1[50]);
- fprintf(grprsm, " Originating centre %9d\n", isec1[51]);
- fprintf(grprsm, " Sub-centre %9d\n", isec1[52]);
- }
- /*
- ECMWF Local definition 12.
- */
- if ( isec1[36] == 12 )
- {
- fprintf(grprsm, " (Mean, average, etc)\n");
- fprintf(grprsm, " Start date of the period %8d\n", isec1[41]);
- fprintf(grprsm, " Start time of the period %4.4d\n", isec1[42]);
- fprintf(grprsm, " Finish date of the period %8d\n", isec1[43]);
- fprintf(grprsm, " Finish time of the period %4.4d\n", isec1[44]);
- fprintf(grprsm, " Verifying date of the period %8d\n", isec1[45]);
- fprintf(grprsm, " Verifying time of the period %4.4d\n", isec1[46]);
- fprintf(grprsm, " Code showing method %8d\n", isec1[47]);
- fprintf(grprsm, " Number of different time intervals used %5d\n", isec1[48]);
- fprintf(grprsm, " List of different time intervals used:\n");
- iprev = isec1[49];
- unsigned icount = 0;
- for (jloop = 1; jloop <= isec1[48]; jloop++)
- {
- icurr = isec1[48+jloop];
- if ( icurr != iprev )
- {
- if ( icount == 1 )
- fprintf(grprsm, " - interval %5.4d used once\n", iprev);
- if ( icount == 2 )
- fprintf(grprsm, " - interval %5.4d used twice\n", iprev);
- if ( icount > 2 )
- fprintf(grprsm, " - interval %5.4d used %5u times\n", iprev, icount);
- iprev = icurr;
- icount = 1;
- }
- else
- icount = icount + 1;
- }
- if ( icount == 1 )
- fprintf(grprsm, " - interval %5.4d used once\n", iprev);
- if ( icount == 2 )
- fprintf(grprsm, " - interval %5.4d used twice\n", iprev);
- if ( icount > 2 )
- fprintf(grprsm, " - interval %5.4d used %5u times\n", iprev, icount);
- }
- /*
- ECMWF Local definition 13.
- (Wave 2D spectra direction and frequency)
- */
- if ( isec1[36] == 13 )
- {
- fprintf(grprsm, " Direction number %9d\n", isec1[43]);
- fprintf(grprsm, " Frequency number %9d\n", isec1[44]);
- fprintf(grprsm, " Total number of directions %9d\n", isec1[45]);
- fprintf(grprsm, " Total number of frequencies %9d\n", isec1[46]);
- fprintf(grprsm, " Scale factor applied to directions %9d\n", isec1[47]);
- fprintf(grprsm, " Scale factor applied to frequencies %9d\n", isec1[48]);
- fprintf(grprsm, " List of directions:\n");
- for (jloop = 1; jloop <= isec1[45]; jloop++)
- {
- value = (float)(isec1[48+jloop])/(float)(isec1[47]);
- if ( isec1[43] == jloop )
- fprintf(grprsm, " %2.2d:%15.7f <-- this field value\n", jloop, value);
- else
- fprintf(grprsm, "%2.2d:%15.7f\n", jloop, value);
- }
- fprintf(grprsm, " List of frequencies:\n");
- for (jloop = 1; jloop <= isec1[46]; jloop++)
- {
- value = (float)(isec1[48+isec1[45]+jloop])/(float)(isec1[48]);
- if ( isec1[44] == jloop )
- fprintf(grprsm, " %2.2d:%15.7f <-- this field value\n", jloop, value);
- else
- fprintf(grprsm, "%2.2d:%15.7f\n", jloop, value);
-
- if ( isec1[49+isec1[45]+isec1[46]] != 0 )
- {
- fprintf(grprsm, " System number (65535 = missing) %9d\n",
- isec1[49+isec1[45]+isec1[46]]);
- fprintf(grprsm, " Method number (65535 = missing) %9d\n",
- isec1[50+isec1[45]+isec1[46]]);
- }
- }
- /*
- ECMWF Local definition 14.
- (Brightness temperature)
- */
- if ( isec1[36] == 14 )
- {
- fprintf(grprsm, " Channel number %9d\n", isec1[43]);
- fprintf(grprsm, " Scale factor applied to frequencies %9d\n", isec1[44]);
- fprintf(grprsm, " Total number of frequencies %9d\n", isec1[45]);
- fprintf(grprsm, " List of frequencies:\n");
- for (jloop = 1; jloop <= isec1[45]; jloop++)
- {
- value = (float)(isec1[45+jloop])/(float)(isec1[44]);
- if ( isec1[43] == jloop )
- fprintf(grprsm, " %3d:%15.9f <-- this channel\n", jloop, value);
- else
- fprintf(grprsm, " %3d:%15.9f\n", jloop, value);
- }
- }
- /*
- ECMWF Local definition 15.
- (Ocean ensemble seasonal forecast)
- */
- if ( isec1[36] == 15 )
- {
- fprintf(grprsm, " Ensemble member number %9d\n", isec1[41]);
- fprintf(grprsm, " System number %9d\n", isec1[42]);
- fprintf(grprsm, " Method number %9d\n", isec1[43]);
- }
- /*
- ECMWF Local definition 16.
- (Seasonal forecast monthly mean atmosphere data)
- */
- if ( isec1[36] == 16 )
- {
- fprintf(grprsm, " Ensemble member number %9d\n", isec1[41]);
- fprintf(grprsm, " System number %9d\n", isec1[43]);
- fprintf(grprsm, " Method number %9d\n", isec1[44]);
- fprintf(grprsm, " Verifying month %9d\n", isec1[45]);
- fprintf(grprsm, " Averaging period %9d\n", isec1[46]);
- }
- /*
- ECMWF Local definition 17.
- (Sst or sea-ice used by analysis)
- */
- if ( isec1[36] == 17 )
- {
- iyear = isec1[43];
- if ( iyear > 100 )
- {
- if ( iyear < 19000000 ) iyear = iyear + 19000000;
- fprintf(grprsm, " Date of sst/ice field used %9d\n", iyear);
- }
- else
- fprintf(grprsm, " Date of sst/ice field used Not given\n");
-
- if ( isec1[44] == 0 )
- fprintf(grprsm, " Type of sst/ice field (= climatology)%9d\n", isec1[44]);
- if ( isec1[44] == 1 )
- fprintf(grprsm, " Type of sst/ice field (= 1/1 degree) %9d\n", isec1[44]);
- if ( isec1[44] == 2 )
- fprintf(grprsm, " Type of sst/ice field (= 2/2 degree) %9d\n", isec1[44]);
-
- fprintf(grprsm, " Number of ICE fields used: %9d\n", isec1[45]);
-
- for (jloop = 1; jloop < isec1[45]; jloop++)
- {
- iyear = isec1[44+(jloop*2)];
- if ( iyear > 100 )
- {
- if ( iyear < 19000000 ) iyear = iyear + 19000000;
- fprintf(grprsm, " Date of ICE field%3d %9d\n", jloop,
- iyear);
- fprintf(grprsm, " Satellite number (ICE field%3d) %9d\n", jloop,
- isec1[45+(jloop*2)]);
- }
- else
- fprintf(grprsm, "Date of sst/ice field used Not given\n");
- }
- }
- }
- }
- /*
- -----------------------------------------------------------------
- Section 3 . Print Washington ensemble product information.
- -----------------------------------------------------------------
- */
- /*
- Washington EPS products (but not reformatted Washington EPS
- products.
- */
- if ( (isec1[1] == 7 && isec1[23] == 1) && (! (ISEC1_SubCenterID == 98)) )
- {
- /* CALL KWPRS1 (iSEC0,iSEC1)*/
- }
- /*
- -----------------------------------------------------------------
- Section 4 . Print local MPIM information.
- -----------------------------------------------------------------
- */
- if (isec1[ 1] == 252 && isec1[36] == 1)
- {
- fprintf(grprsm, " MPIM local usage identifier. %9d\n", isec1[36]);
- fprintf(grprsm, " Type of ensemble forecast %9d\n", isec1[37]);
- fprintf(grprsm, " Individual ensemble member %9d\n", isec1[38]);
- fprintf(grprsm, " Number of forecasts in ensemble %9d\n", isec1[39]);
- }
-}
-
-void printQuasi(int *isec2)
-{
- /*
-
- Print the qusai-regular information in the Grid Description
- Section (Section 2) of decoded GRIB data.
-
- Input Parameters:
-
- isec2 - Array of decoded integers from Section 2.
-
- Comments:
-
- Only data representation types catered for are Gaussian
- grid, latitude/longitude grid, Spherical Harmonics,
- Polar stereographic and Space view perspective.
-
- Converted from EMOS routine PTQUASI.
-
- Uwe Schulzweida MPIfM 01/04/2001
-
- */
-
- char yout[64];
- int nextlat, latcnt;
- int j;
- int ntos;
-
- /*
- -----------------------------------------------------------------
- Section 1. Print quasi-grid data.
- -----------------------------------------------------------------
- */
- /*
- See if scanning is north->south or south->north
- */
- fprintf(grprsm, " Number of points along a parallel varies.\n");
-
- ntos = ( fmod((double) isec2[10], 128.) < 64 );
-
- if ( ntos )
- fprintf(grprsm, " Number of points. Parallel. (North to South)\n");
- else
- fprintf(grprsm, " Number of points. Parallel. (South to North)\n");
-
- /* Display number of points for each latitude */
- latcnt = isec2[2];
- nextlat = 0;
- memset(yout, ' ', (size_t) 11);
-
- for ( j = 0; j < latcnt; j++ )
- {
- nextlat = nextlat + 1;
- sprintf(yout, "%4d", nextlat);
-
- /* Finished? */
- if ( nextlat > latcnt ) break;
- if ( nextlat == latcnt )
- {
- fprintf(grprsm, " %5d %-12s\n", isec2[nextlat+21], yout);
- break;
- }
- /*
- Look for neighbouring latitudes with same number of points
- */
- unsigned nrepeat = 0;
-
- LABEL110:
- /*
- If neighbouring latitudes have same number of points
- increase the repeat count.
- */
- if ( isec2[nextlat+21+1] == isec2[nextlat+21] )
- {
- nrepeat = nrepeat + 1;
- nextlat = nextlat + 1;
- if ( nextlat < latcnt ) goto LABEL110;
- }
- /*
- Display neighbouring latitudes with same number of points as
- 'nn to mm'.
- */
- if ( nrepeat >= 1 )
- {
- strncpy(yout+4, " to", 3);
- sprintf(yout+7, "%5d", nextlat);
- }
- fprintf(grprsm, " %5d %-12s\n", isec2[nextlat+21], yout);
- memset(yout, ' ', (size_t) 11);
- }
-}
-
-void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2)
-{
- /*
-
- Print the information in the Grid Description
- Section (Section 2) of decoded GRIB data.
-
- Input Parameters:
-
- isec0 - Array of decoded integers from Section 0
-
- isec2 - Array of decoded integers from Section 2
-
- fsec2 - Array of decoded floats from Section 2
-
- Comments:
-
- Only data representation types catered for are Gaussian
- grid, latitude/longitude grid, Spherical Harmonics,
- Polar stereographic and Space view perspective.
-
-
- Converted from EMOS routine GRPRS2.
-
- Uwe Schulzweida MPIfM 01/04/2001
-
- */
-
- int i, ibit, iedit, ierr, iout, iresol;
-
- grsdef();
- /*
- -----------------------------------------------------------------
- Section 1 . Print GRIB Edition number.
- -----------------------------------------------------------------
- */
- iedit = isec0[1];
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Section 2 - Grid Description Section.\n");
- fprintf(grprsm, " -------------------------------------\n");
- /*
- -----------------------------------------------------------------
- Section 2 . Print spherical harmonic data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 50 || isec2[0] == 60 ||
- isec2[0] == 70 || isec2[0] == 80 )
- {
- fprintf(grprsm, " Data represent type = spectral (Table 6) %9d\n", isec2[0]);
- fprintf(grprsm, " J - Pentagonal resolution parameter. %9d\n", isec2[1]);
- fprintf(grprsm, " K - Pentagonal resolution parameter. %9d\n", isec2[2]);
- fprintf(grprsm, " M - Pentagonal resolution parameter. %9d\n", isec2[3]);
- fprintf(grprsm, " Representation type (Table 9) %9d\n", isec2[4]);
- fprintf(grprsm, " Representation mode (Table 10). %9d\n", isec2[5]);
- for (i = 7; i <= 11; i++)
- fprintf(grprsm, " Not used. %9d\n", isec2[i-1]);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 3 . Print Gaussian grid data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 4 || isec2[0] == 14 ||
- isec2[0] == 24 || isec2[0] == 34 )
- {
- fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
- fprintf(grprsm, " Data represent type = gaussian (Table 6) %9d\n", isec2[0]);
- /*
- Quasi-regular grids introduced in Edition 1.
- */
- if ( isec2[16] == 0 || iedit < 1 )
- fprintf(grprsm, " Number of points along a parallel. %9d\n", isec2[1]);
- else
- printQuasi(isec2);
-
- fprintf(grprsm, " Number of points along a meridian. %9d\n", isec2[2]);
- fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
- fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
-
- ibit = 8;
- iresol = isec2[5] + isec2[17] + isec2[18];
- prtbin(iresol, ibit, &iout, &ierr);
-
- fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
- fprintf(grprsm, " Latitude of last grid point. %9d\n", isec2[6]);
- fprintf(grprsm, " Longitude of last grid point. %9d\n", isec2[7]);
- /*
- Print increment if given.
- */
- if ( isec2[5] == 128 )
- fprintf(grprsm, " i direction (East-West) increment. %9d\n", isec2[8]);
- else
- fprintf(grprsm, " i direction (East-West) increment Not given\n");
-
- fprintf(grprsm, " Number of parallels between pole and equator.%9d\n", isec2[9]);
-
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
-
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 4 . Print Latitude / longitude grid data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 0 || isec2[0] == 10 ||
- isec2[0] == 20 || isec2[0] == 30 )
- {
- fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
- fprintf(grprsm, " Data represent type = lat/long (Table 6) %9d\n", isec2[0]);
- /*
- Quasi-regular lat/long grids also possible.
- */
- if ( isec2[16] == 0 )
- fprintf(grprsm, " Number of points along a parallel. %9d\n", isec2[1]);
- else
- printQuasi(isec2);
-
- fprintf(grprsm, " Number of points along a meridian. %9d\n", isec2[2]);
- fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
- fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
-
- ibit = 8;
- iresol = isec2[5] + isec2[17] + isec2[18];
- prtbin(iresol, ibit, &iout, &ierr);
-
- fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
- fprintf(grprsm, " Latitude of last grid point. %9d\n", isec2[6]);
- fprintf(grprsm, " Longitude of last grid point. %9d\n", isec2[7]);
- /*
- Print increment if given.
- */
- if ( isec2[8] < 0 )
- fprintf(grprsm, " i direction (East-West) increment Not given\n");
- else
- fprintf(grprsm, " i direction (East-West) increment. %9d\n", isec2[8]);
-
- if ( isec2[9] < 0 )
- fprintf(grprsm, " j direction (North-South) increment Not given\n");
- else
- fprintf(grprsm, " j direction (North-South) increment. %9d\n", isec2[9]);
-
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
-
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 5 . Print polar stereographic data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 5 )
- {
- fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
- fprintf(grprsm, " Data represent type = polar stereo (Table 6) %9d\n", isec2[0]);
- fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
- fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
- fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
- fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
- ibit = 8;
- iresol = isec2[17] + isec2[18];
- prtbin(iresol, ibit, &iout, &ierr);
- fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
- fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
- fprintf(grprsm, " X direction increment. %9d\n", isec2[8]);
- fprintf(grprsm, " Y direction increment. %9d\n", isec2[9]);
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- fprintf(grprsm, " Projection centre flag. %9d\n", isec2[12]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 6 . Print Lambert conformal data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 3 )
- {
- fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
- fprintf(grprsm, " Data represent type = Lambert (Table 6) %9d\n", isec2[0]);
- fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
- fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
- fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
- fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
- ibit = 8;
- iresol = isec2[17] + isec2[18] + isec2[5];
- prtbin(iresol, ibit, &iout, &ierr);
- fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
- fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
- fprintf(grprsm, " X direction increment. %9d\n", isec2[8]);
- fprintf(grprsm, " Y direction increment. %9d\n", isec2[9]);
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- fprintf(grprsm, " Projection centre flag. %9d\n", isec2[12]);
- fprintf(grprsm, " Latitude intersection 1 - Latin 1 -. %9d\n", isec2[13]);
- fprintf(grprsm, " Latitude intersection 2 - Latin 2 -. %9d\n", isec2[14]);
- fprintf(grprsm, " Latitude of Southern Pole. %9d\n", isec2[19]);
- fprintf(grprsm, " Longitude of Southern Pole. %9d\n", isec2[20]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 7 . Print space view perspective or orthographic data.
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 90 )
- {
- fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
- fprintf(grprsm, " Data represent type = space/ortho (Table 6) %9d\n", isec2[0]);
- fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
- fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
- fprintf(grprsm, " Latitude of sub-satellite point. %9d\n", isec2[3]);
- fprintf(grprsm, " Longitude of sub-satellite point. %9d\n", isec2[4]);
- //iresol = isec2[17] + isec2[18];
- fprintf(grprsm, " Diameter of the earth in x direction. %9d\n", isec2[6]);
- fprintf(grprsm, " Y coordinate of sub-satellite point. %9d\n", isec2[9]);
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
- fprintf(grprsm, " Altitude of the camera. %9d\n", isec2[13]);
- fprintf(grprsm, " Y coordinate of origin of sector image. %9d\n", isec2[14]);
- fprintf(grprsm, " X coordinate of origin of sector image. %9d\n", isec2[15]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Section 7.5 . Print ocean data
- -----------------------------------------------------------------
- */
- /*
- if ( isec2[0] == 192 && ISEC1_CenterID == 98 )
- {
- fprintf(grprsm, " Data represent type = ECMWF ocean (Table 6) %9d\n", isec2[0]);
- if ( isec2[1] == 32767 )
- fprintf(grprsm, " Number of points along the first axis. Not used\n");
- else
- fprintf(grprsm, " Number of points along the first axis. %9d\n", isec2[1]);
-
- if ( isec2[2] == 32767 )
- fprintf(grprsm, " Number of points along the second axis. Not used\n");
- else
- fprintf(grprsm, " Number of points along the second axis. %9d\n", isec2[2]);
-
- ibit = 8;
- prtbin(isec2[10], ibit, &iout, &ierr);
- fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
- goto LABEL800;
- }
- */
- /*
- -----------------------------------------------------------------
- Section 7.6 . Print triangular data
- -----------------------------------------------------------------
- */
- if ( isec2[0] == 192 /* && ISEC1_CenterID == 78 */ )
- {
- fprintf(grprsm, " Data represent type = triangular (Table 6) %9d\n", isec2[0]);
- fprintf(grprsm, " Number of factor 2 in factorisation of Ni. %9d\n", isec2[1]);
- fprintf(grprsm, " Number of factor 3 in factorisation of Ni. %9d\n", isec2[2]);
- fprintf(grprsm, " Number of diamonds (Nd). %9d\n", isec2[3]);
- fprintf(grprsm, " Number of triangular subdivisions of the\n");
- fprintf(grprsm, " icosahedron (Ni). %9d\n", isec2[4]);
- fprintf(grprsm, " Flag for orientation of diamonds (Table A). %9d\n", isec2[5]);
- fprintf(grprsm, " Latitude of pole point. %9d\n", isec2[6]);
- fprintf(grprsm, " Longitude of pole point. %9d\n", isec2[7]);
- fprintf(grprsm, " Longitude of the first diamond. %9d\n", isec2[8]);
- fprintf(grprsm, " Flag for storage sequence (Table B). %9d\n", isec2[9]);
- fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
- goto LABEL800;
- }
- /*
- -----------------------------------------------------------------
- Drop through to here => representation type not catered for.
- -----------------------------------------------------------------
- */
- fprintf(grprsm, "GRPRS2 :Data representation type not catered for -%d\n", isec2[0]);
-
- goto LABEL900;
- /*
- -----------------------------------------------------------------
- Section 8 . Print vertical coordinate parameters,
- rotated grid information,
- stretched grid information, if any.
- -----------------------------------------------------------------
- */
- LABEL800:;
- /*
- Vertical coordinate parameters ...
- */
- if ( isec2[11] != 0 )
- {
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Vertical Coordinate Parameters.\n");
- fprintf(grprsm, " -------------------------------\n");
- for ( i = 10; i < isec2[11]+10; i++ )
- fprintf(grprsm, " %20.12f\n", fsec2[i]);
- }
- /*
- Rotated and stretched grids introduced in Edition 1.
- */
- if ( iedit < 1 ) goto LABEL900;
- /*
- Rotated grid information ...
- */
- if ( isec2[0] == 10 || isec2[0] == 30 ||
- isec2[0] == 14 || isec2[0] == 34 ||
- isec2[0] == 60 || isec2[0] == 80 ||
- isec2[0] == 30 )
- {
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Latitude of southern pole of rotation. %9d\n", isec2[12]);
- fprintf(grprsm, " Longitude of southern pole of rotation. %9d\n", isec2[13]);
- fprintf(grprsm, " Angle of rotation. %20.10f\n", fsec2[0]);
- }
- /*
- Stretched grid information ...
- */
- if ( isec2[0] == 20 || isec2[0] == 30 ||
- isec2[0] == 24 || isec2[0] == 34 ||
- isec2[0] == 70 || isec2[0] == 80 )
- {
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Latitude of pole of stretching. %9d\n", isec2[14]);
- fprintf(grprsm, " Longitude of pole of stretching. %9d\n", isec2[15]);
- fprintf(grprsm, " Stretching factor. %20.10f\n", fsec2[1]);
- }
-
- LABEL900:;
-
- return;
-}
-
-void gribPrintSec2SP(int *isec0, int *isec2, float *fsec2sp)
-{
- int inum;
- int j;
- double *fsec2;
-
- inum = 10 + isec2[11];
-
- fsec2 = (double*) Malloc((size_t)inum*sizeof(double));
- if ( fsec2 == NULL ) SysError("No Memory!");
-
- for ( j = 0; j < inum; j++ )
- fsec2[j] = fsec2sp[j];
-
- gribPrintSec2DP(isec0, isec2, fsec2);
-
- Free(fsec2);
-}
-
-void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3)
-{
- /*
-
- Print the information in the Bit-Map Section
- (Section 3) of decoded GRIB data.
-
- Input Parameters:
-
- isec0 - Array of decoded integers from Section 0
-
- isec3 - Array of decoded integers from Section 3
-
- fsec3 - Array of decoded floats from Section 3
-
-
- Converted from EMOS routine GRPRS3.
-
- Uwe Schulzweida MPIfM 01/04/2001
-
- */
-
- UNUSED(isec0);
-
- grsdef();
-
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Section 3 - Bit-map Section.\n");
- fprintf(grprsm, " -------------------------------------\n");
-
- if ( isec3[0] != 0 )
- fprintf(grprsm, " Predetermined bit-map number. %9d\n", isec3[0]);
- else
- fprintf(grprsm, " No predetermined bit-map.\n");
-
- fprintf(grprsm, " Missing data value for integer data. %14d\n", isec3[1]);
-
- fprintf(grprsm, " Missing data value for real data. %20.6g\n", fsec3[1]);
-}
-
-void gribPrintSec3SP(int *isec0, int *isec3, float *fsec3sp)
-{
- double fsec3[2];
-
- fsec3[0] = fsec3sp[0];
- fsec3[1] = fsec3sp[1];
-
- gribPrintSec3DP(isec0, isec3, fsec3);
-}
-
-void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4)
-{
- /*
-
- Print the information in the Binary Data Section
- (Section 4) of decoded GRIB data.
-
- Input Parameters:
-
- isec0 - Array of decoded integers from Section 0
-
- isec4 - Array of decoded integers from Section 4
-
- fsec4 - Array of decoded floats from Section 4
-
-
- Converted from EMOS routine GRPRS4.
-
- Uwe Schulzweida MPIfM 01/04/2001
-
- */
- int inum;
- int j;
-
- UNUSED(isec0);
-
- grsdef();
-
- /*
- -----------------------------------------------------------------
- Section 1 . Print integer information from isec4.
- -----------------------------------------------------------------
- */
- fprintf(grprsm, " \n");
- fprintf(grprsm, " Section 4 - Binary Data Section.\n");
- fprintf(grprsm, " -------------------------------------\n");
-
- fprintf(grprsm, " Number of data values coded/decoded. %9d\n", isec4[0]);
- fprintf(grprsm, " Number of bits per data value. %9d\n", isec4[1]);
- fprintf(grprsm, " Type of data (0=grid pt, 128=spectral).%9d\n", isec4[2]);
- fprintf(grprsm, " Type of packing (0=simple, 64=complex). %9d\n", isec4[3]);
- fprintf(grprsm, " Type of data (0=float, 32=integer). %9d\n", isec4[4]);
- fprintf(grprsm, " Additional flags (0=none, 16=present). %9d\n", isec4[5]);
- fprintf(grprsm, " Reserved. %9d\n", isec4[6]);
- fprintf(grprsm, " Number of values (0=single, 64=matrix). %9d\n", isec4[7]);
- fprintf(grprsm, " Secondary bit-maps (0=none, 32=present). %9d\n", isec4[8]);
- fprintf(grprsm, " Values width (0=constant, 16=variable).%9d\n", isec4[9]);
- /*
- If complex packing ..
- */
- if ( isec4[3] == 64 )
- {
- if ( isec4[2] == 128 )
- {
- fprintf(grprsm, " Byte offset of start of packed data (N). %9d\n", isec4[15]);
- fprintf(grprsm, " Power (P * 1000). %9d\n", isec4[16]);
- fprintf(grprsm, " Pentagonal resolution parameter J for subset.%9d\n", isec4[17]);
- fprintf(grprsm, " Pentagonal resolution parameter K for subset.%9d\n", isec4[18]);
- fprintf(grprsm, " Pentagonal resolution parameter M for subset.%9d\n", isec4[19]);
- }
- else
- {
- fprintf(grprsm, " Bits number of 2nd order values (none=>0).%9d\n", isec4[10]);
- fprintf(grprsm, " General extend. 2-order packing (0=no,8=yes).%9d\n", isec4[11]);
- fprintf(grprsm, " Boustrophedonic ordering (0=no,4=yes).%9d\n", isec4[12]);
- fprintf(grprsm, " Spatial differencing order (0=none).%9d\n", isec4[13]+isec4[14]);
- }
- }
- /*
- Number of non-missing values
- */
- if ( isec4[20] != 0 )
- fprintf(grprsm, " Number of non-missing values %9d\n", isec4[20]);
- /*
- Information on matrix of values , if present.
- */
- if ( isec4[7] == 64 )
- {
- fprintf(grprsm, " First dimension (rows) of each matrix. %9d\n", isec4[49]);
- fprintf(grprsm, " Second dimension (columns) of each matrix. %9d\n", isec4[50]);
- fprintf(grprsm, " First dimension coordinate values definition.%9d\n", isec4[51]);
- fprintf(grprsm, " (Code Table 12)\n");
- fprintf(grprsm, " NC1 - Number of coefficients for 1st dimension.%7d\n", isec4[52]);
- fprintf(grprsm, " Second dimension coordinate values definition.%8d\n", isec4[53]);
- fprintf(grprsm, " (Code Table 12)\n");
- fprintf(grprsm, " NC2 - Number of coefficients for 2nd dimension.%7d\n", isec4[54]);
- fprintf(grprsm, " 1st dimension physical signifance (Table 13). %8d\n", isec4[55]);
- fprintf(grprsm, " 2nd dimension physical signifance (Table 13).%8d\n", isec4[56]);
- }
- /*
- -----------------------------------------------------------------
- Section 2. Print values from fsec4.
- -----------------------------------------------------------------
- */
-
- inum = isec4[0];
- if ( inum < 0 ) inum = - inum;
- if ( inum > 20 ) inum = 20;
- /*
- Print first inum values.
- */
- fprintf(grprsm, " \n");
- fprintf(grprsm, " First %4d data values.\n", inum);
-
- if ( isec4[4] == 0 )
- {
- /*
- Print real values ...
- */
- for ( j = 0; j < inum; j++ )
- {
- if ( fabs(fsec4[j]) > 0 )
- {
- if ( fabs(fsec4[j]) >= 0.1 && fabs(fsec4[j]) <= 1.e8 )
- fprintf(grprsm, " %#16.8G \n", fsec4[j]);
- else
- fprintf(grprsm, " %#20.8E\n", fsec4[j]);
- }
- else
- fprintf(grprsm, " %#16.0f \n", fabs(fsec4[j]));
- }
- }
- else
- {
- /*
- Print integer values ...
- */
- fprintf(grprsm, " Print of integer values not supported\n");
- /*
- CALL SETPAR(IBIT,IDUM,IDUM)
- DO 212 J=1,INUM
- INSPT = 0
- CALL INXBIT(IVALUE,1,INSPT,FSEC4(J),1,IBIT,IBIT,'C',IRET)
- WRITE (*,9033) IVALUE
- 9033 FORMAT(' ',I15)
- 212 CONTINUE
- ENDIF
- */
- }
-}
-
-void gribPrintSec4SP(int *isec0, int *isec4, float *fsec4sp)
-{
- int inum;
- int j;
- double fsec4[20];
-
- inum = isec4[0];
- if ( inum < 0 ) inum = -inum;
- if ( inum > 20 ) inum = 20;
-
- for ( j = 0; j < inum; j++ ) fsec4[j] = fsec4sp[j];
-
- gribPrintSec4DP(isec0, isec4, fsec4);
-}
-
-void gribPrintSec4Wave(int *isec4)
-{
- /*
-
- Print the wave coordinate information in the Binary Data
- Section (Section 4) of decoded GRIB data.
-
- Input Parameters:
-
- isec4 - Array of decoded integers from Section 4
-
- Comments:
-
- Wave coordinate information held in isec4 are 32-bit floats,
- hence the PTEMP and NTEMP used for printing are 4-byte variables.
-
-
- Converted from EMOS routine GRPRS4W.
-
- Uwe Schulzweida MPIfM 01/04/2001
-
- */
- int jloop;
- int ntemp[100];
- float *ptemp;
-
- grsdef();
-
- /*
- -----------------------------------------------------------------
- Section 1 . Print integer information from isec4.
- -----------------------------------------------------------------
- */
- fprintf(grprsm, " Coefficients defining first dimension coordinates:\n");
- for ( jloop = 0; jloop < isec4[52]; jloop++ )
- {
- ntemp[jloop] = isec4[59 + jloop];
- ptemp = (float *) &ntemp[jloop];
- fprintf(grprsm, "%20.10f\n", *ptemp);
- }
- fprintf(grprsm, " Coefficients defining second dimension coordinates:\n");
- for ( jloop = 0; jloop < isec4[54]; jloop++ )
- {
- ntemp[jloop] = isec4[59 + isec4[52] + jloop];
- ptemp = (float *) &ntemp[jloop];
- fprintf(grprsm, "%20.10f\n", *ptemp);
- }
-}
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <string.h>
-#include <ctype.h>
-
-
-
-int gribOpen(const char *filename, const char *mode)
-{
- int fileID = fileOpen(filename, mode);
-
-#if defined (__sun)
- if ( fileID != FILE_UNDEFID && tolower(*mode) == 'r' )
- {
- fileSetBufferType(fileID, FILE_BUFTYPE_MMAP);
- }
-#endif
-
- return fileID;
-}
-
-
-void gribClose(int fileID)
-{
- fileClose(fileID);
-}
-
-
-off_t gribGetPos(int fileID)
-{
- return fileGetPos(fileID);
-}
-
-
-int gribCheckFiletype(int fileID)
-{
- int found = 0;
- char buffer[4];
-
- if ( fileRead(fileID, buffer, 4) != 4 ) return found;
-
- if ( memcmp(buffer, "GRIB", 4) == 0 )
- {
- found = 1;
- if ( CGRIBEX_Debug ) Message("found GRIB file = %s", fileInqName(fileID));
- }
- else
- {
- long offset;
- int ierr = gribFileSeek(fileID, &offset);
- fileRewind(fileID);
- if ( !ierr )
- {
- found = 1;
- if ( CGRIBEX_Debug ) Message("found seek GRIB file = %s", fileInqName(fileID));
- }
- }
-
- return found;
-}
-
-
-int gribCheckSeek(int fileID, long *offset, int *version)
-{
- int ierr = gribFileSeek(fileID, offset);
-
- *version = -1;
- if ( !ierr )
- {
- char buffer[4];
- if ( fileRead(fileID, buffer, 4) == 4 )
- *version = buffer[3];
- }
-
- return ierr;
-}
-
-
-int gribFileSeekOld(int fileID, long *offset)
-{
- /* position file pointer after GRIB */
- enum { buffersize = 4096 };
- unsigned char buffer[buffersize];
- int retry = 4096;
-
- *offset = 0;
-
- void *fileptr = filePtr(fileID);
-
- for ( size_t i = 0; i < 4; ++i)
- {
- int ch = filePtrGetc(fileptr);
- if ( ch == EOF ) return (-1);
- buffer[i] = (unsigned char)ch;
- }
- /*
- fileRead(fileID, buffer, 4);
- */
-
- while ( retry-- )
- {
- size_t i;
- for ( i = 0; i < buffersize-4; ++i )
- {
- if (buffer[i ] == 'G' &&
- buffer[i+1] == 'R' &&
- buffer[i+2] == 'I' &&
- buffer[i+3] == 'B')
- {
- if ( CGRIBEX_Debug )
- Message("record offset = %d", (int) *offset);
- return (0);
- }
- else
- {
- int ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[i+4] = (unsigned char)ch;
- (*offset)++;
- }
- }
- buffer[0] = buffer[i ];
- buffer[1] = buffer[i+1];
- buffer[2] = buffer[i+2];
- buffer[3] = buffer[i+3];
- }
-
- if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
-
- return 1;
-}
-
-
-int gribFileSeek(int fileID, long *offset)
-{
- /* position file pointer after GRIB */
- const long GRIB = 0x47524942;
- long code = 0;
- int ch;
- int retry = 4096*4096;
-
- *offset = 0;
-
- void *fileptr = filePtr(fileID);
-
- while ( retry-- )
- {
- ch = filePtrGetc(fileptr);
- if ( ch == EOF ) return (-1);
-
- code = ( (code << 8) + ch ) & 0xFFFFFFFF;
-
- if ( code == GRIB )
- {
- if ( CGRIBEX_Debug )
- Message("record offset = %d", (int) *offset);
- return (0);
- }
-
- (*offset)++;
- }
-
- if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
-
- return 1;
-}
-
-
-int gribFileSeekTest(int fileID, long *offset)
-{
- /* position file pointer after GRIB */
- const long GRIB = 0x47524942L;
- long code = 0;
- int ch;
- int i = 0;
- enum { buffersize = 8 };
- unsigned char buffer[buffersize];
- unsigned long retry = 4096L*4096L;
- int nread = 0;
-
- *offset = 0;
-
- void *fileptr = filePtr(fileID);
-
- while ( retry-- )
- {
- if ( i >= nread )
- {
- nread = (int) filePtrRead(fileptr, buffer, buffersize);
- if ( nread == 0 ) return (-1);
- i = 0;
- }
-
- ch = buffer[i++];
- code = ( (code << 8) + ch ) & 0xFFFFFFFFL;
-
- if ( code == GRIB )
- {
- /* printf("end: %d %d\n", nread, i); */
- if ( CGRIBEX_Debug )
- Message("record offset = %d", (int) *offset);
-
- if ( i != nread ) fileSetPos(fileID, (off_t) i-nread, SEEK_CUR);
-
- return (0);
- }
-
- (*offset)++;
- }
-
- if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
-
- return 1;
-}
-
-static inline int
-read3ByteMSBFirst(void *fileptr)
-{
- unsigned b1 = (unsigned)(filePtrGetc(fileptr));
- unsigned b2 = (unsigned)(filePtrGetc(fileptr));
- unsigned b3 = (unsigned)(filePtrGetc(fileptr));
- return (int)((b1 << 16) + (b2 << 8) + b3);
-}
-
-int gribReadSize(int fileID)
-{
- void *fileptr = filePtr(fileID);
- off_t pos = fileGetPos(fileID);
-
- unsigned b1 = (unsigned) filePtrGetc(fileptr);
- unsigned b2 = (unsigned) filePtrGetc(fileptr);
- unsigned b3 = (unsigned) filePtrGetc(fileptr);
-
- int gribsize = gribrec_len(b1, b2, b3);
- int gribversion = filePtrGetc(fileptr);
-
- if ( gribsize == 24 )
- {
- if ( gribversion != 1 && gribversion != 2 ) gribversion = 0;
- }
-
- if ( CGRIBEX_Debug )
- Message("gribversion = %d", gribversion);
-
- if ( gribversion == 0 )
- {
- int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
- int issize = 4, essize = 4;
- int flag = 0;
-
- pdssize = gribsize;
- fileSetPos(fileID, (off_t) 3, SEEK_CUR);
- if ( CGRIBEX_Debug ) Message("pdssize = %d", pdssize);
- flag = filePtrGetc(fileptr);
- if ( CGRIBEX_Debug ) Message("flag = %d", flag);
-
- fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
-
- if ( flag & 128 )
- {
- gdssize = read3ByteMSBFirst(fileptr);
- fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
- if ( CGRIBEX_Debug ) Message("gdssize = %d", gdssize);
- }
-
- if ( flag & 64 )
- {
- bmssize = read3ByteMSBFirst(fileptr);
- fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
- if ( CGRIBEX_Debug ) Message("bmssize = %d", bmssize);
- }
-
- bdssize = read3ByteMSBFirst(fileptr);
- if ( CGRIBEX_Debug ) Message("bdssize = %d", bdssize);
-
- gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
- }
- else if ( gribversion == 1 )
- {
- if ( gribsize > JP23SET ) /* Large GRIB record */
- {
- int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
- int issize = 4, essize = 4;
- int flag;
-
- pdssize = read3ByteMSBFirst(fileptr);
- if ( CGRIBEX_Debug ) Message("pdssize = %d", pdssize);
-
- for ( int i = 0; i < 5; ++i ) flag = filePtrGetc(fileptr);
- if ( CGRIBEX_Debug ) Message("flag = %d", flag);
-
- fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
-
- if ( flag & 128 )
- {
- gdssize = read3ByteMSBFirst(fileptr);
- fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
- if ( CGRIBEX_Debug ) Message("gdssize = %d", gdssize);
- }
-
- if ( flag & 64 )
- {
- bmssize = read3ByteMSBFirst(fileptr);
- fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
- if ( CGRIBEX_Debug ) Message("bmssize = %d", bmssize);
- }
-
- bdssize = read3ByteMSBFirst(fileptr);
- bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
- if ( CGRIBEX_Debug ) Message("bdssize = %d", bdssize);
-
- gribsize = issize+pdssize+gdssize+bmssize+bdssize+essize;
- }
- }
- else if ( gribversion == 2 )
- {
- int i;
- /* we set gribsize the following way because it doesn't matter then
- whether int is 4 or 8 bytes long - we don't have to care if the size
- really fits: if it does not, the record can not be read at all */
- gribsize = 0;
- for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | filePtrGetc(fileptr);
- }
- else
- {
- gribsize = 0;
- Warning("GRIB version %d unsupported!", gribversion);
- }
-
- if ( filePtrEOF(fileptr) ) gribsize = 0;
-
- if ( CGRIBEX_Debug )
- Message("gribsize = %d", gribsize);
-
- fileSetPos(fileID, pos, SEEK_SET);
-
- return gribsize;
-}
-
-
-int gribGetSize(int fileID)
-{
- long offset;
- int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
- if ( ierr > 0 )
- {
- Warning("GRIB record not found!");
- return (0);
- }
-
- if ( ierr == -1 ) return 0;
- else if ( ierr == 1 ) return 0;
-
- int recSize = gribReadSize(fileID);
-
- if ( CGRIBEX_Debug ) Message("recsize = %d", recSize);
-
- fileSetPos(fileID, (off_t) -4, SEEK_CUR);
-
- return recSize;
-}
-
-
-int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
-{
- long offset;
- int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
- if ( ierr > 0 )
- {
- Warning("GRIB record not found!");
- return (-2);
- }
-
- if ( ierr == -1 ) { *buffersize = 0; return -1; }
- else if ( ierr == 1 ) { *buffersize = 0; return -2; }
-
- size_t recSize = (size_t)gribReadSize(fileID);
- size_t readSize = recSize;
-
- if ( readSize > *buffersize )
- {
- readSize = *buffersize;
- ierr = -3; // Tell the caller that the buffer was insufficient.
- }
-
- *buffersize = recSize; // Inform the caller about the record size.
-
- // Write the stuff to the buffer that has already been read in gribFileSeek().
- buffer[0] = 'G';
- buffer[1] = 'R';
- buffer[2] = 'I';
- buffer[3] = 'B';
-
- readSize -= 4;
- // Read the rest of the record into the buffer.
- size_t nread = fileRead(fileID, &buffer[4], readSize);
-
- if ( nread != readSize ) ierr = 1;
-
- return ierr;
-}
-
-
-int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
-{
- int nwrite = 0;
-
- if ( (nwrite = (int)(fileWrite(fileID, buffer, buffersize))) != (int) buffersize )
- {
- perror(__func__);
- nwrite = -1;
- }
-
- return nwrite;
-}
-
-
-int gribrec_len(unsigned b1, unsigned b2, unsigned b3)
-{
- /*
- If bit 7 of b1 is set, we have to rescale by factor of 120.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- int needRescaling = b1 & (1 << 7);
-
- int gribsize = (int)((((b1&127) << 16)+(b2<<8) + b3));
-
- if ( needRescaling ) gribsize *= 120;
-
- return gribsize;
-}
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-
-FILE *grprsm = NULL;
-double fref;
-double fmaxval;
-int nfref;
-int nfmaxval;
-int nrnd;
-int ndbg;
-int nvck;
-int nonoff;
-int noabort;
-int num2ok;
-int next2o;
-int nloc2o;
-int nsubce;
-int grib_calendar = -1;
-
-
-void gribSetCalendar(int calendar)
-{
- grib_calendar = calendar;
-}
-
-
-void grsdef(void)
-{
- /*
-C---->
-C**** GRSDEF - Initial (default) setting of common area variables
-C for GRIBEX package.
-C
-C Purpose.
-C --------
-C
-C Sets initial values for common area variables for all
-C routines of GRIBEX package, if not already done.
-C
-C** Interface.
-C ----------
-C
-C CALL GRSDEF
-C
-C Input Parameters.
-C -----------------
-C
-C None.
-C
-C Output Parameters.
-C ------------------
-C
-C None.
-C
-C Method.
-C -------
-C
-C Self-explanatory.
-C
-C Externals.
-C ----------
-C
-C None.
-C
-C Reference.
-C ----------
-C
-C See subroutine GRIBEX.
-C
-C Comments.
-C ---------
-C
-C None
-C
-C Author.
-C -------
-C
-C J. Clochard, Meteo France, for ECMWF - March 1998.
-C
-C Modifications.
-C --------------
-C
-C J. Clochard, Meteo France, for ECMWF - June 1999.
-C Add variable NSUBCE.
-C Use a static variable to determine if initialisation has already
-C been done. NUSER removed .
-C Reverse defaults for NEXT2O and NLOC2O, for consistency with
-C version 13.023 of software .
-C
- */
- /*
-C ----------------------------------------------------------------
-C* Section 0 . Definition of variables.
-C ----------------------------------------------------------------
- */
- char *envString;
- char *env_stream;
- static int lfirst = TRUE;
- extern int CGRIBEX_Const;
-
- if ( ! lfirst ) return;
-
- /*
- ----------------------------------------------------------------
- Section 1 . Set values, conditionally.
- ----------------------------------------------------------------
- */
- /*
- Common area variables have not been set. Set them.
-
- User supplied reference value.
- */
- fref = 0.0;
- /*
- Reference value supplied by user flag. Set to off.
- */
- nfref = 0;
- /*
- User supplied maximum value.
- */
- fmaxval = 0.0;
- /*
- Maximum value supplied by user flag. Set to off.
- */
- nfmaxval = 0;
- /*
- Set rounding to 120 bytes on.
- */
- nrnd = 1;
- /*
- Set GRIB calendar.
- */
- if ( grib_calendar == -1 )
- {
- grib_calendar = CALENDAR_PROLEPTIC;
-
- envString = getenv("GRIB_CALENDAR");
- if ( envString )
- {
- if ( strncmp(envString, "standard", 8) == 0 )
- grib_calendar = CALENDAR_STANDARD;
- else if ( strncmp(envString, "proleptic", 9) == 0 )
- grib_calendar = CALENDAR_PROLEPTIC;
- else if ( strncmp(envString, "360days", 7) == 0 )
- grib_calendar = CALENDAR_360DAYS;
- else if ( strncmp(envString, "365days", 7) == 0 )
- grib_calendar = CALENDAR_365DAYS;
- else if ( strncmp(envString, "366days", 7) == 0 )
- grib_calendar = CALENDAR_366DAYS;
- else if ( strncmp(envString, "none", 4) == 0 )
- grib_calendar = CALENDAR_NONE;
- }
- }
- /*
- Set debug print off.
- */
- ndbg = 0;
-
- envString = getenv("GRIBEX_DEBUG");
- if ( envString != NULL )
- {
- if ( !strncmp(envString, "ON", 2) )
- ndbg = 1;
- else if( *envString == '1')
- ndbg = 1;
- else if( *envString == '2')
- ndbg = 2;
- else
- ndbg = 0;
- }
- /*
- Set GRIBEX compatibility mode.
- */
- envString = getenv("GRIB_GRIBEX_MODE_ON");
- if ( envString != NULL )
- {
- if ( atoi(envString) == 1 ) CGRIBEX_Const = 0;
- }
-
- /*
- Set GRIB value checking on.
- */
- nvck = 1;
-
- envString = getenv("GRIBEX_CHECK");
- if ( envString )
- {
- if ( !strncmp(envString, "OFF", 3) )
- nvck = 0;
- else
- nvck = 1;
- }
- /*
- See if output stream needs changing
- */
- grprsm = stdout;
- env_stream = getenv("GRPRS_STREAM");
- if ( env_stream )
- {
- if ( isdigit((int) env_stream[0]) )
- {
- int unit;
- unit = atoi(env_stream);
- if ( unit < 1 || unit > 99 )
- Warning("Invalid number for GRPRS_STREAM: %d", unit);
- else if ( unit == 2 )
- grprsm = stderr;
- else if ( unit == 6 )
- grprsm = stdout;
- else
- {
- char filename[] = "unit.00";
- sprintf(filename, "%2.2d", unit);
- grprsm = fopen(filename, "w");
- if ( ! grprsm )
- SysError("GRPRS_STREAM = %d", unit);
- }
- }
- else
- {
- if ( env_stream[0] )
- {
- grprsm = fopen(env_stream, "w");
- if ( ! grprsm )
- SysError("GRPRS_STREAM = %s", env_stream);
- }
- }
- }
- /*
- Set P factor switch to default, user supplies the P factor.
- */
- nonoff = 0;
- /*
- Set abort flag to NO abort
- */
- noabort = 1;
- /*
- Mark common area values set by user.
- */
- lfirst = FALSE;
- /*
- Exhaustive use of all possible second-order packing methods
- for HOPER='K'. Set to off.
- */
- num2ok = 0;
- /*
- Use of extended second-order packing methods for grid-point
- encoding (HOPER='C' and 'K'). Set to on.
- */
- next2o = 1;
- /*
- Use of non-local second-order packing methods for grid-point
- encoding (HOPER='C' and 'K'). Set to on.
- */
- nloc2o = 1;
- /*
- Use of (all valid) sub-centre values for ECMWF fields encoding .
- encoding. Set to off.
- */
- nsubce = 0;
-}
-
-/* pack 8-bit bytes from 64-bit words to a packed buffer */
-/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (unsigned char) up[i]; */
-
-long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc)
-{
-#if defined (CRAY)
- (void) _pack(up, cp, bc, tc);
-#else
- U_BYTEORDER;
- unsigned char *cp0;
- unsigned INT64 upi, *up0, *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
- long head, trail, inner, i, j;
- long ipack = sizeof(INT64);
-
- /* Bytes until first word boundary in destination buffer */
-
- head = ( (long) cp ) & (ipack-1);
- if ( head != 0 ) head = ipack - head;
-
- inner = bc - head;
-
- /* Trailing bytes which do not make a full word */
-
- trail = inner & (ipack-1);
-
- /* Number of bytes/words to be processed in fast loop */
-
- inner -= trail;
- inner /= ipack;
-
- ip0 = up + head;
- ip1 = ip0 + 1;
- ip2 = ip0 + 2;
- ip3 = ip0 + 3;
- ip4 = ip0 + 4;
- ip5 = ip0 + 5;
- ip6 = ip0 + 6;
- ip7 = ip0 + 7;
-
- up0 = (unsigned INT64 *) (cp + head);
-
- /* Here we should process any bytes until the first word boundary
- * of our destination buffer
- * That code is missing so far because our output buffer is
- * word aligned by FORTRAN
- */
-
- j = 0;
-
- if ( IS_BIGENDIAN() )
- {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0 ; i < inner ; i++ )
- {
- upi = ( ip0[j] << 56 )
- | ( ( ip1[j] & 0xFF ) << 48 )
- | ( ( ip2[j] & 0xFF ) << 40 )
- | ( ( ip3[j] & 0xFF ) << 32 )
- | ( ( ip4[j] & 0xFF ) << 24 ) ;
- up0[i] = upi | ( ( ip5[j] & 0xFF ) << 16 )
- | ( ( ip6[j] & 0xFF ) << 8 )
- | ( ip7[j] & 0xFF ) ;
- j += ipack;
- }
- }
- else
- {
- for ( i = 0 ; i < inner ; i++ )
- {
- upi = ( ip7[j] << 56 )
- | ( ( ip6[j] & 0xFF ) << 48 )
- | ( ( ip5[j] & 0xFF ) << 40 )
- | ( ( ip4[j] & 0xFF ) << 32 )
- | ( ( ip3[j] & 0xFF ) << 24 ) ;
- up0[i] = upi | ( ( ip2[j] & 0xFF ) << 16 )
- | ( ( ip1[j] & 0xFF ) << 8 )
- | ( ip0[j] & 0xFF ) ;
- j += ipack;
- }
- }
-
- cp0 = (unsigned char *) ( up0 + inner );
- if ( trail > 0 )
- {
- up0[inner] = 0;
- for ( i = 0 ; i < trail ; i ++ )
- {
- *cp0 = (unsigned char) ip0[ipack*inner+i];
- cp0++;
- }
- }
-
- if ( tc != -1 )
- {
- bc++;
- *cp0 = (unsigned char) tc;
- }
-#endif
- return (bc);
-}
-
-/* unpack 8-bit bytes from a packed buffer with 64-bit words */
-/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT64) cp[i]; */
-
-long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc)
-{
- U_BYTEORDER;
- const unsigned char *cp0;
- unsigned INT64 *up0;
- unsigned INT64 *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
- long head, trail, inner, i, j;
- long offset;
- long ipack = sizeof(INT64);
-
- UNUSED(tc);
-
- /* Bytes until first word boundary in source buffer */
-
- head = ( (long) cp ) & (ipack-1);
- if ( head != 0 ) head = ipack - head;
- if ( head > bc ) head = bc;
-
- inner = bc - head;
-
- /* Trailing bytes which do not make a full word */
-
- trail = inner & (ipack-1);
-
- /* Number of bytes/words to be processed in fast loop */
-
- inner -= trail;
- inner /= ipack;
-
- ip0 = up + head;
- ip1 = ip0 + 1;
- ip2 = ip0 + 2;
- ip3 = ip0 + 3;
- ip4 = ip0 + 4;
- ip5 = ip0 + 5;
- ip6 = ip0 + 6;
- ip7 = ip0 + 7;
-
- up0 = (unsigned INT64 *) (cp + head);
-
- /* Process any bytes until the first word boundary
- * of our source buffer
- */
- for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT64) cp[i];
-
- j = 0;
-
- if ( IS_BIGENDIAN() )
- {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0 ; i < inner ; i++ )
- {
- ip0[j] = (up0[i] >> 56) & 0xFF;
- ip1[j] = (up0[i] >> 48) & 0xFF;
- ip2[j] = (up0[i] >> 40) & 0xFF;
- ip3[j] = (up0[i] >> 32) & 0xFF;
- ip4[j] = (up0[i] >> 24) & 0xFF;
- ip5[j] = (up0[i] >> 16) & 0xFF;
- ip6[j] = (up0[i] >> 8) & 0xFF;
- ip7[j] = (up0[i]) & 0xFF;
-
- j += ipack;
- }
- }
- else
- {
- for ( i = 0 ; i < inner ; i++ )
- {
- ip7[j] = (up0[i] >> 56) & 0xFF;
- ip6[j] = (up0[i] >> 48) & 0xFF;
- ip5[j] = (up0[i] >> 40) & 0xFF;
- ip4[j] = (up0[i] >> 32) & 0xFF;
- ip3[j] = (up0[i] >> 24) & 0xFF;
- ip2[j] = (up0[i] >> 16) & 0xFF;
- ip1[j] = (up0[i] >> 8) & 0xFF;
- ip0[j] = (up0[i]) & 0xFF;
-
- j += ipack;
- }
- }
-
- if ( trail > 0 )
- {
- offset = head + ipack*inner;
- cp0 = cp + offset;
- for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT64) cp0[i];
- }
- /*
- if ( tc != -1 ) {
- bc++;
- *cp0 = (unsigned char) tc;
- }
- */
- return (bc);
-}
-
-/* pack 8-bit bytes from 32-bit words to a packed buffer */
-/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (char) up[i]; */
-
-#if defined (INT32)
-long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc)
-{
- U_BYTEORDER;
- unsigned char *cp0;
- unsigned INT32 *up0, *ip0, *ip1, *ip2, *ip3;
- long head, trail, inner, i, j;
- long ipack = sizeof(INT32);
-
- /* Bytes until first word boundary in destination buffer */
-
- head = ( (long) cp ) & (ipack-1);
- if ( head != 0 ) head = ipack - head;
-
- inner = bc - head;
-
- /* Trailing bytes which do not make a full word */
-
- trail = inner & (ipack-1);
-
- /* Number of bytes/words to be processed in fast loop */
-
- inner -= trail;
- inner /= ipack;
-
- ip0 = up + head;
- ip1 = ip0 + 1;
- ip2 = ip0 + 2;
- ip3 = ip0 + 3;
-
- up0 = (unsigned INT32 *) (cp + head);
-
- /* Here we should process any bytes until the first word boundary
- * of our destination buffer
- * That code is missing so far because our output buffer is
- * word aligned by FORTRAN
- */
-
- j = 0;
+ Method:
+ -------
- if ( IS_BIGENDIAN() )
- {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0 ; i < inner ; i++ )
- {
- up0[i] = ( ip0[j] << 24 )
- | ( ( ip1[j] & 0xFF ) << 16 )
- | ( ( ip2[j] & 0xFF ) << 8 )
- | ( ip3[j] & 0xFF ) ;
- j += ipack;
- }
- }
- else
- {
- for ( i = 0 ; i < inner ; i++ )
- {
- up0[i] = ( ip3[j] << 24 )
- | ( ( ip2[j] & 0xFF ) << 16 )
- | ( ( ip1[j] & 0xFF ) << 8 )
- | ( ip0[j] & 0xFF ) ;
- j += ipack;
- }
- }
+ Floating point number represented as 8 bit signed
+ exponent and 24 bit mantissa in integer values.
- cp0 = (unsigned char *) ( up0 + inner );
- if ( trail > 0 )
- {
- up0[inner] = 0;
- for ( i = 0 ; i < trail ; i ++ )
- {
- *cp0 = (unsigned char) ip0[ipack*inner+i];
- cp0++;
- }
- }
+ Externals.
+ ----------
- if ( tc != -1 )
- {
- bc++;
- *cp0 = (unsigned char) tc;
- }
+ decfp2 - Decode from IBM floating point format.
- return (bc);
-}
-#endif
+ Reference:
+ ----------
-/* unpack 8-bit bytes from a packed buffer with 32-bit words */
-/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT32) cp[i]; */
+ WMO Manual on Codes re GRIB representation.
-#if defined (INT32)
-long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc)
-{
- U_BYTEORDER;
- const unsigned char *cp0;
- unsigned INT32 *up0;
- unsigned INT32 *ip0, *ip1, *ip2, *ip3;
- long head, trail, inner, i, j;
- long offset;
- long ipack = sizeof(INT32);
+ Comments:
+ ---------
- UNUSED(tc);
+ Routine aborts if an invalid conversion type parameter
+ is used or if a 24 bit mantissa is not produced.
- /* Bytes until first word boundary in source buffer */
+ Author:
+ -------
+
+ John Hennessy ECMWF 18.06.91
- head = ( (long) cp ) & (ipack-1);
- if ( head != 0 ) head = ipack - head;
- if ( head > bc ) head = bc;
+ Modifications:
+ --------------
- inner = bc - head;
+ Uwe Schulzweida MPIfM 01/04/2001
- /* Trailing bytes which do not make a full word */
-
- trail = inner & (ipack-1);
-
- /* Number of bytes/words to be processed in fast loop */
+ Convert to C from EMOS library version 130
- inner -= trail;
- inner /= ipack;
+ Uwe Schulzweida MPIfM 02/08/2002
- ip0 = up + head;
- ip1 = ip0 + 1;
- ip2 = ip0 + 2;
- ip3 = ip0 + 3;
+ - speed up by factor 1.6 on NEC SX6
+ - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
+ */
- up0 = (unsigned INT32 *) (cp + head);
+ // extern int CGRIBEX_Debug;
- /* Process any bytes until the first word boundary
- * of our source buffer
- */
- for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT32) cp[i];
+ /* ----------------------------------------------------------------- */
+ /* Section 1 . Initialise */
+ /* ----------------------------------------------------------------- */
- j = 0;
+ /* Check conversion type parameter. */
- if ( IS_BIGENDIAN() )
+ int iround = kround;
+ if ( iround != 0 && iround != 1 )
{
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0 ; i < inner ; i++ )
- {
- ip0[j] = (up0[i] >> 24) & 0xFF;
- ip1[j] = (up0[i] >> 16) & 0xFF;
- ip2[j] = (up0[i] >> 8) & 0xFF;
- ip3[j] = (up0[i]) & 0xFF;
+ Error("Invalid conversion type = %d", iround);
- j += ipack;
- }
+ /* If not aborting, arbitrarily set rounding to 'up'. */
+ iround = 1;
}
- else
- {
- for ( i = 0 ; i < inner ; i++ )
- {
- ip3[j] = (up0[i] >> 24) & 0xFF;
- ip2[j] = (up0[i] >> 16) & 0xFF;
- ip1[j] = (up0[i] >> 8) & 0xFF;
- ip0[j] = (up0[i]) & 0xFF;
- j += ipack;
- }
- }
+ /* ----------------------------------------------------------------- */
+ /* Section 2 . Convert value of zero. */
+ /* ----------------------------------------------------------------- */
- if ( trail > 0 )
+ if ( ! (fabs(pval) > 0))
{
- offset = head + ipack*inner;
- cp0 = cp + offset;
- for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT32) cp0[i];
+ *kexp = 0;
+ *kmant = 0;
+ // iexp = 0;
+ // isign = 0;
+ goto LABEL900;
}
- /*
- if ( tc != -1 ) {
- bc++;
- *cp0 = (unsigned char) tc;
- }
- */
-
- return (bc);
-}
-#endif
-#include <stdio.h>
-
-void prtbin(int kin, int knbit, int *kout, int *kerr)
-{
- /*
-
- Produces a decimal number with ones and zeroes
- corresponding to the ones and zeroes of the input
- binary number.
- eg input number 1011 binary, output number 1011 decimal.
+ /* ----------------------------------------------------------------- */
+ /* Section 3 . Convert other values. */
+ /* ----------------------------------------------------------------- */
+ {
+ double zeps = kbits != 32 ? 1.0e-12 : 1.0e-8;
+ double zref = pval;
- Input Parameters:
-
- kin - Integer variable containing binary number.
+ /* Sign of value. */
- knbit - Number of bits in binary number.
+ int isign = zref >= 0.0 ? 0 : 128;
+ zref = fabs(zref);
- Output Parameters:
+ /* Exponent. */
- kout - Integer variable containing decimal value
- with ones and zeroes corresponding to those of
- the input binary number.
+ int iexp = (int) (log(zref)/log(16.0) + 65.0 + zeps);
- kerr - 0, If no error.
- 1, Number of bits in binary number exceeds
- maximum allowed or is less than 1.
+ /* only ANSI C99 has log2 */
+ /* iexp = (int) (log2(zref) * 0.25 + 65.0 + zeps); */
+ if ( iexp < 0 ) iexp = 0;
+ if ( iexp > 127 ) iexp = 127;
- Converted from EMOS routine PRTBIN.
+ double rpowref;
+ /*
+ rpowref = zref / pow(16.0, (double)(iexp - 70));
+ */
- Uwe Schulzweida MPIfM 01/04/2001
+ rpowref = ldexp(zref, 4 * -(iexp - 70));
- */
- int idec;
- int ik;
- int itemp;
- int j;
+ /* Mantissa. */
- /*
- Check length of binary number to ensure decimal number
- generated will fit in the computer word - in this case will
- it fit in a Cray 48 bit integer?
- */
- if ( knbit < 1 || knbit > 14 )
+ if ( iround == 0 )
{
- *kerr = 1;
- printf(" prtbin : Error in binary number length - %3d bits.\n", knbit);
- return;
- }
- else
- *kerr = 0;
- /*
- -----------------------------------------------------------------
- Section 1. Generate required number.
- -----------------------------------------------------------------
- */
- *kout = 0;
- ik = kin;
- idec = 1;
+ /* Closest number in GRIB format less than original number. */
+ /* Truncate for positive numbers. */
+ /* Round up for negative numbers. */
- for ( j = 0; j < knbit; j++ )
- {
- itemp = ik - ( (ik/2)*2 );
- *kout = (*kout) + itemp * idec;
- ik = ik / 2;
- idec = idec * 10;
+ if ( isign == 0 )
+ *kmant = (int)rpowref;
+ else
+ *kmant = (int)lround(rpowref + 0.5);
}
+ else
+ {
+ /* Closest number in GRIB format to the original number */
+ /* (equal to, greater than or less than original number). */
- return;
-}
-
-
-void ref2ibm(double *pref, int kbits)
-{
- /*
-
- Purpose:
- --------
-
- Code and check reference value in IBM format
-
- Input Parameters:
- -----------------
-
- pref - Reference value
- kbits - Number of bits per computer word.
+ *kmant = (int)lround(rpowref);
+ }
- Output Parameters:
- ------------------
+ /* Check that mantissa value does not exceed 24 bits. */
+ /* If it does, adjust the exponent upwards and recalculate */
+ /* the mantissa. */
+ /* 16777215 = 2**24 - 1 */
- pref - Reference value
+ if ( *kmant > 16777215 )
+ {
- Method:
- -------
+ LABEL350:
- Codes in IBM format, then decides to ensure that reference
- value used for packing is not different from that stored
- because of packing differences.
+ ++iexp;
- Externals.
- ----------
+ /* Check for exponent overflow during adjustment */
- confp3 - Encode into IBM floating point format.
- decfp2 - Decode from IBM floating point format.
+ if ( iexp > 127 )
+ {
+ Message("Exponent overflow");
+ Message("Original number = %30.20f", pval);
+ Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
+ isign, iexp, *kmant);
- Reference:
- ----------
+ Error("Exponent overflow");
- None.
+ /* If not aborting, arbitrarily set value to zero */
- Comments:
- --------
+ Message("Value arbitrarily set to zero.");
+ *kexp = 0;
+ *kmant = 0;
+ // iexp = 0;
+ // isign = 0;
+ goto LABEL900;
+ }
- None.
+ rpowref = ldexp(zref, 4 * -(iexp - 70));
- Author:
- -------
+ if ( iround == 0 )
+ {
+ /* Closest number in GRIB format less than original number. */
+ /* Truncate for positive numbers. */
+ /* Round up for negative numbers. */
- J.D.Chambers ECMWF 17:05:94
+ if ( isign == 0 )
+ *kmant = (int)rpowref;
+ else
+ *kmant = (int)lround(rpowref + 0.5);
+ }
+ else
+ {
+ /* Closest number in GRIB format to the original number */
+ /* (equal to, greater or less than original number). */
- Modifications:
- --------------
+ *kmant = (int)lround(rpowref);
+ }
- Uwe Schulzweida MPIfM 01/04/2001
+ /* Repeat calculation (with modified exponent) if still have */
+ /* mantissa overflow. */
- Convert to C from EMOS library version 130
+ if ( *kmant > 16777215 ) goto LABEL350;
+ }
- */
+ /* Add sign bit to exponent. */
- static int itrnd;
- static int kexp, kmant;
- static double ztemp, zdumm;
- extern int CGRIBEX_Debug;
+ *kexp = iexp + isign;
+ }
/* ----------------------------------------------------------------- */
- /* Section 1. Convert to and from IBM format. */
+ /* Section 9. Return */
/* ----------------------------------------------------------------- */
- /* Convert floating point reference value to IBM representation. */
-
- itrnd = 1;
- zdumm = ztemp = *pref;
- confp3(zdumm, &kexp, &kmant, kbits, itrnd);
-
- if ( kexp == 0 && kmant == 0 ) return;
-
- /* Set reference value to that actually stored in the GRIB code. */
-
- *pref = decfp2(kexp, kmant);
-
- /* If the nearest number which can be represented in */
- /* GRIB format is greater than the reference value, */
- /* find the nearest number in GRIB format lower */
- /* than the reference value. */
-
- if ( ztemp < *pref )
+LABEL900:
+ /*
+ if ( CGRIBEX_Debug )
{
- /* Convert floating point to GRIB representation */
- /* using truncation to ensure that the converted */
- /* number is smaller than the original one. */
-
- itrnd = 0;
- zdumm = *pref = ztemp;
- confp3(zdumm, &kexp, &kmant, kbits, itrnd);
+ double zval;
- /* Set reference value to that stored in the GRIB code. */
+ Message("Conversion type parameter = %4d", kround);
+ Message("Original number = %30.20f", pval);
- *pref = decfp2(kexp, kmant);
+ zval = decfp2(*kexp, *kmant);
- if ( ztemp < *pref )
- {
- if ( CGRIBEX_Debug )
- {
- Message("Reference value error.");
- Message("Notify Met.Applications Section.");
- Message("ZTEMP = ", ztemp);
- Message("PREF = ", pref);
- }
- *pref = ztemp;
- }
+ Message("Converted to %30.20f", zval);
+ Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
}
-
+ */
return;
-} /* ref2ibm */
+} /* confp3 */
#include <math.h>
-#include <string.h>
-int correct_bdslen(int bdslen, long recsize, long gribpos)
+double decfp2(int kexp, int kmant)
{
/*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- if ( recsize > JP23SET ) bdslen = (int)(recsize - gribpos - bdslen);
- return (bdslen);
-}
-
-
-int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
- unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize)
-{
- unsigned char *pds, *gds, *bms, *bds;
- unsigned char *bufpointer, *is, *section;
- int gribversion, grib1offset;
- long gribsize = 0, recsize;
- int bdslen;
-
- *gribrecsize = 0;
- *pdsp = NULL;
- *gdsp = NULL;
- *bmsp = NULL;
- *bdsp = NULL;
-
- section = gribbuffer;
- is = gribbuffer;
- if ( ! GRIB_START(section) )
- {
- fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
- section[0], section[1], section[2], section[3]);
- return (-1);
- }
-
- recsize = gribrec_len(section[4], section[5], section[6]);
-
- gribversion = GRIB_EDITION(section);
- if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
-
- if ( gribversion == 1 )
- grib1offset = 4;
- else
- grib1offset = 0;
-
- pds = is + 4 + grib1offset;
- bufpointer = pds + PDS_Len;
- gribsize += 4 + grib1offset + PDS_Len;
-
- if ( PDS_HAS_GDS )
- {
- gds = bufpointer;
- bufpointer += GDS_Len;
- gribsize += GDS_Len;
- }
- else
- {
- gds = NULL;
- }
-
- if ( PDS_HAS_BMS )
- {
- bms = bufpointer;
- bufpointer += BMS_Len;
- gribsize += BMS_Len;
- }
- else
- {
- bms = NULL;
- }
-
- bds = bufpointer;
- bdslen = BDS_Len;
- bdslen = correct_bdslen(bdslen, recsize, gribsize);
- bufpointer += bdslen;
- gribsize += bdslen;
- gribsize += 4;
-
- *pdsp = pds;
- *gdsp = gds;
- *bmsp = bms;
- *bdsp = bds;
-
- *gribrecsize = gribsize;
-
- if ( gribbufsize < gribsize )
- {
- fprintf(stderr, "Length of GRIB message is inconsistent (grib_buffer_size=%ld < grib_record_size=%ld)!\n", gribbufsize, gribsize);
- return (1);
- }
- /* end section - "7777" in ascii */
- if ( !GRIB_FIN(bufpointer) )
- {
- fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
- bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
- return (-2);
- }
+ Purpose:
+ --------
- return (0);
-}
+ Convert GRIB representation of a floating point
+ number to machine representation.
+ Input Parameters:
+ -----------------
-int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
- unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
- unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp)
-{
- unsigned char *section;
- long sec_len;
- int sec_num;
- int gribversion;
- int i, msec;
- long gribsize;
- long grib_len = 0;
+ kexp - 8 Bit signed exponent.
+ kmant - 24 Bit mantissa.
- UNUSED(gribbufsize);
+ Output Parameters:
+ ------------------
- *idsp = NULL;
- *lusp = NULL;
- *gdsp = NULL;
- *pdsp = NULL;
- *drsp = NULL;
- *bmsp = NULL;
- *bdsp = NULL;
+ Return value - Floating point number represented
+ by kexp and kmant.
- section = gribbuffer;
- sec_len = 16;
+ Method:
+ -------
- if ( !GRIB_START(section) )
- {
- fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
- section[0], section[1], section[2], section[3]);
- return (-1);
- }
+ Floating point number represented as 8 bit exponent
+ and 24 bit mantissa in integer values converted to
+ machine floating point format.
- gribversion = GRIB_EDITION(section);
- if ( gribversion != 2 )
- {
- fprintf(stderr, "wrong GRIB version %d\n", gribversion);
- return (-1);
- }
+ Externals:
+ ----------
- gribsize = 0;
- for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
+ None.
- grib_len += sec_len;
- section += sec_len;
+ Reference:
+ ----------
- /* section 1 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "ids %d %ld\n", sec_num, sec_len);
+ WMO Manual on Codes re GRIB representation.
- if ( sec_num != 1 )
- {
- fprintf(stderr, "Unexpected section1 number %d\n", sec_num);
- return (-1);
- }
+ Comments:
+ ---------
- *idsp = section;
+ Rewritten from DECFP, to conform to programming standards.
+ Sign bit on 0 value now ignored, if present.
+ If using 32 bit reals, check power of 16 is not so small as to
+ cause overflows (underflows!); this causes warning to be given
+ on Fujitsus.
- grib_len += sec_len;
- section += sec_len;
+ Author:
+ -------
- /* section 2 and 3 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "lus %d %ld\n", sec_num, sec_len);
+ John Hennessy ECMWF 18.06.91
- if ( sec_num == 2 )
- {
- *lusp = section;
+ Modifications:
+ --------------
- grib_len += sec_len;
- section += sec_len;
+ Uwe Schulzweida MPIfM 01/04/2001
- /* section 3 */
- sec_len = GRIB2_SECLEN(section);
- //sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "gds %d %ld\n", sec_num, sec_len);
+ - Convert to C from EMOS library version 130
- *gdsp = section;
- }
- else if ( sec_num == 3 )
- {
- *gdsp = section;
- }
- else
- {
- fprintf(stderr, "Unexpected section3 number %d\n", sec_num);
- return (-1);
- }
+ Uwe Schulzweida MPIfM 02/08/2002
- grib_len += sec_len;
- section += sec_len;
+ - speed up by factor 2 on NEC SX6
+ - replace pow(2.0, -24.0) by constant POW_2_M24
+ - replace pow(16.0, (double)(iexp - 64)) by pow16m64tab[iexp]
+ */
- /* section 4 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "pds %d %ld\n", sec_num, sec_len);
+ /* ----------------------------------------------------------------- */
+ /* Section 1 . Convert value of 0.0. Ignore sign bit. */
+ /* ----------------------------------------------------------------- */
- if ( sec_num != 4 )
- {
- fprintf(stderr, "Unexpected section4 number %d\n", sec_num);
- return (-1);
- }
+ if ( (kexp == 128) || (kexp == 0) || (kexp == 255) ) return 0.0;
- *pdsp = section;
+ /* ----------------------------------------------------------------- */
+ /* Section 2 . Convert other values. */
+ /* ----------------------------------------------------------------- */
- grib_len += sec_len;
- section += sec_len;
+ /* Sign of value. */
- /* section 5 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "drs %d %ld\n", sec_num, sec_len);
+ int iexp = kexp,
+ isign = (iexp < 128) * 2 - 1;
- if ( sec_num != 5 )
- {
- fprintf(stderr, "Unexpected section5 number %d\n", sec_num);
- return (-1);
- }
+ iexp -= iexp < 128 ? 0 : 128;
- *drsp = section;
+ /* Decode value. */
- grib_len += sec_len;
- section += sec_len;
+ /* pval = isign * pow(2.0, -24.0) * kmant * pow(16.0, (double)(iexp - 64)); */
- /* section 6 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "bms %d %ld\n", sec_num, sec_len);
+ iexp -= 64;
- if ( sec_num != 6 )
- {
- fprintf(stderr, "Unexpected section6 number %d\n", sec_num);
- return (-1);
- }
+ double pval = ldexp(1.0, 4 * iexp) * isign * POW_2_M24 * kmant;
- *bmsp = section;
+ /* ----------------------------------------------------------------- */
+ /* Section 9. Return to calling routine. */
+ /* ----------------------------------------------------------------- */
- grib_len += sec_len;
- section += sec_len;
+ return pval;
+} /* decfp2 */
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
- /* section 7 */
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
- //fprintf(stderr, "bds %d %ld\n", sec_num, sec_len);
- if ( sec_num != 7 )
- {
- fprintf(stderr, "Unexpected section7 number %d\n", sec_num);
- return (-1);
- }
- *bdsp = section;
+int gribRefDate(int *isec1)
+{
+ int century = ISEC1_Century;
+ if ( century < 0 ) century = -century;
+ century -= 1;
- grib_len += sec_len;
- section += sec_len;
+ int ryear = ISEC1_Year;
- /* skip multi GRIB sections */
- msec = 1;
- while ( !GRIB_FIN(section) )
+ /* if ( century != 0 ) */
{
- sec_len = GRIB2_SECLEN(section);
- sec_num = GRIB2_SECNUM(section);
+ if ( ryear == 100 )
+ {
+ ryear = 0;
+ century += 1;
+ }
- if ( sec_num < 1 || sec_num > 7 ) break;
+ if ( ryear != 255 )
+ {
+ ryear = century*100 + ryear;
+ if ( ISEC1_Century < 0 ) ryear = -ryear;
+ }
+ else
+ ryear = 1;
+ }
- if ( sec_num == 7 )
- fprintf(stderr, "Skipped unsupported multi GRIB section %d!\n", ++msec);
+ int rmonth = ISEC1_Month;
+ int rday = ISEC1_Day;
- if ( (grib_len + sec_len) > gribsize ) break;
+ int date = cdiEncodeDate(ryear, rmonth, rday);
- grib_len += sec_len;
- section += sec_len;
- }
+ return date ;
+}
- /* end section - "7777" in ASCII */
- if ( !GRIB_FIN(section) )
- {
- fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
- section[0], section[1], section[2], section[3]);
- return (-2);
- }
- return (0);
+int gribRefTime(int *isec1)
+{
+ int rhour = ISEC1_Hour;
+ int rminute = ISEC1_Minute;
+
+ int time = cdiEncodeTime(rhour, rminute, 0);
+
+ return time;
}
-int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
- int *intnum, float *fltnum, off_t *bignum)
+bool gribTimeIsFC(int *isec1)
{
- unsigned char *pds, *gds, *bms, *bds;
- unsigned char *bufpointer, *is, *section;
- int gribversion, grib1offset;
- long gribsize = 0;
- off_t dpos, bpos = 0;
- int bdslen;
- float bsf;
+ bool isFC = false;
- section = gribbuffer;
- is = gribbuffer;
- if ( ! GRIB_START(section) )
+ int time_period = (ISEC1_TimeRange == 10) ? (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2 : ISEC1_TimePeriod1;
+
+ if ( time_period > 0 && ISEC1_Day > 0 )
{
- fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
- section[0], section[1], section[2], section[3]);
- return (-1);
+ if ( ISEC1_TimeRange == 0 || ISEC1_TimeRange == 10 ) isFC = true;
}
- gribversion = GRIB_EDITION(section);
- if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
+ return isFC;
+}
- if ( gribversion == 1 )
- grib1offset = 4;
- else
- grib1offset = 0;
- pds = is + 4 + grib1offset;
- bufpointer = pds + PDS_Len;
- gribsize += 4 + grib1offset + PDS_Len;
+void gribDateTime(int *isec1, int *date, int *time)
+{
+ static bool lprint = true;
+ int julday, secofday;
+ int64_t addsec = 0;
+ int64_t time_period = 0;
+ extern int grib_calendar;
- if ( PDS_HAS_GDS )
+ int century = ISEC1_Century;
+ int ryear = ISEC1_Year;
+
+ if ( century == -255 && ryear == 127 )
{
- gds = bufpointer;
- bufpointer += GDS_Len;
- gribsize += GDS_Len;
+ century = 0;
+ ryear = 0;
}
else
{
- gds = NULL;
- }
-
- if ( PDS_HAS_BMS )
- {
- bms = bufpointer;
- bufpointer += BMS_Len;
+ if ( century < 0 ) century = -century;
+ century -= 1;
- bpos = recpos + gribsize + 6;
+ /* if ( century != 0 ) */
+ {
+ if ( ryear == 100 )
+ {
+ ryear = 0;
+ century += 1;
+ }
- gribsize += BMS_Len;
- }
- else
- {
- bms = NULL;
+ if ( ryear != 255 )
+ {
+ ryear = century*100 + ryear;
+ if ( ISEC1_Century < 0 ) ryear = -ryear;
+ }
+ else
+ ryear = 1;
+ }
}
- bds = bufpointer;
+ int rmonth = ISEC1_Month;
+ int rday = ISEC1_Day;
- dpos = recpos + gribsize + 11;
+ int rhour = ISEC1_Hour;
+ int rminute = ISEC1_Minute;
+ int second = 0;
- bdslen = BDS_Len;
- bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
- bufpointer += bdslen;
- gribsize += bdslen;
- gribsize += 4;
+ /* printf("ref %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute); */
- if ( gribsize > recsize )
- {
- fprintf(stderr, "GRIB buffer size %ld too small! Min size = %ld\n", recsize, gribsize);
- return (1);
- }
+ if ( ISEC1_TimeRange == 10 )
+ time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
+ else if ( ISEC1_TimeRange >=2 && ISEC1_TimeRange <= 5 )
+ time_period = ISEC1_TimePeriod2;
+ else if ( ISEC1_TimeRange == 0 )
+ time_period = ISEC1_TimePeriod1;
- /* end section - "7777" in ascii */
- if ( !GRIB_FIN(bufpointer) )
+ if ( time_period > 0 && rday > 0 )
{
- fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
- bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
- }
+ encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, second, &julday, &secofday);
- {
- int bs = BDS_BinScale;
- if ( bs > 32767 ) bs = 32768-bs;
- bsf = ldexpf(1.0f, bs);
- }
+ addsec = 0;
+ switch ( ISEC1_TimeUnit )
+ {
+ case ISEC1_TABLE4_MINUTE: addsec = 60 * time_period; break;
+ case ISEC1_TABLE4_QUARTER: addsec = 900 * time_period; break;
+ case ISEC1_TABLE4_30MINUTES: addsec = 1800 * time_period; break;
+ case ISEC1_TABLE4_HOUR: addsec = 3600 * time_period; break;
+ case ISEC1_TABLE4_3HOURS: addsec = 10800 * time_period; break;
+ case ISEC1_TABLE4_6HOURS: addsec = 21600 * time_period; break;
+ case ISEC1_TABLE4_12HOURS: addsec = 43200 * time_period; break;
+ case ISEC1_TABLE4_DAY: addsec = 86400 * time_period; break;
+ default:
+ if ( lprint )
+ {
+ gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
+ lprint = false;
+ }
+ break;
+ }
- bignum[0] = dpos;
- bignum[1] = bms ? bpos : -999;
- intnum[0] = BDS_NumBits;
+ julday_add_seconds(addsec, &julday, &secofday);
- /* fltnum[0] = 1.0; */
- fltnum[0] = powf(10.0f, (float)PDS_DecimalScale);
- fltnum[1] = bsf;
- fltnum[2] = (float)BDS_RefValue;
+ decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &second);
+ }
/*
- printf("intnum %d %d %d\n", intnum[0], intnum[1], intnum[2]);
- printf("fltnum %g %g %g\n", fltnum[0], fltnum[1], fltnum[2]);
+ printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
*/
- return (0);
+ *date = cdiEncodeDate(ryear, rmonth, rday);
+ *time = cdiEncodeTime(rhour, rminute, 0);
+
+ return;
}
-void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+void gprintf(const char *caller, const char *fmt, ...)
{
- static int header = 1;
- int GridType, level, nerr;
- unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- double cr = 1;
- int bdslen;
- int llarge = 0;
+ va_list args;
- if ( header )
- {
- fprintf(stdout,
- " Rec : Off Position Size : V PDS GDS BMS BDS : Code Level : LType GType: CR LL\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
- }
+ if ( grprsm == NULL ) Error("GRIBEX initialization missing!");
+
+ va_start(args, fmt);
- is = gribbuffer;
+ fprintf(grprsm, "%-18s : ", caller);
+ vfprintf(grprsm, fmt, args);
+ fprintf(grprsm, "\n");
- if ( gribrec_len(is[4], is[5], is[6]) > JP23SET ) llarge = 1;
+ va_end(args);
+}
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
+
+void
+gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+ double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, const char *hoper, int *kret)
+{
+ int yfunc = *hoper;
+
+ if ( yfunc == 'C' )
{
- fprintf(stdout, "%5d :%4ld %8ld %6ld : GRIB message error\n", nrec, offset, recpos, recsize);
- return;
+ grib_encode_double(isec0, isec1, isec2, fsec2, isec3,
+ fsec3, isec4, fsec4, klenp, kgrib,
+ kleng, kword, yfunc, kret);
+ }
+ else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+ {
+ grib_decode_double(isec0, isec1, isec2, fsec2, isec3,
+ fsec3, isec4, fsec4, klenp, kgrib,
+ kleng, kword, yfunc, kret);
+ }
+ else if ( yfunc == 'V' )
+ {
+ fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
}
-
- if ( gds == NULL )
- GridType = -1;
else
- GridType = GDS_GridType;
+ {
+ Error("oper %c unsupported!", yfunc);
+ *kret=-9;
+ }
+}
- if ( PDS_LevelType == 100 )
- level = PDS_Level * 100;
- else if ( PDS_LevelType == 99 )
- level = PDS_Level;
- else if ( PDS_LevelType == 109 )
- level = PDS_Level;
- else
- level = PDS_Level1;
- bdslen = BDS_Len;
- bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
+void
+gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+ float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, const char *hoper, int *kret)
+{
+ int yfunc = *hoper;
- if ( ((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130) )
+ if ( yfunc == 'C' )
+ {
+ grib_encode_float(isec0, isec1, isec2, fsec2, isec3,
+ fsec3, isec4, fsec4, klenp, kgrib,
+ kleng, kword, yfunc, kret);
+ }
+ else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+ {
+ grib_decode_float(isec0, isec1, isec2, fsec2, isec3,
+ fsec3, isec4, fsec4, klenp, kgrib,
+ kleng, kword, yfunc, kret);
+ }
+ else if ( yfunc == 'V' )
+ {
+ fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
+ }
+ else
{
- int s1, s2;
- s1 = gribrec_len(bds[14], bds[15], bds[16]);
- s2 = gribrec_len(gribbuffer[4], gribbuffer[5], gribbuffer[6]);
- cr = ((double)s1)/s2;
+ Error("oper %c unsupported!", yfunc);
+ *kret=-9;
}
+}
- fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d%4d%5d %6d %6d : %3d %6d : %5d %5d %6.4g %c",
- nrec, offset, recpos, recsize, GRIB_EDITION(is),
- PDS_Len, GDS_Len, BMS_Len, bdslen,
- PDS_Parameter, level, PDS_LevelType, GridType, cr, llarge?'T':'F');
+int CGRIBEX_Fix_ZSE = 0; /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
+int CGRIBEX_Const = 0; /* 1: Don't pack constant fields on regular grids */
+int CGRIBEX_Debug = 0; /* 1: Debugging */
- if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
- fprintf(stdout, "\n");
+void gribSetDebug(int debug)
+{
+ CGRIBEX_Debug = debug;
+
+ if ( CGRIBEX_Debug )
+ Message("debug level %d", debug);
}
-void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+void gribFixZSE(int flag)
{
- static int header = 1;
- int nerr;
- unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- unsigned char *ids = NULL, *lus = NULL, *drs = NULL;
- long ids_len = 0, lus_len = 0, gds_len = 0, pds_len = 0, drs_len = 0, bms_len = 0, bds_len = 0;
- int gridtype, paramnum, level1type /*, level2type*/;
- int level1 /*, level1sf*/;
- /* int level2, level2sf; */
- double cr = 1;
+ CGRIBEX_Fix_ZSE = flag;
- if ( header )
- {
- fprintf(stdout,
- " Rec : Off Position Size : V IDS LUS GDS PDS DRS BMS BDS : Code Level : LType GType: CR\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
- }
+ if ( CGRIBEX_Debug )
+ Message("Fix ZeroShiftError set to %d", flag);
+}
- is = gribbuffer;
- nerr = grib2Sections(gribbuffer, recsize, &ids, &lus, &gds, &pds, &drs, &bms, &bds);
- if ( nerr )
- {
- fprintf(stdout, "%5d :%4ld %8ld %6ld : error\n", nrec, offset, recpos, recsize);
- return;
- }
+void gribSetConst(int flag)
+{
+ CGRIBEX_Const = flag;
- if ( ids ) ids_len = GRIB2_SECLEN(ids);
- if ( lus ) lus_len = GRIB2_SECLEN(lus);
- if ( gds ) gds_len = GRIB2_SECLEN(gds);
- if ( pds ) pds_len = GRIB2_SECLEN(pds);
- if ( drs ) drs_len = GRIB2_SECLEN(drs);
- if ( bms ) bms_len = GRIB2_SECLEN(bms);
- if ( bds ) bds_len = GRIB2_SECLEN(bds);
+ if ( CGRIBEX_Debug )
+ Message("Const set to %d", flag);
+}
- /*
- if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
- {
- int s1, s2;
- s1 = ((int) ((bds[14]<<16)+(bds[15]<<8)+bds[16]));
- s2 = ((int) ((gribbuffer[4]<<16)+(gribbuffer[5]<<8)+gribbuffer[6]));
- cr = ((double)s1)/s2;
- }
- */
- gridtype = GET_UINT2(gds[12],gds[13]);
- paramnum = GET_UINT1(pds[10]);
- level1type = GET_UINT1(pds[22]);
- /* level1sf = GET_UINT1(pds[23]); */
- level1 = GET_UINT4(pds[24],pds[25],pds[26],pds[27]);
- /* level2type = GET_UINT1(pds[28]); */
- /* level2sf = GET_UINT1(pds[29]); */
- /* level2 = GET_UINT4(pds[30],pds[31],pds[32],pds[33]); */
- /*
- printf("level %d %d %d %d %d %d %d\n", level1type, level1sf, level1, level1*level1sf, level2sf, level2, level2*level2sf);
- */
- fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d %3ld %3ld %3ld %3ld %4ld %6ld %6ld : %3d%7d : %5d %5d %6.4g\n",
- nrec, offset, recpos, recsize, GRIB_EDITION(is),
- ids_len, lus_len, gds_len, pds_len, drs_len, bms_len, bds_len,
- paramnum, level1, level1type, gridtype, cr);
+
+void gribSetRound(int round)
+{
+ UNUSED(round);
}
-void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+void gribSetRefDP(double refval)
{
- int gribversion;
+ UNUSED(refval);
+}
- gribversion = gribVersion(gribbuffer, (size_t)recsize);
- if ( gribversion == 0 || gribversion == 1 )
- grib1PrintALL(nrec, offset, recpos, recsize, gribbuffer);
- else if ( gribversion == 2 )
- grib2PrintALL(nrec, offset, recpos, recsize, gribbuffer);
- else
- {
- fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
- nrec, offset, recpos, recsize, gribversion);
- }
+void gribSetRefSP(float refval)
+{
+ gribSetRefDP((double) refval);
}
-void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void gribSetValueCheck(int vcheck)
{
- static int header = 1;
- unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- int century, subcenter, decimalscale, nerr;
- int fc_num = 0;
- int year = 0, date;
+ UNUSED(vcheck);
+}
+#include <string.h>
+#include <math.h>
- UNUSED(recpos);
- if ( header )
- {
- fprintf(stdout,
- " Rec : PDS Tab Cen Sub Ver Grid Code LTyp Level1 Level2 Date Time P1 P2 TU TR NAVE Scale FCnum CT\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
- }
- is = gribbuffer;
+void gribPrintSec0(int *isec0)
+{
+ /*
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
- }
+ Print the information in the Indicator
+ Section (Section 0) of decoded GRIB data.
- switch(GRIB_EDITION(is))
- {
- case 0:
- year = GET_UINT1(pds[12]);
- century = 1;
- subcenter = 0;
- decimalscale = 0;
- break;
- case 1:
- year = PDS_Year;
- century = PDS_Century;
- subcenter = PDS_Subcenter;
- decimalscale = PDS_DecimalScale;
- break;
- default:
- fprintf(stderr, "Grib version %d not supported!", GRIB_EDITION(is));
- exit(EXIT_FAILURE);
- }
+ Input Parameters:
- if ( PDS_Len > 28 )
- if ( PDS_CenterID == 98 || PDS_Subcenter == 98 ||
- (PDS_CenterID == 7 && PDS_Subcenter == 98) )
- if ( pds[40] == 1 )
- fc_num = GET_UINT1(pds[49]);
+ isec0 - Array of decoded integers from Section 0
- if ( year < 0 )
- {
- date = (-year)*10000+PDS_Month*100+PDS_Day;
- century = -century;
- }
- else
- {
- date = year*10000+PDS_Month*100+PDS_Day;
- }
-
- fprintf(stdout, "%5d :%4d%4d%4d%4d%4d %4d %4d%4d%7d%7d %8d%6d%3d%3d%3d%3d%5d%6d%5d%4d", nrec,
- PDS_Len, PDS_CodeTable, PDS_CenterID, subcenter, PDS_ModelID,
- PDS_GridDefinition, PDS_Parameter, PDS_LevelType, PDS_Level1, PDS_Level2,
- date, PDS_Time, PDS_TimePeriod1, PDS_TimePeriod2, PDS_TimeUnit, PDS_TimeRange,
- PDS_AvgNum, decimalscale, fc_num, century);
- if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
- fprintf(stdout, "\n");
-}
+ Converted from EMOS routine GRPRS0.
+ Uwe Schulzweida MPIfM 01/04/2001
-void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- int gribversion;
+ */
- gribversion = gribVersion(gribbuffer, (size_t)recsize);
+ grsdef();
- if ( gribversion == 0 || gribversion == 1 )
- grib1PrintPDS(nrec, recpos, recsize, gribbuffer);
- /*
- else if ( gribversion == 2 )
- grib2PrintPDS(nrec, recpos, recsize, gribbuffer);
- */
- else
- {
- fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
- nrec, 0L, recpos, recsize, gribversion);
- }
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Section 0 - Indicator Section. \n");
+ fprintf(grprsm, " -------------------------------------\n");
+ fprintf(grprsm, " Length of GRIB message (octets). %9d\n", ISEC0_GRIB_Len);
+ fprintf(grprsm, " GRIB Edition Number. %9d\n", ISEC0_GRIB_Version);
}
-
-void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void gribPrintSec1(int *isec0, int *isec1)
{
- static int header = 1;
- int nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ /*
- UNUSED(recpos);
+ Print the information in the Product Definition
+ Section (Section 1) of decoded GRIB data.
- if ( header )
- {
- fprintf(stdout,
- " Rec : GDS NV PVPL Typ : xsize ysize Lat1 Lon1 Lat2 Lon2 dx dy\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
- }
+ Input Parameters:
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
- }
+ isec0 - Array of decoded integers from Section 0
- fprintf(stdout, "%5d :", nrec);
+ isec1 - Array of decoded integers from Section 1
- if ( gds )
- fprintf(stdout, "%4d%4d%4d %4d :%6d%6d%7d%7d%7d%7d%6d%6d",
- GDS_Len, GDS_NV, GDS_PVPL, GDS_GridType,
- GDS_NumLon, GDS_NumLat,
- GDS_FirstLat, GDS_FirstLon,
- GDS_LastLat, GDS_LastLon,
- GDS_LonIncr, GDS_LatIncr);
- else
- fprintf(stdout, " Grid Description Section not defined");
+ Comments:
- if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
- fprintf(stdout, "\n");
-}
+ When decoding data from Experimental Edition or Edition 0,
+ routine GRIBEX adds the additional fields available in
+ Edition 1.
-void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- int gribversion;
+ Converted from EMOS routine GRPRS1.
+
+ Uwe Schulzweida MPIfM 01/04/2001
- gribversion = gribVersion(gribbuffer, (size_t)recsize);
+ */
- if ( gribversion == 0 || gribversion == 1 )
- grib1PrintGDS(nrec, recpos, recsize, gribbuffer);
+ int iprev, icurr, ioffset;
+ int ibit, ierr, iout, iyear;
+ int jloop, jiloop;
+ float value;
+
+ char hversion[9];
/*
- else if ( gribversion == 2 )
- grib2PrintGDS(nrec, recpos, recsize, gribbuffer);
+ char hfirst[121], hsecond[121], hthird[121], hfourth[121];
*/
- else
- {
- fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
- nrec, 0L, recpos, recsize, gribversion);
- }
-}
+ grsdef();
-void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- static int header = 1;
- int level, nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ /*
+ -----------------------------------------------------------------
+ Section 0 . Print required information.
+ -----------------------------------------------------------------
+ */
- UNUSED(recpos);
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Section 1 - Product Definition Section.\n");
+ fprintf(grprsm, " ---------------------------------------\n");
- if ( header )
+ fprintf(grprsm, " Code Table 2 Version Number. %9d\n", isec1[0]);
+ fprintf(grprsm, " Originating centre identifier. %9d\n", isec1[1]);
+ fprintf(grprsm, " Model identification. %9d\n", isec1[2]);
+ fprintf(grprsm, " Grid definition. %9d\n", isec1[3]);
+
+ ibit = 8;
+ prtbin(isec1[4], ibit, &iout, &ierr);
+ fprintf(grprsm, " Flag (Code Table 1) %8.8d\n", iout);
+ fprintf(grprsm, " Parameter identifier (Code Table 2). %9d\n", isec1[5]);
+
+ /*
+ IERR = CHKTAB2(ISEC1,HFIRST,HSECOND,HTHIRD,HFOURTH)
+ IF( IERR .EQ. 0 ) THEN
+ DO JLOOP = 121, 1, -1
+ IF( HSECOND(JLOOP:JLOOP).NE.' ' ) THEN
+ IOFFSET = JLOOP
+ GOTO 110
+ ENDIF
+ ENDDO
+ GOTO 120
+ 110 CONTINUE
+ WRITE(*,'(2H ",A,1H")') HSECOND(1:IOFFSET)
+ 120 CONTINUE
+ ENDIF
+ */
+
+ if ( isec1[5] != 127 )
{
- fprintf(stdout,
- " Rec : Code Level BMS Size\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
+ fprintf(grprsm, " Type of level (Code Table 3). %9d\n", isec1[6]);
+ fprintf(grprsm, " Value 1 of level (Code Table 3). %9d\n", isec1[7]);
+ fprintf(grprsm, " Value 2 of level (Code Table 3). %9d\n", isec1[8]);
}
-
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
+ else
{
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
+ fprintf(grprsm, " Satellite identifier. %9d\n", isec1[6]);
+ fprintf(grprsm, " Spectral band. %9d\n", isec1[7]);
}
- if ( PDS_LevelType == 100 )
- level = PDS_Level * 100;
- else if ( PDS_LevelType == 99 )
- level = PDS_Level;
+ iyear = isec1[9];
+ if ( iyear != 255 )
+ {
+ int date, time;
+ /* iyear = ((isec1[20]-1)*100 + isec1[9]); */
+ gribDateTime(isec1, &date, &time);
+ iyear = date/10000;
+ fprintf(grprsm, " Year of reference time of data. %9d (%4d)\n", isec1[9], iyear);
+ }
else
- level = PDS_Level1;
-
- fprintf(stdout, "%5d :", nrec);
+ {
+ fprintf(grprsm, " Year of reference time of data MISSING (=255)\n");
+ }
- if ( bms )
- fprintf(stdout, "%4d%7d %7d %7d",
- PDS_Parameter, level,
- BMS_Len, BMS_BitmapSize);
+ fprintf(grprsm, " Month of reference time of data. %9d\n", isec1[10]);
+ fprintf(grprsm, " Day of reference time of data. %9d\n", isec1[11]);
+ fprintf(grprsm, " Hour of reference time of data. %9d\n", isec1[12]);
+ fprintf(grprsm, " Minute of reference time of data. %9d\n", isec1[13]);
+ fprintf(grprsm, " Time unit (Code Table 4). %9d\n", isec1[14]);
+ fprintf(grprsm, " Time range one. %9d\n", isec1[15]);
+ fprintf(grprsm, " Time range two. %9d\n", isec1[16]);
+ fprintf(grprsm, " Time range indicator (Code Table 5) %9d\n", isec1[17]);
+ fprintf(grprsm, " Number averaged. %9d\n", isec1[18]);
+ fprintf(grprsm, " Number missing from average. %9d\n", isec1[19]);
+ /*
+ All ECMWF data in GRIB Editions before Edition 1 is decoded
+ as 20th century data. Other centres are decoded as missing.
+ */
+ if ( isec0[1] < 1 && isec1[1] != 98 )
+ fprintf(grprsm, " Century of reference time of data. Not given\n");
else
- fprintf(stdout, "%4d%7d Bit Map Section not defined", PDS_Parameter, level);
+ fprintf(grprsm, " Century of reference time of data. %9d\n", isec1[20]);
- if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
- fprintf(stdout, "\n");
-}
+ /* Print sub-centre */
+ fprintf(grprsm, " Sub-centre identifier. %9d\n", ISEC1_SubCenterID);
+ /* Decimal scale factor */
+ fprintf(grprsm, " Units decimal scaling factor. %9d\n", isec1[22]);
-void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- int gribversion;
+ /*
+ -----------------------------------------------------------------
+ Section 1 . Print local DWD information.
+ -----------------------------------------------------------------
+ */
+ if ( (ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250) &&
+ (isec1[36] == 253 || isec1[36] == 254) )
+ {
+ fprintf(grprsm, " DWD local usage identifier. %9d\n", isec1[36]);
+ if ( isec1[36] == 253 )
+ fprintf(grprsm, " (Database labelling and ensemble forecast)\n");
+ if ( isec1[36] == 254 )
+ fprintf(grprsm, " (Database labelling)\n");
- gribversion = gribVersion(gribbuffer, (size_t)recsize);
+ fprintf(grprsm, " Year of database entry %3d (%4d)\n", isec1[43], 1900+isec1[43]);
+ fprintf(grprsm, " Month of database entry %3d\n", isec1[44]);
+ fprintf(grprsm, " Day of database entry %3d\n", isec1[45]);
+ fprintf(grprsm, " Hour of database entry %3d\n", isec1[46]);
+ fprintf(grprsm, " Minute of database entry %3d\n", isec1[47]);
+ fprintf(grprsm, " DWD experiment number %9d\n",isec1[48]);
+ fprintf(grprsm, " DWD run type %9d\n",isec1[49]);
+ if ( isec1[36] == 253 )
+ {
+ fprintf(grprsm, " User id %9d\n",isec1[50]);
+ fprintf(grprsm, " Experiment identifier %9d\n",isec1[51]);
+ fprintf(grprsm, " Ensemble identification type %9d\n",isec1[52]);
+ fprintf(grprsm, " Number of ensemble members %9d\n",isec1[53]);
+ fprintf(grprsm, " Actual number of ensemble member %9d\n",isec1[54]);
+ fprintf(grprsm, " Model version %2d.%2.2d\n",isec1[55],isec1[56]);
+ }
+ }
- if ( gribversion == 0 || gribversion == 1 )
- grib1PrintBMS(nrec, recpos, recsize, gribbuffer);
/*
- else if ( gribversion == 2 )
- grib2PrintBMS(nrec, recpos, recsize, gribbuffer);
+ -----------------------------------------------------------------
+ Section 2 . Print local ECMWF information.
+ -----------------------------------------------------------------
*/
- else
+ /*
+ Regular MARS labelling, or reformatted Washington EPS products.
+ */
+ if ( (ISEC1_CenterID == 98 && ISEC1_LocalFLag == 1) ||
+ (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag == 1) ||
+ (ISEC1_CenterID == 7 && ISEC1_SubCenterID == 98) )
{
- fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
- nrec, 0L, recpos, recsize, gribversion);
- }
-}
+ /* Parameters common to all definitions. */
+
+ fprintf(grprsm, " ECMWF local usage identifier. %9d\n", isec1[36]);
+ if ( isec1[36] == 1 )
+ fprintf(grprsm, " (Mars labelling or ensemble forecast)\n");
+ if ( isec1[36] == 2 )
+ fprintf(grprsm, " (Cluster means and standard deviations)\n");
+ if ( isec1[36] == 3 )
+ fprintf(grprsm, " (Satellite image data)\n");
+ if ( isec1[36] == 4 )
+ fprintf(grprsm, " (Ocean model data)\n");
+ if ( isec1[36] == 5 )
+ fprintf(grprsm, " (Forecast probability data)\n");
+ if ( isec1[36] == 6 )
+ fprintf(grprsm, " (Surface temperature data)\n");
+ if ( isec1[36] == 7 )
+ fprintf(grprsm, " (Sensitivity data)\n");
+ if ( isec1[36] == 8 )
+ fprintf(grprsm, " (ECMWF re-analysis data)\n");
+ if ( isec1[36] == 9 )
+ fprintf(grprsm, " (Singular vectors and ensemble perturbations)\n");
+ if ( isec1[36] == 10 )
+ fprintf(grprsm, " (EPS tubes)\n");
+ if ( isec1[36] == 11 )
+ fprintf(grprsm, " (Supplementary data used by analysis)\n");
+ if ( isec1[36] == 13 )
+ fprintf(grprsm, " (Wave 2D spectra direction and frequency)\n");
+
+ fprintf(grprsm, " Class. %9d\n", isec1[37]);
+ fprintf(grprsm, " Type. %9d\n", isec1[38]);
+ fprintf(grprsm, " Stream. %9d\n", isec1[39]);
+ sprintf(hversion, "%4s", (char*)&isec1[40]); hversion[4] = 0;
+ fprintf(grprsm, " Version number or Experiment identifier. %4s\n", hversion);
+ /*
+ ECMWF Local definition 1.
+ (MARS labelling or ensemble forecast data)
+ */
+ if ( isec1[36] == 1 )
+ {
+ fprintf(grprsm, " Forecast number. %9d\n", isec1[41]);
+ if ( isec1[39] != 1090 )
+ fprintf(grprsm, " Total number of forecasts. %9d\n", isec1[42]);
+
+ return;
+ }
+ /*
+ ECMWF Local definition 2.
+ (Cluster means and standard deviations)
+ */
+ if ( isec1[36] == 2 )
+ {
+ fprintf(grprsm, " Cluster number. %9d\n", isec1[41]);
+ fprintf(grprsm, " Total number of clusters. %9d\n", isec1[42]);
+ fprintf(grprsm, " Clustering method. %9d\n", isec1[43]);
+ fprintf(grprsm, " Start time step when clustering. %9d\n", isec1[44]);
+ fprintf(grprsm, " End time step when clustering. %9d\n", isec1[45]);
+ fprintf(grprsm, " Northern latitude of domain. %9d\n", isec1[46]);
+ fprintf(grprsm, " Western longitude of domain. %9d\n", isec1[47]);
+ fprintf(grprsm, " Southern latitude of domain. %9d\n", isec1[48]);
+ fprintf(grprsm, " Eastern longitude of domain. %9d\n", isec1[49]);
+ fprintf(grprsm, " Operational forecast in cluster %9d\n", isec1[50]);
+ fprintf(grprsm, " Control forecast in cluster %9d\n", isec1[51]);
+ fprintf(grprsm, " Number of forecasts in cluster. %9d\n", isec1[52]);
+ for (jloop = 0; jloop < isec1[52]; jloop++)
+ fprintf(grprsm, " Forecast number %9d\n", isec1[jloop+53]);
+
+ return;
+ }
+ /*
+ ECMWF Local definition 3.
+ (Satellite image data)
+ */
+ if ( isec1[36] == 3 )
+ {
+ fprintf(grprsm, " Satellite spectral band. %9d\n", isec1[41]);
+ fprintf(grprsm, " Function code. %9d\n", isec1[42]);
+ return;
+ }
+ /*
+ ECMWF Local definition 4.
+ (Ocean model data)
+ */
+ if ( isec1[36] == 4 )
+ {
+ fprintf(grprsm, " Satellite spectral band. %9d\n", isec1[41]);
+ if ( isec1[39] != 1090 )
+ fprintf(grprsm, " Function code. %9d\n", isec1[42]);
+ fprintf(grprsm, " Coordinate structure definition.\n");
+ fprintf(grprsm, " Fundamental spatial reference system.%9d\n", isec1[43]);
+ fprintf(grprsm, " Fundamental time reference. %9d\n", isec1[44]);
+ fprintf(grprsm, " Space unit flag. %9d\n", isec1[45]);
+ fprintf(grprsm, " Vertical coordinate definition. %9d\n", isec1[46]);
+ fprintf(grprsm, " Horizontal coordinate definition. %9d\n", isec1[47]);
+ fprintf(grprsm, " Time unit flag. %9d\n", isec1[48]);
+ fprintf(grprsm, " Time coordinate definition. %9d\n", isec1[49]);
+ fprintf(grprsm, " Position definition. \n");
+ fprintf(grprsm, " Mixed coordinate field flag. %9d\n", isec1[50]);
+ fprintf(grprsm, " Coordinate 1 flag. %9d\n", isec1[51]);
+ fprintf(grprsm, " Averaging flag. %9d\n", isec1[52]);
+ fprintf(grprsm, " Position of level 1. %9d\n", isec1[53]);
+ fprintf(grprsm, " Position of level 2. %9d\n", isec1[54]);
+ fprintf(grprsm, " Coordinate 2 flag. %9d\n", isec1[55]);
+ fprintf(grprsm, " Averaging flag. %9d\n", isec1[56]);
+ fprintf(grprsm, " Position of level 1. %9d\n", isec1[57]);
+ fprintf(grprsm, " Position of level 2. %9d\n", isec1[58]);
+ fprintf(grprsm, " Grid Definition.\n");
+ fprintf(grprsm, " Coordinate 3 flag (x-axis) %9d\n", isec1[59]);
+ fprintf(grprsm, " Coordinate 4 flag (y-axis) %9d\n", isec1[60]);
+ fprintf(grprsm, " Coordinate 4 of first grid point. %9d\n", isec1[61]);
+ fprintf(grprsm, " Coordinate 3 of first grid point. %9d\n", isec1[62]);
+ fprintf(grprsm, " Coordinate 4 of last grid point. %9d\n", isec1[63]);
+ fprintf(grprsm, " Coordinate 3 of last grid point. %9d\n", isec1[64]);
+ fprintf(grprsm, " i - increment. %9d\n", isec1[65]);
+ fprintf(grprsm, " j - increment. %9d\n", isec1[66]);
+ fprintf(grprsm, " Flag for irregular grid coordinates. %9d\n", isec1[67]);
+ fprintf(grprsm, " Flag for normal or staggered grids. %9d\n", isec1[68]);
+ fprintf(grprsm, " Further information.\n");
+ fprintf(grprsm, " Further information flag. %9d\n", isec1[69]);
+ fprintf(grprsm, " Auxiliary information.\n");
+ fprintf(grprsm, " No. entries in horizontal coordinate %9d\n", isec1[70]);
+ fprintf(grprsm, " No. entries in mixed coordinate defn.%9d\n", isec1[71]);
+ fprintf(grprsm, " No. entries in grid coordinate list. %9d\n", isec1[72]);
+ fprintf(grprsm, " No. entries in auxiliary array. %9d\n", isec1[73]);
+ /*
+ Horizontal coordinate supplement.
+ */
+ fprintf(grprsm, " Horizontal coordinate supplement.\n");
+ if ( isec1[70] == 0 )
+ {
+ fprintf(grprsm, "(None).\n");
+ }
+ else
+ {
+ fprintf(grprsm, "Number of items = %d\n", isec1[70]);
+ for (jloop = 0; jloop < isec1[70]; jloop++)
+ fprintf(grprsm, " %12d\n", isec1[74+jloop]);
+ }
+ /*
+ Mixed coordinate definition.
+ */
+ fprintf(grprsm, " Mixed coordinate definition.\n");
+ if ( isec1[71] == 0 )
+ {
+ fprintf(grprsm, "(None).\n");
+ }
+ else
+ {
+ fprintf(grprsm, "Number of items = %d\n", isec1[71]);
+ ioffset = 74 + isec1[70];
+ for (jloop = 0; jloop < isec1[71]; jloop++)
+ fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
+ }
+ /*
+ Grid coordinate list.
+ */
+ fprintf(grprsm, " Grid coordinate list. \n");
+ if ( isec1[72] == 0 )
+ {
+ fprintf(grprsm, "(None).\n");
+ }
+ else
+ {
+ fprintf(grprsm, "Number of items = %d\n", isec1[72]);
+ ioffset = 74 + isec1[70] + isec1[71];
+ for (jloop = 0; jloop < isec1[72]; jloop++)
+ fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
+ }
+ /*
+ Auxiliary array.
+ */
+ fprintf(grprsm, " Auxiliary array. \n");
+ if ( isec1[73] == 0 )
+ {
+ fprintf(grprsm, "(None).\n");
+ }
+ else
+ {
+ fprintf(grprsm, "Number of items = %d\n", isec1[73]);
+ ioffset = 74 + isec1[70] + isec1[71] + isec1[72];
+ for (jloop = 0; jloop < isec1[73]; jloop++)
+ fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
+ }
+ /*
+ Post-auxiliary array.
+ */
+ fprintf(grprsm, " Post-auxiliary array. \n");
+ ioffset = 74 + isec1[70] + isec1[71] + isec1[72] + isec1[73];
+ if ( isec1[ioffset] == 0 )
+ {
+ fprintf(grprsm, "(None).\n");
+ }
+ else
+ {
+ fprintf(grprsm, "Number of items = %d\n", isec1[ioffset]);
+ for (jloop = 1; jloop < isec1[ioffset]; jloop++)
+ fprintf(grprsm, " %12d\n", isec1[ioffset+jloop]);
+ }
-void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- static int header = 1;
- int level, nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- double cr = 1;
- double refval, scale;
+ return;
+ }
+ /*
+ ECMWF Local definition 5.
+ (Forecast probability data)
+ */
+ if ( isec1[36] == 5 )
+ {
+ fprintf(grprsm, " Forecast probability number %9d\n", isec1[41]);
+ fprintf(grprsm, " Total number of forecast probabilities %7d\n", isec1[42]);
+ fprintf(grprsm, " Threshold units decimal scale factor %9d\n", isec1[43]);
+ fprintf(grprsm, " Threshold indicator(1=lower,2=upper,3=both) %2d\n", isec1[44]);
+ if ( isec1[44] != 2 )
+ fprintf(grprsm, " Lower threshold value %9d\n", isec1[45]);
+ if ( isec1[44] != 1 )
+ fprintf(grprsm, " Upper threshold value %9d\n", isec1[46]);
+ return;
+ }
+ /*
+ ECMWF Local definition 6.
+ (Surface temperature data)
+ */
+ if ( isec1[36] == 6 )
+ {
+ iyear = isec1[43];
+ if ( iyear > 100 )
+ {
+ if ( iyear < 19000000 ) iyear = iyear + 19000000;
+ fprintf(grprsm, " Date of SST field used %9d\n", iyear);
+ }
+ else
+ fprintf(grprsm, "Date of SST field used Not given\n");
+ }
+ if ( isec1[44] == 0 )
+ fprintf(grprsm, " Type of SST field (= climatology) %9d\n", isec1[44]);
+ if ( isec1[44] == 1 )
+ fprintf(grprsm, " Type of SST field (= 1/1 degree) %9d\n", isec1[44]);
+ if ( isec1[44] == 2 )
+ fprintf(grprsm, " Type of SST field (= 2/2 degree) %9d\n", isec1[44]);
- UNUSED(recpos);
+ fprintf(grprsm, " Number of ICE fields used: %9d\n", isec1[45]);
- if ( header )
- {
- fprintf(stdout,
- " Rec : Code Level BDS Flag Scale RefValue Bits CR\n");
-/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
- header = 0;
- }
+ for (jloop = 1; jloop <= isec1[45]; jloop++)
+ {
+ iyear = isec1[44+(jloop*2)];
+ if ( iyear > 100 )
+ {
+ if ( iyear < 19000000 ) iyear = iyear + 19000000;
+ fprintf(grprsm, " Date of ICE field%3d %9d\n", jloop, iyear);
+ fprintf(grprsm, " Satellite number (ICE field%3d) %9d\n", jloop,
+ isec1[45+(jloop*2)]);
+ }
+ else
+ fprintf(grprsm, "Date of SST field used Not given\n");
+ }
+ /*
+ ECMWF Local definition 7.
+ (Sensitivity data)
+ */
+ if ( isec1[36] == 7 )
+ {
+ if ( isec1[38] == 51 )
+ fprintf(grprsm, " Forecast number %9d\n", isec1[41]);
+ if ( isec1[38] != 51 )
+ fprintf(grprsm, " Iteration number %9d\n", isec1[41]);
+ if ( isec1[38] != 52 )
+ fprintf(grprsm, " Total number of diagnostics %9d\n", isec1[42]);
+ if ( isec1[38] == 52 )
+ fprintf(grprsm, " No.interations in diag. minimisation %9d\n", isec1[42]);
+ fprintf(grprsm, " Domain(0=Global,1=Europe,2=N.Hem.,3=S.Hem.) %2d\n", isec1[43]);
+ fprintf(grprsm, " Diagnostic number %9d\n", isec1[44]);
+ }
+ /*
+ ECMWF Local definition 8.
+ (ECMWF re-analysis data)
+ */
+ if ( isec1[36] == 8 )
+ {
+ if ( (isec1[39] == 1043) ||
+ (isec1[39] == 1070) ||
+ (isec1[39] == 1071) )
+ {
+ fprintf(grprsm, " Interval between reference times %9d\n", isec1[41]);
+ for (jloop = 43; jloop <= 54; jloop++)
+ {
+ jiloop = jloop + 8;
+ fprintf(grprsm, " ERA section 1 octet %2d. %9d\n",
+ jiloop, isec1[jloop-1]);
+ }
+ }
+ else
+ {
+ for (jloop = 42; jloop <= 54; jloop++)
+ {
+ jiloop = jloop + 8;
+ fprintf(grprsm, " ERA section 1 octet %2d. %9d\n",
+ jiloop, isec1[jloop-1]);
+ }
+ }
+ return;
+ }
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
- }
+ if ( isec1[38] > 4 && isec1[38] < 9 )
+ {
+ fprintf(grprsm, " Simulation number. %9d\n", isec1[41]);
+ fprintf(grprsm, " Total number of simulations. %9d\n", isec1[42]);
+ }
+ /*
+ ECMWF Local definition 9.
+ (Singular vectors and ensemble perturbations)
+ */
+ if ( isec1[36] == 9 )
+ {
+ if ( isec1[38] == 60 )
+ fprintf(grprsm, " Perturbed ensemble forecast number %9d\n", isec1[41]);
+ if ( isec1[38] == 61 )
+ fprintf(grprsm, " Initial state perturbation number %9d\n", isec1[41]);
+ if ( isec1[38] == 62 )
+ fprintf(grprsm, " Singular vector number %9d\n", isec1[41]);
+ if ( isec1[38] == 62 )
+ {
+ fprintf(grprsm, " Number of iterations %9d\n", isec1[42]);
+ fprintf(grprsm, " Number of singular vectors computed %9d\n", isec1[43]);
+ fprintf(grprsm, " Norm used at initial time %9d\n", isec1[44]);
+ fprintf(grprsm, " Norm used at final time %9d\n", isec1[45]);
+ fprintf(grprsm, " Multiplication factor %9d\n", isec1[46]);
+ fprintf(grprsm, " Latitude of north-west corner %9d\n", isec1[47]);
+ fprintf(grprsm, " Longitude of north-west corner %9d\n", isec1[48]);
+ fprintf(grprsm, " Latitude of south-east corner %9d\n", isec1[49]);
+ fprintf(grprsm, " Longitude of south-east corner %9d\n", isec1[50]);
+ fprintf(grprsm, " Accuracy %9d\n", isec1[51]);
+ fprintf(grprsm, " Number of singular vectors evolved %9d\n", isec1[52]);
+ fprintf(grprsm, " Ritz number one %9d\n", isec1[53]);
+ fprintf(grprsm, " Ritz number two %9d\n", isec1[54]);
+ }
+ }
+ /*
+ ECMWF Local definition 10.
+ (EPS tubes)
+ */
+ if ( isec1[36] == 10 )
+ {
+ fprintf(grprsm, " Tube number %9d\n", isec1[41]);
+ fprintf(grprsm, " Total number of tubes %9d\n", isec1[42]);
+ fprintf(grprsm, " Central cluster definition %9d\n", isec1[43]);
+ fprintf(grprsm, " Parameter %9d\n", isec1[44]);
+ fprintf(grprsm, " Type of level %9d\n", isec1[45]);
+ fprintf(grprsm, " Northern latitude of domain of tubing%9d\n", isec1[46]);
+ fprintf(grprsm, " Western longitude of domain of tubing%9d\n", isec1[47]);
+ fprintf(grprsm, " Southern latitude of domain of tubing%9d\n", isec1[48]);
+ fprintf(grprsm, " Eastern longitude of domain of tubing%9d\n", isec1[49]);
+ fprintf(grprsm, " Tube number of operational forecast %9d\n", isec1[50]);
+ fprintf(grprsm, " Tube number of control forecast %9d\n", isec1[51]);
+ fprintf(grprsm, " Height/pressure of level %9d\n", isec1[52]);
+ fprintf(grprsm, " Reference step %9d\n", isec1[53]);
+ fprintf(grprsm, " Radius of central cluster %9d\n", isec1[54]);
+ fprintf(grprsm, " Ensemble standard deviation %9d\n", isec1[55]);
+ fprintf(grprsm, " Dist.of tube extreme to ensemble mean%9d\n", isec1[56]);
+ fprintf(grprsm, " Number of forecasts in the tube %9d\n", isec1[57]);
- if ( PDS_LevelType == 100 )
- level = PDS_Level * 100;
- else if ( PDS_LevelType == 99 )
- level = PDS_Level;
- else
- level = PDS_Level1;
+ fprintf(grprsm, " List of ensemble forecast numbers:\n");
+ for (jloop = 1; jloop <= isec1[57]; jloop++)
+ fprintf(grprsm, " %9d\n", isec1[57+jloop]);
+ }
+ /*
+ ECMWF Local definition 11.
+ (Supplementary data used by the analysis)
+ */
+ if ( isec1[36] == 11 )
+ {
+ fprintf(grprsm, " Details of analysis which used the supplementary data:\n");
+ fprintf(grprsm, " Class %9d\n", isec1[41]);
+ fprintf(grprsm, " Type %9d\n", isec1[42]);
+ fprintf(grprsm, " Stream %9d\n", isec1[43]);
+ /*
+ sprintf(hversion, "%8d", isec1[44]);
+ fprintf(grprsm, " Version number/experiment identifier: %4s\n", &hversion[4]);
+ */
+ iyear = isec1[45];
+ if ( iyear > 50 )
+ iyear = iyear + 1900;
+ else
+ iyear = iyear + 2000;
- if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
- {
- int s1, s2;
- s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
- s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
- cr = ((double)s1)/s2;
- }
+ fprintf(grprsm, " Year %9d\n", iyear);
+ fprintf(grprsm, " Month %9d\n", isec1[46]);
+ fprintf(grprsm, " Day %9d\n", isec1[47]);
+ fprintf(grprsm, " Hour %9d\n", isec1[48]);
+ fprintf(grprsm, " Minute %9d\n", isec1[49]);
+ fprintf(grprsm, " Century %9d\n", isec1[50]);
+ fprintf(grprsm, " Originating centre %9d\n", isec1[51]);
+ fprintf(grprsm, " Sub-centre %9d\n", isec1[52]);
+ }
+ /*
+ ECMWF Local definition 12.
+ */
+ if ( isec1[36] == 12 )
+ {
+ fprintf(grprsm, " (Mean, average, etc)\n");
+ fprintf(grprsm, " Start date of the period %8d\n", isec1[41]);
+ fprintf(grprsm, " Start time of the period %4.4d\n", isec1[42]);
+ fprintf(grprsm, " Finish date of the period %8d\n", isec1[43]);
+ fprintf(grprsm, " Finish time of the period %4.4d\n", isec1[44]);
+ fprintf(grprsm, " Verifying date of the period %8d\n", isec1[45]);
+ fprintf(grprsm, " Verifying time of the period %4.4d\n", isec1[46]);
+ fprintf(grprsm, " Code showing method %8d\n", isec1[47]);
+ fprintf(grprsm, " Number of different time intervals used %5d\n", isec1[48]);
+ fprintf(grprsm, " List of different time intervals used:\n");
+ iprev = isec1[49];
+ unsigned icount = 0;
+ for (jloop = 1; jloop <= isec1[48]; jloop++)
+ {
+ icurr = isec1[48+jloop];
+ if ( icurr != iprev )
+ {
+ if ( icount == 1 )
+ fprintf(grprsm, " - interval %5.4d used once\n", iprev);
+ if ( icount == 2 )
+ fprintf(grprsm, " - interval %5.4d used twice\n", iprev);
+ if ( icount > 2 )
+ fprintf(grprsm, " - interval %5.4d used %5u times\n", iprev, icount);
+ iprev = icurr;
+ icount = 1;
+ }
+ else
+ icount = icount + 1;
+ }
+ if ( icount == 1 )
+ fprintf(grprsm, " - interval %5.4d used once\n", iprev);
+ if ( icount == 2 )
+ fprintf(grprsm, " - interval %5.4d used twice\n", iprev);
+ if ( icount > 2 )
+ fprintf(grprsm, " - interval %5.4d used %5u times\n", iprev, icount);
+ }
+ /*
+ ECMWF Local definition 13.
+ (Wave 2D spectra direction and frequency)
+ */
+ if ( isec1[36] == 13 )
+ {
+ fprintf(grprsm, " Direction number %9d\n", isec1[43]);
+ fprintf(grprsm, " Frequency number %9d\n", isec1[44]);
+ fprintf(grprsm, " Total number of directions %9d\n", isec1[45]);
+ fprintf(grprsm, " Total number of frequencies %9d\n", isec1[46]);
+ fprintf(grprsm, " Scale factor applied to directions %9d\n", isec1[47]);
+ fprintf(grprsm, " Scale factor applied to frequencies %9d\n", isec1[48]);
+ fprintf(grprsm, " List of directions:\n");
+ for (jloop = 1; jloop <= isec1[45]; jloop++)
+ {
+ value = (float)(isec1[48+jloop])/(float)(isec1[47]);
+ if ( isec1[43] == jloop )
+ fprintf(grprsm, " %2.2d:%15.7f <-- this field value\n", jloop, value);
+ else
+ fprintf(grprsm, "%2.2d:%15.7f\n", jloop, value);
+ }
+ fprintf(grprsm, " List of frequencies:\n");
+ for (jloop = 1; jloop <= isec1[46]; jloop++)
+ {
+ value = (float)(isec1[48+isec1[45]+jloop])/(float)(isec1[48]);
+ if ( isec1[44] == jloop )
+ fprintf(grprsm, " %2.2d:%15.7f <-- this field value\n", jloop, value);
+ else
+ fprintf(grprsm, "%2.2d:%15.7f\n", jloop, value);
- refval = BDS_RefValue;
+ if ( isec1[49+isec1[45]+isec1[46]] != 0 )
+ {
+ fprintf(grprsm, " System number (65535 = missing) %9d\n",
+ isec1[49+isec1[45]+isec1[46]]);
+ fprintf(grprsm, " Method number (65535 = missing) %9d\n",
+ isec1[50+isec1[45]+isec1[46]]);
+ }
+ }
+ /*
+ ECMWF Local definition 14.
+ (Brightness temperature)
+ */
+ if ( isec1[36] == 14 )
+ {
+ fprintf(grprsm, " Channel number %9d\n", isec1[43]);
+ fprintf(grprsm, " Scale factor applied to frequencies %9d\n", isec1[44]);
+ fprintf(grprsm, " Total number of frequencies %9d\n", isec1[45]);
+ fprintf(grprsm, " List of frequencies:\n");
+ for (jloop = 1; jloop <= isec1[45]; jloop++)
+ {
+ value = (float)(isec1[45+jloop])/(float)(isec1[44]);
+ if ( isec1[43] == jloop )
+ fprintf(grprsm, " %3d:%15.9f <-- this channel\n", jloop, value);
+ else
+ fprintf(grprsm, " %3d:%15.9f\n", jloop, value);
+ }
+ }
+ /*
+ ECMWF Local definition 15.
+ (Ocean ensemble seasonal forecast)
+ */
+ if ( isec1[36] == 15 )
+ {
+ fprintf(grprsm, " Ensemble member number %9d\n", isec1[41]);
+ fprintf(grprsm, " System number %9d\n", isec1[42]);
+ fprintf(grprsm, " Method number %9d\n", isec1[43]);
+ }
+ /*
+ ECMWF Local definition 16.
+ (Seasonal forecast monthly mean atmosphere data)
+ */
+ if ( isec1[36] == 16 )
+ {
+ fprintf(grprsm, " Ensemble member number %9d\n", isec1[41]);
+ fprintf(grprsm, " System number %9d\n", isec1[43]);
+ fprintf(grprsm, " Method number %9d\n", isec1[44]);
+ fprintf(grprsm, " Verifying month %9d\n", isec1[45]);
+ fprintf(grprsm, " Averaging period %9d\n", isec1[46]);
+ }
+ /*
+ ECMWF Local definition 17.
+ (Sst or sea-ice used by analysis)
+ */
+ if ( isec1[36] == 17 )
+ {
+ iyear = isec1[43];
+ if ( iyear > 100 )
+ {
+ if ( iyear < 19000000 ) iyear = iyear + 19000000;
+ fprintf(grprsm, " Date of sst/ice field used %9d\n", iyear);
+ }
+ else
+ fprintf(grprsm, " Date of sst/ice field used Not given\n");
+
+ if ( isec1[44] == 0 )
+ fprintf(grprsm, " Type of sst/ice field (= climatology)%9d\n", isec1[44]);
+ if ( isec1[44] == 1 )
+ fprintf(grprsm, " Type of sst/ice field (= 1/1 degree) %9d\n", isec1[44]);
+ if ( isec1[44] == 2 )
+ fprintf(grprsm, " Type of sst/ice field (= 2/2 degree) %9d\n", isec1[44]);
- if ( BDS_BinScale < 0 )
- scale = 1.0/pow(2.0, (double) -BDS_BinScale);
- else
- scale = pow(2.0, (double) BDS_BinScale);
+ fprintf(grprsm, " Number of ICE fields used: %9d\n", isec1[45]);
- if ( PDS_DecimalScale )
- {
- double decscale;
- decscale = pow(10.0, (double)-PDS_DecimalScale);
- refval *= decscale;
- scale *= decscale;
+ for (jloop = 1; jloop < isec1[45]; jloop++)
+ {
+ iyear = isec1[44+(jloop*2)];
+ if ( iyear > 100 )
+ {
+ if ( iyear < 19000000 ) iyear = iyear + 19000000;
+ fprintf(grprsm, " Date of ICE field%3d %9d\n", jloop,
+ iyear);
+ fprintf(grprsm, " Satellite number (ICE field%3d) %9d\n", jloop,
+ isec1[45+(jloop*2)]);
+ }
+ else
+ fprintf(grprsm, "Date of sst/ice field used Not given\n");
+ }
+ }
+ }
}
-
- fprintf(stdout, "%5d :", nrec);
-
- if ( bds )
- fprintf(stdout, "%4d%7d %7d %4d %8.5g %11.5g%4d %6.4g",
- PDS_Parameter, level,
- BDS_Len, BDS_Flag, scale, refval, BDS_NumBits, cr);
- else
- fprintf(stdout, " Binary Data Section not defined");
-
- if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
- fprintf(stdout, "\n");
-}
-
-
-void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- int gribversion;
-
- gribversion = gribVersion(gribbuffer, (size_t)recsize);
-
- if ( gribversion == 0 || gribversion == 1 )
- grib1PrintBDS(nrec, recpos, recsize, gribbuffer);
/*
- else if ( gribversion == 2 )
- grib2PrintBDS(nrec, recpos, recsize, gribbuffer);
+ -----------------------------------------------------------------
+ Section 3 . Print Washington ensemble product information.
+ -----------------------------------------------------------------
*/
- else
- {
- fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
- nrec, 0L, recpos, recsize, gribversion);
- }
-}
-
-
-void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
- int level, nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- double cr = 1;
-
- UNUSED(recpos);
-
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
- }
-
- if ( nerr > 0 )
- {
- fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
- return;
- }
-
- if ( PDS_LevelType == 100 )
- level = PDS_Level * 100;
- else if ( PDS_LevelType == 99 )
- level = PDS_Level;
- else
- level = PDS_Level1;
-
- if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
+ /*
+ Washington EPS products (but not reformatted Washington EPS
+ products.
+ */
+ if ( (isec1[1] == 7 && isec1[23] == 1) && (! (ISEC1_SubCenterID == 98)) )
{
- int s1, s2;
- s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
- s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
- cr = ((double)s1)/s2;
+ /* CALL KWPRS1 (iSEC0,iSEC1)*/
}
-
- if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+ /*
+ -----------------------------------------------------------------
+ Section 4 . Print local MPIM information.
+ -----------------------------------------------------------------
+ */
+ if (isec1[ 1] == 252 && isec1[36] == 1)
{
- fprintf(stdout, "GRIB record %5d : code = %4d level = %7d\n", nrec, PDS_Parameter, level);
+ fprintf(grprsm, " MPIM local usage identifier. %9d\n", isec1[36]);
+ fprintf(grprsm, " Type of ensemble forecast %9d\n", isec1[37]);
+ fprintf(grprsm, " Individual ensemble member %9d\n", isec1[38]);
+ fprintf(grprsm, " Number of forecasts in ensemble %9d\n", isec1[39]);
}
}
-
-static
-void repair1(unsigned char *gbuf, long gbufsize)
+void printQuasi(int *isec2)
{
- int nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- /* int recLen; */
- unsigned char *source;
- size_t sourceLen;
- int bds_len, bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress */;
- int bds_head = 11;
- int bds_ext = 0, bds_ubits;
- int datstart = 0;
- /* int llarge = FALSE; */
-
- long gribrecsize;
- nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "GRIB message error\n");
- return;
- }
-
- if ( nerr > 0 )
- {
- fprintf(stdout, "GRIB data corrupted!\n");
- return;
- }
+ /*
- /* recLen = gribrec_len(gbuf[4], gbuf[5], gbuf[6]); */
- /* if ( recLen > JP23SET ) llarge = TRUE; */
+ Print the qusai-regular information in the Grid Description
+ Section (Section 2) of decoded GRIB data.
- bds_len = BDS_Len;
- bds_nbits = BDS_NumBits;
- bds_flag = BDS_Flag;
- bds_ubits = bds_flag & 15;
- lspherc = bds_flag >> 7;
- lcomplex = (bds_flag >> 6)&1;
- /* lcompress = (bds_flag >> 4)&1; */
+ Input Parameters:
- if ( lspherc )
- {
- if ( lcomplex )
- {
- int jup, ioff;
- jup = bds[15];
- ioff = (jup+1)*(jup+2);
- bds_ext = 4 + 3 + 4*ioff;
- }
- else
- {
- bds_ext = 4;
- }
- }
+ isec2 - Array of decoded integers from Section 2.
- datstart = bds_head + bds_ext;
+ Comments:
- source = bds + datstart;
+ Only data representation types catered for are Gaussian
+ grid, latitude/longitude grid, Spherical Harmonics,
+ Polar stereographic and Space view perspective.
- sourceLen = (size_t)(((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8);
+ Converted from EMOS routine PTQUASI.
- if ( bds_nbits == 24 )
- {
- unsigned char *pbuf = (unsigned char*) Malloc(sourceLen);;
- size_t nelem = sourceLen/3;
- for ( size_t i = 0; i < nelem; i++ )
- {
- pbuf[3*i ] = source[ i];
- pbuf[3*i+1] = source[ nelem+i];
- pbuf[3*i+2] = source[2*nelem+i];
- }
- memcpy(source, pbuf, sourceLen);
- Free(pbuf);
- }
-}
+ Uwe Schulzweida MPIfM 01/04/2001
+ */
-void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
-{
- int level, nerr;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- double cr = 1;
+ char yout[64];
+ int nextlat, latcnt;
+ int j;
+ int ntos;
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "%5d : GRIB message error\n", nrec);
- return;
- }
+ /*
+ -----------------------------------------------------------------
+ Section 1. Print quasi-grid data.
+ -----------------------------------------------------------------
+ */
+ /*
+ See if scanning is north->south or south->north
+ */
+ fprintf(grprsm, " Number of points along a parallel varies.\n");
- if ( nerr > 0 )
- {
- fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
- return;
- }
+ ntos = ( fmod((double) isec2[10], 128.) < 64 );
- if ( PDS_LevelType == 100 )
- level = PDS_Level * 100;
- else if ( PDS_LevelType == 99 )
- level = PDS_Level;
+ if ( ntos )
+ fprintf(grprsm, " Number of points. Parallel. (North to South)\n");
else
- level = PDS_Level1;
+ fprintf(grprsm, " Number of points. Parallel. (South to North)\n");
- if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
- {
- int s1, s2;
- s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
- s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
- cr = ((double)s1)/s2;
- }
+ /* Display number of points for each latitude */
+ latcnt = isec2[2];
+ nextlat = 0;
+ memset(yout, ' ', (size_t) 11);
- if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+ for ( j = 0; j < latcnt; j++ )
{
- fprintf(stdout, "Repair GRIB record %5d : code = %4d level = %7d\n", nrec, PDS_Parameter, level);
- repair1(gribbuffer, recsize);
+ nextlat = nextlat + 1;
+ sprintf(yout, "%4d", nextlat);
+
+ /* Finished? */
+ if ( nextlat > latcnt ) break;
+ if ( nextlat == latcnt )
+ {
+ fprintf(grprsm, " %5d %-12s\n", isec2[nextlat+21], yout);
+ break;
+ }
+ /*
+ Look for neighbouring latitudes with same number of points
+ */
+ unsigned nrepeat = 0;
+
+ LABEL110:
+ /*
+ If neighbouring latitudes have same number of points
+ increase the repeat count.
+ */
+ if ( isec2[nextlat+21+1] == isec2[nextlat+21] )
+ {
+ nrepeat = nrepeat + 1;
+ nextlat = nextlat + 1;
+ if ( nextlat < latcnt ) goto LABEL110;
+ }
+ /*
+ Display neighbouring latitudes with same number of points as
+ 'nn to mm'.
+ */
+ if ( nrepeat >= 1 )
+ {
+ strncpy(yout+4, " to", 3);
+ sprintf(yout+7, "%5d", nextlat);
+ }
+ fprintf(grprsm, " %5d %-12s\n", isec2[nextlat+21], yout);
+ memset(yout, ' ', (size_t) 11);
}
}
-#include <stdio.h>
-#include <string.h>
-#if defined (HAVE_CONFIG_H)
-#endif
+void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2)
+{
+ /*
-#if defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
-#if defined(__cplusplus)
-extern "C" {
-#endif
-#if defined (HAVE_LIBAEC)
-# include <libaec.h>
-#else
-# include <szlib.h>
-#endif
-#if defined (__cplusplus)
-}
-#endif
+ Print the information in the Grid Description
+ Section (Section 2) of decoded GRIB data.
-#if defined (HAVE_LIBAEC)
-# define AEC_FLAGS (AEC_DATA_MSB | AEC_DATA_PREPROCESS)
-#else
-# define OPTIONS_MASK (SZ_RAW_OPTION_MASK | SZ_MSB_OPTION_MASK | SZ_NN_OPTION_MASK)
-#endif
+ Input Parameters:
+
+ isec0 - Array of decoded integers from Section 0
-# define PIXELS_PER_BLOCK (8)
-# define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
+ isec2 - Array of decoded integers from Section 2
-# define MIN_COMPRESS (0.95)
-# define MIN_SIZE (256)
-#endif
+ fsec2 - Array of decoded floats from Section 2
-#define Z_SZIP 128
-#define Z_AEC 130
+ Comments:
+ Only data representation types catered for are Gaussian
+ grid, latitude/longitude grid, Spherical Harmonics,
+ Polar stereographic and Space view perspective.
-#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
- (var[offset+1] = 0xFF & (value >> 8)), \
- (var[offset+2] = 0xFF & (value )))
-#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
- (var[offset+1] = 0xFF & (value >> 16)), \
- (var[offset+2] = 0xFF & (value >> 8)), \
- (var[offset+3] = 0xFF & (value )))
+ Converted from EMOS routine GRPRS2.
-int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
-{
- /* urecsize : uncompressed record size */
- int compress = 0;
- int nerr;
- /* int bds_len, bds_nbits, lspherc, lcomplex; */
- int bds_flag, lcompress;
- long gribsize = 0;
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ Uwe Schulzweida MPIfM 01/04/2001
- int gribversion = gribVersion(gribbuffer, (size_t)recsize);
+ */
- if ( gribversion == 2 ) return (compress);
+ int i, ibit, iedit, ierr, iout, iresol;
- long gribrecsize;
- nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
+ grsdef();
+ /*
+ -----------------------------------------------------------------
+ Section 1 . Print GRIB Edition number.
+ -----------------------------------------------------------------
+ */
+ iedit = isec0[1];
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Section 2 - Grid Description Section.\n");
+ fprintf(grprsm, " -------------------------------------\n");
+ /*
+ -----------------------------------------------------------------
+ Section 2 . Print spherical harmonic data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 50 || isec2[0] == 60 ||
+ isec2[0] == 70 || isec2[0] == 80 )
{
- fprintf(stdout, "GRIB message error\n");
- return (compress);
+ fprintf(grprsm, " Data represent type = spectral (Table 6) %9d\n", isec2[0]);
+ fprintf(grprsm, " J - Pentagonal resolution parameter. %9d\n", isec2[1]);
+ fprintf(grprsm, " K - Pentagonal resolution parameter. %9d\n", isec2[2]);
+ fprintf(grprsm, " M - Pentagonal resolution parameter. %9d\n", isec2[3]);
+ fprintf(grprsm, " Representation type (Table 9) %9d\n", isec2[4]);
+ fprintf(grprsm, " Representation mode (Table 10). %9d\n", isec2[5]);
+ for (i = 7; i <= 11; i++)
+ fprintf(grprsm, " Not used. %9d\n", isec2[i-1]);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ goto LABEL800;
}
-
- if ( nerr > 0 )
+ /*
+ -----------------------------------------------------------------
+ Section 3 . Print Gaussian grid data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 4 || isec2[0] == 14 ||
+ isec2[0] == 24 || isec2[0] == 34 )
{
- fprintf(stdout, "GRIB data corrupted!\n");
- return (compress);
- }
+ fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+ fprintf(grprsm, " Data represent type = gaussian (Table 6) %9d\n", isec2[0]);
+ /*
+ Quasi-regular grids introduced in Edition 1.
+ */
+ if ( isec2[16] == 0 || iedit < 1 )
+ fprintf(grprsm, " Number of points along a parallel. %9d\n", isec2[1]);
+ else
+ printQuasi(isec2);
- /* bds_len = BDS_Len; */
- /* bds_nbits = BDS_NumBits; */
- bds_flag = BDS_Flag;
- /* lspherc = bds_flag >> 7; */
- /* lcomplex = (bds_flag >> 6)&1; */
- lcompress = (bds_flag >> 4)&1;
+ fprintf(grprsm, " Number of points along a meridian. %9d\n", isec2[2]);
+ fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
+ fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
- *urecsize = 0;
- if ( lcompress )
- {
- compress = BDS_Z;
- if ( compress == Z_SZIP || compress == Z_AEC )
- {
- gribsize = gribrec_len(bds[14], bds[15], bds[16]);
- }
- }
+ ibit = 8;
+ iresol = isec2[5] + isec2[17] + isec2[18];
+ prtbin(iresol, ibit, &iout, &ierr);
- *urecsize = gribsize;
+ fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
+ fprintf(grprsm, " Latitude of last grid point. %9d\n", isec2[6]);
+ fprintf(grprsm, " Longitude of last grid point. %9d\n", isec2[7]);
+ /*
+ Print increment if given.
+ */
+ if ( isec2[5] == 128 )
+ fprintf(grprsm, " i direction (East-West) increment. %9d\n", isec2[8]);
+ else
+ fprintf(grprsm, " i direction (East-West) increment Not given\n");
- return (compress);
-}
+ fprintf(grprsm, " Number of parallels between pole and equator.%9d\n", isec2[9]);
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
-int gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
-{
- int nerr;
- int gribLen;
- int rec_len;
- int llarge = FALSE;
-#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
- static int libszwarn = 1;
-#endif
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ goto LABEL800;
+ }
+ /*
+ -----------------------------------------------------------------
+ Section 4 . Print Latitude / longitude grid data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 0 || isec2[0] == 10 ||
+ isec2[0] == 20 || isec2[0] == 30 )
+ {
+ fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+ fprintf(grprsm, " Data represent type = lat/long (Table 6) %9d\n", isec2[0]);
+ /*
+ Quasi-regular lat/long grids also possible.
+ */
+ if ( isec2[16] == 0 )
+ fprintf(grprsm, " Number of points along a parallel. %9d\n", isec2[1]);
+ else
+ printQuasi(isec2);
- gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
- if ( gribLen > JP23SET ) llarge = TRUE;
+ fprintf(grprsm, " Number of points along a meridian. %9d\n", isec2[2]);
+ fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
+ fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
- rec_len = gribLen;
+ ibit = 8;
+ iresol = isec2[5] + isec2[17] + isec2[18];
+ prtbin(iresol, ibit, &iout, &ierr);
- long gribrecsize;
- nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
+ fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
+ fprintf(grprsm, " Latitude of last grid point. %9d\n", isec2[6]);
+ fprintf(grprsm, " Longitude of last grid point. %9d\n", isec2[7]);
+ /*
+ Print increment if given.
+ */
+ if ( isec2[8] < 0 )
+ fprintf(grprsm, " i direction (East-West) increment Not given\n");
+ else
+ fprintf(grprsm, " i direction (East-West) increment. %9d\n", isec2[8]);
+
+ if ( isec2[9] < 0 )
+ fprintf(grprsm, " j direction (North-South) increment Not given\n");
+ else
+ fprintf(grprsm, " j direction (North-South) increment. %9d\n", isec2[9]);
+
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
+
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ goto LABEL800;
+ }
+ /*
+ -----------------------------------------------------------------
+ Section 5 . Print polar stereographic data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 5 )
{
- fprintf(stdout, "GRIB message error\n");
- return (rec_len);
+ fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+ fprintf(grprsm, " Data represent type = polar stereo (Table 6) %9d\n", isec2[0]);
+ fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
+ fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
+ fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
+ fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
+ ibit = 8;
+ iresol = isec2[17] + isec2[18];
+ prtbin(iresol, ibit, &iout, &ierr);
+ fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
+ fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
+ fprintf(grprsm, " X direction increment. %9d\n", isec2[8]);
+ fprintf(grprsm, " Y direction increment. %9d\n", isec2[9]);
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ fprintf(grprsm, " Projection centre flag. %9d\n", isec2[12]);
+ goto LABEL800;
}
-
- if ( nerr > 0 )
+ /*
+ -----------------------------------------------------------------
+ Section 6 . Print Lambert conformal data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 3 )
{
- fprintf(stdout, "GRIB data corrupted!\n");
- return (rec_len);
+ fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+ fprintf(grprsm, " Data represent type = Lambert (Table 6) %9d\n", isec2[0]);
+ fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
+ fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
+ fprintf(grprsm, " Latitude of first grid point. %9d\n", isec2[3]);
+ fprintf(grprsm, " Longitude of first grid point. %9d\n", isec2[4]);
+ ibit = 8;
+ iresol = isec2[17] + isec2[18] + isec2[5];
+ prtbin(iresol, ibit, &iout, &ierr);
+ fprintf(grprsm, " Resolution and components flag. %8.8d\n", iout);
+ fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
+ fprintf(grprsm, " X direction increment. %9d\n", isec2[8]);
+ fprintf(grprsm, " Y direction increment. %9d\n", isec2[9]);
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ fprintf(grprsm, " Projection centre flag. %9d\n", isec2[12]);
+ fprintf(grprsm, " Latitude intersection 1 - Latin 1 -. %9d\n", isec2[13]);
+ fprintf(grprsm, " Latitude intersection 2 - Latin 2 -. %9d\n", isec2[14]);
+ fprintf(grprsm, " Latitude of Southern Pole. %9d\n", isec2[19]);
+ fprintf(grprsm, " Longitude of Southern Pole. %9d\n", isec2[20]);
+ goto LABEL800;
}
+ /*
+ -----------------------------------------------------------------
+ Section 7 . Print space view perspective or orthographic data.
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 90 )
+ {
+ fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+ fprintf(grprsm, " Data represent type = space/ortho (Table 6) %9d\n", isec2[0]);
+ fprintf(grprsm, " Number of points along X axis. %9d\n", isec2[1]);
+ fprintf(grprsm, " Number of points along Y axis. %9d\n", isec2[2]);
+ fprintf(grprsm, " Latitude of sub-satellite point. %9d\n", isec2[3]);
+ fprintf(grprsm, " Longitude of sub-satellite point. %9d\n", isec2[4]);
+ //iresol = isec2[17] + isec2[18];
+ fprintf(grprsm, " Diameter of the earth in x direction. %9d\n", isec2[6]);
+ fprintf(grprsm, " Y coordinate of sub-satellite point. %9d\n", isec2[9]);
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ fprintf(grprsm, " Orientation of the grid. %9d\n", isec2[6]);
+ fprintf(grprsm, " Altitude of the camera. %9d\n", isec2[13]);
+ fprintf(grprsm, " Y coordinate of origin of sector image. %9d\n", isec2[14]);
+ fprintf(grprsm, " X coordinate of origin of sector image. %9d\n", isec2[15]);
+ goto LABEL800;
+ }
+ /*
+ -----------------------------------------------------------------
+ Section 7.5 . Print ocean data
+ -----------------------------------------------------------------
+ */
+ /*
+ if ( isec2[0] == 192 && ISEC1_CenterID == 98 )
+ {
+ fprintf(grprsm, " Data represent type = ECMWF ocean (Table 6) %9d\n", isec2[0]);
+ if ( isec2[1] == 32767 )
+ fprintf(grprsm, " Number of points along the first axis. Not used\n");
+ else
+ fprintf(grprsm, " Number of points along the first axis. %9d\n", isec2[1]);
-#if defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
-
- {
- long i;
- int bdsLen;
- int gribLenOld = 0;
- int status;
- size_t datstart, datsize;
-#if defined (HAVE_LIBAEC)
- struct aec_stream strm;
-#else
- SZ_com_t sz_param; /* szip parameter block */
-#endif
- unsigned char *dest, *source;
- size_t destLen, sourceLen;
- int bits_per_sample;
- int bds_len, bds_nbits, bds_flag, lspherc, lcomplex,/* lcompress,*/ bds_ubits;
- int bds_head = 11;
- int bds_ext = 0;
- int bds_zoffset, bds_zstart;
- unsigned char *pbuf = NULL;
-
- bds_zstart = 14;
- bds_zoffset = 12;
- if ( llarge ) bds_zoffset += 2;
-
- bds_len = BDS_Len;
- bds_len = correct_bdslen(bds_len, gribLen, bds-dbuf);
- bds_nbits = BDS_NumBits;
- bds_flag = BDS_Flag;
- bds_ubits = bds_flag & 15;
- lspherc = bds_flag >> 7;
- lcomplex = (bds_flag >> 6)&1;
- /* lcompress = (bds_flag >> 4)&1; */
-
- if ( bds_nbits != 8 && bds_nbits != 16 && bds_nbits != 24 && bds_nbits != 32 )
- {
- static int linfo = 1;
- if ( linfo && bds_nbits != 0 )
- {
- linfo = 0;
- fprintf(stderr, "GRIB szip only supports 8, 16, 24 and 32 bit data!\n");
- }
- return (rec_len);
- }
+ if ( isec2[2] == 32767 )
+ fprintf(grprsm, " Number of points along the second axis. Not used\n");
+ else
+ fprintf(grprsm, " Number of points along the second axis. %9d\n", isec2[2]);
-#if defined (HAVE_LIBSZ)
- if ( bds_nbits == 24 )
- bits_per_sample = 8;
- else
-#endif
- bits_per_sample = bds_nbits;
+ ibit = 8;
+ prtbin(isec2[10], ibit, &iout, &ierr);
+ fprintf(grprsm, " Scanning mode flags (Code Table 8) %8.8d\n", iout);
+ goto LABEL800;
+ }
+ */
+ /*
+ -----------------------------------------------------------------
+ Section 7.6 . Print triangular data
+ -----------------------------------------------------------------
+ */
+ if ( isec2[0] == 192 /* && ISEC1_CenterID == 78 */ )
+ {
+ fprintf(grprsm, " Data represent type = triangular (Table 6) %9d\n", isec2[0]);
+ fprintf(grprsm, " Number of factor 2 in factorisation of Ni. %9d\n", isec2[1]);
+ fprintf(grprsm, " Number of factor 3 in factorisation of Ni. %9d\n", isec2[2]);
+ fprintf(grprsm, " Number of diamonds (Nd). %9d\n", isec2[3]);
+ fprintf(grprsm, " Number of triangular subdivisions of the\n");
+ fprintf(grprsm, " icosahedron (Ni). %9d\n", isec2[4]);
+ fprintf(grprsm, " Flag for orientation of diamonds (Table A). %9d\n", isec2[5]);
+ fprintf(grprsm, " Latitude of pole point. %9d\n", isec2[6]);
+ fprintf(grprsm, " Longitude of pole point. %9d\n", isec2[7]);
+ fprintf(grprsm, " Longitude of the first diamond. %9d\n", isec2[8]);
+ fprintf(grprsm, " Flag for storage sequence (Table B). %9d\n", isec2[9]);
+ fprintf(grprsm, " Number of vertical coordinate parameters. %9d\n", isec2[11]);
+ goto LABEL800;
+ }
+ /*
+ -----------------------------------------------------------------
+ Drop through to here => representation type not catered for.
+ -----------------------------------------------------------------
+ */
+ fprintf(grprsm, "GRPRS2 :Data representation type not catered for -%d\n", isec2[0]);
-#if defined (HAVE_LIBAEC)
- strm.bits_per_sample = bits_per_sample;
- strm.block_size = PIXELS_PER_BLOCK;
- strm.rsi = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
- strm.flags = AEC_FLAGS;
- if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE;
-#else
- sz_param.options_mask = OPTIONS_MASK;
- sz_param.bits_per_pixel = bits_per_sample;
- sz_param.pixels_per_block = PIXELS_PER_BLOCK;
- sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
-#endif
+ goto LABEL900;
+ /*
+ -----------------------------------------------------------------
+ Section 8 . Print vertical coordinate parameters,
+ rotated grid information,
+ stretched grid information, if any.
+ -----------------------------------------------------------------
+ */
+ LABEL800:;
+ /*
+ Vertical coordinate parameters ...
+ */
+ if ( isec2[11] != 0 )
+ {
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Vertical Coordinate Parameters.\n");
+ fprintf(grprsm, " -------------------------------\n");
+ for ( i = 10; i < isec2[11]+10; i++ )
+ fprintf(grprsm, " %20.12f\n", fsec2[i]);
+ }
+ /*
+ Rotated and stretched grids introduced in Edition 1.
+ */
+ if ( iedit < 1 ) goto LABEL900;
+ /*
+ Rotated grid information ...
+ */
+ if ( isec2[0] == 10 || isec2[0] == 30 ||
+ isec2[0] == 14 || isec2[0] == 34 ||
+ isec2[0] == 60 || isec2[0] == 80 ||
+ isec2[0] == 30 )
+ {
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Latitude of southern pole of rotation. %9d\n", isec2[12]);
+ fprintf(grprsm, " Longitude of southern pole of rotation. %9d\n", isec2[13]);
+ fprintf(grprsm, " Angle of rotation. %20.10f\n", fsec2[0]);
+ }
+ /*
+ Stretched grid information ...
+ */
+ if ( isec2[0] == 20 || isec2[0] == 30 ||
+ isec2[0] == 24 || isec2[0] == 34 ||
+ isec2[0] == 70 || isec2[0] == 80 )
+ {
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Latitude of pole of stretching. %9d\n", isec2[14]);
+ fprintf(grprsm, " Longitude of pole of stretching. %9d\n", isec2[15]);
+ fprintf(grprsm, " Stretching factor. %20.10f\n", fsec2[1]);
+ }
- if ( lspherc )
- {
- if ( lcomplex )
- {
- int jup, ioff;
- jup = bds[15];
- ioff = (jup+1)*(jup+2);
- bds_ext = 4 + 3 + 4*ioff;
- }
- else
- {
- bds_ext = 4;
- }
- }
+ LABEL900:;
- datstart = bds_head + bds_ext;
+ return;
+}
- datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
+void gribPrintSec2SP(int *isec0, int *isec2, float *fsec2sp)
+{
+ int inum;
+ int j;
+ double *fsec2;
- if ( datsize < MIN_SIZE ) return (rec_len);
- /*
- fprintf(stderr, "%d %d %d %d\n", bds_len, datstart, bds_len - datstart, datsize);
- */
- sourceLen = datsize;
- destLen = sbufsize;
-
- source = bds + datstart;
- dest = sbuf;
+ inum = 10 + isec2[11];
-#if defined (HAVE_LIBSZ)
- if ( bds_nbits == 24 )
- {
- long nelem;
- nelem = sourceLen/3;
- pbuf = (unsigned char*) Malloc(sourceLen);
- for ( i = 0; i < nelem; i++ )
- {
- pbuf[ i] = source[3*i ];
- pbuf[ nelem+i] = source[3*i+1];
- pbuf[2*nelem+i] = source[3*i+2];
- }
- source = pbuf;
- }
-#endif
+ fsec2 = (double*) Malloc((size_t)inum*sizeof(double));
+ if ( fsec2 == NULL ) SysError("No Memory!");
-#if defined (HAVE_LIBAEC)
- strm.next_in = source;
- strm.avail_in = sourceLen;
- strm.next_out = dest;
- strm.avail_out = destLen;
+ for ( j = 0; j < inum; j++ )
+ fsec2[j] = fsec2sp[j];
+
+ gribPrintSec2DP(isec0, isec2, fsec2);
- status = aec_buffer_encode(&strm);
- if ( status != AEC_OK )
- {
- if ( status != AEC_DATA_ERROR )
- Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
- }
+ Free(fsec2);
+}
- destLen = strm.total_out;
-#else
- status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
- if ( status != SZ_OK )
- {
- if ( status == SZ_NO_ENCODER_ERROR )
- Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_PARAM_ERROR )
- Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_MEM_ERROR )
- Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_OUTBUFF_FULL )
- /*Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2)*/;
- else
- Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
- }
-#endif
-
- if ( pbuf ) Free(pbuf);
- /*
- fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
- */
- if ( destLen < MIN_COMPRESS*sourceLen )
- {
- source = bds + datstart + bds_zoffset;
- memcpy(source, dest, destLen);
-
- /* ----++++ number of unused bits at end of section) */
+void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3)
+{
+ /*
- BDS_Flag -= bds_ubits;
-
- gribLenOld = gribLen;
+ Print the information in the Bit-Map Section
+ (Section 3) of decoded GRIB data.
- if ( bds_ext )
- for ( i = bds_ext-1; i >= 0; --i )
- bds[bds_zoffset+bds_head+i] = bds[bds_head+i];
+ Input Parameters:
- /*
- fprintf(stderr, "destLen, datsize, datstart %d %d %d\n", destLen, datsize, datstart);
- */
- /* memcpy(bds + datstart + bds_zoffset, source, destLen); */
- /*
- fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
- (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
- */
- if ( llarge )
- {
- if ( gribLenOld%120 )
- {
- fprintf(stderr, "Internal problem, record length not multiple of 120!");
- while ( gribLenOld%120 ) gribLenOld++;
- }
- gribLenOld = gribLenOld / (-120);
- gribLenOld = JP23SET - gribLenOld + 1;
+ isec0 - Array of decoded integers from Section 0
- SetLen3(bds, bds_zstart, gribLenOld);
- SetLen4(bds, bds_zstart+3, sourceLen);
- SetLen4(bds, bds_zstart+7, destLen);
- }
- else
- {
- SetLen3(bds, bds_zstart, gribLenOld);
- SetLen3(bds, bds_zstart+3, sourceLen);
- SetLen3(bds, bds_zstart+6, destLen);
- }
+ isec3 - Array of decoded integers from Section 3
- bdsLen = datstart + bds_zoffset + destLen;
+ fsec3 - Array of decoded floats from Section 3
- bds[11] = 0;
- bds[12] = 0;
-#if defined (HAVE_LIBAEC)
- BDS_Z = Z_AEC;
-#else
- BDS_Z = Z_SZIP;
-#endif
- BDS_Flag += 16;
- if ( (bdsLen%2) == 1 )
- {
- BDS_Flag += 8;
- bds[bdsLen++] = 0;
- }
+ Converted from EMOS routine GRPRS3.
- SetLen3(bds, 0, bdsLen);
+ Uwe Schulzweida MPIfM 01/04/2001
- gribLen = (bds - dbuf) + bdsLen;
+ */
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
+ UNUSED(isec0);
- if ( llarge )
- {
- long itemp;
- long bdslen = gribLen - 4;
+ grsdef();
- /*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- while ( gribLen%120 ) dbuf[gribLen++] = 0;
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Section 3 - Bit-map Section.\n");
+ fprintf(grprsm, " -------------------------------------\n");
- itemp = gribLen / (-120);
- itemp = JP23SET - itemp + 1;
+ if ( isec3[0] != 0 )
+ fprintf(grprsm, " Predetermined bit-map number. %9d\n", isec3[0]);
+ else
+ fprintf(grprsm, " No predetermined bit-map.\n");
- SetLen3(dbuf, 4, itemp);
+ fprintf(grprsm, " Missing data value for integer data. %14d\n", isec3[1]);
- bdslen = gribLen - bdslen;
+ fprintf(grprsm, " Missing data value for real data. %20.6g\n", fsec3[1]);
+}
- SetLen3(bds, 0, bdslen);
- }
- else
- {
- SetLen3(dbuf, 4, gribLen);
- }
- }
- else
- {
- }
- /*
- fprintf(stderr, "%3d %3d griblen in %6d out %6d CR %g slen %6d dlen %6d CR %g\n",
- PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
- ((double)gribLenOld)/gribLen, sourceLen, destLen,
- ((double)sourceLen)/destLen);
- */
- }
+void gribPrintSec3SP(int *isec0, int *isec3, float *fsec3sp)
+{
+ double fsec3[2];
-#else
+ fsec3[0] = fsec3sp[0];
+ fsec3[1] = fsec3sp[1];
- UNUSED(sbuf);
- UNUSED(sbufsize);
+ gribPrintSec3DP(isec0, isec3, fsec3);
+}
- if ( libszwarn )
- {
- Warning("Compression disabled, szlib or libaec not available!");
- libszwarn = 0;
- }
-#endif
+void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4)
+{
+ /*
- if ( llarge )
- while ( gribLen%120 ) dbuf[gribLen++] = 0;
- else
- while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+ Print the information in the Binary Data Section
+ (Section 4) of decoded GRIB data.
- rec_len = gribLen;
+ Input Parameters:
- return (rec_len);
-}
+ isec0 - Array of decoded integers from Section 0
+ isec4 - Array of decoded integers from Section 4
-int gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
-{
-#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
- static int libszwarn = 1;
-#endif
- unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- size_t gribLen = 0;
- unsigned char *dest, *source;
- size_t destLen, sourceLen;
- int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
- enum { bds_head = 11 };
- int bds_ext = 0;
- int bds_zoffset, bds_zstart;
- int llarge = FALSE;
+ fsec4 - Array of decoded floats from Section 4
- UNUSED(dbufsize);
- long gribrecsize;
- int nerr = grib1Sections(sbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
- {
- fprintf(stdout, "GRIB message error\n");
- return (0);
- }
+ Converted from EMOS routine GRPRS4.
- if ( nerr > 0 )
- {
- fprintf(stdout, "GRIB data corrupted!\n");
- return (0);
- }
+ Uwe Schulzweida MPIfM 01/04/2001
- bds_zstart = 14;
+ */
+ int inum;
+ int j;
- int recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
- if ( recLen > JP23SET ) llarge = TRUE;
+ UNUSED(isec0);
- bds_zoffset = 12;
- if ( llarge ) bds_zoffset += 2;
+ grsdef();
- /* bds_len = BDS_Len; */
- bds_nbits = BDS_NumBits;
- bds_flag = BDS_Flag;
- lspherc = bds_flag >> 7;
- lcomplex = (bds_flag >> 6)&1;
- /* lcompress = (bds_flag >> 4)&1; */
+ /*
+ -----------------------------------------------------------------
+ Section 1 . Print integer information from isec4.
+ -----------------------------------------------------------------
+ */
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " Section 4 - Binary Data Section.\n");
+ fprintf(grprsm, " -------------------------------------\n");
- if ( lspherc )
+ fprintf(grprsm, " Number of data values coded/decoded. %9d\n", isec4[0]);
+ fprintf(grprsm, " Number of bits per data value. %9d\n", isec4[1]);
+ fprintf(grprsm, " Type of data (0=grid pt, 128=spectral).%9d\n", isec4[2]);
+ fprintf(grprsm, " Type of packing (0=simple, 64=complex). %9d\n", isec4[3]);
+ fprintf(grprsm, " Type of data (0=float, 32=integer). %9d\n", isec4[4]);
+ fprintf(grprsm, " Additional flags (0=none, 16=present). %9d\n", isec4[5]);
+ fprintf(grprsm, " Reserved. %9d\n", isec4[6]);
+ fprintf(grprsm, " Number of values (0=single, 64=matrix). %9d\n", isec4[7]);
+ fprintf(grprsm, " Secondary bit-maps (0=none, 32=present). %9d\n", isec4[8]);
+ fprintf(grprsm, " Values width (0=constant, 16=variable).%9d\n", isec4[9]);
+ /*
+ If complex packing ..
+ */
+ if ( isec4[3] == 64 )
{
- if ( lcomplex )
+ if ( isec4[2] == 128 )
{
- int jup, ioff;
- jup = bds[bds_zoffset+15];
- ioff = (jup+1)*(jup+2);
- bds_ext = 4 + 3 + 4*ioff;
+ fprintf(grprsm, " Byte offset of start of packed data (N). %9d\n", isec4[15]);
+ fprintf(grprsm, " Power (P * 1000). %9d\n", isec4[16]);
+ fprintf(grprsm, " Pentagonal resolution parameter J for subset.%9d\n", isec4[17]);
+ fprintf(grprsm, " Pentagonal resolution parameter K for subset.%9d\n", isec4[18]);
+ fprintf(grprsm, " Pentagonal resolution parameter M for subset.%9d\n", isec4[19]);
}
else
{
- bds_ext = 4;
- }
+ fprintf(grprsm, " Bits number of 2nd order values (none=>0).%9d\n", isec4[10]);
+ fprintf(grprsm, " General extend. 2-order packing (0=no,8=yes).%9d\n", isec4[11]);
+ fprintf(grprsm, " Boustrophedonic ordering (0=no,4=yes).%9d\n", isec4[12]);
+ fprintf(grprsm, " Spatial differencing order (0=none).%9d\n", isec4[13]+isec4[14]);
+ }
}
-
- size_t datstart = bds_head + (size_t)bds_ext;
-
- source = bds + datstart + bds_zoffset;
- if ( llarge )
- sourceLen = ((size_t) ((bds[21]<<24)+(bds[22]<<16)+(bds[23]<<8)+bds[24]));
- else
- sourceLen = ((size_t) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
-
- nerr = grib1Sections(dbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
- if ( nerr < 0 )
+ /*
+ Number of non-missing values
+ */
+ if ( isec4[20] != 0 )
+ fprintf(grprsm, " Number of non-missing values %9d\n", isec4[20]);
+ /*
+ Information on matrix of values , if present.
+ */
+ if ( isec4[7] == 64 )
{
- fprintf(stdout, "GRIB message error\n");
- return (0);
+ fprintf(grprsm, " First dimension (rows) of each matrix. %9d\n", isec4[49]);
+ fprintf(grprsm, " Second dimension (columns) of each matrix. %9d\n", isec4[50]);
+ fprintf(grprsm, " First dimension coordinate values definition.%9d\n", isec4[51]);
+ fprintf(grprsm, " (Code Table 12)\n");
+ fprintf(grprsm, " NC1 - Number of coefficients for 1st dimension.%7d\n", isec4[52]);
+ fprintf(grprsm, " Second dimension coordinate values definition.%8d\n", isec4[53]);
+ fprintf(grprsm, " (Code Table 12)\n");
+ fprintf(grprsm, " NC2 - Number of coefficients for 2nd dimension.%7d\n", isec4[54]);
+ fprintf(grprsm, " 1st dimension physical signifance (Table 13). %8d\n", isec4[55]);
+ fprintf(grprsm, " 2nd dimension physical signifance (Table 13).%8d\n", isec4[56]);
}
+ /*
+ -----------------------------------------------------------------
+ Section 2. Print values from fsec4.
+ -----------------------------------------------------------------
+ */
- if ( nerr > 0 )
+ inum = isec4[0];
+ if ( inum < 0 ) inum = - inum;
+ if ( inum > 20 ) inum = 20;
+ /*
+ Print first inum values.
+ */
+ fprintf(grprsm, " \n");
+ fprintf(grprsm, " First %4d data values.\n", inum);
+
+ if ( isec4[4] == 0 )
{
- fprintf(stdout, "GRIB data corrupted!\n");
- return (0);
+ /*
+ Print real values ...
+ */
+ for ( j = 0; j < inum; j++ )
+ {
+ if ( fabs(fsec4[j]) > 0 )
+ {
+ if ( fabs(fsec4[j]) >= 0.1 && fabs(fsec4[j]) <= 1.e8 )
+ fprintf(grprsm, " %#16.8G \n", fsec4[j]);
+ else
+ fprintf(grprsm, " %#20.8E\n", fsec4[j]);
+ }
+ else
+ fprintf(grprsm, " %#16.0f \n", fabs(fsec4[j]));
+ }
}
-
- dest = bds + datstart;
- if ( llarge )
- destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
else
- destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-
- BDS_Flag = (unsigned char)(BDS_Flag - 16);
-
- size_t bdsLen = datstart + destLen;
-
-#if defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
- {
- int status;
- long i;
- size_t tmpLen;
- int bds_ubits;
- int bits_per_sample;
-#if defined (HAVE_LIBAEC)
- struct aec_stream strm;
-#else
- SZ_com_t sz_param; /* szip parameter block */
-#endif
-
-#if defined (HAVE_LIBSZ)
- if ( bds_nbits == 24 )
- bits_per_sample = 8;
- else
-#endif
- bits_per_sample = bds_nbits;
-
-#if defined (HAVE_LIBAEC)
- strm.bits_per_sample = bits_per_sample;
- strm.block_size = PIXELS_PER_BLOCK;
- strm.rsi = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
- strm.flags = AEC_FLAGS;
- if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE;
-#else
- sz_param.options_mask = OPTIONS_MASK;
- sz_param.bits_per_pixel = bits_per_sample;
- sz_param.pixels_per_block = PIXELS_PER_BLOCK;
- sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
-#endif
-
- if ( bds_ext )
- for ( i = 0; i < bds_ext; ++i )
- bds[bds_head+i] = bds[bds_zoffset+bds_head+i];
-
- /*
- fprintf(stderr, "gribUnzip: sourceLen %ld; destLen %ld\n", (long)sourceLen, (long)destLen);
- fprintf(stderr, "gribUnzip: sourceOff %d; destOff %d\n", bds[12], bds[11]);
- fprintf(stderr, "gribUnzip: reclen %d; bdslen %d\n", recLen, bdsLen);
- */
-
- tmpLen = destLen;
-#if defined (HAVE_LIBAEC)
- strm.next_in = source;
- strm.avail_in = sourceLen;
- strm.next_out = dest;
- strm.avail_out = tmpLen;
-
- status = aec_buffer_decode(&strm);
- if ( status != AEC_OK )
- Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
-
- tmpLen = strm.total_out;
-#else
- status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
- if ( status != SZ_OK )
- {
- if ( status == SZ_NO_ENCODER_ERROR )
- Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_PARAM_ERROR )
- Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_MEM_ERROR )
- Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
- else if ( status == SZ_OUTBUFF_FULL )
- Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2);
- else
- Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
- }
-#endif
- /*
- fprintf(stderr, "gribUnzip: sl = %ld dl = %ld tl = %ld\n",
- (long)sourceLen, (long)destLen,(long) tmpLen);
- */
- if ( tmpLen != destLen )
- Warning("unzip size differ: code %3d level %3d ibuflen %ld ubuflen %ld",
- PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
-
-#if defined (HAVE_LIBSZ)
- if ( bds_nbits == 24 )
- {
- long nelem;
- unsigned char *pbuf;
- nelem = tmpLen/3;
- pbuf = (unsigned char*) Malloc(tmpLen);
- for ( i = 0; i < nelem; i++ )
- {
- pbuf[3*i ] = dest[ i];
- pbuf[3*i+1] = dest[ nelem+i];
- pbuf[3*i+2] = dest[2*nelem+i];
- }
- memcpy(dest, pbuf, tmpLen);
- Free(pbuf);
- }
-#endif
-
- bds_ubits = BDS_Flag & 15;
- BDS_Flag -= bds_ubits;
-
- if ( (bdsLen%2) == 1 )
- {
- BDS_Flag += 8;
- bds[bdsLen++] = 0;
- }
-
- SetLen3(bds, 0, bdsLen);
-
- gribLen = (bds - dbuf) + bdsLen;
-
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
- dbuf[gribLen++] = '7';
-
- if ( llarge )
- {
- long itemp;
- bdsLen = gribLen - 4;
- /*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- while ( gribLen%120 ) dbuf[gribLen++] = 0;
-
- if ( gribLen != (size_t)recLen )
- fprintf(stderr, "Internal problem, recLen and gribLen differ!\n");
-
- itemp = gribLen / (-120);
- itemp = JP23SET - itemp + 1;
-
- SetLen3(dbuf, 4, itemp);
-
- bdsLen = gribLen - bdsLen;
-
- SetLen3(bds, 0, bdsLen);
- }
- else
- {
- SetLen3(dbuf, 4, recLen);
- }
- /*
- fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
- */
- if ( llarge )
- while ( gribLen%120 ) dbuf[gribLen++] = 0;
- else
- while ( gribLen & 7 ) dbuf[gribLen++] = 0;
- /*
- fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
- */
- }
-#else
- UNUSED(bds_nbits);
- UNUSED(sourceLen);
- UNUSED(source);
- UNUSED(bdsLen);
- UNUSED(dest);
-
- if ( libszwarn )
{
- Warning("Decompression disabled, szlib or libaec not available!");
- libszwarn = 0;
- }
-#endif
-
- return (int)gribLen;
-}
-#include <stdio.h>
-#include <math.h>
-
-
-
-static
-int rowina2(double *p, int ko, int ki, double *pw,
- int kcode, double msval, int *kret)
-{
- /* System generated locals */
- int pw_dim1, pw_offset, i_1;
-
- /* Local variables */
- double zwt1, zrdi, zpos;
- int jl, ip;
- double zdo, zwt;
-
- /* Parameter adjustments */
- --p;
- pw_dim1 = ko + 3;
- pw_offset = pw_dim1;
- pw -= pw_offset;
-
- /* **** ROWINA2 - Interpolation of row of values. */
- /* Input Parameters. */
- /* ----------------- */
- /* P - Row of values to be interpolated. */
- /* Dimension must be at least KO. */
- /* KO - Number of values required. */
- /* KI - Number of values in P on input. */
- /* PW - Working array. */
- /* Dimension must be at least (0:KO+2,3). */
- /* KCODE - Interpolation required. */
- /* 1 , linear. */
- /* 3 , cubic. */
- /* PMSVAL - Value used for missing data indicator. */
+ /*
+ Print integer values ...
+ */
+ fprintf(grprsm, " Print of integer values not supported\n");
+ /*
+ CALL SETPAR(IBIT,IDUM,IDUM)
+ DO 212 J=1,INUM
+ INSPT = 0
+ CALL INXBIT(IVALUE,1,INSPT,FSEC4(J),1,IBIT,IBIT,'C',IRET)
+ WRITE (*,9033) IVALUE
+ 9033 FORMAT(' ',I15)
+ 212 CONTINUE
+ ENDIF
+ */
+ }
+}
- /* Output Parameters. */
- /* ------------------ */
- /* P - Now contains KO values. */
- /* KRET - Return code */
- /* 0, OK */
- /* Non-zero, error */
+void gribPrintSec4SP(int *isec0, int *isec4, float *fsec4sp)
+{
+ int inum;
+ int j;
+ double fsec4[20];
- /* Author. */
- /* ------- */
- /* J.D.Chambers ECMWF 22.07.94 */
+ inum = isec4[0];
+ if ( inum < 0 ) inum = -inum;
+ if ( inum > 20 ) inum = 20;
- /* ******************************** */
- /* Section 1. Linear interpolation .. */
- /* ******************************** */
+ for ( j = 0; j < inum; j++ ) fsec4[j] = fsec4sp[j];
+
+ gribPrintSec4DP(isec0, isec4, fsec4);
+}
- *kret = 0;
+void gribPrintSec4Wave(int *isec4)
+{
+ /*
- if ( kcode == 1 )
- {
- /* Move input values to work array */
- for ( jl = 1; jl <= ki; ++jl )
- pw[jl + pw_dim1] = p[jl];
+ Print the wave coordinate information in the Binary Data
+ Section (Section 4) of decoded GRIB data.
- /* Arrange wrap-around value in work array */
- pw[ki + 1 + pw_dim1] = p[1];
+ Input Parameters:
- /* Set up constants to be used to figure out weighting for */
- /* values in interpolation. */
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
+ isec4 - Array of decoded integers from Section 4
- /* Loop through the output points */
- for ( jl = 1; jl <= ko; ++jl )
- {
+ Comments:
- /* Calculate weight from the start of row */
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
+ Wave coordinate information held in isec4 are 32-bit floats,
+ hence the PTEMP and NTEMP used for printing are 4-byte variables.
- /* Get the current array position(minus 1) from the weight - */
- /* note the implicit truncation. */
- ip = (int) zwt;
- /* If the left value is missing, use the right value */
- if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 2 + pw_dim1];
- }
- /* If the right value is missing, use the left value */
- else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 1 + pw_dim1];
- }
- /* If neither missing, interpolate ... */
- else
- {
+ Converted from EMOS routine GRPRS4W.
- /* Adjust the weight to range (0.0 to 1.0) */
- zwt -= ip;
+ Uwe Schulzweida MPIfM 01/04/2001
- /* Interpolate using the weighted values on either side */
- /* of the output point position */
- p[jl] = (1.0 - zwt) * pw[ip + 1 + pw_dim1] +
- zwt * pw[ip + 2 + pw_dim1];
- }
- }
+ */
+ int jloop;
+ int ntemp[100];
+ float *ptemp;
- /* ******************************* */
- /* Section 2. Cubic interpolation .. */
- /* ******************************* */
+ grsdef();
- }
- else if ( kcode == 3 )
+ /*
+ -----------------------------------------------------------------
+ Section 1 . Print integer information from isec4.
+ -----------------------------------------------------------------
+ */
+ fprintf(grprsm, " Coefficients defining first dimension coordinates:\n");
+ for ( jloop = 0; jloop < isec4[52]; jloop++ )
{
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
- {
- if ( IS_EQUAL(p[jl], msval) )
- {
- fprintf(stderr," ROWINA2: ");
- fprintf(stderr," Cubic interpolation not supported");
- fprintf(stderr," for fields containing missing data.\n");
- *kret = 1;
- goto L900;
- }
- pw[jl + pw_dim1] = p[jl];
- }
- pw[pw_dim1] = p[ki];
- pw[ki + 1 + pw_dim1] = p[1];
- pw[ki + 2 + pw_dim1] = p[2];
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
- {
- pw[jl + (pw_dim1 << 1)] =
- - pw[jl - 1 + pw_dim1] / 3.0 -
- pw[jl + pw_dim1] * 0.5 +
- pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
- pw[jl + 1 + pw_dim1 * 3] =
- pw[jl - 1 + pw_dim1] / 6.0 -
- pw[jl + pw_dim1] +
- pw[jl + 1 + pw_dim1] * 0.5 +
- pw[jl + 2 + pw_dim1] / 3.0;
- }
-
- scm0_double(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
- &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
-
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
- for ( jl = 1; jl <= ko; ++jl )
- {
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
- ip = (int) zwt + 1;
- zwt = zwt + 1.0 - ip;
- zwt1 = 1.0 - zwt;
- p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
- zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
- ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
- zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
- }
-
+ ntemp[jloop] = isec4[59 + jloop];
+ ptemp = (float *) &ntemp[jloop];
+ fprintf(grprsm, "%20.10f\n", *ptemp);
}
- else
+ fprintf(grprsm, " Coefficients defining second dimension coordinates:\n");
+ for ( jloop = 0; jloop < isec4[54]; jloop++ )
{
- /* ************************************** */
- /* Section 3. Invalid interpolation code .. */
- /* ************************************** */
- fprintf(stderr," ROWINA2:");
- fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
- *kret = 2;
+ ntemp[jloop] = isec4[59 + isec4[52] + jloop];
+ ptemp = (float *) &ntemp[jloop];
+ fprintf(grprsm, "%20.10f\n", *ptemp);
}
+}
+#if defined (HAVE_CONFIG_H)
+#endif
-L900:
- return 0;
-} /* rowina2 */
+#include <string.h>
+#include <ctype.h>
-int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
- double *ztemp, double msval, int *kret)
+int gribOpen(const char *filename, const char *mode)
{
- /* System generated locals */
- int i_1, i_2;
- int kcode = 1;
+ int fileID = fileOpen(filename, mode);
- /* Local variables */
- int ilii, ilio, icode;
- double *zline = NULL;
- double *zwork = NULL;
- int iregno, iquano, j210, j220, j230, j240, j225;
+#if defined (__sun)
+ if ( fileID != FILE_UNDEFID && tolower(*mode) == 'r' )
+ {
+ fileSetBufferType(fileID, FILE_BUFTYPE_MMAP);
+ }
+#endif
+ return fileID;
+}
- zline = (double*) Malloc(2*(size_t)klon*sizeof(double));
- if ( zline == NULL ) SysError("No Memory!");
- zwork = (double*) Malloc(3*(2*(size_t)klon+3)*sizeof(double));
- if ( zwork == NULL ) SysError("No Memory!");
+void gribClose(int fileID)
+{
+ fileClose(fileID);
+}
- /* Parameter adjustments */
- --pfield;
- --kpoint;
-/* **** QU2REG - Convert quasi-regular grid data to regular. */
-/* Input Parameters. */
-/* ----------------- */
-/* PFIELD - Array containing quasi-regular grid */
-/* data. */
-/* KPOINT - Array containing list of the number of */
-/* points on each latitude (or longitude) of */
-/* the quasi-regular grid. */
-/* KLAT - Number of latitude lines */
-/* KLON - Number of longitude lines */
-/* KCODE - Interpolation required. */
-/* 1 , linear - data quasi-regular on */
-/* latitude lines. */
-/* 3 , cubic - data quasi-regular on */
-/* latitude lines. */
-/* 11, linear - data quasi-regular on */
-/* longitude lines. */
-/* 13, cubic - data quasi-regular on */
-/* longitude lines. */
-/* PMSVAL - Value used for missing data indicator. */
-/* Output Parameters. */
-/* ------------------ */
-/* KRET - return code */
-/* 0 = OK */
-/* non-zero indicates fatal error */
-/* PFIELD - Array containing regular grid data. */
-/* Author. */
-/* ------- */
-/* J.D.Chambers ECMWF 22.07.94 */
-/* J.D.Chambers ECMWF 13.09.94 */
-/* Add return code KRET and remove calls to ABORT. */
+off_t gribGetPos(int fileID)
+{
+ return fileGetPos(fileID);
+}
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+int gribCheckSeek(int fileID, long *offset, int *version)
+{
+ int ierr = gribFileSeek(fileID, offset);
- *kret = 0;
+ *version = -1;
+ if ( !ierr )
+ {
+ char buffer[4];
+ if ( fileRead(fileID, buffer, 4) == 4 )
+ *version = buffer[3];
+ }
-/* Check input parameters. */
+ return ierr;
+}
- if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
- fprintf(stderr," QU2REG :");
- fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
- *kret = 1;
- goto L900;
- }
-/* Set array indices to 0. */
+int gribFileSeek(int fileID, long *offset)
+{
+ /* position file pointer after GRIB */
+ const long GRIB = 0x47524942;
+ long code = 0;
+ int ch;
+ int retry = 4096*4096;
- ilii = 0;
- ilio = 0;
+ *offset = 0;
-/* Establish values of loop parameters. */
+ void *fileptr = filePtr(fileID);
- if (kcode > 10) {
+ while ( retry-- )
+ {
+ ch = filePtrGetc(fileptr);
+ if ( ch == EOF ) return -1;
+
+ code = ( (code << 8) + ch ) & 0xFFFFFFFF;
+ if ( code == GRIB )
+ {
+ if ( CGRIBEX_Debug ) Message("record offset = %ld", *offset);
+ return 0;
+ }
-/* Quasi-regular along longitude lines. */
+ (*offset)++;
+ }
- iquano = klon;
- iregno = klat;
- icode = kcode - 10;
- } else {
+ if ( CGRIBEX_Debug ) Message("record offset = %ld", *offset);
-/* Quasi-regular along latitude lines. */
+ return 1;
+}
- iquano = klat;
- iregno = klon;
- icode = kcode;
- }
+static inline
+unsigned read3ByteMSBFirst(void *fileptr)
+{
+ unsigned b1 = (unsigned)(filePtrGetc(fileptr));
+ unsigned b2 = (unsigned)(filePtrGetc(fileptr));
+ unsigned b3 = (unsigned)(filePtrGetc(fileptr));
+ return GET_UINT3(b1, b2, b3);
+}
-/* -------------------------------------------------------- */
-/** Section 2. Interpolate field from quasi to regular grid. */
-/* -------------------------------------------------------- */
- i_1 = iquano;
- for (j230 = 1; j230 <= i_1; ++j230) {
+size_t gribReadSize(int fileID)
+{
+ size_t rgribsize = 0;
+ void *fileptr = filePtr(fileID);
+ off_t pos = fileGetPos(fileID);
- if (iregno != kpoint[j230]) {
+ unsigned gribsize = read3ByteMSBFirst(fileptr);
-/* Line contains less values than required,so */
-/* extract quasi-regular grid values for a line */
+ int gribversion = filePtrGetc(fileptr);
- i_2 = kpoint[j230];
- for (j210 = 1; j210 <= i_2; ++j210) {
- ++ilii;
- zline[j210 - 1] = pfield[ilii];
- }
+ if ( gribsize == 24 && gribversion != 1 && gribversion != 2 ) gribversion = 0;
-/* and interpolate this line. */
+ if ( CGRIBEX_Debug ) Message("gribversion = %d", gribversion);
- rowina2(zline, iregno, kpoint[j230], zwork, icode, msval, kret);
- if (*kret != 0) goto L900;
+ if ( gribversion == 0 )
+ {
+ unsigned gdssize = 0, bmssize = 0;
+ unsigned issize = 4, essize = 4;
-/* Add regular grid values for this line to the
- temporary array. */
+ unsigned pdssize = gribsize;
+ fileSetPos(fileID, (off_t) 3, SEEK_CUR);
+ if ( CGRIBEX_Debug ) Message("pdssize = %u", pdssize);
+ int flag = filePtrGetc(fileptr);
+ if ( CGRIBEX_Debug ) Message("flag = %d", flag);
+
+ fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
- i_2 = iregno;
- for (j220 = 1; j220 <= i_2; ++j220) {
- ++ilio;
- ztemp[ilio - 1] = zline[j220 - 1];
- }
+ if ( flag & 128 )
+ {
+ gdssize = read3ByteMSBFirst(fileptr);
+ fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
+ if ( CGRIBEX_Debug ) Message("gdssize = %u", gdssize);
+ }
- } else {
+ if ( flag & 64 )
+ {
+ bmssize = read3ByteMSBFirst(fileptr);
+ fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
+ if ( CGRIBEX_Debug ) Message("bmssize = %u", bmssize);
+ }
-/* Line contains the required number of values, so add */
-/* this line to the temporary array. */
+ unsigned bdssize = read3ByteMSBFirst(fileptr);
+ if ( CGRIBEX_Debug ) Message("bdssize = %u", bdssize);
- i_2 = iregno;
- for (j225 = 1; j225 <= i_2; ++j225) {
- ++ilio;
- ++ilii;
- ztemp[ilio - 1] = pfield[ilii];
- }
- }
- }
+ gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
+ rgribsize = (size_t) gribsize;
+ }
+ else if ( gribversion == 1 )
+ {
+ if ( gribsize > JP23SET ) // Large GRIB record
+ {
+ unsigned pdssize = read3ByteMSBFirst(fileptr);
+ if ( CGRIBEX_Debug ) Message("pdssize = %u", pdssize);
-/* Copy temporary array to user array. */
+ int flag;
+ for ( int i = 0; i < 5; ++i ) flag = filePtrGetc(fileptr);
+ if ( CGRIBEX_Debug ) Message("flag = %d", flag);
+
+ fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
- i_1 = klon * klat;
- for (j240 = 1; j240 <= i_1; ++j240) {
- pfield[j240] = ztemp[j240 - 1];
- }
+ unsigned gdssize = 0;
+ if ( flag & 128 )
+ {
+ gdssize = read3ByteMSBFirst(fileptr);
+ fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
+ if ( CGRIBEX_Debug ) Message("gdssize = %u", gdssize);
+ }
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
+ unsigned bmssize = 0;
+ if ( flag & 64 )
+ {
+ bmssize = read3ByteMSBFirst(fileptr);
+ fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
+ if ( CGRIBEX_Debug ) Message("bmssize = %u", bmssize);
+ }
-L900:
+ unsigned bdssize = read3ByteMSBFirst(fileptr);
+ if ( CGRIBEX_Debug ) Message("bdssize = %u", bdssize);
+ if ( bdssize <= 120 )
+ {
+ const int issize = 4;
+ gribsize &= JP23SET;
+ gribsize *= 120;
+ bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
+ if ( CGRIBEX_Debug ) Message("bdssize = %u", bdssize);
- Free(zline);
- Free(zwork);
+ gribsize = issize + pdssize + gdssize + bmssize + bdssize + 4;
+ }
+ }
+ rgribsize = (size_t) gribsize;
+ }
+ else if ( gribversion == 2 )
+ {
+ /* we set gribsize the following way because it doesn't matter then
+ whether int is 4 or 8 bytes long - we don't have to care if the size
+ really fits: if it does not, the record can not be read at all */
+ rgribsize = 0;
+ for ( int i = 0; i < 8; i++ ) rgribsize = (rgribsize << 8) | filePtrGetc(fileptr);
+ }
+ else
+ {
+ rgribsize = 0;
+ Warning("GRIB version %d unsupported!", gribversion);
+ }
- return 0;
-} /* qu2reg2 */
+ if ( filePtrEOF(fileptr) ) rgribsize = 0;
+ if ( CGRIBEX_Debug ) Message("gribsize = %zu", rgribsize);
+ fileSetPos(fileID, pos, SEEK_SET);
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
+ return rgribsize;
+}
-/* calculate_pfactor: source code from grib_api-1.8.0 */
-double TEMPLATE(calculate_pfactor,T)(const T *spectralField, long fieldTruncation, long subsetTruncation)
-{
- /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
- long loop, index, m, n = 0;
- double pFactor, zeps = 1.0e-15;
- long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
- double* weights, range, * norms;
- double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
- double numerator = 0.0, denominator = 0.0, slope;
- /*
- // Setup the weights
- */
+size_t gribGetSize(int fileID)
+{
+ long offset;
+ int ierr = gribFileSeek(fileID, &offset); // position file pointer after GRIB
+ if ( ierr > 0 )
+ {
+ Warning("GRIB record not found!");
+ return 0;
+ }
- range = (double) (ismax - ismin +1);
+ if ( ierr == -1 ) return 0;
+ else if ( ierr == 1 ) return 0;
- weights = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
- for( loop = ismin; loop <= ismax; loop++ )
- weights[loop] = range / (double) (loop-ismin+1);
- /*
- // Compute norms
- // Handle values 2 at a time (real and imaginary parts).
- */
- norms = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
+ size_t recSize = gribReadSize(fileID);
- for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
- /*
- // Form norms for the rows which contain part of the unscaled subset.
- */
+ if ( CGRIBEX_Debug ) Message("recsize = %zu", recSize);
- index = -2;
- for( m = 0; m < subsetTruncation; m++ )
- for( n = m; n <= fieldTruncation; n++ ) {
- index += 2;
- if( n >= subsetTruncation ) {
- double tval = spectralField[index];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- tval = spectralField[index+1];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- }
- }
- /*
- // Form norms for the rows which do not contain part of the unscaled subset.
- */
+ fileSetPos(fileID, (off_t) -4, SEEK_CUR);
- for( m = subsetTruncation; m <= fieldTruncation; m++ )
- for( n = m; n <= fieldTruncation; n++ ) {
- double tval = spectralField[index];
- index += 2;
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- tval = spectralField[index+1];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- }
+ return recSize;
+}
- /*
- // Ensure the norms have a value which is not too small in case of
- // problems with math functions (e.g. LOG).
- */
- for( loop = ismin; loop <= ismax; loop++ ) {
- norms[n] = norms[n] > zeps ? norms[n] : zeps;
- if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
- }
+int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
+{
+ long offset;
+ int ierr = gribFileSeek(fileID, &offset); // position file pointer after GRIB
+ if ( ierr > 0 )
+ {
+ Warning("GRIB record not found!");
+ return -2;
+ }
- /*
- // Do linear fit to find the slope
- */
+ if ( ierr == -1 ) { *buffersize = 0; return -1; }
+ else if ( ierr == 1 ) { *buffersize = 0; return -2; }
- for( loop = ismin; loop <= ismax; loop++ ) {
- x = log( (double) (loop*(loop+1)) );
- y = log( norms[loop] );
- weightedSumOverX = weightedSumOverX + x * weights[loop];
- weightedSumOverY = weightedSumOverY + y * weights[loop];
- sumOfWeights = sumOfWeights + weights[loop];
- }
- weightedSumOverX = weightedSumOverX / sumOfWeights;
- weightedSumOverY = weightedSumOverY / sumOfWeights;
+ size_t recSize = gribReadSize(fileID);
+ size_t readSize = recSize;
- /*
- // Perform a least square fit for the equation
- */
+ if ( readSize > *buffersize )
+ {
+ readSize = *buffersize;
+ ierr = -3; // Tell the caller that the buffer was insufficient.
+ }
- for( loop = ismin; loop <= ismax; loop++ ) {
+ *buffersize = recSize; // Inform the caller about the record size.
- x = log( (double)(loop*(loop+1)) );
- y = log( norms[loop] );
- numerator =
- numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
- denominator =
- denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
- }
- slope = numerator / denominator;
+ // Write the stuff to the buffer that has already been read in gribFileSeek().
+ buffer[0] = 'G';
+ buffer[1] = 'R';
+ buffer[2] = 'I';
+ buffer[3] = 'B';
- Free(weights);
- Free(norms);
+ readSize -= 4;
+ // Read the rest of the record into the buffer.
+ size_t nread = fileRead(fileID, &buffer[4], readSize);
- pFactor = -slope;
- if( pFactor < -9999.9 ) pFactor = -9999.9;
- if( pFactor > 9999.9 ) pFactor = 9999.9;
+ if ( nread != readSize ) ierr = 1;
- return pFactor;
+ return ierr;
}
-void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
-{
- double power;
- double *scale = (double*) Malloc(((size_t)trunc+1)*sizeof(double));
- if ( scale == NULL ) SysError("No Memory!");
+int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
+{
+ int nwrite = 0;
- if ( pcScale < -10000 || pcScale > 10000 )
+ if ( (nwrite = (int)(fileWrite(fileID, buffer, buffersize))) != (int) buffersize )
{
- fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
- return;
- }
+ perror(__func__);
+ nwrite = -1;
+ }
- /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
+ return nwrite;
+}
+#include <string.h>
+#include <ctype.h>
- if ( pcScale == 0 ) return;
- power = (double) pcScale / 1000.;
- scale[0] = 1.0;
+FILE *grprsm = NULL;
+double fref;
+double fmaxval;
+int nfref;
+int nfmaxval;
+int nrnd;
+int ndbg;
+int nvck;
+int nonoff;
+int noabort;
+int num2ok;
+int next2o;
+int nloc2o;
+int nsubce;
+int grib_calendar = -1;
- if (pcScale != 1000)
- for ( int n = 1; n <= trunc; n++ )
- scale[n] = pow((double) (n*(n+1)), power);
- else
- for ( int n = 1; n <= trunc; n++ )
- scale[n] = (double) (n*(n+1));
- if ( inv )
- for ( int n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
+void gribSetCalendar(int calendar)
+{
+ grib_calendar = calendar;
+}
- /* Scale the values */
- size_t index = 0;
+void grsdef(void)
+{
+ /*
+C---->
+C**** GRSDEF - Initial (default) setting of common area variables
+C for GRIBEX package.
+C
+C Purpose.
+C --------
+C
+C Sets initial values for common area variables for all
+C routines of GRIBEX package, if not already done.
+C
+C** Interface.
+C ----------
+C
+C CALL GRSDEF
+C
+C Input Parameters.
+C -----------------
+C
+C None.
+C
+C Output Parameters.
+C ------------------
+C
+C None.
+C
+C Method.
+C -------
+C
+C Self-explanatory.
+C
+C Externals.
+C ----------
+C
+C None.
+C
+C Reference.
+C ----------
+C
+C See subroutine GRIBEX.
+C
+C Comments.
+C ---------
+C
+C None
+C
+C Author.
+C -------
+C
+C J. Clochard, Meteo France, for ECMWF - March 1998.
+C
+C Modifications.
+C --------------
+C
+C J. Clochard, Meteo France, for ECMWF - June 1999.
+C Add variable NSUBCE.
+C Use a static variable to determine if initialisation has already
+C been done. NUSER removed .
+C Reverse defaults for NEXT2O and NLOC2O, for consistency with
+C version 13.023 of software .
+C
+ */
+ /*
+C ----------------------------------------------------------------
+C* Section 0 . Definition of variables.
+C ----------------------------------------------------------------
+ */
+ char *envString;
+ char *env_stream;
+ static bool lfirst = true;
+ extern int CGRIBEX_Const;
- for ( int m = 0; m < pcStart; m++ )
- for ( int n = m; n <= trunc; n++, index += 2 )
- if ( n >= pcStart )
- {
- fpdata[index ] = (T)(fpdata[index ] * scale[n]);
- fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
- }
+ if ( ! lfirst ) return;
- for ( int m = pcStart; m <= trunc; m++ )
- for ( int n = m; n <= trunc; n++, index += 2 )
- {
- fpdata[index ] = (T)(fpdata[index ] * scale[n]);
- fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
- }
+ /*
+ ----------------------------------------------------------------
+ Section 1 . Set values, conditionally.
+ ----------------------------------------------------------------
+ */
+ /*
+ Common area variables have not been set. Set them.
+
+ User supplied reference value.
+ */
+ fref = 0.0;
+ /*
+ Reference value supplied by user flag. Set to off.
+ */
+ nfref = 0;
+ /*
+ User supplied maximum value.
+ */
+ fmaxval = 0.0;
+ /*
+ Maximum value supplied by user flag. Set to off.
+ */
+ nfmaxval = 0;
+ /*
+ Set rounding to 120 bytes on.
+ */
+ nrnd = 1;
+ /*
+ Set GRIB calendar.
+ */
+ if ( grib_calendar == -1 )
+ {
+ grib_calendar = CALENDAR_PROLEPTIC;
+
+ envString = getenv("GRIB_CALENDAR");
+ if ( envString )
+ {
+ if ( strncmp(envString, "standard", 8) == 0 )
+ grib_calendar = CALENDAR_STANDARD;
+ else if ( strncmp(envString, "proleptic", 9) == 0 )
+ grib_calendar = CALENDAR_PROLEPTIC;
+ else if ( strncmp(envString, "360days", 7) == 0 )
+ grib_calendar = CALENDAR_360DAYS;
+ else if ( strncmp(envString, "365days", 7) == 0 )
+ grib_calendar = CALENDAR_365DAYS;
+ else if ( strncmp(envString, "366days", 7) == 0 )
+ grib_calendar = CALENDAR_366DAYS;
+ else if ( strncmp(envString, "none", 4) == 0 )
+ grib_calendar = CALENDAR_NONE;
+ }
+ }
+ /*
+ Set debug print off.
+ */
+ ndbg = 0;
+
+ envString = getenv("GRIBEX_DEBUG");
+ if ( envString != NULL )
+ {
+ if ( !strncmp(envString, "ON", 2) )
+ ndbg = 1;
+ else if( *envString == '1')
+ ndbg = 1;
+ else if( *envString == '2')
+ ndbg = 2;
+ else
+ ndbg = 0;
+ }
+ /*
+ Set GRIBEX compatibility mode.
+ */
+ envString = getenv("GRIB_GRIBEX_MODE_ON");
+ if ( envString != NULL )
+ {
+ if ( atoi(envString) == 1 ) CGRIBEX_Const = 0;
+ }
- Free(scale);
+ /*
+ Set GRIB value checking on.
+ */
+ nvck = 1;
+
+ envString = getenv("GRIBEX_CHECK");
+ if ( envString )
+ {
+ if ( !strncmp(envString, "OFF", 3) )
+ nvck = 0;
+ else
+ nvck = 1;
+ }
+ /*
+ See if output stream needs changing
+ */
+ grprsm = stdout;
+ env_stream = getenv("GRPRS_STREAM");
+ if ( env_stream )
+ {
+ if ( isdigit((int) env_stream[0]) )
+ {
+ int unit;
+ unit = atoi(env_stream);
+ if ( unit < 1 || unit > 99 )
+ Warning("Invalid number for GRPRS_STREAM: %d", unit);
+ else if ( unit == 2 )
+ grprsm = stderr;
+ else if ( unit == 6 )
+ grprsm = stdout;
+ else
+ {
+ char filename[] = "unit.00";
+ sprintf(filename, "%2.2d", unit);
+ grprsm = fopen(filename, "w");
+ if ( ! grprsm )
+ SysError("GRPRS_STREAM = %d", unit);
+ }
+ }
+ else
+ {
+ if ( env_stream[0] )
+ {
+ grprsm = fopen(env_stream, "w");
+ if ( ! grprsm )
+ SysError("GRPRS_STREAM = %s", env_stream);
+ }
+ }
+ }
+ /*
+ Set P factor switch to default, user supplies the P factor.
+ */
+ nonoff = 0;
+ /*
+ Set abort flag to NO abort
+ */
+ noabort = 1;
+ /*
+ Mark common area values set by user.
+ */
+ lfirst = false;
+ /*
+ Exhaustive use of all possible second-order packing methods
+ for HOPER='K'. Set to off.
+ */
+ num2ok = 0;
+ /*
+ Use of extended second-order packing methods for grid-point
+ encoding (HOPER='C' and 'K'). Set to on.
+ */
+ next2o = 1;
+ /*
+ Use of non-local second-order packing methods for grid-point
+ encoding (HOPER='C' and 'K'). Set to on.
+ */
+ nloc2o = 1;
+ /*
+ Use of (all valid) sub-centre values for ECMWF fields encoding .
+ encoding. Set to off.
+ */
+ nsubce = 0;
}
+/* pack 8-bit bytes from 64-bit words to a packed buffer */
+/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (unsigned char) up[i]; */
-void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc)
{
- T *fphelp = (T*) Malloc((size_t)nsp*sizeof(T));
- int m, n;
- int index, inext;
+#if defined (CRAY)
+ (void) _pack(up, cp, bc, tc);
+#else
+ U_BYTEORDER;
+ unsigned char *cp0;
+ unsigned INT64 upi, *up0, *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
+ long head, trail, inner, i, j;
+ long ipack = sizeof(INT64);
+
+ /* Bytes until first word boundary in destination buffer */
- if ( fphelp == NULL ) SysError("No Memory!");
+ head = ( (long) cp ) & (ipack-1);
+ if ( head != 0 ) head = ipack - head;
- index = inext = 0;
+ inner = bc - head;
- for ( m = 0; m <= pcStart; m++ )
- for ( n = m; n <= trunc; n++ )
- {
- if ( pcStart >= n )
- {
- fphelp[index ] = fpdata[inext++];
- fphelp[index+1] = fpdata[inext++];
- }
- index += 2;
- }
+ /* Trailing bytes which do not make a full word */
- index = 0;
- for ( m = 0; m <= trunc; m++ )
- for ( n = m; n <= trunc; n++ )
- {
- if ( n > pcStart )
- {
- fphelp[index ] = fpdata[inext++];
- fphelp[index+1] = fpdata[inext++];
- }
- index += 2;
- }
+ trail = inner & (ipack-1);
- for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+ /* Number of bytes/words to be processed in fast loop */
- Free(fphelp);
-}
+ inner -= trail;
+ inner /= ipack;
+
+ ip0 = up + head;
+ ip1 = ip0 + 1;
+ ip2 = ip0 + 2;
+ ip3 = ip0 + 3;
+ ip4 = ip0 + 4;
+ ip5 = ip0 + 5;
+ ip6 = ip0 + 6;
+ ip7 = ip0 + 7;
+ up0 = (unsigned INT64 *) (cp + head);
-void TEMPLATE(gather_complex,T)(T *fpdata, size_t pcStart, size_t trunc, size_t nsp)
-{
- T *restrict fphelp = (T*) Malloc(nsp*sizeof(T));
- size_t inext = 0;
+ /* Here we should process any bytes until the first word boundary
+ * of our destination buffer
+ * That code is missing so far because our output buffer is
+ * word aligned by FORTRAN
+ */
- for ( size_t m = 0, index = 0; m <= pcStart; m++ )
- for ( size_t n = m; n <= trunc; n++ )
- {
- if ( pcStart >= n )
- {
- fphelp[inext++] = fpdata[index];
- fphelp[inext++] = fpdata[index+1];
- }
- index += 2;
- }
+ j = 0;
- for ( size_t m = 0, index = 0; m <= trunc; m++ )
- for ( size_t n = m; n <= trunc; n++ )
- {
- if ( n > pcStart )
- {
- fphelp[inext++] = fpdata[index];
- fphelp[inext++] = fpdata[index+1];
- }
- index += 2;
- }
+ if ( IS_BIGENDIAN() )
+ {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( i = 0 ; i < inner ; i++ )
+ {
+ upi = ( ip0[j] << 56 )
+ | ( ( ip1[j] & 0xFF ) << 48 )
+ | ( ( ip2[j] & 0xFF ) << 40 )
+ | ( ( ip3[j] & 0xFF ) << 32 )
+ | ( ( ip4[j] & 0xFF ) << 24 ) ;
+ up0[i] = upi | ( ( ip5[j] & 0xFF ) << 16 )
+ | ( ( ip6[j] & 0xFF ) << 8 )
+ | ( ip7[j] & 0xFF ) ;
+ j += ipack;
+ }
+ }
+ else
+ {
+ for ( i = 0 ; i < inner ; i++ )
+ {
+ upi = ( ip7[j] << 56 )
+ | ( ( ip6[j] & 0xFF ) << 48 )
+ | ( ( ip5[j] & 0xFF ) << 40 )
+ | ( ( ip4[j] & 0xFF ) << 32 )
+ | ( ( ip3[j] & 0xFF ) << 24 ) ;
+ up0[i] = upi | ( ( ip2[j] & 0xFF ) << 16 )
+ | ( ( ip1[j] & 0xFF ) << 8 )
+ | ( ip0[j] & 0xFF ) ;
+ j += ipack;
+ }
+ }
- for ( size_t m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+ cp0 = (unsigned char *) ( up0 + inner );
+ if ( trail > 0 )
+ {
+ up0[inner] = 0;
+ for ( i = 0 ; i < trail ; i ++ )
+ {
+ *cp0 = (unsigned char) ip0[ipack*inner+i];
+ cp0++;
+ }
+ }
- Free(fphelp);
+ if ( tc != -1 )
+ {
+ bc++;
+ *cp0 = (unsigned char) tc;
+ }
+#endif
+ return (bc);
}
+/* unpack 8-bit bytes from a packed buffer with 64-bit words */
+/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT64) cp[i]; */
-void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
+long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc)
{
- /* System generated locals */
- double r_1;
+ U_BYTEORDER;
+ const unsigned char *cp0;
+ unsigned INT64 *up0;
+ unsigned INT64 *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
+ long head, trail, inner, i, j;
+ long offset;
+ long ipack = sizeof(INT64);
- /* Local variables */
- int jl;
- double zfac, zeps, zbeta;
- double zalpha;
+ UNUSED(tc);
+
+ /* Bytes until first word boundary in source buffer */
+
+ head = ( (long) cp ) & (ipack-1);
+ if ( head != 0 ) head = ipack - head;
+ if ( head > bc ) head = bc;
+
+ inner = bc - head;
+
+ /* Trailing bytes which do not make a full word */
+
+ trail = inner & (ipack-1);
+
+ /* Number of bytes/words to be processed in fast loop */
+
+ inner -= trail;
+ inner /= ipack;
+
+ ip0 = up + head;
+ ip1 = ip0 + 1;
+ ip2 = ip0 + 2;
+ ip3 = ip0 + 3;
+ ip4 = ip0 + 4;
+ ip5 = ip0 + 5;
+ ip6 = ip0 + 6;
+ ip7 = ip0 + 7;
- /* **** SCM0 - Apply SCM0 limiter to derivative estimates. */
- /* output: */
- /* pdl = the limited derivative at the left edge of the interval */
- /* pdr = the limited derivative at the right edge of the interval */
- /* inputs */
- /* pdl = the original derivative at the left edge */
- /* pdr = the original derivative at the right edge */
- /* pfl = function value at the left edge of the interval */
- /* pfr = function value at the right edge of the interval */
- /* klg = number of intervals where the derivatives are limited */
+ up0 = (unsigned INT64 *) (cp + head);
- /* define constants */
+ /* Process any bytes until the first word boundary
+ * of our source buffer
+ */
+ for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT64) cp[i];
- zeps = 1.0e-12;
- zfac = (1.0 - zeps) * 3.0;
+ j = 0;
- for ( jl = 0; jl < klg; ++jl )
+ if ( IS_BIGENDIAN() )
{
- if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( i = 0 ; i < inner ; i++ )
{
- zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
- zbeta = pdr[jl] / (pfr[jl] - pfl[jl]);
- if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
- if ( zbeta <= 0.0 ) pdr[jl] = 0.0;
- if ( zalpha > zfac ) pdl[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
- if ( zbeta > zfac ) pdr[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
+ ip0[j] = (up0[i] >> 56) & 0xFF;
+ ip1[j] = (up0[i] >> 48) & 0xFF;
+ ip2[j] = (up0[i] >> 40) & 0xFF;
+ ip3[j] = (up0[i] >> 32) & 0xFF;
+ ip4[j] = (up0[i] >> 24) & 0xFF;
+ ip5[j] = (up0[i] >> 16) & 0xFF;
+ ip6[j] = (up0[i] >> 8) & 0xFF;
+ ip7[j] = (up0[i]) & 0xFF;
+
+ j += ipack;
}
- else
+ }
+ else
+ {
+ for ( i = 0 ; i < inner ; i++ )
{
- pdl[jl] = 0.0;
- pdr[jl] = 0.0;
+ ip7[j] = (up0[i] >> 56) & 0xFF;
+ ip6[j] = (up0[i] >> 48) & 0xFF;
+ ip5[j] = (up0[i] >> 40) & 0xFF;
+ ip4[j] = (up0[i] >> 32) & 0xFF;
+ ip3[j] = (up0[i] >> 24) & 0xFF;
+ ip2[j] = (up0[i] >> 16) & 0xFF;
+ ip1[j] = (up0[i] >> 8) & 0xFF;
+ ip0[j] = (up0[i]) & 0xFF;
+
+ j += ipack;
}
}
-} /* scm0 */
-static
-int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
- int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
-{
+ if ( trail > 0 )
+ {
+ offset = head + ipack*inner;
+ cp0 = cp + offset;
+ for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT64) cp0[i];
+ }
/*
-C---->
-C**** ROWINA3 - Interpolation of row of values.
-C
-C Purpose.
-C --------
-C
-C Interpolate a row of values.
-C
-C
-C** Interface.
-C ----------
-C
-C CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
-C
-C
-C Input Parameters.
-C -----------------
-C
-C P - Row of values to be interpolated.
-C Dimension must be at least KO.
-C
-C KO - Number of values required.
-C
-C KI - Number of values in P on input.
-C
-C PW - Working array.
-C Dimension must be at least (0:KO+2,3).
-C
-C KCODE - Interpolation required.
-C 1 , linear.
-C 3 , cubic.
-C
-C PMSVAL - Value used for missing data indicator.
-C
-C OMISNG - True if missing values are present in field.
-C
-C OPERIO - True if input field is periodic.
-C
-C OVEGGY - True if 'nearest neighbour' processing must be used
-C for interpolation
-C
-C Output Parameters.
-C ------------------
-C
-C P - Now contains KO values.
-C KRET - Return code
-C 0, OK
-C Non-zero, error
-C
-C
-C Method.
-C -------
-C
-C Linear or cubic interpolation performed as required.
-C
-C Comments.
-C ---------
-C
-C This is a version of ROWINA which allows for missing data
-C values and hence for bitmapped fields.
-C
-C
-C Author.
-C -------
-C
-C J.D.Chambers ECMWF 22.07.94
-C
-C
-C Modifications.
-C --------------
-C
-C J.D.Chambers ECMWF 13.09.94
-C Add return code KRET and remove calls to ABORT.
-C
-C J. Clochard, Meteo France, for ECMWF - January 1998.
-C Addition of OMISNG and OPERIO arguments.
-C
-C
-C -----------------------------------------------------------------
-*/
- /* System generated locals */
- int pw_dim1, pw_offset, i_1;
+ if ( tc != -1 ) {
+ bc++;
+ *cp0 = (unsigned char) tc;
+ }
+ */
+ return (bc);
+}
- /* Local variables */
- int jl, ip;
- double zwt1, zrdi, zpos;
- double zdo, zwt;
+/* pack 8-bit bytes from 32-bit words to a packed buffer */
+/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (char) up[i]; */
- UNUSED(omisng);
+#if defined (INT32)
+long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc)
+{
+ U_BYTEORDER;
+ unsigned char *cp0;
+ unsigned INT32 *up0, *ip0, *ip1, *ip2, *ip3;
+ long head, trail, inner, i, j;
+ long ipack = sizeof(INT32);
+
+ /* Bytes until first word boundary in destination buffer */
- /* Parameter adjustments */
- --p;
- pw_dim1 = ko + 3;
- pw_offset = pw_dim1;
- pw -= pw_offset;
+ head = ( (long) cp ) & (ipack-1);
+ if ( head != 0 ) head = ipack - head;
- *kret = 0;
+ inner = bc - head;
- if ( kcode == 1 )
- {
- /* Move input values to work array */
- for ( jl = 1; jl <= ki; ++jl )
- pw[jl + pw_dim1] = p[jl];
+ /* Trailing bytes which do not make a full word */
- if ( operio )
- {
- /* Arrange wrap-around value in work array */
- pw[ki + 1 + pw_dim1] = p[1];
+ trail = inner & (ipack-1);
- /* Set up constants to be used to figure out weighting for */
- /* values in interpolation. */
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
- }
- else
- {
- /* Repeat last value, to cope with "implicit truncation" below */
- pw[ki + 1 + pw_dim1] = p[ki];
+ /* Number of bytes/words to be processed in fast loop */
- /* Set up constants to be used to figure out weighting for */
- /* values in interpolation. */
- zrdi = (double) (ki-1);
- zdo = 1.0 / (double) (ko-1);
- }
+ inner -= trail;
+ inner /= ipack;
- /* Loop through the output points */
- for ( jl = 1; jl <= ko; ++jl )
- {
+ ip0 = up + head;
+ ip1 = ip0 + 1;
+ ip2 = ip0 + 2;
+ ip3 = ip0 + 3;
- /* Calculate weight from the start of row */
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
+ up0 = (unsigned INT32 *) (cp + head);
- /* Get the current array position(minus 1) from the weight - */
- /* note the implicit truncation. */
- ip = (int) zwt;
-
- /* Adjust the weight to range (0.0 to 1.0) */
- zwt -= ip;
+ /* Here we should process any bytes until the first word boundary
+ * of our destination buffer
+ * That code is missing so far because our output buffer is
+ * word aligned by FORTRAN
+ */
- /* If 'nearest neighbour' processing must be used */
- if ( oveggy )
- {
- if ( zwt < 0.5 )
- p[jl] = pw[ip + 1 + pw_dim1];
- else
- p[jl] = pw[ip + 2 + pw_dim1];
- }
- else
- {
- /* If the left value is missing, use the right value */
- if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 2 + pw_dim1];
- }
- /* If the right value is missing, use the left value */
- else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 1 + pw_dim1];
- }
- /* If neither missing, interpolate ... */
- else
- {
- /* Interpolate using the weighted values on either side */
- /* of the output point position */
- p[jl] = (T)((1.0 - zwt) * pw[ip+1 + pw_dim1]
- + zwt * pw[ip+2 + pw_dim1]);
- }
- }
- }
- }
- else if ( kcode == 3 )
+ j = 0;
+
+ if ( IS_BIGENDIAN() )
{
- /* ******************************* */
- /* Section 2. Cubic interpolation .. */
- /* ******************************* */
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( i = 0 ; i < inner ; i++ )
{
- if ( IS_EQUAL(p[jl], msval) )
- {
- fprintf(stderr," ROWINA3: ");
- fprintf(stderr," Cubic interpolation not supported");
- fprintf(stderr," for fields containing missing data.\n");
- *kret = 1;
- goto L900;
- }
- pw[jl + pw_dim1] = p[jl];
+ up0[i] = ( ip0[j] << 24 )
+ | ( ( ip1[j] & 0xFF ) << 16 )
+ | ( ( ip2[j] & 0xFF ) << 8 )
+ | ( ip3[j] & 0xFF ) ;
+ j += ipack;
}
- pw[pw_dim1] = p[ki];
- pw[ki + 1 + pw_dim1] = p[1];
- pw[ki + 2 + pw_dim1] = p[2];
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
+ }
+ else
+ {
+ for ( i = 0 ; i < inner ; i++ )
{
- pw[jl + (pw_dim1 << 1)] =
- (T)(- pw[jl - 1 + pw_dim1] / 3.0 -
- pw[jl + pw_dim1] * 0.5 +
- pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0);
- pw[jl + 1 + pw_dim1 * 3] =
- (T)(pw[jl - 1 + pw_dim1] / 6.0 -
- pw[jl + pw_dim1] +
- pw[jl + 1 + pw_dim1] * 0.5 +
- pw[jl + 2 + pw_dim1] / 3.0);
+ up0[i] = ( ip3[j] << 24 )
+ | ( ( ip2[j] & 0xFF ) << 16 )
+ | ( ( ip1[j] & 0xFF ) << 8 )
+ | ( ip0[j] & 0xFF ) ;
+ j += ipack;
}
+ }
- TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
- &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
-
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
- for ( jl = 1; jl <= ko; ++jl )
+ cp0 = (unsigned char *) ( up0 + inner );
+ if ( trail > 0 )
+ {
+ up0[inner] = 0;
+ for ( i = 0 ; i < trail ; i ++ )
{
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
- ip = (int) zwt + 1;
- zwt = zwt + 1.0 - ip;
- zwt1 = 1.0 - zwt;
- p[jl] = (T)(((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
- zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
- ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
- zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt);
+ *cp0 = (unsigned char) ip0[ipack*inner+i];
+ cp0++;
}
-
}
- else
+
+ if ( tc != -1 )
{
- /* ************************************** */
- /* Section 3. Invalid interpolation code .. */
- /* ************************************** */
- fprintf(stderr," ROWINA3:");
- fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
- *kret = 2;
+ bc++;
+ *cp0 = (unsigned char) tc;
}
-L900:
- return 0;
-} /* rowina3 */
+ return (bc);
+}
+#endif
+/* unpack 8-bit bytes from a packed buffer with 32-bit words */
+/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT32) cp[i]; */
-int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
- T msval, int *kret, int omisng, int operio, int oveggy)
+#if defined (INT32)
+long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc)
{
- /*
-C**** QU2REG3 - Convert quasi-regular grid data to regular.
-C
-C Purpose.
-C --------
-C
-C Convert quasi-regular grid data to regular,
-C using either a linear or cubic interpolation.
-C
-C
-C** Interface.
-C ----------
-C
-C CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
-C X OVEGGY)
-C
-C
-C Input Parameters.
-C -----------------
-C
-C PFIELD - Array containing quasi-regular grid data.
-C
-C KPOINT - Array containing list of the number of
-C points on each latitude (or longitude) of
-C the quasi-regular grid.
-C
-C KLAT - Number of latitude lines
-C
-C KLON - Number of longitude lines
-C
-C KCODE - Interpolation required.
-C 1 , linear - data quasi-regular on latitude lines.
-C 3 , cubic - data quasi-regular on latitude lines.
-C 11, linear - data quasi-regular on longitude lines.
-C 13, cubic - data quasi-regular on longitude lines.
-C
-C PMSVAL - Value used for missing data indicator.
-C
-C OMISNG - True if missing values are present in field.
-C
-C OPERIO - True if input field is periodic.
-C
-C OVEGGY - True if 'nearest neighbour' processing must be used
-C for interpolation
-C
-C
-C Output Parameters.
-C ------------------
-C
-C KRET - return code
-C 0 = OK
-C non-zero indicates fatal error
-C
-C
-C Output Parameters.
-C ------------------
-C
-C PFIELD - Array containing regular grid data.
-C
-C
-C Method.
-C -------
-C
-C Data is interpolated and expanded into a temporary array,
-C which is then copied back into the user's array.
-C Returns an error code if an invalid interpolation is requested
-C or field size exceeds array dimensions.
-C
-C Comments.
-C ---------
-C
-C This routine is an adaptation of QU2REG to allow missing data
-C values, and hence bit mapped fields.
-C
-C
-C Author.
-C -------
-C
-C J.D.Chambers ECMWF 22.07.94
-C
-C
-C Modifications.
-C --------------
-C
-C J.D.Chambers ECMWF 13.09.94
-C Add return code KRET and remove calls to ABORT.
-C
-C J.D.Chambers ECMWF Feb 1997
-C Allow for 64-bit pointers
-C
-C J. Clochard, Meteo France, for ECMWF - January 1998.
-C Addition of OMISNG and OPERIO arguments.
-C Fix message for longitude number out of bounds, and routine
-C name in title and formats.
-C
-*/
- /* System generated locals */
- int i_1, i_2;
- int kcode = 1;
+ U_BYTEORDER;
+ const unsigned char *cp0;
+ unsigned INT32 *up0;
+ unsigned INT32 *ip0, *ip1, *ip2, *ip3;
+ long head, trail, inner, i, j;
+ long offset;
+ long ipack = sizeof(INT32);
+
+ UNUSED(tc);
+
+ /* Bytes until first word boundary in source buffer */
+
+ head = ( (long) cp ) & (ipack-1);
+ if ( head != 0 ) head = ipack - head;
+ if ( head > bc ) head = bc;
+
+ inner = bc - head;
+
+ /* Trailing bytes which do not make a full word */
+
+ trail = inner & (ipack-1);
+
+ /* Number of bytes/words to be processed in fast loop */
+
+ inner -= trail;
+ inner /= ipack;
+
+ ip0 = up + head;
+ ip1 = ip0 + 1;
+ ip2 = ip0 + 2;
+ ip3 = ip0 + 3;
+
+ up0 = (unsigned INT32 *) (cp + head);
- /* Local variables */
- int ilii, ilio, icode;
- int iregno, iquano, j210, j220, j230, j240, j225;
- T *ztemp = NULL;
- T *zline = NULL;
- T *zwork = NULL;
+ /* Process any bytes until the first word boundary
+ * of our source buffer
+ */
+ for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT32) cp[i];
- ztemp = (T*) Malloc((size_t)klon*(size_t)klat*sizeof(T));
+ j = 0;
- zline = (T*) Malloc(2*(size_t)klon*sizeof(T));
+ if ( IS_BIGENDIAN() )
+ {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( i = 0 ; i < inner ; i++ )
+ {
+ ip0[j] = (up0[i] >> 24) & 0xFF;
+ ip1[j] = (up0[i] >> 16) & 0xFF;
+ ip2[j] = (up0[i] >> 8) & 0xFF;
+ ip3[j] = (up0[i]) & 0xFF;
- zwork = (T*) Malloc(3*(2*(size_t)klon+3)*sizeof(T));
+ j += ipack;
+ }
+ }
+ else
+ {
+ for ( i = 0 ; i < inner ; i++ )
+ {
+ ip3[j] = (up0[i] >> 24) & 0xFF;
+ ip2[j] = (up0[i] >> 16) & 0xFF;
+ ip1[j] = (up0[i] >> 8) & 0xFF;
+ ip0[j] = (up0[i]) & 0xFF;
- /* Parameter adjustments */
- --pfield;
- --kpoint;
+ j += ipack;
+ }
+ }
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+ if ( trail > 0 )
+ {
+ offset = head + ipack*inner;
+ cp0 = cp + offset;
+ for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT32) cp0[i];
+ }
+ /*
+ if ( tc != -1 ) {
+ bc++;
+ *cp0 = (unsigned char) tc;
+ }
+ */
- *kret = 0;
+ return (bc);
+}
+#endif
+#include <stdio.h>
-/* Check input parameters. */
+void prtbin(int kin, int knbit, int *kout, int *kerr)
+{
+ /*
- if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
- fprintf(stderr," QU2REG :");
- fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
- *kret = 1;
- goto L900;
- }
+ Produces a decimal number with ones and zeroes
+ corresponding to the ones and zeroes of the input
+ binary number.
+ eg input number 1011 binary, output number 1011 decimal.
-/* Set array indices to 0. */
- ilii = 0;
- ilio = 0;
+ Input Parameters:
+
+ kin - Integer variable containing binary number.
-/* Establish values of loop parameters. */
+ knbit - Number of bits in binary number.
- if (kcode > 10) {
+ Output Parameters:
-/* Quasi-regular along longitude lines. */
+ kout - Integer variable containing decimal value
+ with ones and zeroes corresponding to those of
+ the input binary number.
- iquano = klon;
- iregno = klat;
- icode = kcode - 10;
- } else {
+ kerr - 0, If no error.
+ 1, Number of bits in binary number exceeds
+ maximum allowed or is less than 1.
-/* Quasi-regular along latitude lines. */
- iquano = klat;
- iregno = klon;
- icode = kcode;
- }
+ Converted from EMOS routine PRTBIN.
-/* -------------------------------------------------------- */
-/** Section 2. Interpolate field from quasi to regular grid. */
-/* -------------------------------------------------------- */
+ Uwe Schulzweida MPIfM 01/04/2001
- i_1 = iquano;
- for (j230 = 1; j230 <= i_1; ++j230) {
+ */
+ int idec;
+ int ik;
+ int itemp;
+ int j;
- if (iregno != kpoint[j230]) {
+ /*
+ Check length of binary number to ensure decimal number
+ generated will fit in the computer word - in this case will
+ it fit in a Cray 48 bit integer?
+ */
+ if ( knbit < 1 || knbit > 14 )
+ {
+ *kerr = 1;
+ printf(" prtbin : Error in binary number length - %3d bits.\n", knbit);
+ return;
+ }
+ else
+ *kerr = 0;
+ /*
+ -----------------------------------------------------------------
+ Section 1. Generate required number.
+ -----------------------------------------------------------------
+ */
+ *kout = 0;
+ ik = kin;
+ idec = 1;
-/* Line contains less values than required,so */
-/* extract quasi-regular grid values for a line */
+ for ( j = 0; j < knbit; j++ )
+ {
+ itemp = ik - ( (ik/2)*2 );
+ *kout = (*kout) + itemp * idec;
+ ik = ik / 2;
+ idec = idec * 10;
+ }
- i_2 = kpoint[j230];
- for (j210 = 1; j210 <= i_2; ++j210) {
- ++ilii;
- zline[j210 - 1] = pfield[ilii];
- }
+ return;
+}
-/* and interpolate this line. */
- TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
- if (*kret != 0) goto L900;
+void ref2ibm(double *pref, int kbits)
+{
+ /*
-/* Add regular grid values for this line to the
- temporary array. */
+ Purpose:
+ --------
- i_2 = iregno;
- for (j220 = 1; j220 <= i_2; ++j220) {
- ++ilio;
- ztemp[ilio - 1] = zline[j220 - 1];
- }
+ Code and check reference value in IBM format
- } else {
+ Input Parameters:
+ -----------------
-/* Line contains the required number of values, so add */
-/* this line to the temporary array. */
+ pref - Reference value
+ kbits - Number of bits per computer word.
- i_2 = iregno;
- for (j225 = 1; j225 <= i_2; ++j225) {
- ++ilio;
- ++ilii;
- ztemp[ilio - 1] = pfield[ilii];
- }
- }
- }
+ Output Parameters:
+ ------------------
-/* Copy temporary array to user array. */
+ pref - Reference value
- i_1 = klon * klat;
- for (j240 = 1; j240 <= i_1; ++j240) {
- pfield[j240] = ztemp[j240 - 1];
- }
+ Method:
+ -------
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
+ Codes in IBM format, then decides to ensure that reference
+ value used for packing is not different from that stored
+ because of packing differences.
-L900:
+ Externals.
+ ----------
- Free(zwork);
- Free(zline);
- Free(ztemp);
+ confp3 - Encode into IBM floating point format.
+ decfp2 - Decode from IBM floating point format.
- return 0;
-} /* qu2reg3 */
+ Reference:
+ ----------
-#endif /* T */
+ None.
-/*
- * Local Variables:
- * mode: c
- * End:
- */
+ Comments:
+ --------
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
+ None.
-/* calculate_pfactor: source code from grib_api-1.8.0 */
-double TEMPLATE(calculate_pfactor,T)(const T *spectralField, long fieldTruncation, long subsetTruncation)
-{
- /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
- long loop, index, m, n = 0;
- double pFactor, zeps = 1.0e-15;
- long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
- double* weights, range, * norms;
- double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
- double numerator = 0.0, denominator = 0.0, slope;
+ Author:
+ -------
- /*
- // Setup the weights
- */
+ J.D.Chambers ECMWF 17:05:94
- range = (double) (ismax - ismin +1);
+ Modifications:
+ --------------
- weights = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
- for( loop = ismin; loop <= ismax; loop++ )
- weights[loop] = range / (double) (loop-ismin+1);
- /*
- // Compute norms
- // Handle values 2 at a time (real and imaginary parts).
- */
- norms = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
+ Uwe Schulzweida MPIfM 01/04/2001
- for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
- /*
- // Form norms for the rows which contain part of the unscaled subset.
- */
+ Convert to C from EMOS library version 130
- index = -2;
- for( m = 0; m < subsetTruncation; m++ )
- for( n = m; n <= fieldTruncation; n++ ) {
- index += 2;
- if( n >= subsetTruncation ) {
- double tval = spectralField[index];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- tval = spectralField[index+1];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- }
- }
- /*
- // Form norms for the rows which do not contain part of the unscaled subset.
- */
+ */
- for( m = subsetTruncation; m <= fieldTruncation; m++ )
- for( n = m; n <= fieldTruncation; n++ ) {
- double tval = spectralField[index];
- index += 2;
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- tval = spectralField[index+1];
- tval=tval<0?-tval:tval;
- norms[n] = norms[n] > tval ? norms[n] : tval;
- }
+ static int itrnd;
+ static int kexp, kmant;
+ static double ztemp, zdumm;
+ extern int CGRIBEX_Debug;
- /*
- // Ensure the norms have a value which is not too small in case of
- // problems with math functions (e.g. LOG).
- */
+ /* ----------------------------------------------------------------- */
+ /* Section 1. Convert to and from IBM format. */
+ /* ----------------------------------------------------------------- */
- for( loop = ismin; loop <= ismax; loop++ ) {
- norms[n] = norms[n] > zeps ? norms[n] : zeps;
- if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
- }
+ /* Convert floating point reference value to IBM representation. */
- /*
- // Do linear fit to find the slope
- */
+ itrnd = 1;
+ zdumm = ztemp = *pref;
+ confp3(zdumm, &kexp, &kmant, kbits, itrnd);
- for( loop = ismin; loop <= ismax; loop++ ) {
- x = log( (double) (loop*(loop+1)) );
- y = log( norms[loop] );
- weightedSumOverX = weightedSumOverX + x * weights[loop];
- weightedSumOverY = weightedSumOverY + y * weights[loop];
- sumOfWeights = sumOfWeights + weights[loop];
- }
- weightedSumOverX = weightedSumOverX / sumOfWeights;
- weightedSumOverY = weightedSumOverY / sumOfWeights;
+ if ( kexp == 0 && kmant == 0 ) return;
- /*
- // Perform a least square fit for the equation
- */
+ /* Set reference value to that actually stored in the GRIB code. */
- for( loop = ismin; loop <= ismax; loop++ ) {
+ *pref = decfp2(kexp, kmant);
- x = log( (double)(loop*(loop+1)) );
- y = log( norms[loop] );
- numerator =
- numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
- denominator =
- denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
- }
- slope = numerator / denominator;
+ /* If the nearest number which can be represented in */
+ /* GRIB format is greater than the reference value, */
+ /* find the nearest number in GRIB format lower */
+ /* than the reference value. */
- Free(weights);
- Free(norms);
+ if ( ztemp < *pref )
+ {
+ /* Convert floating point to GRIB representation */
+ /* using truncation to ensure that the converted */
+ /* number is smaller than the original one. */
- pFactor = -slope;
- if( pFactor < -9999.9 ) pFactor = -9999.9;
- if( pFactor > 9999.9 ) pFactor = 9999.9;
+ itrnd = 0;
+ zdumm = *pref = ztemp;
+ confp3(zdumm, &kexp, &kmant, kbits, itrnd);
- return pFactor;
-}
+ /* Set reference value to that stored in the GRIB code. */
-void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
-{
- double power;
- double *scale = (double*) Malloc(((size_t)trunc+1)*sizeof(double));
+ *pref = decfp2(kexp, kmant);
- if ( scale == NULL ) SysError("No Memory!");
+ if ( ztemp < *pref )
+ {
+ if ( CGRIBEX_Debug )
+ {
+ Message("Reference value error.");
+ Message("Notify Met.Applications Section.");
+ Message("ZTEMP = ", ztemp);
+ Message("PREF = ", pref);
+ }
+ *pref = ztemp;
+ }
+ }
- if ( pcScale < -10000 || pcScale > 10000 )
- {
- fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
- return;
- }
+ return;
+} /* ref2ibm */
+#include <math.h>
+#include <string.h>
- /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
- if ( pcScale == 0 ) return;
+unsigned correct_bdslen(unsigned bdslen, long recsize, long gribpos)
+{
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ if ( recsize > JP23SET && bdslen <= 120 ) bdslen = (unsigned)(recsize - gribpos - bdslen);
+ return bdslen;
+}
- power = (double) pcScale / 1000.;
- scale[0] = 1.0;
- if (pcScale != 1000)
- for ( int n = 1; n <= trunc; n++ )
- scale[n] = pow((double) (n*(n+1)), power);
- else
- for ( int n = 1; n <= trunc; n++ )
- scale[n] = (double) (n*(n+1));
+int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
+ unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize)
+{
+ *gribrecsize = 0;
+ *pdsp = NULL;
+ *gdsp = NULL;
+ *bmsp = NULL;
+ *bdsp = NULL;
- if ( inv )
- for ( int n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
+ unsigned char *section = gribbuffer;
+ unsigned char *is = gribbuffer;
+ if ( ! GRIB_START(section) )
+ {
+ fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
+ section[0], section[1], section[2], section[3]);
+ return -1;
+ }
- /* Scale the values */
+ unsigned recsize = GET_UINT3(section[4], section[5], section[6]);
- size_t index = 0;
+ int gribversion = GRIB_EDITION(section);
+ if ( recsize == 24 && gribversion == 0 ) gribversion = 0;
- for ( int m = 0; m < pcStart; m++ )
- for ( int n = m; n <= trunc; n++, index += 2 )
- if ( n >= pcStart )
- {
- fpdata[index ] = (T)(fpdata[index ] * scale[n]);
- fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
- }
+ unsigned grib1offset = (gribversion == 1) ? 4 : 0;
- for ( int m = pcStart; m <= trunc; m++ )
- for ( int n = m; n <= trunc; n++, index += 2 )
- {
- fpdata[index ] = (T)(fpdata[index ] * scale[n]);
- fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
- }
+ unsigned char *pds = is + 4 + grib1offset;
+ unsigned char *bufpointer = pds + PDS_Len;
+ unsigned gribsize = 4 + grib1offset + PDS_Len;
- Free(scale);
-}
+ unsigned char *gds = NULL;
+ if ( PDS_HAS_GDS )
+ {
+ gds = bufpointer;
+ bufpointer += GDS_Len;
+ gribsize += GDS_Len;
+ }
+
+ unsigned char *bms = NULL;
+ if ( PDS_HAS_BMS )
+ {
+ bms = bufpointer;
+ bufpointer += BMS_Len;
+ gribsize += BMS_Len;
+ }
+ unsigned char *bds = bufpointer;
+ unsigned bdslen = BDS_Len;
+ if ( recsize > JP23SET && bdslen <= 120 )
+ {
+ recsize &= JP23SET;
+ recsize *= 120;
+ bdslen = correct_bdslen(bdslen, recsize, gribsize);
+ }
+ bufpointer += bdslen;
+ gribsize += bdslen;
+ gribsize += 4;
-void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
-{
- T *fphelp = (T*) Malloc((size_t)nsp*sizeof(T));
- int m, n;
- int index, inext;
+ *pdsp = pds;
+ *gdsp = gds;
+ *bmsp = bms;
+ *bdsp = bds;
- if ( fphelp == NULL ) SysError("No Memory!");
+ *gribrecsize = gribsize;
+ if ( gribbufsize < gribsize )
+ {
+ fprintf(stderr, "Inconsistent length of GRIB message (grib_buffer_size=%ld < grib_record_size=%u)!\n", gribbufsize, gribsize);
+ return 1;
+ }
- index = inext = 0;
+ if ( !GRIB_FIN(bufpointer) ) // end section - "7777" in ASCII
+ {
+ fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
+ bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
+ return -2;
+ }
- for ( m = 0; m <= pcStart; m++ )
- for ( n = m; n <= trunc; n++ )
- {
- if ( pcStart >= n )
- {
- fphelp[index ] = fpdata[inext++];
- fphelp[index+1] = fpdata[inext++];
- }
- index += 2;
- }
+ return 0;
+}
- index = 0;
- for ( m = 0; m <= trunc; m++ )
- for ( n = m; n <= trunc; n++ )
- {
- if ( n > pcStart )
- {
- fphelp[index ] = fpdata[inext++];
- fphelp[index+1] = fpdata[inext++];
- }
- index += 2;
- }
- for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
+ unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
+ unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp)
+{
+ UNUSED(gribbufsize);
+
+ *idsp = NULL;
+ *lusp = NULL;
+ *gdsp = NULL;
+ *pdsp = NULL;
+ *drsp = NULL;
+ *bmsp = NULL;
+ *bdsp = NULL;
- Free(fphelp);
-}
+ unsigned char *section = gribbuffer;
+ unsigned sec_len = 16;
+ if ( !GRIB_START(section) )
+ {
+ fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
+ section[0], section[1], section[2], section[3]);
+ return -1;
+ }
-void TEMPLATE(gather_complex,T)(T *fpdata, size_t pcStart, size_t trunc, size_t nsp)
-{
- T *restrict fphelp = (T*) Malloc(nsp*sizeof(T));
- size_t inext = 0;
+ int gribversion = GRIB_EDITION(section);
+ if ( gribversion != 2 )
+ {
+ fprintf(stderr, "wrong GRIB version %d\n", gribversion);
+ return -1;
+ }
- for ( size_t m = 0, index = 0; m <= pcStart; m++ )
- for ( size_t n = m; n <= trunc; n++ )
- {
- if ( pcStart >= n )
- {
- fphelp[inext++] = fpdata[index];
- fphelp[inext++] = fpdata[index+1];
- }
- index += 2;
- }
+ unsigned gribsize = 0;
+ for ( int i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
- for ( size_t m = 0, index = 0; m <= trunc; m++ )
- for ( size_t n = m; n <= trunc; n++ )
- {
- if ( n > pcStart )
- {
- fphelp[inext++] = fpdata[index];
- fphelp[inext++] = fpdata[index+1];
- }
- index += 2;
- }
+ unsigned grib_len = sec_len;
+ section += sec_len;
- for ( size_t m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+ /* section 1 */
+ sec_len = GRIB2_SECLEN(section);
+ int sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "ids %d %ld\n", sec_num, sec_len);
- Free(fphelp);
-}
+ if ( sec_num != 1 )
+ {
+ fprintf(stderr, "Unexpected section1 number %d\n", sec_num);
+ return -1;
+ }
+ *idsp = section;
-void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
-{
- /* System generated locals */
- double r_1;
+ grib_len += sec_len;
+ section += sec_len;
- /* Local variables */
- int jl;
- double zfac, zeps, zbeta;
- double zalpha;
+ /* section 2 and 3 */
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "lus %d %ld\n", sec_num, sec_len);
- /* **** SCM0 - Apply SCM0 limiter to derivative estimates. */
- /* output: */
- /* pdl = the limited derivative at the left edge of the interval */
- /* pdr = the limited derivative at the right edge of the interval */
- /* inputs */
- /* pdl = the original derivative at the left edge */
- /* pdr = the original derivative at the right edge */
- /* pfl = function value at the left edge of the interval */
- /* pfr = function value at the right edge of the interval */
- /* klg = number of intervals where the derivatives are limited */
+ if ( sec_num == 2 )
+ {
+ *lusp = section;
- /* define constants */
+ grib_len += sec_len;
+ section += sec_len;
- zeps = 1.0e-12;
- zfac = (1.0 - zeps) * 3.0;
+ /* section 3 */
+ sec_len = GRIB2_SECLEN(section);
+ //sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "gds %d %ld\n", sec_num, sec_len);
- for ( jl = 0; jl < klg; ++jl )
+ *gdsp = section;
+ }
+ else if ( sec_num == 3 )
{
- if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
- {
- zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
- zbeta = pdr[jl] / (pfr[jl] - pfl[jl]);
- if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
- if ( zbeta <= 0.0 ) pdr[jl] = 0.0;
- if ( zalpha > zfac ) pdl[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
- if ( zbeta > zfac ) pdr[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
- }
- else
- {
- pdl[jl] = 0.0;
- pdr[jl] = 0.0;
- }
+ *gdsp = section;
+ }
+ else
+ {
+ fprintf(stderr, "Unexpected section3 number %d\n", sec_num);
+ return -1;
}
-} /* scm0 */
-static
-int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
- int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
-{
- /*
-C---->
-C**** ROWINA3 - Interpolation of row of values.
-C
-C Purpose.
-C --------
-C
-C Interpolate a row of values.
-C
-C
-C** Interface.
-C ----------
-C
-C CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
-C
-C
-C Input Parameters.
-C -----------------
-C
-C P - Row of values to be interpolated.
-C Dimension must be at least KO.
-C
-C KO - Number of values required.
-C
-C KI - Number of values in P on input.
-C
-C PW - Working array.
-C Dimension must be at least (0:KO+2,3).
-C
-C KCODE - Interpolation required.
-C 1 , linear.
-C 3 , cubic.
-C
-C PMSVAL - Value used for missing data indicator.
-C
-C OMISNG - True if missing values are present in field.
-C
-C OPERIO - True if input field is periodic.
-C
-C OVEGGY - True if 'nearest neighbour' processing must be used
-C for interpolation
-C
-C Output Parameters.
-C ------------------
-C
-C P - Now contains KO values.
-C KRET - Return code
-C 0, OK
-C Non-zero, error
-C
-C
-C Method.
-C -------
-C
-C Linear or cubic interpolation performed as required.
-C
-C Comments.
-C ---------
-C
-C This is a version of ROWINA which allows for missing data
-C values and hence for bitmapped fields.
-C
-C
-C Author.
-C -------
-C
-C J.D.Chambers ECMWF 22.07.94
-C
-C
-C Modifications.
-C --------------
-C
-C J.D.Chambers ECMWF 13.09.94
-C Add return code KRET and remove calls to ABORT.
-C
-C J. Clochard, Meteo France, for ECMWF - January 1998.
-C Addition of OMISNG and OPERIO arguments.
-C
-C
-C -----------------------------------------------------------------
-*/
- /* System generated locals */
- int pw_dim1, pw_offset, i_1;
+ grib_len += sec_len;
+ section += sec_len;
- /* Local variables */
- int jl, ip;
- double zwt1, zrdi, zpos;
- double zdo, zwt;
+ /* section 4 */
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "pds %d %ld\n", sec_num, sec_len);
- UNUSED(omisng);
+ if ( sec_num != 4 )
+ {
+ fprintf(stderr, "Unexpected section4 number %d\n", sec_num);
+ return -1;
+ }
- /* Parameter adjustments */
- --p;
- pw_dim1 = ko + 3;
- pw_offset = pw_dim1;
- pw -= pw_offset;
+ *pdsp = section;
- *kret = 0;
+ grib_len += sec_len;
+ section += sec_len;
- if ( kcode == 1 )
+ /* section 5 */
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "drs %d %ld\n", sec_num, sec_len);
+
+ if ( sec_num != 5 )
{
- /* Move input values to work array */
- for ( jl = 1; jl <= ki; ++jl )
- pw[jl + pw_dim1] = p[jl];
+ fprintf(stderr, "Unexpected section5 number %d\n", sec_num);
+ return -1;
+ }
- if ( operio )
- {
- /* Arrange wrap-around value in work array */
- pw[ki + 1 + pw_dim1] = p[1];
+ *drsp = section;
- /* Set up constants to be used to figure out weighting for */
- /* values in interpolation. */
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
- }
- else
- {
- /* Repeat last value, to cope with "implicit truncation" below */
- pw[ki + 1 + pw_dim1] = p[ki];
+ grib_len += sec_len;
+ section += sec_len;
- /* Set up constants to be used to figure out weighting for */
- /* values in interpolation. */
- zrdi = (double) (ki-1);
- zdo = 1.0 / (double) (ko-1);
- }
+ /* section 6 */
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "bms %d %ld\n", sec_num, sec_len);
- /* Loop through the output points */
- for ( jl = 1; jl <= ko; ++jl )
- {
+ if ( sec_num != 6 )
+ {
+ fprintf(stderr, "Unexpected section6 number %d\n", sec_num);
+ return -1;
+ }
- /* Calculate weight from the start of row */
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
+ *bmsp = section;
- /* Get the current array position(minus 1) from the weight - */
- /* note the implicit truncation. */
- ip = (int) zwt;
-
- /* Adjust the weight to range (0.0 to 1.0) */
- zwt -= ip;
+ grib_len += sec_len;
+ section += sec_len;
- /* If 'nearest neighbour' processing must be used */
- if ( oveggy )
- {
- if ( zwt < 0.5 )
- p[jl] = pw[ip + 1 + pw_dim1];
- else
- p[jl] = pw[ip + 2 + pw_dim1];
- }
- else
- {
- /* If the left value is missing, use the right value */
- if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 2 + pw_dim1];
- }
- /* If the right value is missing, use the left value */
- else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
- {
- p[jl] = pw[ip + 1 + pw_dim1];
- }
- /* If neither missing, interpolate ... */
- else
- {
- /* Interpolate using the weighted values on either side */
- /* of the output point position */
- p[jl] = (T)((1.0 - zwt) * pw[ip+1 + pw_dim1]
- + zwt * pw[ip+2 + pw_dim1]);
- }
- }
- }
+ /* section 7 */
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
+ //fprintf(stderr, "bds %d %ld\n", sec_num, sec_len);
+
+ if ( sec_num != 7 )
+ {
+ fprintf(stderr, "Unexpected section7 number %d\n", sec_num);
+ return -1;
}
- else if ( kcode == 3 )
+
+ *bdsp = section;
+
+ grib_len += sec_len;
+ section += sec_len;
+
+ /* skip multi GRIB sections */
+ int msec = 1;
+ while ( !GRIB_FIN(section) )
{
- /* ******************************* */
- /* Section 2. Cubic interpolation .. */
- /* ******************************* */
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
- {
- if ( IS_EQUAL(p[jl], msval) )
- {
- fprintf(stderr," ROWINA3: ");
- fprintf(stderr," Cubic interpolation not supported");
- fprintf(stderr," for fields containing missing data.\n");
- *kret = 1;
- goto L900;
- }
- pw[jl + pw_dim1] = p[jl];
- }
- pw[pw_dim1] = p[ki];
- pw[ki + 1 + pw_dim1] = p[1];
- pw[ki + 2 + pw_dim1] = p[2];
- i_1 = ki;
- for ( jl = 1; jl <= i_1; ++jl )
- {
- pw[jl + (pw_dim1 << 1)] =
- (T)(- pw[jl - 1 + pw_dim1] / 3.0 -
- pw[jl + pw_dim1] * 0.5 +
- pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0);
- pw[jl + 1 + pw_dim1 * 3] =
- (T)(pw[jl - 1 + pw_dim1] / 6.0 -
- pw[jl + pw_dim1] +
- pw[jl + 1 + pw_dim1] * 0.5 +
- pw[jl + 2 + pw_dim1] / 3.0);
- }
+ sec_len = GRIB2_SECLEN(section);
+ sec_num = GRIB2_SECNUM(section);
- TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
- &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
+ if ( sec_num < 1 || sec_num > 7 ) break;
- zrdi = (double) ki;
- zdo = 1.0 / (double) ko;
- for ( jl = 1; jl <= ko; ++jl )
- {
- zpos = (jl - 1) * zdo;
- zwt = zpos * zrdi;
- ip = (int) zwt + 1;
- zwt = zwt + 1.0 - ip;
- zwt1 = 1.0 - zwt;
- p[jl] = (T)(((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
- zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
- ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
- zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt);
- }
+ if ( sec_num == 7 )
+ fprintf(stderr, "Skipped unsupported multi GRIB section %d!\n", ++msec);
+
+ if ( (grib_len + sec_len) > gribsize ) break;
+ grib_len += sec_len;
+ section += sec_len;
}
- else
+
+ /* end section - "7777" in ASCII */
+ if ( !GRIB_FIN(section) )
{
- /* ************************************** */
- /* Section 3. Invalid interpolation code .. */
- /* ************************************** */
- fprintf(stderr," ROWINA3:");
- fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
- *kret = 2;
+ fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
+ section[0], section[1], section[2], section[3]);
+ return -2;
}
-L900:
- return 0;
-} /* rowina3 */
-
+ return 0;
+}
-int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
- T msval, int *kret, int omisng, int operio, int oveggy)
-{
- /*
-C**** QU2REG3 - Convert quasi-regular grid data to regular.
-C
-C Purpose.
-C --------
-C
-C Convert quasi-regular grid data to regular,
-C using either a linear or cubic interpolation.
-C
-C
-C** Interface.
-C ----------
-C
-C CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
-C X OVEGGY)
-C
-C
-C Input Parameters.
-C -----------------
-C
-C PFIELD - Array containing quasi-regular grid data.
-C
-C KPOINT - Array containing list of the number of
-C points on each latitude (or longitude) of
-C the quasi-regular grid.
-C
-C KLAT - Number of latitude lines
-C
-C KLON - Number of longitude lines
-C
-C KCODE - Interpolation required.
-C 1 , linear - data quasi-regular on latitude lines.
-C 3 , cubic - data quasi-regular on latitude lines.
-C 11, linear - data quasi-regular on longitude lines.
-C 13, cubic - data quasi-regular on longitude lines.
-C
-C PMSVAL - Value used for missing data indicator.
-C
-C OMISNG - True if missing values are present in field.
-C
-C OPERIO - True if input field is periodic.
-C
-C OVEGGY - True if 'nearest neighbour' processing must be used
-C for interpolation
-C
-C
-C Output Parameters.
-C ------------------
-C
-C KRET - return code
-C 0 = OK
-C non-zero indicates fatal error
-C
-C
-C Output Parameters.
-C ------------------
-C
-C PFIELD - Array containing regular grid data.
-C
-C
-C Method.
-C -------
-C
-C Data is interpolated and expanded into a temporary array,
-C which is then copied back into the user's array.
-C Returns an error code if an invalid interpolation is requested
-C or field size exceeds array dimensions.
-C
-C Comments.
-C ---------
-C
-C This routine is an adaptation of QU2REG to allow missing data
-C values, and hence bit mapped fields.
-C
-C
-C Author.
-C -------
-C
-C J.D.Chambers ECMWF 22.07.94
-C
-C
-C Modifications.
-C --------------
-C
-C J.D.Chambers ECMWF 13.09.94
-C Add return code KRET and remove calls to ABORT.
-C
-C J.D.Chambers ECMWF Feb 1997
-C Allow for 64-bit pointers
-C
-C J. Clochard, Meteo France, for ECMWF - January 1998.
-C Addition of OMISNG and OPERIO arguments.
-C Fix message for longitude number out of bounds, and routine
-C name in title and formats.
-C
-*/
- /* System generated locals */
- int i_1, i_2;
- int kcode = 1;
- /* Local variables */
- int ilii, ilio, icode;
- int iregno, iquano, j210, j220, j230, j240, j225;
- T *ztemp = NULL;
- T *zline = NULL;
- T *zwork = NULL;
+int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
+ int *intnum, float *fltnum, off_t *bignum)
+{
+ long gribsize = 0;
+ off_t bpos = 0;
- ztemp = (T*) Malloc((size_t)klon*(size_t)klat*sizeof(T));
+ unsigned char *section = gribbuffer;
+ unsigned char *is = gribbuffer;
+ if ( ! GRIB_START(section) )
+ {
+ fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
+ section[0], section[1], section[2], section[3]);
+ return -1;
+ }
- zline = (T*) Malloc(2*(size_t)klon*sizeof(T));
+ int gribversion = GRIB_EDITION(section);
+ if ( recsize == 24 && gribversion == 0 ) gribversion = 0;
- zwork = (T*) Malloc(3*(2*(size_t)klon+3)*sizeof(T));
+ unsigned grib1offset = (gribversion == 1) ? 4 : 0;
- /* Parameter adjustments */
- --pfield;
- --kpoint;
+ unsigned char *pds = is + 4 + grib1offset;
+ unsigned char *bufpointer = pds + PDS_Len;
+ gribsize += 4 + grib1offset + PDS_Len;
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+ unsigned char *gds = NULL;
+ if ( PDS_HAS_GDS )
+ {
+ gds = bufpointer;
+ bufpointer += GDS_Len;
+ gribsize += GDS_Len;
+ }
- *kret = 0;
+ unsigned char *bms = NULL;
+ if ( PDS_HAS_BMS )
+ {
+ bms = bufpointer;
+ bufpointer += BMS_Len;
+ bpos = recpos + gribsize + 6;
+ gribsize += BMS_Len;
+ }
-/* Check input parameters. */
+ unsigned char *bds = bufpointer;
- if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
- fprintf(stderr," QU2REG :");
- fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
- *kret = 1;
- goto L900;
- }
+ off_t dpos = recpos + gribsize + 11;
-/* Set array indices to 0. */
+ unsigned bdslen = BDS_Len;
+ bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
+ bufpointer += bdslen;
+ gribsize += bdslen;
+ gribsize += 4;
- ilii = 0;
- ilio = 0;
+ if ( gribsize > recsize )
+ {
+ fprintf(stderr, "GRIB buffer size %ld too small! Min size = %ld\n", recsize, gribsize);
+ return 1;
+ }
-/* Establish values of loop parameters. */
+ /* end section - "7777" in ascii */
+ if ( !GRIB_FIN(bufpointer) )
+ {
+ fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
+ bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
+ }
- if (kcode > 10) {
+ int bs = BDS_BinScale;
+ if ( bs > 32767 ) bs = 32768-bs;
+ float bsf = ldexpf(1.0f, bs);
-/* Quasi-regular along longitude lines. */
+ bignum[0] = dpos;
+ bignum[1] = bms ? bpos : -999;
+ intnum[0] = BDS_NumBits;
- iquano = klon;
- iregno = klat;
- icode = kcode - 10;
- } else {
+ /* fltnum[0] = 1.0; */
+ fltnum[0] = powf(10.0f, (float)PDS_DecimalScale);
+ fltnum[1] = bsf;
+ fltnum[2] = (float)BDS_RefValue;
+ /*
+ printf("intnum %d %d %d\n", intnum[0], intnum[1], intnum[2]);
+ printf("fltnum %g %g %g\n", fltnum[0], fltnum[1], fltnum[2]);
+ */
+ return 0;
+}
-/* Quasi-regular along latitude lines. */
+static
+int get_level(unsigned char *pds)
+{
+ int level = 0;
- iquano = klat;
- iregno = klon;
- icode = kcode;
- }
+ if ( PDS_LevelType == 100 )
+ level = PDS_Level * 100;
+ else if ( PDS_LevelType == 99 )
+ level = PDS_Level;
+ else if ( PDS_LevelType == 109 )
+ level = PDS_Level;
+ else
+ level = PDS_Level1;
-/* -------------------------------------------------------- */
-/** Section 2. Interpolate field from quasi to regular grid. */
-/* -------------------------------------------------------- */
+ return level;
+}
- i_1 = iquano;
- for (j230 = 1; j230 <= i_1; ++j230) {
+static
+double get_cr(unsigned char *w1, unsigned char *w2)
+{
+ unsigned s1 = GET_UINT3(w1[0], w1[1], w1[2]);
+ unsigned s2 = GET_UINT3(w2[0], w2[1], w2[2]);
+ return ((double)s1)/s2;
+}
- if (iregno != kpoint[j230]) {
-/* Line contains less values than required,so */
-/* extract quasi-regular grid values for a line */
+void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ static int header = 1;
+ unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- i_2 = kpoint[j230];
- for (j210 = 1; j210 <= i_2; ++j210) {
- ++ilii;
- zline[j210 - 1] = pfield[ilii];
- }
+ if ( header )
+ {
+ fprintf(stdout,
+ " Rec : Off Position Size : V PDS GDS BMS BDS : Code Level : LType GType: CR LL\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
+ }
-/* and interpolate this line. */
+ is = gribbuffer;
- TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
- if (*kret != 0) goto L900;
+ unsigned gribsize = GET_UINT3(is[4], is[5], is[6]);
-/* Add regular grid values for this line to the
- temporary array. */
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
+ {
+ fprintf(stdout, "%5d :%4ld %8ld %6ld : GRIB message error\n", nrec, offset, recpos, recsize);
+ return;
+ }
- i_2 = iregno;
- for (j220 = 1; j220 <= i_2; ++j220) {
- ++ilio;
- ztemp[ilio - 1] = zline[j220 - 1];
- }
+ int GridType = (gds == NULL) ? -1 : (int)GDS_GridType;
- } else {
+ int level = get_level(pds);
-/* Line contains the required number of values, so add */
-/* this line to the temporary array. */
+ unsigned bdslen = BDS_Len;
- i_2 = iregno;
- for (j225 = 1; j225 <= i_2; ++j225) {
- ++ilio;
- ++ilii;
- ztemp[ilio - 1] = pfield[ilii];
- }
- }
- }
+ bool llarge = (gribsize > JP23SET && bdslen <= 120);
-/* Copy temporary array to user array. */
+ bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
- i_1 = klon * klat;
- for (j240 = 1; j240 <= i_1; ++j240) {
- pfield[j240] = ztemp[j240 - 1];
- }
+ double cr = (((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130)) ? get_cr(&bds[14], &gribbuffer[4]) : 1;
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
+ fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d%4d%5d %6d %6d : %3d %6d : %5d %5d %6.4g %c",
+ nrec, offset, recpos, recsize, GRIB_EDITION(is),
+ PDS_Len, GDS_Len, BMS_Len, bdslen,
+ PDS_Parameter, level, PDS_LevelType, GridType, cr, llarge?'T':'F');
-L900:
+ if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+ fprintf(stdout, "\n");
+}
- Free(zwork);
- Free(zline);
- Free(ztemp);
- return 0;
-} /* qu2reg3 */
+void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ static int header = 1;
+ unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ unsigned char *ids = NULL, *lus = NULL, *drs = NULL;
+ long ids_len = 0, lus_len = 0, gds_len = 0, pds_len = 0, drs_len = 0, bms_len = 0, bds_len = 0;
+ int gridtype, paramnum, level1type /*, level2type*/;
+ int level1 /*, level1sf*/;
+ /* int level2, level2sf; */
+ double cr = 1;
-#endif /* T */
+ if ( header )
+ {
+ fprintf(stdout,
+ " Rec : Off Position Size : V IDS LUS GDS PDS DRS BMS BDS : Code Level : LType GType: CR\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
+ }
-/*
- * Local Variables:
- * mode: c
- * End:
- */
-#include <string.h>
+ is = gribbuffer;
+ int nerr = grib2Sections(gribbuffer, recsize, &ids, &lus, &gds, &pds, &drs, &bms, &bds);
+ if ( nerr )
+ {
+ fprintf(stdout, "%5d :%4ld %8ld %6ld : error\n", nrec, offset, recpos, recsize);
+ return;
+ }
+ if ( ids ) ids_len = GRIB2_SECLEN(ids);
+ if ( lus ) lus_len = GRIB2_SECLEN(lus);
+ if ( gds ) gds_len = GRIB2_SECLEN(gds);
+ if ( pds ) pds_len = GRIB2_SECLEN(pds);
+ if ( drs ) drs_len = GRIB2_SECLEN(drs);
+ if ( bms ) bms_len = GRIB2_SECLEN(bms);
+ if ( bds ) bds_len = GRIB2_SECLEN(bds);
-int gribVersion(unsigned char *is, size_t buffersize)
-{
- if ( buffersize < 8 )
- Error("Buffer too small (current size %d)!", (int) buffersize);
+ // double cr = (((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130)) ? get_cr(&bds[14], &gribbuffer[4]) : 1;
- return (GRIB_EDITION(is));
+ gridtype = GET_UINT2(gds[12],gds[13]);
+ paramnum = GET_UINT1(pds[10]);
+ level1type = GET_UINT1(pds[22]);
+ /* level1sf = GET_UINT1(pds[23]); */
+ level1 = GET_UINT4(pds[24],pds[25],pds[26],pds[27]);
+ /* level2type = GET_UINT1(pds[28]); */
+ /* level2sf = GET_UINT1(pds[29]); */
+ /* level2 = GET_UINT4(pds[30],pds[31],pds[32],pds[33]); */
+ /*
+ printf("level %d %d %d %d %d %d %d\n", level1type, level1sf, level1, level1*level1sf, level2sf, level2, level2*level2sf);
+ */
+ fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d %3ld %3ld %3ld %3ld %4ld %6ld %6ld : %3d%7d : %5d %5d %6.4g\n",
+ nrec, offset, recpos, recsize, GRIB_EDITION(is),
+ ids_len, lus_len, gds_len, pds_len, drs_len, bms_len, bds_len,
+ paramnum, level1, level1type, gridtype, cr);
}
-static
-double GET_Real(unsigned char *grib)
-{
- int iexp, imant;
- iexp = GET_UINT1(grib[0]);
- imant = GET_UINT3(grib[1], grib[2], grib[3]);
+void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ int gribversion = gribVersion(gribbuffer, (size_t)recsize);
- return (decfp2(iexp, imant));
+ if ( gribversion == 0 || gribversion == 1 )
+ grib1PrintALL(nrec, offset, recpos, recsize, gribbuffer);
+ else if ( gribversion == 2 )
+ grib2PrintALL(nrec, offset, recpos, recsize, gribbuffer);
+ else
+ {
+ fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+ nrec, offset, recpos, recsize, gribversion);
+ }
}
-static
-int decodeIS(unsigned char *is, int *isec0, int *iret)
+
+void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- int isLen = 0;
- int grib1offset;
- int lgrib = FALSE, lbudg = FALSE, ltide = FALSE;
+ static int header = 1;
+ unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ int century, subcenter, decimalscale;
+ int fc_num = 0;
+ int year = 0, date;
- /*
- Octets 1 - 4 : The letters G R I B.
- Four 8 bit fields.
- */
- /*
- Check letters -> GRIB, BUDG or TIDE.
- */
- /*
- Check that 'GRIB' is found where expected.
- */
- if ( GRIB_START(is) ) lgrib = TRUE;
- /*
- ECMWF pseudo-grib data uses 'BUDG' and 'TIDE'.
- */
- if ( BUDG_START(is) ) lbudg = TRUE;
- if ( TIDE_START(is) ) ltide = TRUE;
- /*
- Data is not GRIB or pseudo-grib.
- */
- if ( lgrib == FALSE && lbudg == FALSE && ltide == FALSE )
+ UNUSED(recpos);
+
+ if ( header )
{
- *iret = 305;
- gprintf(__func__, "Input data is not GRIB or pseudo-grib.");
- gprintf(__func__, "Return code = %d", *iret);
+ fprintf(stdout,
+ " Rec : PDS Tab Cen Sub Ver Grid Code LTyp Level1 Level2 Date Time P1 P2 TU TR NAVE Scale FCnum CT\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
}
- if ( lbudg == TRUE || ltide == TRUE )
+
+ is = gribbuffer;
+
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- *iret = 305;
- gprintf(__func__, "Pseudo-grib data unsupported.");
- gprintf(__func__, "Return code = %d", *iret);
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
}
- /*
- Octets 5 - 7 : Length of message.
- One 24 bit field.
- */
- ISEC0_GRIB_Len = GRIB1_SECLEN(is);
- /*
- Octet 8 : GRIB Edition Number.
- One 8 bit field.
- */
- ISEC0_GRIB_Version = GRIB_EDITION(is);
-
- if ( ISEC0_GRIB_Version > 1 )
- Error("GRIB version %d unsupported!", ISEC0_GRIB_Version);
+ switch(GRIB_EDITION(is))
+ {
+ case 0:
+ year = GET_UINT1(pds[12]);
+ century = 1;
+ subcenter = 0;
+ decimalscale = 0;
+ break;
+ case 1:
+ year = PDS_Year;
+ century = PDS_Century;
+ subcenter = PDS_Subcenter;
+ decimalscale = PDS_DecimalScale;
+ break;
+ default:
+ fprintf(stderr, "Grib version %d not supported!", GRIB_EDITION(is));
+ exit(EXIT_FAILURE);
+ }
- grib1offset = ISEC0_GRIB_Version * 4;
+ if ( PDS_Len > 28 )
+ if ( PDS_CenterID == 98 || PDS_Subcenter == 98 ||
+ (PDS_CenterID == 7 && PDS_Subcenter == 98) )
+ if ( pds[40] == 1 )
+ fc_num = GET_UINT1(pds[49]);
- isLen = 4 + grib1offset;
+ if ( year < 0 )
+ {
+ date = (-year)*10000+PDS_Month*100+PDS_Day;
+ century = -century;
+ }
+ else
+ {
+ date = year*10000+PDS_Month*100+PDS_Day;
+ }
+
+ fprintf(stdout, "%5d :%4d%4d%4d%4d%4d %4d %4d%4d%7d%7d %8d%6d%3d%3d%3d%3d%5d%6d%5d%4d", nrec,
+ PDS_Len, PDS_CodeTable, PDS_CenterID, subcenter, PDS_ModelID,
+ PDS_GridDefinition, PDS_Parameter, PDS_LevelType, PDS_Level1, PDS_Level2,
+ date, PDS_Time, PDS_TimePeriod1, PDS_TimePeriod2, PDS_TimeUnit, PDS_TimeRange,
+ PDS_AvgNum, decimalscale, fc_num, century);
- return (isLen);
+ if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+ fprintf(stdout, "\n");
}
-static
-void decodePDS_ECMWF_local_Extension_1(unsigned char *pds, int *isec1)
+
+void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
- isec1[37] = GET_UINT1(pds[41]); /* Class */
- isec1[38] = GET_UINT1(pds[42]); /* Type */
- isec1[39] = GET_UINT2(pds[43],pds[44]); /* Stream */
- /* isec1[40] = GET_UINT4(pds[45],pds[46],pds[47],pds[48]); */
- memcpy((char*) &isec1[40], &pds[45], 4);
- isec1[41] = GET_UINT1(pds[49]); /* Forecast number */
- isec1[42] = GET_UINT1(pds[50]); /* Total number of forecasts */
+ int gribversion = gribVersion(gribbuffer, (size_t)recsize);
+
+ if ( gribversion == 0 || gribversion == 1 )
+ grib1PrintPDS(nrec, recpos, recsize, gribbuffer);
+ /*
+ else if ( gribversion == 2 )
+ grib2PrintPDS(nrec, recpos, recsize, gribbuffer);
+ */
+ else
+ {
+ fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+ nrec, 0L, recpos, recsize, gribversion);
+ }
}
-static
-void decodePDS_DWD_local_Extension_254(unsigned char *pds, int *isec1)
-{
- long i;
- int isvn;
- isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
- for ( i = 0; i < 11; i++ )
- {
- isec1[37+i] = GET_UINT1(pds[41+i]);
- }
+void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ static int header = 1;
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- isvn = GET_UINT2(pds[52],pds[53]);
-
- isec1[48] = isvn % 0x8000; /* DWD experiment identifier */
- isec1[49] = isvn >> 15; /* DWD run type (0=main, 2=ass, 3=test) */
+ UNUSED(recpos);
-}
+ if ( header )
+ {
+ fprintf(stdout,
+ " Rec : GDS NV PVPL Typ : xsize ysize Lat1 Lon1 Lat2 Lon2 dx dy\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
+ }
-static
-void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
-{
- long i;
- int isvn;
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
+ {
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
+ }
- isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
- for ( i = 0; i < 11; i++ )
- {
- isec1[37+i] = GET_UINT1(pds[41+i]);
- }
+ fprintf(stdout, "%5d :", nrec);
- isvn = GET_UINT2(pds[52],pds[53]);
-
- isec1[48] = isvn % 0x8000; /* DWD experiment identifier */
- isec1[49] = isvn >> 15; /* DWD run type (0=main, 2=ass, 3=test) */
- isec1[50] = GET_UINT1(pds[54]); /* User id, specified by table */
- isec1[51] = GET_UINT2(pds[55],pds[56]); /* Experiment identifier */
- isec1[52] = GET_UINT2(pds[57],pds[58]); /* Ensemble identification by table */
- isec1[53] = GET_UINT2(pds[59],pds[60]); /* Number of ensemble members */
- isec1[54] = GET_UINT2(pds[61],pds[62]); /* Actual number of ensemble member */
- isec1[55] = GET_UINT1(pds[63]); /* Model major version number */
- isec1[56] = GET_UINT1(pds[64]); /* Model minor version number */
+ if ( gds )
+ fprintf(stdout, "%4d%4d%4d %4d :%6d%6d%7d%7d%7d%7d%6d%6d",
+ GDS_Len, GDS_NV, GDS_PVPL, GDS_GridType,
+ GDS_NumLon, GDS_NumLat,
+ GDS_FirstLat, GDS_FirstLon,
+ GDS_LastLat, GDS_LastLon,
+ GDS_LonIncr, GDS_LatIncr);
+ else
+ fprintf(stdout, " Grid Description Section not defined");
+ if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+ fprintf(stdout, "\n");
}
-static
-void decodePDS_MPIM_local_Extension_1(unsigned char *pds, int *isec1)
+
+void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
- isec1[37] = GET_UINT1(pds[41]); /* type of ensemble forecast */
- isec1[38] = GET_UINT2(pds[42],pds[43]); /* individual ensemble member */
- isec1[39] = GET_UINT2(pds[44],pds[45]); /* number of forecasts in ensemble */
+ int gribversion = gribVersion(gribbuffer, (size_t)recsize);
+
+ if ( gribversion == 0 || gribversion == 1 )
+ grib1PrintGDS(nrec, recpos, recsize, gribbuffer);
+ /*
+ else if ( gribversion == 2 )
+ grib2PrintGDS(nrec, recpos, recsize, gribbuffer);
+ */
+ else
+ {
+ fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+ nrec, 0L, recpos, recsize, gribversion);
+ }
}
-static
-int decodePDS(unsigned char *pds, int *isec0, int *isec1)
+
+void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- int pdsLen;
+ static int header = 1;
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- pdsLen = PDS_Len;
+ UNUSED(recpos);
- ISEC1_CodeTable = PDS_CodeTable;
- ISEC1_CenterID = PDS_CenterID;
- ISEC1_ModelID = PDS_ModelID;
- ISEC1_GridDefinition = PDS_GridDefinition;
- ISEC1_Sec2Or3Flag = PDS_Sec2Or3Flag;
- ISEC1_Parameter = PDS_Parameter;
- ISEC1_LevelType = PDS_LevelType;
+ if ( header )
+ {
+ fprintf(stdout,
+ " Rec : Code Level BMS Size\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
+ }
- if ( (ISEC1_LevelType != 20) &&
- (ISEC1_LevelType != GRIB1_LTYPE_99) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE) &&
- (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT) &&
- (ISEC1_LevelType != GRIB1_LTYPE_SIGMA) &&
- (ISEC1_LevelType != GRIB1_LTYPE_HYBRID) &&
- (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
- (ISEC1_LevelType != 115) &&
- (ISEC1_LevelType != 117) &&
- (ISEC1_LevelType != 125) &&
- (ISEC1_LevelType != 127) &&
- (ISEC1_LevelType != GRIB1_LTYPE_SEADEPTH) &&
- (ISEC1_LevelType != 210) )
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- ISEC1_Level1 = PDS_Level1;
- ISEC1_Level2 = PDS_Level2;
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
}
+
+ int level = get_level(pds);
+
+ fprintf(stdout, "%5d :", nrec);
+
+ if ( bms )
+ fprintf(stdout, "%4d%7d %7d %7d",
+ PDS_Parameter, level, BMS_Len, BMS_BitmapSize);
+ else
+ fprintf(stdout, "%4d%7d Bit Map Section not defined", PDS_Parameter, level);
+
+ if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+ fprintf(stdout, "\n");
+}
+
+
+void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ int gribversion = gribVersion(gribbuffer, (size_t)recsize);
+
+ if ( gribversion == 0 || gribversion == 1 )
+ grib1PrintBMS(nrec, recpos, recsize, gribbuffer);
+ /*
+ else if ( gribversion == 2 )
+ grib2PrintBMS(nrec, recpos, recsize, gribbuffer);
+ */
else
{
- ISEC1_Level1 = PDS_Level;
- ISEC1_Level2 = 0;
+ fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+ nrec, 0L, recpos, recsize, gribversion);
}
+}
- /* ISEC1_Year = PDS_Year; */
- ISEC1_Month = PDS_Month;
- ISEC1_Day = PDS_Day;
- ISEC1_Hour = PDS_Hour;
- ISEC1_Minute = PDS_Minute;
- ISEC1_TimeUnit = PDS_TimeUnit;
- ISEC1_TimePeriod1 = PDS_TimePeriod1;
- ISEC1_TimePeriod2 = PDS_TimePeriod2;
- ISEC1_TimeRange = PDS_TimeRange;
- ISEC1_AvgNum = PDS_AvgNum;
- ISEC1_AvgMiss = PDS_AvgMiss;
- if ( ISEC0_GRIB_Version == 1 )
- {
- ISEC1_Year = PDS_Year;
- ISEC1_Century = PDS_Century;
- ISEC1_SubCenterID = PDS_Subcenter;
- ISEC1_DecScaleFactor = PDS_DecimalScale;
- }
- else
+void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+ static int header = 1;
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ double scale;
+
+ UNUSED(recpos);
+
+ if ( header )
{
- int year;
- year = GET_UINT1(pds[12]);
- if ( year <= 100 )
- {
- ISEC1_Year = year;
- ISEC1_Century = 1;
- }
- else
- {
- ISEC1_Year = year%100;
- ISEC1_Century = 1 + (year-ISEC1_Year)/100;
- }
- ISEC1_SubCenterID = 0;
- ISEC1_DecScaleFactor = 0;
+ fprintf(stdout,
+ " Rec : Code Level BDS Flag Scale RefValue Bits CR\n");
+/* ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+ header = 0;
}
- if ( ISEC1_Year < 0 )
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- ISEC1_Year = -ISEC1_Year;
- ISEC1_Century = -ISEC1_Century;
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
}
- ISEC1_LocalFLag = 0;
- if ( pdsLen > 28 )
- {
- int localextlen;
- localextlen = pdsLen-28;
+ int level = get_level(pds);
- if ( localextlen > 4000 )
- {
- Warning("PDS larger than 4000 bytes not supported!");
- }
- else
- {
- ISEC1_LocalFLag = 1;
+ double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
- if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
- {
- if ( pds[40] == 254 )
- {
- decodePDS_DWD_local_Extension_254(pds, isec1);
- }
- else if ( pds[40] == 253 )
- {
- decodePDS_DWD_local_Extension_253(pds, isec1);
- }
- }
- else if ( (ISEC1_CenterID == 98 && ISEC1_LocalFLag == 1) ||
- (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag == 1) ||
- (ISEC1_CenterID == 7 && ISEC1_SubCenterID == 98) )
- {
- if ( pds[40] == 1 )
- decodePDS_ECMWF_local_Extension_1(pds, isec1);
- }
- else if ( ISEC1_CenterID == 252 && ISEC1_LocalFLag == 1 )
- {
- if ( pds[40] == 1 )
- decodePDS_MPIM_local_Extension_1(pds, isec1);
- }
- else
- {
- long i;
- for ( i = 0; i < localextlen; i++ )
- {
- isec1[24+i] = pds[28+i];
- }
- }
- }
- }
+ double refval = BDS_RefValue;
- return (pdsLen);
-}
+ if ( BDS_BinScale < 0 )
+ scale = 1.0/pow(2.0, (double) -BDS_BinScale);
+ else
+ scale = pow(2.0, (double) BDS_BinScale);
+ if ( PDS_DecimalScale )
+ {
+ double decscale = pow(10.0, (double)-PDS_DecimalScale);
+ refval *= decscale;
+ scale *= decscale;
+ }
-void gribPrintSec2_double(int *isec0, int *isec2, double *fsec2) {gribPrintSec2DP(isec0, isec2, fsec2);}
-void gribPrintSec3_double(int *isec0, int *isec3, double *fsec3) {gribPrintSec3DP(isec0, isec3, fsec3);}
-void gribPrintSec4_double(int *isec0, int *isec4, double *fsec4) {gribPrintSec4DP(isec0, isec4, fsec4);}
-void gribPrintSec2_float(int *isec0, int *isec2, float *fsec2) {gribPrintSec2SP(isec0, isec2, fsec2);}
-void gribPrintSec3_float(int *isec0, int *isec3, float *fsec3) {gribPrintSec3SP(isec0, isec3, fsec3);}
-void gribPrintSec4_float(int *isec0, int *isec4, float *fsec4) {gribPrintSec4SP(isec0, isec4, fsec4);}
+ fprintf(stdout, "%5d :", nrec);
+ if ( bds )
+ fprintf(stdout, "%4d%7d %7d %4d %8.5g %11.5g%4d %6.4g",
+ PDS_Parameter, level,
+ BDS_Len, BDS_Flag, scale, refval, BDS_NumBits, cr);
+ else
+ fprintf(stdout, " Binary Data Section not defined");
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
+ if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+ fprintf(stdout, "\n");
+}
-#include <inttypes.h>
-static
-void TEMPLATE(decode_array_common,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
- T fmin, T zscale, T *restrict fpdata)
+void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- /* code from wgrib routine BDS_unpack */
- const unsigned char *bits = igrib;
- long i;
- unsigned int tbits = 0;
- int n_bits = NumBits;
- int t_bits = 0;
+ int gribversion = gribVersion(gribbuffer, (size_t)recsize);
- unsigned jmask = (1U << n_bits) - 1U;
- for ( i = 0; i < jlend; i++ )
+ if ( gribversion == 0 || gribversion == 1 )
+ grib1PrintBDS(nrec, recpos, recsize, gribbuffer);
+ /*
+ else if ( gribversion == 2 )
+ grib2PrintBDS(nrec, recpos, recsize, gribbuffer);
+ */
+ else
{
- if (n_bits - t_bits > 8)
- {
- tbits = (tbits << 16) | ((unsigned)bits[0] << 8) | ((unsigned)bits[1]);
- bits += 2;
- t_bits += 16;
- }
-
- while ( t_bits < n_bits )
- {
- tbits = (tbits * 256) + *bits++;
- t_bits += 8;
- }
- t_bits -= n_bits;
- fpdata[i] = (float)((tbits >> t_bits) & jmask);
+ fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+ nrec, 0L, recpos, recsize, gribversion);
}
- /* at least this vectorizes :) */
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin + zscale*fpdata[i];
}
-static
-void TEMPLATE(decode_array_common2,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
- T fmin, T zscale, T *restrict fpdata)
+
+void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
{
- static const unsigned mask[] = {0,1,3,7,15,31,63,127,255};
- static const double shift[9]
- = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- /* code from wgrib routine BDS_unpack */
- const unsigned char *bits = igrib;
- long i;
- int n_bits = NumBits;
- int c_bits, j_bits;
+ UNUSED(recpos);
- /* older unoptimized code, not often used */
- c_bits = 8;
- for ( i = 0; i < jlend; i++ )
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- double jj = 0.0;
- j_bits = n_bits;
- while (c_bits <= j_bits)
- {
- if (c_bits == 8)
- {
- jj = jj * 256.0 + (double) (*bits++);
- j_bits -= 8;
- }
- else
- {
- jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
- bits++;
- j_bits -= c_bits;
- c_bits = 8;
- }
- }
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
+ }
- if (j_bits)
- {
- c_bits -= j_bits;
- jj = (jj * shift[j_bits]) + (double) (((unsigned)*bits >> c_bits) & mask[j_bits]);
- }
- fpdata[i] = (T)(fmin + zscale*jj);
+ if ( nerr > 0 )
+ {
+ fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
+ return;
}
+
+ int level = get_level(pds);
+
+ double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
+
+ if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+ fprintf(stdout, "GRIB record %5d : code = %4d level = %7d\n", nrec, PDS_Parameter, level);
}
+
static
-void TEMPLATE(decode_array_2byte,T)(size_t jlend, const unsigned char *restrict igrib,
- T *fpdata, T fmin, T zscale)
+void repair1(unsigned char *gbuf, long gbufsize)
{
- U_BYTEORDER;
- const uint16_t *restrict sgrib = (uint16_t *) (igrib);
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ /* int recLen; */
+ unsigned char *source;
+ size_t sourceLen;
+ int bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress */;
+ int bds_head = 11;
+ int bds_ext = 0, bds_ubits;
+ int datstart = 0;
- if ( IS_BIGENDIAN() )
+ long gribrecsize;
+ int nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- for ( size_t i = 0; i < jlend; i++ )
- {
- fpdata[i] = fmin + zscale * sgrib[i];
- }
+ fprintf(stdout, "GRIB message error\n");
+ return;
}
- else
+
+ if ( nerr > 0 )
{
- uint16_t ui16;
- for ( size_t i = 0; i < jlend; i++ )
- {
- ui16 = gribSwapByteOrder_uint16(sgrib[i]);
- fpdata[i] = fmin + zscale * ui16;
- }
+ fprintf(stdout, "GRIB data corrupted!\n");
+ return;
}
-}
-
-static
-void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits,
- T fmin, T zscale, T *restrict fpdata)
-{
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
- uint64_t start_decode, end_decode;
-#endif
- long i;
-#if defined (VECTORCODE)
- GRIBPACK *lgrib = NULL;
+ unsigned bds_len = BDS_Len;
+ bds_nbits = BDS_NumBits;
+ bds_flag = BDS_Flag;
+ bds_ubits = bds_flag & 15;
+ lspherc = bds_flag >> 7;
+ lcomplex = (bds_flag >> 6)&1;
+ /* lcompress = (bds_flag >> 4)&1; */
- if ( numBits%8 == 0 )
+ if ( lspherc )
{
- long jlenc = jlend * numBits / 8;
- if ( jlenc > 0 )
+ if ( lcomplex )
{
- lgrib = (GRIBPACK*) Malloc(jlenc*sizeof(GRIBPACK));
- if ( lgrib == NULL ) SysError("No Memory!");
-
- (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+ int jup, ioff;
+ jup = bds[15];
+ ioff = (jup+1)*(jup+2);
+ bds_ext = 4 + 3 + 4*ioff;
+ }
+ else
+ {
+ bds_ext = 4;
}
}
- if ( numBits == 0 )
- {
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin;
- }
- else if ( numBits == 8 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (int)lgrib[i];
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 16 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (((int)lgrib[2*i ] << 8) + (int)lgrib[2*i+1]);
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 24 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (((int)lgrib[3*i ] << 16) + ((int)lgrib[3*i+1] << 8) +
- (int)lgrib[3*i+2]);
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 32 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (((unsigned int)lgrib[4*i ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
- ((unsigned int)lgrib[4*i+2] << 8) + (unsigned int)lgrib[4*i+3]);
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits <= 25 )
- {
- TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else if ( numBits > 25 && numBits < 32 )
- {
- TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else
- {
- Error("Unimplemented packing factor %d!", numBits);
- }
+ datstart = bds_head + bds_ext;
- if ( lgrib ) Free(lgrib);
+ source = bds + datstart;
-#else
- if ( numBits == 0 )
- {
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin;
- }
- else if ( numBits == 8 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (int)igrib[i];
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 16 )
+ sourceLen = (size_t)(((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8);
+
+ if ( bds_nbits == 24 )
{
- TEMPLATE(decode_array_2byte,T)((size_t) jlend, igrib, fpdata, fmin, zscale);
+ unsigned char *pbuf = (unsigned char*) Malloc(sourceLen);;
+ size_t nelem = sourceLen/3;
+ for ( size_t i = 0; i < nelem; i++ )
+ {
+ pbuf[3*i ] = source[ i];
+ pbuf[3*i+1] = source[ nelem+i];
+ pbuf[3*i+2] = source[2*nelem+i];
+ }
+ memcpy(source, pbuf, sourceLen);
+ Free(pbuf);
}
- else if ( numBits == 24 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (T)(((int)igrib[3*i ] << 16) + ((int)igrib[3*i+1] << 8) +
- (int)igrib[3*i+2]);
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 32 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (T)(((unsigned int)igrib[4*i ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
- ((unsigned int)igrib[4*i+2] << 8) + (unsigned int)igrib[4*i+3]);
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits <= 25 )
+}
+
+
+void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
+{
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ fprintf(stdout, "%5d : GRIB message error\n", nrec);
+ return;
}
- else if ( numBits > 25 && numBits < 32 )
+
+ if ( nerr > 0 )
{
- TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
+ return;
}
- else
+
+ int level = get_level(pds);
+
+ double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
+
+ if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
{
- Error("Unimplemented packing factor %d!", numBits);
+ fprintf(stdout, "Repair GRIB record %5d : code = %4d level = %7d\n", nrec, PDS_Parameter, level);
+ repair1(gribbuffer, recsize);
}
+}
+#include <stdio.h>
+#include <string.h>
+
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#if defined (HAVE_LIBSZ)
+#if defined(__cplusplus)
+extern "C" {
#endif
+#include <szlib.h>
+#if defined (__cplusplus)
}
+#endif
-#endif /* T */
+#define OPTIONS_MASK (SZ_RAW_OPTION_MASK | SZ_MSB_OPTION_MASK | SZ_NN_OPTION_MASK)
-/*
- * Local Variables:
- * mode: c
- * End:
- */
+#define PIXELS_PER_BLOCK (8)
+#define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
-#ifdef T
-#undef T
+#define MIN_COMPRESS (0.95)
+#define MIN_SIZE (256)
#endif
-#define T float
-#ifdef T
-#include <inttypes.h>
+#define Z_SZIP 128
-static
-void TEMPLATE(decode_array_common,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
- T fmin, T zscale, T *restrict fpdata)
-{
- /* code from wgrib routine BDS_unpack */
- const unsigned char *bits = igrib;
- long i;
- unsigned int tbits = 0;
- int n_bits = NumBits;
- int t_bits = 0;
- unsigned jmask = (1U << n_bits) - 1U;
- for ( i = 0; i < jlend; i++ )
- {
- if (n_bits - t_bits > 8)
- {
- tbits = (tbits << 16) | ((unsigned)bits[0] << 8) | ((unsigned)bits[1]);
- bits += 2;
- t_bits += 16;
- }
+#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
+ (var[offset+1] = 0xFF & (value >> 8)), \
+ (var[offset+2] = 0xFF & (value )))
+#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
+ (var[offset+1] = 0xFF & (value >> 16)), \
+ (var[offset+2] = 0xFF & (value >> 8)), \
+ (var[offset+3] = 0xFF & (value )))
- while ( t_bits < n_bits )
- {
- tbits = (tbits * 256) + *bits++;
- t_bits += 8;
- }
- t_bits -= n_bits;
- fpdata[i] = (float)((tbits >> t_bits) & jmask);
- }
- /* at least this vectorizes :) */
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin + zscale*fpdata[i];
-}
-static
-void TEMPLATE(decode_array_common2,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
- T fmin, T zscale, T *restrict fpdata)
+int gribGetZip(size_t recsize, unsigned char *gribbuffer, size_t *urecsize)
{
- static const unsigned mask[] = {0,1,3,7,15,31,63,127,255};
- static const double shift[9]
- = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+ int compress = 0;
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- /* code from wgrib routine BDS_unpack */
- const unsigned char *bits = igrib;
- long i;
- int n_bits = NumBits;
- int c_bits, j_bits;
+ int gribversion = gribVersion(gribbuffer, recsize);
- /* older unoptimized code, not often used */
- c_bits = 8;
- for ( i = 0; i < jlend; i++ )
- {
- double jj = 0.0;
- j_bits = n_bits;
- while (c_bits <= j_bits)
- {
- if (c_bits == 8)
- {
- jj = jj * 256.0 + (double) (*bits++);
- j_bits -= 8;
- }
- else
- {
- jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
- bits++;
- j_bits -= c_bits;
- c_bits = 8;
- }
- }
+ if ( gribversion == 2 ) return compress;
- if (j_bits)
- {
- c_bits -= j_bits;
- jj = (jj * shift[j_bits]) + (double) (((unsigned)*bits >> c_bits) & mask[j_bits]);
- }
- fpdata[i] = (T)(fmin + zscale*jj);
+ long gribrecsize;
+ int nerr = grib1Sections(gribbuffer, (long)recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
+ {
+ fprintf(stdout, "GRIB message error\n");
+ return compress;
}
-}
-
-static
-void TEMPLATE(decode_array_2byte,T)(size_t jlend, const unsigned char *restrict igrib,
- T *fpdata, T fmin, T zscale)
-{
- U_BYTEORDER;
- const uint16_t *restrict sgrib = (uint16_t *) (igrib);
- if ( IS_BIGENDIAN() )
+ if ( nerr > 0 )
{
- for ( size_t i = 0; i < jlend; i++ )
- {
- fpdata[i] = fmin + zscale * sgrib[i];
- }
+ fprintf(stdout, "GRIB data corrupted!\n");
+ return compress;
}
- else
+
+ /* bds_len = BDS_Len; */
+ /* bds_nbits = BDS_NumBits; */
+ int bds_flag = BDS_Flag;
+ /* lspherc = bds_flag >> 7; */
+ /* lcomplex = (bds_flag >> 6)&1; */
+ int lcompress = (bds_flag >> 4)&1;
+
+ size_t gribsize = 0;
+ if ( lcompress )
{
- uint16_t ui16;
- for ( size_t i = 0; i < jlend; i++ )
- {
- ui16 = gribSwapByteOrder_uint16(sgrib[i]);
- fpdata[i] = fmin + zscale * ui16;
- }
+ compress = BDS_Z;
+ if ( compress == Z_SZIP ) gribsize = (size_t) GET_UINT3(bds[14], bds[15], bds[16]);
}
+
+ *urecsize = gribsize;
+
+ return compress;
}
-static
-void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits,
- T fmin, T zscale, T *restrict fpdata)
+
+int gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
{
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
- uint64_t start_decode, end_decode;
+#if ! defined(HAVE_LIBSZ)
+ static int libszwarn = 1;
#endif
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ bool llarge = false;
- long i;
-#if defined (VECTORCODE)
- GRIBPACK *lgrib = NULL;
+ unsigned gribLen = GET_UINT3(dbuf[4], dbuf[5], dbuf[6]);
- if ( numBits%8 == 0 )
- {
- long jlenc = jlend * numBits / 8;
- if ( jlenc > 0 )
- {
- lgrib = (GRIBPACK*) Malloc(jlenc*sizeof(GRIBPACK));
- if ( lgrib == NULL ) SysError("No Memory!");
+ int rec_len = gribLen;
- (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
- }
+ long gribrecsize;
+ int nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
+ {
+ fprintf(stdout, "GRIB message error\n");
+ return gribrecsize;
}
- if ( numBits == 0 )
+ if ( nerr > 0 )
{
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin;
+ fprintf(stdout, "GRIB data corrupted!\n");
+ return gribrecsize;
}
- else if ( numBits == 8 )
- for ( i = 0; i < jlend; i++ )
- {
- T dval = (int)lgrib[i];
- fpdata[i] = fmin + zscale * dval;
- }
- else if ( numBits == 16 )
- for ( i = 0; i < jlend; i++ )
+
+ int bds_zoffset = 12;
+
+ int bds_len = BDS_Len;
+ if ( gribLen > JP23SET && bds_len <= 120 )
+ {
+ gribLen &= JP23SET;
+ gribLen *= 120;
+ bds_len = correct_bdslen(bds_len, gribLen, bds-dbuf);
+ llarge = true;
+ bds_zoffset += 2;
+ }
+
+ if ( gribLen > JP24SET || llarge ) return gribLen;
+
+#if defined(HAVE_LIBSZ)
+ {
+ int bds_zstart = 14;
+ unsigned gribLenOld = 0;
+ int bds_head = 11;
+ int bds_ext = 0;
+ unsigned char *pbuf = NULL;
+
+ int bds_nbits = BDS_NumBits;
+ int bds_flag = BDS_Flag;
+ int bds_ubits = bds_flag & 15;
+ int lspherc = bds_flag >> 7;
+ int lcomplex = (bds_flag >> 6)&1;
+ /* lcompress = (bds_flag >> 4)&1; */
+
+ if ( bds_nbits != 8 && bds_nbits != 16 && bds_nbits != 24 && bds_nbits != 32 )
{
- T dval = (((int)lgrib[2*i ] << 8) + (int)lgrib[2*i+1]);
- fpdata[i] = fmin + zscale * dval;
+ static bool linfo = true;
+ if ( linfo && bds_nbits != 0 )
+ {
+ linfo = false;
+ fprintf(stderr, "GRIB szip supports only 8, 16, 24 and 32 bit data!\n");
+ }
+ return rec_len;
}
- else if ( numBits == 24 )
- for ( i = 0; i < jlend; i++ )
+
+ int bits_per_sample = (bds_nbits == 24) ? 8 : bds_nbits;
+
+ SZ_com_t sz_param; /* szip parameter block */
+ sz_param.options_mask = OPTIONS_MASK;
+ sz_param.bits_per_pixel = bits_per_sample;
+ sz_param.pixels_per_block = PIXELS_PER_BLOCK;
+ sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
+
+ if ( lspherc )
{
- T dval = (((int)lgrib[3*i ] << 16) + ((int)lgrib[3*i+1] << 8) +
- (int)lgrib[3*i+2]);
- fpdata[i] = fmin + zscale * dval;
+ bds_ext = 4;
+ if ( lcomplex )
+ {
+ int jup = bds[15];
+ int ioff = (jup+1)*(jup+2);
+ bds_ext += 3 + 4*ioff;
+ }
}
- else if ( numBits == 32 )
- for ( i = 0; i < jlend; i++ )
+
+ size_t datstart = bds_head + bds_ext;
+
+ size_t datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
+
+ if ( datsize < MIN_SIZE ) return rec_len;
+ /*
+ fprintf(stderr, "%d %d %d %d\n", bds_len, datstart, bds_len - datstart, datsize);
+ */
+ size_t sourceLen = datsize;
+ size_t destLen = sbufsize;
+
+ unsigned char *source = bds + datstart;
+ unsigned char *dest = sbuf;
+
+ if ( bds_nbits == 24 )
{
- T dval = (((unsigned int)lgrib[4*i ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
- ((unsigned int)lgrib[4*i+2] << 8) + (unsigned int)lgrib[4*i+3]);
- fpdata[i] = fmin + zscale * dval;
+ long nelem = sourceLen/3;
+ pbuf = (unsigned char*) Malloc(sourceLen);
+ for ( long i = 0; i < nelem; i++ )
+ {
+ pbuf[ i] = source[3*i ];
+ pbuf[ nelem+i] = source[3*i+1];
+ pbuf[2*nelem+i] = source[3*i+2];
+ }
+ source = pbuf;
}
- else if ( numBits <= 25 )
- {
- TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else if ( numBits > 25 && numBits < 32 )
- {
- TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else
- {
- Error("Unimplemented packing factor %d!", numBits);
- }
-
- if ( lgrib ) Free(lgrib);
-#else
- if ( numBits == 0 )
- {
- for ( i = 0; i < jlend; i++ )
- fpdata[i] = fmin;
- }
- else if ( numBits == 8 )
- for ( i = 0; i < jlend; i++ )
+ int status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
+ if ( status != SZ_OK )
{
- T dval = (int)igrib[i];
- fpdata[i] = fmin + zscale * dval;
+ if ( status == SZ_NO_ENCODER_ERROR )
+ Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_PARAM_ERROR )
+ Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_MEM_ERROR )
+ Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_OUTBUFF_FULL )
+ /*Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2)*/;
+ else
+ Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
}
- else if ( numBits == 16 )
- {
- TEMPLATE(decode_array_2byte,T)((size_t) jlend, igrib, fpdata, fmin, zscale);
- }
- else if ( numBits == 24 )
- for ( i = 0; i < jlend; i++ )
+
+ if ( pbuf ) Free(pbuf);
+ /*
+ fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
+ */
+ if ( destLen < MIN_COMPRESS*sourceLen )
{
- T dval = (T)(((int)igrib[3*i ] << 16) + ((int)igrib[3*i+1] << 8) +
- (int)igrib[3*i+2]);
- fpdata[i] = fmin + zscale * dval;
+ source = bds + datstart + bds_zoffset;
+ memcpy(source, dest, destLen);
+
+ /* ----++++ number of unused bits at end of section) */
+
+ BDS_Flag -= bds_ubits;
+
+ gribLenOld = gribLen;
+
+ if ( bds_ext )
+ for ( long i = bds_ext-1; i >= 0; --i )
+ bds[bds_zoffset+bds_head+i] = bds[bds_head+i];
+
+ /*
+ fprintf(stderr, "destLen, datsize, datstart %d %d %d\n", destLen, datsize, datstart);
+ */
+ /* memcpy(bds + datstart + bds_zoffset, source, destLen); */
+ /*
+ fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
+ (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
+ */
+ if ( llarge )
+ {
+ if ( gribLenOld%120 )
+ {
+ fprintf(stderr, "Internal problem, record length not multiple of 120!");
+ while ( gribLenOld%120 ) gribLenOld++;
+ }
+ // gribLenOld = gribLenOld / (-120);
+ // gribLenOld = JP23SET - gribLenOld + 1;
+
+ SetLen3(bds, bds_zstart, gribLenOld);
+ SetLen4(bds, bds_zstart+3, sourceLen);
+ SetLen4(bds, bds_zstart+7, destLen);
+ }
+ else
+ {
+ SetLen3(bds, bds_zstart, gribLenOld);
+ SetLen3(bds, bds_zstart+3, sourceLen);
+ SetLen3(bds, bds_zstart+6, destLen);
+ }
+
+ int bdsLen = datstart + bds_zoffset + destLen;
+
+ bds[11] = 0;
+ bds[12] = 0;
+
+ BDS_Z = Z_SZIP;
+
+ BDS_Flag += 16;
+ if ( (bdsLen%2) == 1 )
+ {
+ BDS_Flag += 8;
+ bds[bdsLen++] = 0;
+ }
+
+ SetLen3(bds, 0, bdsLen);
+
+ gribLen = (bds - dbuf) + bdsLen;
+
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
+
+ if ( llarge )
+ {
+ long bdslen = gribLen - 4;
+
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ while ( gribLen%120 ) dbuf[gribLen++] = 0;
+
+ long itemp = gribLen / (-120);
+ itemp = JP23SET - itemp + 1;
+
+ SetLen3(dbuf, 4, itemp);
+
+ bdslen = gribLen - bdslen;
+
+ SetLen3(bds, 0, bdslen);
+ }
+ else
+ {
+ SetLen3(dbuf, 4, gribLen);
+ }
}
- else if ( numBits == 32 )
- for ( i = 0; i < jlend; i++ )
+ else
{
- T dval = (T)(((unsigned int)igrib[4*i ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
- ((unsigned int)igrib[4*i+2] << 8) + (unsigned int)igrib[4*i+3]);
- fpdata[i] = fmin + zscale * dval;
}
- else if ( numBits <= 25 )
- {
- TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else if ( numBits > 25 && numBits < 32 )
- {
- TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
- }
- else
+ /*
+ fprintf(stderr, "%3d %3d griblen in %6d out %6d CR %g slen %6d dlen %6d CR %g\n",
+ PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
+ ((double)gribLenOld)/gribLen, sourceLen, destLen,
+ ((double)sourceLen)/destLen);
+ */
+ }
+
+#else
+
+ UNUSED(sbuf);
+ UNUSED(sbufsize);
+
+ if ( libszwarn )
{
- Error("Unimplemented packing factor %d!", numBits);
+ Warning("Compression disabled, szlib not available!");
+ libszwarn = 0;
}
#endif
-}
-#endif /* T */
+ if ( llarge )
+ while ( gribLen%120 ) dbuf[gribLen++] = 0;
+ else
+ while ( gribLen & 7 ) dbuf[gribLen++] = 0;
-/*
- * Local Variables:
- * mode: c
- * End:
- */
+ rec_len = gribLen;
+ return rec_len;
+}
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
-static
-int TEMPLATE(decodeGDS,T)(unsigned char *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
+int gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
{
- /* int imisng = 0; */
- int ReducedGrid = FALSE, VertCoorTab = FALSE;
-#if defined (VECTORCODE)
- unsigned char *igrib;
- GRIBPACK *lgrib = NULL;
- size_t lGribLen = 0;
+#if ! defined(HAVE_LIBSZ)
+ static int libszwarn = 1;
#endif
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ size_t gribLen = 0;
+ size_t destLen, sourceLen;
+ enum { bds_head = 11 };
+ int bds_ext = 0;
- *numGridVals = 0;
-
- memset(isec2, 0, 22*sizeof(int));
-
- int gdsLen = GDS_Len;
-
- int ipvpl = GDS_PVPL;
- if ( ipvpl == 0 ) ipvpl = 0xFF;
+ UNUSED(dbufsize);
- if ( ipvpl != 0xFF )
- { /* Either vct or reduced grid */
- if ( GDS_NV != 0 )
- { /* we have vct */
- VertCoorTab = TRUE;
- int ipl = 4*GDS_NV + ipvpl - 1;
- if ( ipl < gdsLen )
- {
- ReducedGrid = TRUE;
- }
- }
- else
- {
- VertCoorTab = FALSE;
- ReducedGrid = TRUE;
- }
- /* ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+ long gribrecsize;
+ int nerr = grib1Sections(sbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
+ {
+ fprintf(stdout, "GRIB message error\n");
+ return 0;
}
-
- if ( ISEC0_GRIB_Version == 0 )
+
+ if ( nerr > 0 )
{
- VertCoorTab = (gdsLen - 32) > 0;
+ fprintf(stdout, "GRIB data corrupted!\n");
+ return 0;
}
-
- if ( ReducedGrid )
+
+ //unsigned bds_len = BDS_Len;
+ bool llarge = false;
+
+ int bds_zoffset = 12;
+ if ( llarge ) bds_zoffset += 2;
+
+ int bds_nbits = BDS_NumBits;
+ int bds_flag = BDS_Flag;
+ int lspherc = bds_flag >> 7;
+ int lcomplex = (bds_flag >> 6)&1;
+ /* lcompress = (bds_flag >> 4)&1; */
+
+ if ( lspherc )
{
- int locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
- int jlenl = (gdsLen - locnl) >> 1;
- if ( jlenl == GDS_NumLat )
+ if ( lcomplex )
{
- *numGridVals = 0;
- ISEC2_Reduced = TRUE;
- for ( int i = 0; i < jlenl; i++ )
- {
- ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
- *numGridVals += ISEC2_RowLon(i);
- }
+ int jup = bds[bds_zoffset+15];
+ int ioff = (jup+1)*(jup+2);
+ bds_ext = 4 + 3 + 4*ioff;
}
else
{
- ReducedGrid = FALSE;
+ bds_ext = 4;
}
}
- ISEC2_GridType = GDS_GridType;
+ size_t datstart = bds_head + (size_t)bds_ext;
- /*
- Gaussian grid definition.
- */
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
- {
- ISEC2_NumLat = GDS_NumLat;
- if ( ! ReducedGrid )
- {
- ISEC2_NumLon = GDS_NumLon;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
- }
- ISEC2_FirstLat = GDS_FirstLat;
- ISEC2_FirstLon = GDS_FirstLon;
- ISEC2_ResFlag = GDS_ResFlag;
- ISEC2_LastLat = GDS_LastLat;
- ISEC2_LastLon = GDS_LastLon;
- ISEC2_LonIncr = GDS_LonIncr;
+ unsigned char *source = bds + datstart + bds_zoffset;
+ if ( llarge )
+ sourceLen = ((size_t) ((bds[21]<<24)+(bds[22]<<16)+(bds[23]<<8)+bds[24]));
+ else
+ sourceLen = ((size_t) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
- ISEC2_NumPar = GDS_NumPar;
- ISEC2_ScanFlag = GDS_ScanFlag;
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
- {
- ISEC2_LatSP = GDS_LatSP;
- ISEC2_LonSP = GDS_LonSP;
- FSEC2_RotAngle = (T)GDS_RotAngle;
- }
- /*
- if ( Lons != Longitudes || Lats != Latitudes )
- Error("Latitude/Longitude Conflict");
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
- {
- /*
- iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
- {
- /*
- iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
- {
- ISEC2_NumLon = GDS_NumLon;
- ISEC2_NumLat = GDS_NumLat;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
- ISEC2_FirstLat = GDS_FirstLat;
- ISEC2_FirstLon = GDS_FirstLon;
- ISEC2_ResFlag = GDS_ResFlag;
- ISEC2_Lambert_Lov = GDS_Lambert_Lov;
- ISEC2_Lambert_dx = GDS_Lambert_dx;
- ISEC2_Lambert_dy = GDS_Lambert_dy;
- ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
- ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
- ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
- ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
- ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
- ISEC2_ScanFlag = GDS_ScanFlag;
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+ nerr = grib1Sections(dbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( nerr < 0 )
{
- ISEC2_PentaJ = GDS_PentaJ; /* Truncation */
- ISEC2_PentaK = GDS_PentaK;
- ISEC2_PentaM = GDS_PentaM;
- ISEC2_RepType = GDS_RepType;
- ISEC2_RepMode = GDS_RepMode;
- *numGridVals = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
- isec2[ 6] = 0;
- isec2[ 7] = 0;
- isec2[ 8] = 0;
- isec2[ 9] = 0;
- isec2[10] = 0;
- /*
- iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
- */
+ fprintf(stdout, "GRIB message error\n");
+ return 0;
}
- else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+
+ if ( nerr > 0 )
{
- ISEC2_GME_NI2 = GDS_GME_NI2;
- ISEC2_GME_NI3 = GDS_GME_NI3;
- ISEC2_GME_ND = GDS_GME_ND;
- ISEC2_GME_NI = GDS_GME_NI;
- ISEC2_GME_AFlag = GDS_GME_AFlag;
- ISEC2_GME_LatPP = GDS_GME_LatPP;
- ISEC2_GME_LonPP = GDS_GME_LonPP;
- ISEC2_GME_LonMPL = GDS_GME_LonMPL;
- ISEC2_GME_BFlag = GDS_GME_BFlag;
- *numGridVals = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
- /*
- iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
- */
+ fprintf(stdout, "GRIB data corrupted!\n");
+ return 0;
}
+
+ unsigned char *dest = bds + datstart;
+ if ( llarge )
+ destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
else
- {
- ISEC2_NumLon = GDS_NumLon;
- ISEC2_NumLat = GDS_NumLat;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
- Message("Gridtype %d unsupported", ISEC2_GridType);
- }
+ destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+
+ BDS_Flag = (unsigned char)(BDS_Flag - 16);
+
+ size_t bdsLen = datstart + destLen;
+
+#if defined(HAVE_LIBSZ)
+ {
+ int bds_zstart = 14;
+ unsigned recLen = GET_UINT3(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
+
+ int bits_per_sample = (bds_nbits == 24) ? 8 : bds_nbits;
+
+ SZ_com_t sz_param; /* szip parameter block */
+ sz_param.options_mask = OPTIONS_MASK;
+ sz_param.bits_per_pixel = bits_per_sample;
+ sz_param.pixels_per_block = PIXELS_PER_BLOCK;
+ sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
+
+ if ( bds_ext )
+ for ( long i = 0; i < bds_ext; ++i )
+ bds[bds_head+i] = bds[bds_zoffset+bds_head+i];
+
+ /* fprintf(stderr, "gribUnzip: sourceLen %ld; destLen %ld\n", (long)sourceLen, (long)destLen);
+ fprintf(stderr, "gribUnzip: sourceOff %d; destOff %d\n", bds[12], bds[11]);
+ fprintf(stderr, "gribUnzip: reclen %d; bdslen %d\n", recLen, bdsLen);
+ */
+
+ size_t tmpLen = destLen;
+
+ int status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
+ if ( status != SZ_OK )
+ {
+ if ( status == SZ_NO_ENCODER_ERROR )
+ Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_PARAM_ERROR )
+ Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_MEM_ERROR )
+ Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else if ( status == SZ_OUTBUFF_FULL )
+ Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2);
+ else
+ Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+ }
+ /*
+ fprintf(stderr, "gribUnzip: sl = %ld dl = %ld tl = %ld\n",
+ (long)sourceLen, (long)destLen,(long) tmpLen);
+ */
+ if ( tmpLen != destLen )
+ Warning("unzip size differ: code %3d level %3d ibuflen %ld ubuflen %ld",
+ PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
+
+ if ( bds_nbits == 24 )
+ {
+ long nelem = tmpLen/3;
+ unsigned char *pbuf = (unsigned char*) Malloc(tmpLen);
+ for ( long i = 0; i < nelem; i++ )
+ {
+ pbuf[3*i ] = dest[ i];
+ pbuf[3*i+1] = dest[ nelem+i];
+ pbuf[3*i+2] = dest[2*nelem+i];
+ }
+ memcpy(dest, pbuf, tmpLen);
+ Free(pbuf);
+ }
+
+ int bds_ubits = BDS_Flag & 15;
+ BDS_Flag -= bds_ubits;
- /* vertical coordinate parameters for hybrid levels. */
- /* get number of vertical coordinate parameters, if any. */
+ if ( (bdsLen%2) == 1 )
+ {
+ BDS_Flag += 8;
+ bds[bdsLen++] = 0;
+ }
- ISEC2_NumVCP = 0;
+ SetLen3(bds, 0, bdsLen);
- isec2[17] = 0;
- isec2[18] = 0;
+ gribLen = (bds - dbuf) + bdsLen;
+
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
+ dbuf[gribLen++] = '7';
- if ( VertCoorTab == TRUE )
- {
- int locnv;
- if ( ISEC0_GRIB_Version == 0 )
- {
- locnv = 32;
- ISEC2_NumVCP = (gdsLen - 32) >> 2;
- }
- else
- {
- locnv = GDS_PVPL - 1;
- ISEC2_NumVCP = GDS_NV;
- }
-#if defined (SX)
- lGribLen = 4*ISEC2_NumVCP;
- lgrib = (GRIBPACK*) Malloc(lGribLen*sizeof(GRIBPACK));
+ if ( llarge )
+ {
+ long itemp;
+ bdsLen = gribLen - 4;
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ while ( gribLen%120 ) dbuf[gribLen++] = 0;
- igrib = &gds[locnv];
- if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
- for ( int i = 0; i < ISEC2_NumVCP; i++ )
- {
- int iexp = (lgrib[4*i ]);
- int imant =(((lgrib[4*i+1]) << 16) +
- ((lgrib[4*i+2]) << 8) +
- ( lgrib[4*i+3]));
- fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
- }
+ if ( gribLen != (size_t)recLen )
+ fprintf(stderr, "Internal problem, recLen and gribLen differ!\n");
+
+ itemp = gribLen / (-120);
+ itemp = JP23SET - itemp + 1;
+
+ SetLen3(dbuf, 4, itemp);
- Free(lgrib);
+ bdsLen = gribLen - bdsLen;
+
+ SetLen3(bds, 0, bdsLen);
+ }
+ else
+ {
+ SetLen3(dbuf, 4, recLen);
+ }
+ /*
+ fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
+ */
+ if ( llarge )
+ while ( gribLen%120 ) dbuf[gribLen++] = 0;
+ else
+ while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+ /*
+ fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
+ */
+ }
#else
- for ( int i = 0; i < ISEC2_NumVCP; i++ )
- {
- int iexp = (gds[locnv+4*i ]);
- int imant =(((gds[locnv+4*i+1]) << 16) +
- ((gds[locnv+4*i+2]) << 8) +
- ( gds[locnv+4*i+3]));
- fsec2[10+i] = (T)decfp2(iexp,imant);
- }
-#endif
+ UNUSED(bds_nbits);
+ UNUSED(sourceLen);
+ UNUSED(source);
+ UNUSED(bdsLen);
+ UNUSED(dest);
+
+ if ( libszwarn )
+ {
+ Warning("Decompression disabled, szlib not available!");
+ libszwarn = 0;
}
+#endif
- return gdsLen;
+ return (int)gribLen;
}
+#include <stdio.h>
+#include <math.h>
+
-#define ldexp_double ldexp
-#define ldexp_float ldexpf
static
-int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4,
- T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
+int rowina2(double *p, int ko, int ki, double *pw,
+ int kcode, double msval, int *kret)
{
- unsigned char *igrib;
- int lspherc = FALSE, lcomplex = FALSE;
- int lcompress;
- int jup, kup, mup;
- int locnd;
- int bds_flag, jscale, imiss;
- int bds_ubits;
- int ioff = 0;
- int iexp, imant;
- int zoff;
- int bds_head = 11;
- T zscale = 0.;
- T fmin = 0.;
- T *fpdata = fsec4;
- int bdsLen;
- extern int CGRIBEX_Fix_ZSE;
-
- *iret = 0;
- igrib = bds;
-
- memset(isec4, 0, 42*sizeof(int));
+ /* System generated locals */
+ int pw_dim1, pw_offset, i_1;
- /* get length of binary data block. */
+ /* Local variables */
+ double zwt1, zrdi, zpos;
+ int jl, ip;
+ double zdo, zwt;
- bdsLen = BDS_Len;
- /*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- if ( llarge ) bdsLen = bdsLenIn - bdsLen;
+ /* Parameter adjustments */
+ --p;
+ pw_dim1 = ko + 3;
+ pw_offset = pw_dim1;
+ pw -= pw_offset;
- /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
+ /* **** ROWINA2 - Interpolation of row of values. */
+ /* Input Parameters. */
+ /* ----------------- */
+ /* P - Row of values to be interpolated. */
+ /* Dimension must be at least KO. */
+ /* KO - Number of values required. */
+ /* KI - Number of values in P on input. */
+ /* PW - Working array. */
+ /* Dimension must be at least (0:KO+2,3). */
+ /* KCODE - Interpolation required. */
+ /* 1 , linear. */
+ /* 3 , cubic. */
+ /* PMSVAL - Value used for missing data indicator. */
- bds_flag = BDS_Flag;
+ /* Output Parameters. */
+ /* ------------------ */
+ /* P - Now contains KO values. */
+ /* KRET - Return code */
+ /* 0, OK */
+ /* Non-zero, error */
- /* 0------- grid point */
- /* 1------- spherical harmonics */
+ /* Author. */
+ /* ------- */
+ /* J.D.Chambers ECMWF 22.07.94 */
- lspherc = bds_flag >> 7;
+ /* ******************************** */
+ /* Section 1. Linear interpolation .. */
+ /* ******************************** */
- if ( lspherc ) isec4[2] = 128;
- else isec4[2] = 0;
+ *kret = 0;
- /* -0------ simple packing */
- /* -1------ complex packing */
+ if ( kcode == 1 )
+ {
+ /* Move input values to work array */
+ for ( jl = 1; jl <= ki; ++jl )
+ pw[jl + pw_dim1] = p[jl];
- lcomplex = (bds_flag >> 6)&1;
+ /* Arrange wrap-around value in work array */
+ pw[ki + 1 + pw_dim1] = p[1];
- if ( lcomplex ) isec4[3] = 64;
- else isec4[3] = 0;
+ /* Set up constants to be used to figure out weighting for */
+ /* values in interpolation. */
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
- /* ---0---- No additional flags */
- /* ---1---- No additional flags */
+ /* Loop through the output points */
+ for ( jl = 1; jl <= ko; ++jl )
+ {
- lcompress = (bds_flag >> 4)&1; /* compress */
+ /* Calculate weight from the start of row */
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
- if ( lcompress )
- { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
- else
- { isec4[5] = 0; isec4[6] = 0; zoff = 0; }
+ /* Get the current array position(minus 1) from the weight - */
+ /* note the implicit truncation. */
+ ip = (int) zwt;
- /* ----++++ number of unused bits at end of section) */
+ /* If the left value is missing, use the right value */
+ if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 2 + pw_dim1];
+ }
+ /* If the right value is missing, use the left value */
+ else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 1 + pw_dim1];
+ }
+ /* If neither missing, interpolate ... */
+ else
+ {
- bds_ubits = bds_flag & 0xF;
-
- /* scale factor (2 bytes) */;
+ /* Adjust the weight to range (0.0 to 1.0) */
+ zwt -= ip;
- jscale = BDS_BinScale;
+ /* Interpolate using the weighted values on either side */
+ /* of the output point position */
+ p[jl] = (1.0 - zwt) * pw[ip + 1 + pw_dim1] +
+ zwt * pw[ip + 2 + pw_dim1];
+ }
+ }
- /* check for missing data indicators. */
+ /* ******************************* */
+ /* Section 2. Cubic interpolation .. */
+ /* ******************************* */
- iexp = bds[ 6];
- imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+ }
+ else if ( kcode == 3 )
+ {
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
+ {
+ if ( IS_EQUAL(p[jl], msval) )
+ {
+ fprintf(stderr," ROWINA2: ");
+ fprintf(stderr," Cubic interpolation not supported");
+ fprintf(stderr," for fields containing missing data.\n");
+ *kret = 1;
+ goto L900;
+ }
+ pw[jl + pw_dim1] = p[jl];
+ }
+ pw[pw_dim1] = p[ki];
+ pw[ki + 1 + pw_dim1] = p[1];
+ pw[ki + 2 + pw_dim1] = p[2];
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
+ {
+ pw[jl + (pw_dim1 << 1)] =
+ - pw[jl - 1 + pw_dim1] / 3.0 -
+ pw[jl + pw_dim1] * 0.5 +
+ pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
+ pw[jl + 1 + pw_dim1 * 3] =
+ pw[jl - 1 + pw_dim1] / 6.0 -
+ pw[jl + pw_dim1] +
+ pw[jl + 1 + pw_dim1] * 0.5 +
+ pw[jl + 2 + pw_dim1] / 3.0;
+ }
- imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+ scm0_double(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+ &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
- /* convert reference value and scale factor. */
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
+ for ( jl = 1; jl <= ko; ++jl )
+ {
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
+ ip = (int) zwt + 1;
+ zwt = zwt + 1.0 - ip;
+ zwt1 = 1.0 - zwt;
+ p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+ zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+ ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+ zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
+ }
- if ( ! (dfunc == 'J') && imiss == 0 )
+ }
+ else
{
- fmin = (T)BDS_RefValue;
- zscale = TEMPLATE(ldexp,T)((T)1.0, jscale);
+ /* ************************************** */
+ /* Section 3. Invalid interpolation code .. */
+ /* ************************************** */
+ fprintf(stderr," ROWINA2:");
+ fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+ *kret = 2;
}
- /* get number of bits in each data value. */
+L900:
+ return 0;
+} /* rowina2 */
- ISEC4_NumBits = BDS_NumBits;
- /* octet number of start of packed data */
- /* calculated from start of block 4 - 1 */
- locnd = zoff + bds_head;
+int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
+ double *ztemp, double msval, int *kret)
+{
+ /* System generated locals */
+ int i_1, i_2;
+ int kcode = 1;
- /* if data is in spherical harmonic form, distinguish */
- /* between simple/complex packing (lcomplex = 0/1) */
+ /* Local variables */
+ int ilii, ilio, icode;
+ double *zline = NULL;
+ double *zwork = NULL;
+ int iregno, iquano, j210, j220, j230, j240, j225;
- if ( lspherc )
- {
- if ( !lcomplex )
- {
- /* no unpacked binary data present */
- //jup = kup = mup = 0;
+ zline = (double*) Malloc(2*(size_t)klon*sizeof(double));
+ if ( zline == NULL ) SysError("No Memory!");
- /* octet number of start of packed data */
- /* calculated from start of block 4 - 1 */
+ zwork = (double*) Malloc(3*(2*(size_t)klon+3)*sizeof(double));
+ if ( zwork == NULL ) SysError("No Memory!");
- ioff = 1;
- locnd += 4*ioff; /* RealCoef */
+ /* Parameter adjustments */
+ --pfield;
+ --kpoint;
- /* get real (0,0) coefficient in grib format and */
- /* convert to floating point. */
+/* **** QU2REG - Convert quasi-regular grid data to regular. */
+/* Input Parameters. */
+/* ----------------- */
+/* PFIELD - Array containing quasi-regular grid */
+/* data. */
+/* KPOINT - Array containing list of the number of */
+/* points on each latitude (or longitude) of */
+/* the quasi-regular grid. */
+/* KLAT - Number of latitude lines */
+/* KLON - Number of longitude lines */
+/* KCODE - Interpolation required. */
+/* 1 , linear - data quasi-regular on */
+/* latitude lines. */
+/* 3 , cubic - data quasi-regular on */
+/* latitude lines. */
+/* 11, linear - data quasi-regular on */
+/* longitude lines. */
+/* 13, cubic - data quasi-regular on */
+/* longitude lines. */
+/* PMSVAL - Value used for missing data indicator. */
+/* Output Parameters. */
+/* ------------------ */
+/* KRET - return code */
+/* 0 = OK */
+/* non-zero indicates fatal error */
+/* PFIELD - Array containing regular grid data. */
+/* Author. */
+/* ------- */
+/* J.D.Chambers ECMWF 22.07.94 */
+/* J.D.Chambers ECMWF 13.09.94 */
+/* Add return code KRET and remove calls to ABORT. */
- if ( dfunc != 'J' )
- {
- if ( imiss ) *fpdata++ = 0.0;
- else *fpdata++ = (T)BDS_RealCoef;
- }
- }
- else /* complex packed spherical harmonics */
- {
- isec4[15] = BDS_PackData;
- /* scaling factor */
- isec4[16] = BDS_Power;
- /* pentagonal resolution parameters of the */
- /* unpacked section of data field */
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
- jup = bds[zoff+15];
- kup = bds[zoff+16];
- mup = bds[zoff+17];
+ *kret = 0;
- isec4[zoff+17] = jup;
- isec4[zoff+18] = kup;
- isec4[zoff+19] = mup;
+/* Check input parameters. */
- /* unpacked binary data */
+ if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+ fprintf(stderr," QU2REG :");
+ fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+ *kret = 1;
+ goto L900;
+ }
- locnd += 4; /* 2 + power */
- locnd += 3; /* j, k, m */
- ioff = (jup+1)*(jup+2);
+/* Set array indices to 0. */
- if ( dfunc != 'J' )
- for ( int i = 0; i < ioff; i++ )
- {
- if ( imiss )
- *fpdata++ = 0.0;
- else
- {
- iexp = (bds[locnd+4*i ]);
- imant =((bds[locnd+4*i+1]) << 16) +
- ((bds[locnd+4*i+2]) << 8) +
- (bds[locnd+4*i+3]);
+ ilii = 0;
+ ilio = 0;
- *fpdata++ = (T)decfp2(iexp,imant);
- }
- }
-
- locnd += 4*ioff; /* RealCoef */
- }
- }
- else
- {
- if ( lcomplex )
- {
- *iret = 1999;
- gprintf(__func__, " Second order packed grids unsupported!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
- }
+/* Establish values of loop parameters. */
- /* Decode data values to floating point and store in fsec4. */
- /* First calculate the number of data values. */
- /* Take into account that spherical harmonics can be packed */
- /* simple (lcomplex = 0) or complex (lcomplex = 1) */
+ if (kcode > 10) {
- int jlend = bdsLen - locnd;
+/* Quasi-regular along longitude lines. */
- if ( ISEC4_NumBits == 0 )
- {
- if ( jlend > 1 )
- {
- *iret = 2001;
- gprintf(__func__, " Number of bits per data value = 0!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
+ iquano = klon;
+ iregno = klat;
+ icode = kcode - 10;
+ } else {
- if ( numGridVals == 0 )
- {
- *iret = 2002;
- gprintf(__func__, " Constant field unsupported for this grid type!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
+/* Quasi-regular along latitude lines. */
- jlend = numGridVals;
- jlend -= ioff;
- }
- else
- {
- jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
- }
+ iquano = klat;
+ iregno = klon;
+ icode = kcode;
+ }
- ISEC4_NumValues = jlend + ioff;
- ISEC4_NumNonMissValues = 0;
+/* -------------------------------------------------------- */
+/** Section 2. Interpolate field from quasi to regular grid. */
+/* -------------------------------------------------------- */
- if ( lcompress )
- {
- size_t len;
+ i_1 = iquano;
+ for (j230 = 1; j230 <= i_1; ++j230) {
- if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
- len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
- else
- len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+ if (iregno != kpoint[j230]) {
- ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
+/* Line contains less values than required,so */
+/* extract quasi-regular grid values for a line */
- if ( lspherc )
- {
- if ( lcomplex )
- ISEC4_NumValues += ioff;
- else
- ISEC4_NumValues++;
- }
- }
+ i_2 = kpoint[j230];
+ for (j210 = 1; j210 <= i_2; ++j210) {
+ ++ilii;
+ zline[j210 - 1] = pfield[ilii];
+ }
- if ( dfunc == 'J' ) return bdsLen;
+/* and interpolate this line. */
- /* check length of output array. */
-
- if ( ISEC4_NumValues > fsec4len )
- {
- *iret = 710;
- gprintf(__func__, " Output array too small. Length = %d", fsec4len);
- gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
+ rowina2(zline, iregno, kpoint[j230], zwork, icode, msval, kret);
+ if (*kret != 0) goto L900;
+
+/* Add regular grid values for this line to the
+ temporary array. */
+
+ i_2 = iregno;
+ for (j220 = 1; j220 <= i_2; ++j220) {
+ ++ilio;
+ ztemp[ilio - 1] = zline[j220 - 1];
+ }
+
+ } else {
+
+/* Line contains the required number of values, so add */
+/* this line to the temporary array. */
+
+ i_2 = iregno;
+ for (j225 = 1; j225 <= i_2; ++j225) {
+ ++ilio;
+ ++ilii;
+ ztemp[ilio - 1] = pfield[ilii];
+ }
+ }
+ }
+
+/* Copy temporary array to user array. */
+
+ i_1 = klon * klat;
+ for (j240 = 1; j240 <= i_1; ++j240) {
+ pfield[j240] = ztemp[j240 - 1];
+ }
- if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
- else
- {
- igrib += locnd;
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
- TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
- }
+L900:
- if ( lspherc && lcomplex )
- {
- int pcStart = isec4[19], pcScale = isec4[16];
- TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
- TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
- }
+ Free(zline);
+ Free(zwork);
- if ( CGRIBEX_Fix_ZSE ) /* Fix ZeroShiftError of simple packed spherical harmonics */
- if ( lspherc && !lcomplex )
- {
- /* 20100705: Fix ZeroShiftError - Edi Kirk */
- if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
- {
- T zserr = fsec4[1];
- for ( int i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
- }
- }
+ return 0;
+} /* qu2reg2 */
- if ( decscale )
- {
- T scale = (T) pow(10.0, (double)-decscale);
- for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
- }
- return bdsLen;
-}
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
-void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
- T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
- int kleng, int *kword, int dfunc, int *iret)
+/* calculate_pfactor: source code from grib_api-1.8.0 */
+double TEMPLATE(calculate_pfactor,T)(const T *spectralField, long fieldTruncation, long subsetTruncation)
{
- UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
- int gdsIncluded = FALSE;
- int bmsIncluded = FALSE;
- int bitmapSize = 0;
- int imaskSize = 0;
- int ldebug = FALSE;
- int llarge = FALSE, l_iorj = FALSE;
- int lsect2 = FALSE, lsect3 = FALSE;
- int numGridVals = 0;
- static int lmissvalinfo = 1;
+ /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
+ long loop, index, m, n = 0;
+ double pFactor, zeps = 1.0e-15;
+ long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
+ double* weights, range, * norms;
+ double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
+ double numerator = 0.0, denominator = 0.0, slope;
- UNUSED(kleng);
+ /*
+ // Setup the weights
+ */
- *iret = 0;
+ range = (double) (ismax - ismin +1);
- grsdef();
+ weights = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
+ for( loop = ismin; loop <= ismax; loop++ )
+ weights[loop] = range / (double) (loop-ismin+1);
+ /*
+ // Compute norms
+ // Handle values 2 at a time (real and imaginary parts).
+ */
+ norms = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
- ISEC2_Reduced = FALSE;
+ for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
+ /*
+ // Form norms for the rows which contain part of the unscaled subset.
+ */
+ index = -2;
+ for( m = 0; m < subsetTruncation; m++ )
+ for( n = m; n <= fieldTruncation; n++ ) {
+ index += 2;
+ if( n >= subsetTruncation ) {
+ double tval = spectralField[index];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ tval = spectralField[index+1];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ }
+ }
/*
- ----------------------------------------------------------------
- IS Indicator Section (Section 0)
- ----------------------------------------------------------------
- */
- is = (unsigned char *) &kgrib[0];
+ // Form norms for the rows which do not contain part of the unscaled subset.
+ */
- isLen = decodeIS(is, isec0, iret);
+ for( m = subsetTruncation; m <= fieldTruncation; m++ )
+ for( n = m; n <= fieldTruncation; n++ ) {
+ double tval = spectralField[index];
+ index += 2;
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ tval = spectralField[index+1];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ }
/*
- If count is negative, have to rescale by factor of -120.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- if ( ISEC0_GRIB_Len < 0 )
- {
- if ( ldebug )
- gprintf(__func__, "Special case, negative length multiplied by -120");
- llarge = TRUE;
- ISEC0_GRIB_Len *= (-120);
- }
+ // Ensure the norms have a value which is not too small in case of
+ // problems with math functions (e.g. LOG).
+ */
+
+ for( loop = ismin; loop <= ismax; loop++ ) {
+ norms[n] = norms[n] > zeps ? norms[n] : zeps;
+ if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
+ }
+
/*
- When decoding or calculating length, previous editions
- of the GRIB code must be taken into account.
+ // Do linear fit to find the slope
+ */
- In the table below, covering sections 0 and 1 of the GRIB
- code, octet numbering is from the beginning of the GRIB
- message;
- * indicates that the value is not available in the code edition;
- R indicates reserved, should be set to 0;
- Experimental edition is considered as edition -1.
+ for( loop = ismin; loop <= ismax; loop++ ) {
+ x = log( (double) (loop*(loop+1)) );
+ y = log( norms[loop] );
+ weightedSumOverX = weightedSumOverX + x * weights[loop];
+ weightedSumOverY = weightedSumOverY + y * weights[loop];
+ sumOfWeights = sumOfWeights + weights[loop];
+ }
+ weightedSumOverX = weightedSumOverX / sumOfWeights;
+ weightedSumOverY = weightedSumOverY / sumOfWeights;
- GRIB code edition -1 has fixed length of 20 octets for
- section 1, the length not included in the message.
- GRIB code edition 0 has fixed length of 24 octets for
- section 1, the length being included in the message.
- GRIB code edition 1 can have different lengths for section
- 1, the minimum being 28 octets, length being included in
- the message.
+ /*
+ // Perform a least square fit for the equation
+ */
- Octet numbers for code
- editions
+ for( loop = ismin; loop <= ismax; loop++ ) {
- Contents. -1 0 1
- --------- ----------------------
- Letters GRIB 1-4 1-4 1-4
- Total length of GRIB message. * * 5-7
- GRIB code edition number * * 8
- Length of Section 1. * 5-7 9-11
- Reserved octet (R). * 8(R) *
- Version no. of Code Table 2. * * 12
- Identification of centre. 5 9 13
- Generating process. 6 10 14
- Grid definition . 7 11 15
- Flag (Code Table 1). 8 12 16
- Indicator of parameter. 9 13 17
- Indicator of type of level. 10 14 18
- Height, pressure etc of levels. 11-12 15-16 19-20
- Year of century. 13 17 21
- Month. 14 18 22
- Day. 15 19 23
- Hour. 16 20 24
- Minute. 17 21 25
- Indicator of unit of time. 18 22 26
- P1 - Period of time. 19 23 27
- P2 - Period of time 20(R) 24 28
- or reserved octet (R).
- Time range indicator. 21(R) 25 29
- or reserved octet (R).
- Number included in average. 22-23(R) 26-27 30-31
- or reserved octet (R).
- Number missing from average. 24(R) 28(R) 32
- or reserved octet (R).
- Century of data. * * 33
- Designates sub-centre if not 0. * * 34
- Decimal scale factor. * * 35-36
- Reserved. Set to 0. * * 37-48
- (Need not be present)
- For originating centre use only. * * 49-nn
- (Need not be present)
+ x = log( (double)(loop*(loop+1)) );
+ y = log( norms[loop] );
+ numerator =
+ numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
+ denominator =
+ denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
+ }
+ slope = numerator / denominator;
- Identify which GRIB code edition is being decoded.
+ Free(weights);
+ Free(norms);
- In GRIB edition 1, the edition number is in octet 8.
- In GRIB edition 0, octet 8 is reserved and set to 0.
- In GRIB edition -1, octet 8 is a flag field and can have a
- a valid value of 0, 1, 2 or 3.
+ pFactor = -slope;
+ if( pFactor < -9999.9 ) pFactor = -9999.9;
+ if( pFactor > 9999.9 ) pFactor = 9999.9;
- However, GRIB edition number 0 has a fixed
- length of 24, included in the message, for section 1, so
- if the value extracted from octets 5-7 is 24 and that from
- octet 8 is 0, it is safe to assume edition 0 of the code.
+ return pFactor;
+}
- */
- if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
+void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
+{
+ double power;
+ double *scale = (double*) Malloc(((size_t)trunc+1)*sizeof(double));
+
+ if ( scale == NULL ) SysError("No Memory!");
+
+ if ( pcScale < -10000 || pcScale > 10000 )
{
- /*
- Set length of GRIB message to missing data value.
- */
- ISEC0_GRIB_Len = 0;
- }
- /*
- If Grib Edition 1 and only length is required, go to section 9.
- */
- if ( dfunc == 'L' ) goto LABEL900;
+ fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
+ return;
+ }
- /*
- ----------------------------------------------------------------
- PDS Product Definition Section (Section 1)
- ----------------------------------------------------------------
- */
- pds = is + isLen;
+ /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
- pdsLen = decodePDS(pds, isec0, isec1);
+ if ( pcScale == 0 ) return;
- /*
- ----------------------------------------------------------------
- GDS Grid Description Section (Section 2)
- ----------------------------------------------------------------
- */
- gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ power = (double) pcScale / 1000.;
+ scale[0] = 1.0;
- if ( gdsIncluded )
- {
- gds = is + isLen + pdsLen;
+ if (pcScale != 1000)
+ for ( int n = 1; n <= trunc; n++ )
+ scale[n] = pow((double) (n*(n+1)), power);
+ else
+ for ( int n = 1; n <= trunc; n++ )
+ scale[n] = (double) (n*(n+1));
- gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
- }
+ if ( inv )
+ for ( int n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
- /*
- ----------------------------------------------------------------
- BMS Bit-Map Section Section (Section 3)
- ----------------------------------------------------------------
- */
- bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ /* Scale the values */
- isec3[0] = 0;
- if ( bmsIncluded )
- {
- bms = is + isLen + pdsLen + gdsLen;
+ size_t index = 0;
- bmsLen = BMS_Len;
- imaskSize = (bmsLen - 6)<<3;
- bitmapSize = imaskSize - BMS_UnusedBits;
- /*
- fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
- */
- }
+ for ( int m = 0; m < pcStart; m++ )
+ for ( int n = m; n <= trunc; n++, index += 2 )
+ if ( n >= pcStart )
+ {
+ fpdata[index ] = (T)(fpdata[index ] * scale[n]);
+ fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
+ }
- /*
- ----------------------------------------------------------------
- BDS Binary Data Section (Section 4)
- ----------------------------------------------------------------
- */
- bds = is + isLen + pdsLen + gdsLen + bmsLen;
+ for ( int m = pcStart; m <= trunc; m++ )
+ for ( int n = m; n <= trunc; n++, index += 2 )
+ {
+ fpdata[index ] = (T)(fpdata[index ] * scale[n]);
+ fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
+ }
- bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+ Free(scale);
+}
- bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4,
- fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
- if ( *iret != 0 ) return;
+void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+{
+ T *fphelp = (T*) Malloc((size_t)nsp*sizeof(T));
+ int m, n;
+ int index, inext;
- ISEC4_NumNonMissValues = ISEC4_NumValues;
+ if ( fphelp == NULL ) SysError("No Memory!");
- if ( bitmapSize > 0 )
- {
- if ( dfunc != 'L' && dfunc != 'J' )
- if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+ index = inext = 0;
+
+ for ( m = 0; m <= pcStart; m++ )
+ for ( n = m; n <= trunc; n++ )
+ {
+ if ( pcStart >= n )
{
- lmissvalinfo = 0;
- FSEC3_MissVal = (T)GRIB_MISSVAL;
- Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+ fphelp[index ] = fpdata[inext++];
+ fphelp[index+1] = fpdata[inext++];
}
+ index += 2;
+ }
- /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
- ISEC4_NumValues = bitmapSize;
-
- if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
- {
- GRIBPACK bitmap;
- /*
- unsigned char *bitmap;
- bitmap = BMS_Bitmap;
- int j = ISEC4_NumNonMissValues;
- for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
- {
- if ( (bitmap[i/8]>>(7-(i&7)))&1 )
- fsec4[i] = fsec4[--j];
- else
- fsec4[i] = FSEC3_MissVal;
- }
- */
+ index = 0;
+ for ( m = 0; m <= trunc; m++ )
+ for ( n = m; n <= trunc; n++ )
+ {
+ if ( n > pcStart )
+ {
+ fphelp[index ] = fpdata[inext++];
+ fphelp[index+1] = fpdata[inext++];
+ }
+ index += 2;
+ }
- GRIBPACK *imask = (GRIBPACK*) Malloc((size_t)imaskSize*sizeof(GRIBPACK));
+ for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
-#if defined (VECTORCODE)
- (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
- GRIBPACK *pbitmap = imask;
-#else
- GRIBPACK *pbitmap = BMS_Bitmap;
-#endif
+ Free(fphelp);
+}
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( int i = imaskSize/8-1; i >= 0; i-- )
- {
- bitmap = pbitmap[i];
- imask[i*8+0] = 1 & (bitmap >> 7);
- imask[i*8+1] = 1 & (bitmap >> 6);
- imask[i*8+2] = 1 & (bitmap >> 5);
- imask[i*8+3] = 1 & (bitmap >> 4);
- imask[i*8+4] = 1 & (bitmap >> 3);
- imask[i*8+5] = 1 & (bitmap >> 2);
- imask[i*8+6] = 1 & (bitmap >> 1);
- imask[i*8+7] = 1 & (bitmap);
- }
- int j = 0;
- for ( int i = 0; i < ISEC4_NumValues; i++ )
- if ( imask[i] ) j++;
+void TEMPLATE(gather_complex,T)(T *fpdata, size_t pcStart, size_t trunc, size_t nsp)
+{
+ T *restrict fphelp = (T*) Malloc(nsp*sizeof(T));
+ size_t inext = 0;
- if ( ISEC4_NumNonMissValues != j )
- {
- if ( dfunc != 'J' && ISEC4_NumBits != 0 )
- Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
- j, ISEC4_NumNonMissValues);
+ for ( size_t m = 0, index = 0; m <= pcStart; m++ )
+ for ( size_t n = m; n <= trunc; n++ )
+ {
+ if ( pcStart >= n )
+ {
+ fphelp[inext++] = fpdata[index];
+ fphelp[inext++] = fpdata[index+1];
+ }
+ index += 2;
+ }
- ISEC4_NumNonMissValues = j;
- }
+ for ( size_t m = 0, index = 0; m <= trunc; m++ )
+ for ( size_t n = m; n <= trunc; n++ )
+ {
+ if ( n > pcStart )
+ {
+ fphelp[inext++] = fpdata[index];
+ fphelp[inext++] = fpdata[index+1];
+ }
+ index += 2;
+ }
- if ( dfunc != 'J' )
- {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
- fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
- }
+ for ( size_t m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
- Free(imask);
- }
- }
+ Free(fphelp);
+}
- if ( ISEC2_Reduced )
- {
- int nvalues = 0;
- int nlat = ISEC2_NumLat;
- int nlon = ISEC2_RowLonPtr[0];
- for ( int ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
- for ( int ilat = 1; ilat < nlat; ++ilat )
- if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
- // int dlon = ISEC2_LastLon-ISEC2_FirstLon;
- // if ( dlon < 0 ) dlon += 360000;
-
- if ( nvalues != ISEC4_NumValues ) *iret = -801;
+void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
+{
+ /* System generated locals */
+ double r_1;
- //printf("nlat %d nlon %d \n", nlat, nlon);
- //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+ /* Local variables */
+ int jl;
+ double zfac, zeps, zbeta;
+ double zalpha;
- if ( dfunc == 'R' && *iret == -801 )
- gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
- ISEC4_NumValues, nvalues);
-
- if ( dfunc == 'R' && *iret != -801 )
- {
- ISEC2_Reduced = 0;
- ISEC2_NumLon = nlon;
- ISEC4_NumValues = nlon*nlat;
+ /* **** SCM0 - Apply SCM0 limiter to derivative estimates. */
+ /* output: */
+ /* pdl = the limited derivative at the left edge of the interval */
+ /* pdr = the limited derivative at the right edge of the interval */
+ /* inputs */
+ /* pdl = the original derivative at the left edge */
+ /* pdr = the original derivative at the right edge */
+ /* pfl = function value at the left edge of the interval */
+ /* pfr = function value at the right edge of the interval */
+ /* klg = number of intervals where the derivatives are limited */
- lsect3 = bitmapSize > 0;
- int lperio = 1;
- int lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) &&
- ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) ||
- (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30) ||
- (ISEC1_Parameter == 39) || (ISEC1_Parameter == 40) ||
- (ISEC1_Parameter == 41) || (ISEC1_Parameter == 42) ||
- (ISEC1_Parameter == 43));
-
- (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
-
- if ( bitmapSize > 0 )
- {
- int j = 0;
- for ( int i = 0; i < ISEC4_NumValues; i++ )
- if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
-
- ISEC4_NumNonMissValues = j;
- }
- }
- }
+ /* define constants */
+ zeps = 1.0e-12;
+ zfac = (1.0 - zeps) * 3.0;
- if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
- esLen = 4;
+ for ( jl = 0; jl < klg; ++jl )
+ {
+ if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
+ {
+ zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
+ zbeta = pdr[jl] / (pfr[jl] - pfl[jl]);
+ if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
+ if ( zbeta <= 0.0 ) pdr[jl] = 0.0;
+ if ( zalpha > zfac ) pdl[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
+ if ( zbeta > zfac ) pdr[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
+ }
+ else
+ {
+ pdl[jl] = 0.0;
+ pdr[jl] = 0.0;
+ }
+ }
+} /* scm0 */
- int gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
+static
+int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
+ int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
+{
+ /*
+C---->
+C**** ROWINA3 - Interpolation of row of values.
+C
+C Purpose.
+C --------
+C
+C Interpolate a row of values.
+C
+C
+C** Interface.
+C ----------
+C
+C CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
+C
+C
+C Input Parameters.
+C -----------------
+C
+C P - Row of values to be interpolated.
+C Dimension must be at least KO.
+C
+C KO - Number of values required.
+C
+C KI - Number of values in P on input.
+C
+C PW - Working array.
+C Dimension must be at least (0:KO+2,3).
+C
+C KCODE - Interpolation required.
+C 1 , linear.
+C 3 , cubic.
+C
+C PMSVAL - Value used for missing data indicator.
+C
+C OMISNG - True if missing values are present in field.
+C
+C OPERIO - True if input field is periodic.
+C
+C OVEGGY - True if 'nearest neighbour' processing must be used
+C for interpolation
+C
+C Output Parameters.
+C ------------------
+C
+C P - Now contains KO values.
+C KRET - Return code
+C 0, OK
+C Non-zero, error
+C
+C
+C Method.
+C -------
+C
+C Linear or cubic interpolation performed as required.
+C
+C Comments.
+C ---------
+C
+C This is a version of ROWINA which allows for missing data
+C values and hence for bitmapped fields.
+C
+C
+C Author.
+C -------
+C
+C J.D.Chambers ECMWF 22.07.94
+C
+C
+C Modifications.
+C --------------
+C
+C J.D.Chambers ECMWF 13.09.94
+C Add return code KRET and remove calls to ABORT.
+C
+C J. Clochard, Meteo France, for ECMWF - January 1998.
+C Addition of OMISNG and OPERIO arguments.
+C
+C
+C -----------------------------------------------------------------
+*/
+ /* System generated locals */
+ int pw_dim1, pw_offset, i_1;
- if ( ISEC0_GRIB_Len )
- if ( ISEC0_GRIB_Len < gribLen )
- Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
+ /* Local variables */
+ int jl, ip;
+ double zwt1, zrdi, zpos;
+ double zdo, zwt;
- ISEC0_GRIB_Len = gribLen;
+ UNUSED(omisng);
- *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
+ /* Parameter adjustments */
+ --p;
+ pw_dim1 = ko + 3;
+ pw_offset = pw_dim1;
+ pw -= pw_offset;
- /*
- ----------------------------------------------------------------
- Section 9 . Abort/return to calling routine.
- ----------------------------------------------------------------
- */
- LABEL900:;
+ *kret = 0;
- if ( ldebug )
+ if ( kcode == 1 )
{
- gprintf(__func__, "Section 9.");
- gprintf(__func__, "Output values set -");
-
- gribPrintSec0(isec0);
- gribPrintSec1(isec0, isec1);
- /*
- Print section 2 if present.
- */
- if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
+ /* Move input values to work array */
+ for ( jl = 1; jl <= ki; ++jl )
+ pw[jl + pw_dim1] = p[jl];
- if ( ! l_iorj )
+ if ( operio )
{
- /*
- Print section 3 if present.
- */
- if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+ /* Arrange wrap-around value in work array */
+ pw[ki + 1 + pw_dim1] = p[1];
- TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
- /*
- Special print for 2D spectra wave field real values in
- section 4
- */
- if ( (isec1[ 0] == 140) &&
- (isec1[ 1] == 98) &&
- (isec1[23] == 1) &&
- ((isec1[39] == 1045) || (isec1[39] == 1081)) &&
- ((isec1[ 5] == 250) || (isec1[ 5] == 251)) )
- gribPrintSec4Wave(isec4);
+ /* Set up constants to be used to figure out weighting for */
+ /* values in interpolation. */
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
}
- }
-}
-
-#endif /* T */
-
-/*
- * Local Variables:
- * mode: c
- * End:
- */
-
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
-
-static
-int TEMPLATE(decodeGDS,T)(unsigned char *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
-{
- /* int imisng = 0; */
- int ReducedGrid = FALSE, VertCoorTab = FALSE;
-#if defined (VECTORCODE)
- unsigned char *igrib;
- GRIBPACK *lgrib = NULL;
- size_t lGribLen = 0;
-#endif
+ else
+ {
+ /* Repeat last value, to cope with "implicit truncation" below */
+ pw[ki + 1 + pw_dim1] = p[ki];
- *numGridVals = 0;
+ /* Set up constants to be used to figure out weighting for */
+ /* values in interpolation. */
+ zrdi = (double) (ki-1);
+ zdo = 1.0 / (double) (ko-1);
+ }
- memset(isec2, 0, 22*sizeof(int));
+ /* Loop through the output points */
+ for ( jl = 1; jl <= ko; ++jl )
+ {
- int gdsLen = GDS_Len;
+ /* Calculate weight from the start of row */
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
- int ipvpl = GDS_PVPL;
- if ( ipvpl == 0 ) ipvpl = 0xFF;
+ /* Get the current array position(minus 1) from the weight - */
+ /* note the implicit truncation. */
+ ip = (int) zwt;
+
+ /* Adjust the weight to range (0.0 to 1.0) */
+ zwt -= ip;
- if ( ipvpl != 0xFF )
- { /* Either vct or reduced grid */
- if ( GDS_NV != 0 )
- { /* we have vct */
- VertCoorTab = TRUE;
- int ipl = 4*GDS_NV + ipvpl - 1;
- if ( ipl < gdsLen )
+ /* If 'nearest neighbour' processing must be used */
+ if ( oveggy )
{
- ReducedGrid = TRUE;
+ if ( zwt < 0.5 )
+ p[jl] = pw[ip + 1 + pw_dim1];
+ else
+ p[jl] = pw[ip + 2 + pw_dim1];
+ }
+ else
+ {
+ /* If the left value is missing, use the right value */
+ if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 2 + pw_dim1];
+ }
+ /* If the right value is missing, use the left value */
+ else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 1 + pw_dim1];
+ }
+ /* If neither missing, interpolate ... */
+ else
+ {
+ /* Interpolate using the weighted values on either side */
+ /* of the output point position */
+ p[jl] = (T)((1.0 - zwt) * pw[ip+1 + pw_dim1]
+ + zwt * pw[ip+2 + pw_dim1]);
+ }
}
}
- else
- {
- VertCoorTab = FALSE;
- ReducedGrid = TRUE;
- }
- /* ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
- }
-
- if ( ISEC0_GRIB_Version == 0 )
- {
- VertCoorTab = (gdsLen - 32) > 0;
}
-
- if ( ReducedGrid )
+ else if ( kcode == 3 )
{
- int locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
- int jlenl = (gdsLen - locnl) >> 1;
- if ( jlenl == GDS_NumLat )
+ /* ******************************* */
+ /* Section 2. Cubic interpolation .. */
+ /* ******************************* */
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
{
- *numGridVals = 0;
- ISEC2_Reduced = TRUE;
- for ( int i = 0; i < jlenl; i++ )
+ if ( IS_EQUAL(p[jl], msval) )
{
- ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
- *numGridVals += ISEC2_RowLon(i);
+ fprintf(stderr," ROWINA3: ");
+ fprintf(stderr," Cubic interpolation not supported");
+ fprintf(stderr," for fields containing missing data.\n");
+ *kret = 1;
+ goto L900;
}
+ pw[jl + pw_dim1] = p[jl];
}
- else
+ pw[pw_dim1] = p[ki];
+ pw[ki + 1 + pw_dim1] = p[1];
+ pw[ki + 2 + pw_dim1] = p[2];
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
{
- ReducedGrid = FALSE;
+ pw[jl + (pw_dim1 << 1)] =
+ (T)(- pw[jl - 1 + pw_dim1] / 3.0 -
+ pw[jl + pw_dim1] * 0.5 +
+ pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0);
+ pw[jl + 1 + pw_dim1 * 3] =
+ (T)(pw[jl - 1 + pw_dim1] / 6.0 -
+ pw[jl + pw_dim1] +
+ pw[jl + 1 + pw_dim1] * 0.5 +
+ pw[jl + 2 + pw_dim1] / 3.0);
}
- }
- ISEC2_GridType = GDS_GridType;
+ TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+ &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
- /*
- Gaussian grid definition.
- */
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
- {
- ISEC2_NumLat = GDS_NumLat;
- if ( ! ReducedGrid )
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
+ for ( jl = 1; jl <= ko; ++jl )
{
- ISEC2_NumLon = GDS_NumLon;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
+ ip = (int) zwt + 1;
+ zwt = zwt + 1.0 - ip;
+ zwt1 = 1.0 - zwt;
+ p[jl] = (T)(((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+ zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+ ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+ zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt);
}
- ISEC2_FirstLat = GDS_FirstLat;
- ISEC2_FirstLon = GDS_FirstLon;
- ISEC2_ResFlag = GDS_ResFlag;
- ISEC2_LastLat = GDS_LastLat;
- ISEC2_LastLon = GDS_LastLon;
- ISEC2_LonIncr = GDS_LonIncr;
- ISEC2_NumPar = GDS_NumPar;
- ISEC2_ScanFlag = GDS_ScanFlag;
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
- {
- ISEC2_LatSP = GDS_LatSP;
- ISEC2_LonSP = GDS_LonSP;
- FSEC2_RotAngle = (T)GDS_RotAngle;
- }
- /*
- if ( Lons != Longitudes || Lats != Latitudes )
- Error("Latitude/Longitude Conflict");
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
- {
- /*
- iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
- {
- /*
- iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
- {
- ISEC2_NumLon = GDS_NumLon;
- ISEC2_NumLat = GDS_NumLat;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
- ISEC2_FirstLat = GDS_FirstLat;
- ISEC2_FirstLon = GDS_FirstLon;
- ISEC2_ResFlag = GDS_ResFlag;
- ISEC2_Lambert_Lov = GDS_Lambert_Lov;
- ISEC2_Lambert_dx = GDS_Lambert_dx;
- ISEC2_Lambert_dy = GDS_Lambert_dy;
- ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
- ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
- ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
- ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
- ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
- ISEC2_ScanFlag = GDS_ScanFlag;
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
- {
- ISEC2_PentaJ = GDS_PentaJ; /* Truncation */
- ISEC2_PentaK = GDS_PentaK;
- ISEC2_PentaM = GDS_PentaM;
- ISEC2_RepType = GDS_RepType;
- ISEC2_RepMode = GDS_RepMode;
- *numGridVals = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
- isec2[ 6] = 0;
- isec2[ 7] = 0;
- isec2[ 8] = 0;
- isec2[ 9] = 0;
- isec2[10] = 0;
- /*
- iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
- */
- }
- else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
- {
- ISEC2_GME_NI2 = GDS_GME_NI2;
- ISEC2_GME_NI3 = GDS_GME_NI3;
- ISEC2_GME_ND = GDS_GME_ND;
- ISEC2_GME_NI = GDS_GME_NI;
- ISEC2_GME_AFlag = GDS_GME_AFlag;
- ISEC2_GME_LatPP = GDS_GME_LatPP;
- ISEC2_GME_LonPP = GDS_GME_LonPP;
- ISEC2_GME_LonMPL = GDS_GME_LonMPL;
- ISEC2_GME_BFlag = GDS_GME_BFlag;
- *numGridVals = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
- /*
- iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
- */
}
else
{
- ISEC2_NumLon = GDS_NumLon;
- ISEC2_NumLat = GDS_NumLat;
- *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
- Message("Gridtype %d unsupported", ISEC2_GridType);
+ /* ************************************** */
+ /* Section 3. Invalid interpolation code .. */
+ /* ************************************** */
+ fprintf(stderr," ROWINA3:");
+ fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+ *kret = 2;
}
- /* vertical coordinate parameters for hybrid levels. */
- /* get number of vertical coordinate parameters, if any. */
-
- ISEC2_NumVCP = 0;
-
- isec2[17] = 0;
- isec2[18] = 0;
-
- if ( VertCoorTab == TRUE )
- {
- int locnv;
- if ( ISEC0_GRIB_Version == 0 )
- {
- locnv = 32;
- ISEC2_NumVCP = (gdsLen - 32) >> 2;
- }
- else
- {
- locnv = GDS_PVPL - 1;
- ISEC2_NumVCP = GDS_NV;
- }
-#if defined (SX)
- lGribLen = 4*ISEC2_NumVCP;
- lgrib = (GRIBPACK*) Malloc(lGribLen*sizeof(GRIBPACK));
+L900:
+ return 0;
+} /* rowina3 */
- igrib = &gds[locnv];
- if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
- for ( int i = 0; i < ISEC2_NumVCP; i++ )
- {
- int iexp = (lgrib[4*i ]);
- int imant =(((lgrib[4*i+1]) << 16) +
- ((lgrib[4*i+2]) << 8) +
- ( lgrib[4*i+3]));
- fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
- }
- Free(lgrib);
-#else
- for ( int i = 0; i < ISEC2_NumVCP; i++ )
- {
- int iexp = (gds[locnv+4*i ]);
- int imant =(((gds[locnv+4*i+1]) << 16) +
- ((gds[locnv+4*i+2]) << 8) +
- ( gds[locnv+4*i+3]));
- fsec2[10+i] = (T)decfp2(iexp,imant);
- }
-#endif
- }
+int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
+ T msval, int *kret, int omisng, int operio, int oveggy)
+{
+ /*
+C**** QU2REG3 - Convert quasi-regular grid data to regular.
+C
+C Purpose.
+C --------
+C
+C Convert quasi-regular grid data to regular,
+C using either a linear or cubic interpolation.
+C
+C
+C** Interface.
+C ----------
+C
+C CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
+C X OVEGGY)
+C
+C
+C Input Parameters.
+C -----------------
+C
+C PFIELD - Array containing quasi-regular grid data.
+C
+C KPOINT - Array containing list of the number of
+C points on each latitude (or longitude) of
+C the quasi-regular grid.
+C
+C KLAT - Number of latitude lines
+C
+C KLON - Number of longitude lines
+C
+C KCODE - Interpolation required.
+C 1 , linear - data quasi-regular on latitude lines.
+C 3 , cubic - data quasi-regular on latitude lines.
+C 11, linear - data quasi-regular on longitude lines.
+C 13, cubic - data quasi-regular on longitude lines.
+C
+C PMSVAL - Value used for missing data indicator.
+C
+C OMISNG - True if missing values are present in field.
+C
+C OPERIO - True if input field is periodic.
+C
+C OVEGGY - True if 'nearest neighbour' processing must be used
+C for interpolation
+C
+C
+C Output Parameters.
+C ------------------
+C
+C KRET - return code
+C 0 = OK
+C non-zero indicates fatal error
+C
+C
+C Output Parameters.
+C ------------------
+C
+C PFIELD - Array containing regular grid data.
+C
+C
+C Method.
+C -------
+C
+C Data is interpolated and expanded into a temporary array,
+C which is then copied back into the user's array.
+C Returns an error code if an invalid interpolation is requested
+C or field size exceeds array dimensions.
+C
+C Comments.
+C ---------
+C
+C This routine is an adaptation of QU2REG to allow missing data
+C values, and hence bit mapped fields.
+C
+C
+C Author.
+C -------
+C
+C J.D.Chambers ECMWF 22.07.94
+C
+C
+C Modifications.
+C --------------
+C
+C J.D.Chambers ECMWF 13.09.94
+C Add return code KRET and remove calls to ABORT.
+C
+C J.D.Chambers ECMWF Feb 1997
+C Allow for 64-bit pointers
+C
+C J. Clochard, Meteo France, for ECMWF - January 1998.
+C Addition of OMISNG and OPERIO arguments.
+C Fix message for longitude number out of bounds, and routine
+C name in title and formats.
+C
+*/
+ /* System generated locals */
+ int i_1, i_2;
+ int kcode = 1;
- return gdsLen;
-}
+ /* Local variables */
+ int ilii, ilio, icode;
+ int iregno, iquano, j210, j220, j230, j240, j225;
+ T *ztemp = NULL;
+ T *zline = NULL;
+ T *zwork = NULL;
-#define ldexp_double ldexp
-#define ldexp_float ldexpf
+ ztemp = (T*) Malloc((size_t)klon*(size_t)klat*sizeof(T));
-static
-int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4,
- T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
-{
- unsigned char *igrib;
- int lspherc = FALSE, lcomplex = FALSE;
- int lcompress;
- int jup, kup, mup;
- int locnd;
- int bds_flag, jscale, imiss;
- int bds_ubits;
- int ioff = 0;
- int iexp, imant;
- int zoff;
- int bds_head = 11;
- T zscale = 0.;
- T fmin = 0.;
- T *fpdata = fsec4;
- int bdsLen;
- extern int CGRIBEX_Fix_ZSE;
+ zline = (T*) Malloc(2*(size_t)klon*sizeof(T));
- *iret = 0;
- igrib = bds;
+ zwork = (T*) Malloc(3*(2*(size_t)klon+3)*sizeof(T));
- memset(isec4, 0, 42*sizeof(int));
+ /* Parameter adjustments */
+ --pfield;
+ --kpoint;
- /* get length of binary data block. */
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
- bdsLen = BDS_Len;
- /*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- if ( llarge ) bdsLen = bdsLenIn - bdsLen;
+ *kret = 0;
- /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
+/* Check input parameters. */
- bds_flag = BDS_Flag;
+ if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+ fprintf(stderr," QU2REG :");
+ fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+ *kret = 1;
+ goto L900;
+ }
- /* 0------- grid point */
- /* 1------- spherical harmonics */
+/* Set array indices to 0. */
- lspherc = bds_flag >> 7;
+ ilii = 0;
+ ilio = 0;
- if ( lspherc ) isec4[2] = 128;
- else isec4[2] = 0;
+/* Establish values of loop parameters. */
- /* -0------ simple packing */
- /* -1------ complex packing */
+ if (kcode > 10) {
- lcomplex = (bds_flag >> 6)&1;
+/* Quasi-regular along longitude lines. */
- if ( lcomplex ) isec4[3] = 64;
- else isec4[3] = 0;
+ iquano = klon;
+ iregno = klat;
+ icode = kcode - 10;
+ } else {
- /* ---0---- No additional flags */
- /* ---1---- No additional flags */
+/* Quasi-regular along latitude lines. */
- lcompress = (bds_flag >> 4)&1; /* compress */
+ iquano = klat;
+ iregno = klon;
+ icode = kcode;
+ }
- if ( lcompress )
- { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
- else
- { isec4[5] = 0; isec4[6] = 0; zoff = 0; }
+/* -------------------------------------------------------- */
+/** Section 2. Interpolate field from quasi to regular grid. */
+/* -------------------------------------------------------- */
- /* ----++++ number of unused bits at end of section) */
+ i_1 = iquano;
+ for (j230 = 1; j230 <= i_1; ++j230) {
- bds_ubits = bds_flag & 0xF;
-
- /* scale factor (2 bytes) */;
+ if (iregno != kpoint[j230]) {
- jscale = BDS_BinScale;
+/* Line contains less values than required,so */
+/* extract quasi-regular grid values for a line */
- /* check for missing data indicators. */
+ i_2 = kpoint[j230];
+ for (j210 = 1; j210 <= i_2; ++j210) {
+ ++ilii;
+ zline[j210 - 1] = pfield[ilii];
+ }
- iexp = bds[ 6];
- imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+/* and interpolate this line. */
- imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+ TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
+ if (*kret != 0) goto L900;
- /* convert reference value and scale factor. */
+/* Add regular grid values for this line to the
+ temporary array. */
- if ( ! (dfunc == 'J') && imiss == 0 )
- {
- fmin = (T)BDS_RefValue;
- zscale = TEMPLATE(ldexp,T)((T)1.0, jscale);
- }
+ i_2 = iregno;
+ for (j220 = 1; j220 <= i_2; ++j220) {
+ ++ilio;
+ ztemp[ilio - 1] = zline[j220 - 1];
+ }
- /* get number of bits in each data value. */
+ } else {
- ISEC4_NumBits = BDS_NumBits;
+/* Line contains the required number of values, so add */
+/* this line to the temporary array. */
- /* octet number of start of packed data */
- /* calculated from start of block 4 - 1 */
+ i_2 = iregno;
+ for (j225 = 1; j225 <= i_2; ++j225) {
+ ++ilio;
+ ++ilii;
+ ztemp[ilio - 1] = pfield[ilii];
+ }
+ }
+ }
- locnd = zoff + bds_head;
+/* Copy temporary array to user array. */
- /* if data is in spherical harmonic form, distinguish */
- /* between simple/complex packing (lcomplex = 0/1) */
+ i_1 = klon * klat;
+ for (j240 = 1; j240 <= i_1; ++j240) {
+ pfield[j240] = ztemp[j240 - 1];
+ }
- if ( lspherc )
- {
- if ( !lcomplex )
- {
- /* no unpacked binary data present */
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
- //jup = kup = mup = 0;
+L900:
- /* octet number of start of packed data */
- /* calculated from start of block 4 - 1 */
+ Free(zwork);
+ Free(zline);
+ Free(ztemp);
- ioff = 1;
- locnd += 4*ioff; /* RealCoef */
+ return 0;
+} /* qu2reg3 */
- /* get real (0,0) coefficient in grib format and */
- /* convert to floating point. */
+#endif /* T */
- if ( dfunc != 'J' )
- {
- if ( imiss ) *fpdata++ = 0.0;
- else *fpdata++ = (T)BDS_RealCoef;
- }
- }
- else /* complex packed spherical harmonics */
- {
- isec4[15] = BDS_PackData;
- /* scaling factor */
- isec4[16] = BDS_Power;
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
- /* pentagonal resolution parameters of the */
- /* unpacked section of data field */
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
- jup = bds[zoff+15];
- kup = bds[zoff+16];
- mup = bds[zoff+17];
+/* calculate_pfactor: source code from grib_api-1.8.0 */
+double TEMPLATE(calculate_pfactor,T)(const T *spectralField, long fieldTruncation, long subsetTruncation)
+{
+ /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
+ long loop, index, m, n = 0;
+ double pFactor, zeps = 1.0e-15;
+ long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
+ double* weights, range, * norms;
+ double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
+ double numerator = 0.0, denominator = 0.0, slope;
- isec4[zoff+17] = jup;
- isec4[zoff+18] = kup;
- isec4[zoff+19] = mup;
+ /*
+ // Setup the weights
+ */
- /* unpacked binary data */
+ range = (double) (ismax - ismin +1);
- locnd += 4; /* 2 + power */
- locnd += 3; /* j, k, m */
- ioff = (jup+1)*(jup+2);
+ weights = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
+ for( loop = ismin; loop <= ismax; loop++ )
+ weights[loop] = range / (double) (loop-ismin+1);
+ /*
+ // Compute norms
+ // Handle values 2 at a time (real and imaginary parts).
+ */
+ norms = (double*) Malloc(((size_t)ismax+1)*sizeof(double));
- if ( dfunc != 'J' )
- for ( int i = 0; i < ioff; i++ )
- {
- if ( imiss )
- *fpdata++ = 0.0;
- else
- {
- iexp = (bds[locnd+4*i ]);
- imant =((bds[locnd+4*i+1]) << 16) +
- ((bds[locnd+4*i+2]) << 8) +
- (bds[locnd+4*i+3]);
+ for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
+ /*
+ // Form norms for the rows which contain part of the unscaled subset.
+ */
- *fpdata++ = (T)decfp2(iexp,imant);
- }
- }
-
- locnd += 4*ioff; /* RealCoef */
- }
- }
- else
- {
- if ( lcomplex )
- {
- *iret = 1999;
- gprintf(__func__, " Second order packed grids unsupported!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
+ index = -2;
+ for( m = 0; m < subsetTruncation; m++ )
+ for( n = m; n <= fieldTruncation; n++ ) {
+ index += 2;
+ if( n >= subsetTruncation ) {
+ double tval = spectralField[index];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ tval = spectralField[index+1];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ }
}
+ /*
+ // Form norms for the rows which do not contain part of the unscaled subset.
+ */
- /* Decode data values to floating point and store in fsec4. */
- /* First calculate the number of data values. */
- /* Take into account that spherical harmonics can be packed */
- /* simple (lcomplex = 0) or complex (lcomplex = 1) */
-
- int jlend = bdsLen - locnd;
-
- if ( ISEC4_NumBits == 0 )
- {
- if ( jlend > 1 )
- {
- *iret = 2001;
- gprintf(__func__, " Number of bits per data value = 0!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
-
- if ( numGridVals == 0 )
- {
- *iret = 2002;
- gprintf(__func__, " Constant field unsupported for this grid type!");
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
-
- jlend = numGridVals;
- jlend -= ioff;
- }
- else
- {
- jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+ for( m = subsetTruncation; m <= fieldTruncation; m++ )
+ for( n = m; n <= fieldTruncation; n++ ) {
+ double tval = spectralField[index];
+ index += 2;
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
+ tval = spectralField[index+1];
+ tval=tval<0?-tval:tval;
+ norms[n] = norms[n] > tval ? norms[n] : tval;
}
- ISEC4_NumValues = jlend + ioff;
- ISEC4_NumNonMissValues = 0;
-
- if ( lcompress )
- {
- size_t len;
-
- if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
- len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
- else
- len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-
- ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
+ /*
+ // Ensure the norms have a value which is not too small in case of
+ // problems with math functions (e.g. LOG).
+ */
- if ( lspherc )
- {
- if ( lcomplex )
- ISEC4_NumValues += ioff;
- else
- ISEC4_NumValues++;
- }
- }
+ for( loop = ismin; loop <= ismax; loop++ ) {
+ norms[n] = norms[n] > zeps ? norms[n] : zeps;
+ if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
+ }
- if ( dfunc == 'J' ) return bdsLen;
+ /*
+ // Do linear fit to find the slope
+ */
- /* check length of output array. */
-
- if ( ISEC4_NumValues > fsec4len )
- {
- *iret = 710;
- gprintf(__func__, " Output array too small. Length = %d", fsec4len);
- gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
- gprintf(__func__, " Return code = %d", *iret);
- return 0;
- }
+ for( loop = ismin; loop <= ismax; loop++ ) {
+ x = log( (double) (loop*(loop+1)) );
+ y = log( norms[loop] );
+ weightedSumOverX = weightedSumOverX + x * weights[loop];
+ weightedSumOverY = weightedSumOverY + y * weights[loop];
+ sumOfWeights = sumOfWeights + weights[loop];
+ }
+ weightedSumOverX = weightedSumOverX / sumOfWeights;
+ weightedSumOverY = weightedSumOverY / sumOfWeights;
- if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
- else
- {
- igrib += locnd;
+ /*
+ // Perform a least square fit for the equation
+ */
- TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
- }
+ for( loop = ismin; loop <= ismax; loop++ ) {
- if ( lspherc && lcomplex )
- {
- int pcStart = isec4[19], pcScale = isec4[16];
- TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
- TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
- }
+ x = log( (double)(loop*(loop+1)) );
+ y = log( norms[loop] );
+ numerator =
+ numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
+ denominator =
+ denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
+ }
+ slope = numerator / denominator;
- if ( CGRIBEX_Fix_ZSE ) /* Fix ZeroShiftError of simple packed spherical harmonics */
- if ( lspherc && !lcomplex )
- {
- /* 20100705: Fix ZeroShiftError - Edi Kirk */
- if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
- {
- T zserr = fsec4[1];
- for ( int i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
- }
- }
+ Free(weights);
+ Free(norms);
- if ( decscale )
- {
- T scale = (T) pow(10.0, (double)-decscale);
- for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
- }
+ pFactor = -slope;
+ if( pFactor < -9999.9 ) pFactor = -9999.9;
+ if( pFactor > 9999.9 ) pFactor = 9999.9;
- return bdsLen;
+ return pFactor;
}
-
-void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
- T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
- int kleng, int *kword, int dfunc, int *iret)
+void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
{
- UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
- int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
- int gdsIncluded = FALSE;
- int bmsIncluded = FALSE;
- int bitmapSize = 0;
- int imaskSize = 0;
- int ldebug = FALSE;
- int llarge = FALSE, l_iorj = FALSE;
- int lsect2 = FALSE, lsect3 = FALSE;
- int numGridVals = 0;
- static int lmissvalinfo = 1;
-
- UNUSED(kleng);
-
- *iret = 0;
-
- grsdef();
-
- ISEC2_Reduced = FALSE;
-
- /*
- ----------------------------------------------------------------
- IS Indicator Section (Section 0)
- ----------------------------------------------------------------
- */
- is = (unsigned char *) &kgrib[0];
+ double power;
+ double *scale = (double*) Malloc(((size_t)trunc+1)*sizeof(double));
- isLen = decodeIS(is, isec0, iret);
+ if ( scale == NULL ) SysError("No Memory!");
- /*
- If count is negative, have to rescale by factor of -120.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- if ( ISEC0_GRIB_Len < 0 )
+ if ( pcScale < -10000 || pcScale > 10000 )
{
- if ( ldebug )
- gprintf(__func__, "Special case, negative length multiplied by -120");
- llarge = TRUE;
- ISEC0_GRIB_Len *= (-120);
- }
- /*
- When decoding or calculating length, previous editions
- of the GRIB code must be taken into account.
-
- In the table below, covering sections 0 and 1 of the GRIB
- code, octet numbering is from the beginning of the GRIB
- message;
- * indicates that the value is not available in the code edition;
- R indicates reserved, should be set to 0;
- Experimental edition is considered as edition -1.
-
- GRIB code edition -1 has fixed length of 20 octets for
- section 1, the length not included in the message.
- GRIB code edition 0 has fixed length of 24 octets for
- section 1, the length being included in the message.
- GRIB code edition 1 can have different lengths for section
- 1, the minimum being 28 octets, length being included in
- the message.
-
- Octet numbers for code
- editions
-
- Contents. -1 0 1
- --------- ----------------------
- Letters GRIB 1-4 1-4 1-4
- Total length of GRIB message. * * 5-7
- GRIB code edition number * * 8
- Length of Section 1. * 5-7 9-11
- Reserved octet (R). * 8(R) *
- Version no. of Code Table 2. * * 12
- Identification of centre. 5 9 13
- Generating process. 6 10 14
- Grid definition . 7 11 15
- Flag (Code Table 1). 8 12 16
- Indicator of parameter. 9 13 17
- Indicator of type of level. 10 14 18
- Height, pressure etc of levels. 11-12 15-16 19-20
- Year of century. 13 17 21
- Month. 14 18 22
- Day. 15 19 23
- Hour. 16 20 24
- Minute. 17 21 25
- Indicator of unit of time. 18 22 26
- P1 - Period of time. 19 23 27
- P2 - Period of time 20(R) 24 28
- or reserved octet (R).
- Time range indicator. 21(R) 25 29
- or reserved octet (R).
- Number included in average. 22-23(R) 26-27 30-31
- or reserved octet (R).
- Number missing from average. 24(R) 28(R) 32
- or reserved octet (R).
- Century of data. * * 33
- Designates sub-centre if not 0. * * 34
- Decimal scale factor. * * 35-36
- Reserved. Set to 0. * * 37-48
- (Need not be present)
- For originating centre use only. * * 49-nn
- (Need not be present)
-
- Identify which GRIB code edition is being decoded.
-
- In GRIB edition 1, the edition number is in octet 8.
- In GRIB edition 0, octet 8 is reserved and set to 0.
- In GRIB edition -1, octet 8 is a flag field and can have a
- a valid value of 0, 1, 2 or 3.
+ fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
+ return;
+ }
- However, GRIB edition number 0 has a fixed
- length of 24, included in the message, for section 1, so
- if the value extracted from octets 5-7 is 24 and that from
- octet 8 is 0, it is safe to assume edition 0 of the code.
+ /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
- */
- if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
- {
- /*
- Set length of GRIB message to missing data value.
- */
- ISEC0_GRIB_Len = 0;
- }
- /*
- If Grib Edition 1 and only length is required, go to section 9.
- */
- if ( dfunc == 'L' ) goto LABEL900;
+ if ( pcScale == 0 ) return;
- /*
- ----------------------------------------------------------------
- PDS Product Definition Section (Section 1)
- ----------------------------------------------------------------
- */
- pds = is + isLen;
+ power = (double) pcScale / 1000.;
+ scale[0] = 1.0;
- pdsLen = decodePDS(pds, isec0, isec1);
+ if (pcScale != 1000)
+ for ( int n = 1; n <= trunc; n++ )
+ scale[n] = pow((double) (n*(n+1)), power);
+ else
+ for ( int n = 1; n <= trunc; n++ )
+ scale[n] = (double) (n*(n+1));
- /*
- ----------------------------------------------------------------
- GDS Grid Description Section (Section 2)
- ----------------------------------------------------------------
- */
- gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ if ( inv )
+ for ( int n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
- if ( gdsIncluded )
- {
- gds = is + isLen + pdsLen;
+ /* Scale the values */
- gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
- }
+ size_t index = 0;
- /*
- ----------------------------------------------------------------
- BMS Bit-Map Section Section (Section 3)
- ----------------------------------------------------------------
- */
- bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ for ( int m = 0; m < pcStart; m++ )
+ for ( int n = m; n <= trunc; n++, index += 2 )
+ if ( n >= pcStart )
+ {
+ fpdata[index ] = (T)(fpdata[index ] * scale[n]);
+ fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
+ }
- isec3[0] = 0;
- if ( bmsIncluded )
- {
- bms = is + isLen + pdsLen + gdsLen;
+ for ( int m = pcStart; m <= trunc; m++ )
+ for ( int n = m; n <= trunc; n++, index += 2 )
+ {
+ fpdata[index ] = (T)(fpdata[index ] * scale[n]);
+ fpdata[index+1] = (T)(fpdata[index+1] * scale[n]);
+ }
- bmsLen = BMS_Len;
- imaskSize = (bmsLen - 6)<<3;
- bitmapSize = imaskSize - BMS_UnusedBits;
- /*
- fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
- */
- }
+ Free(scale);
+}
- /*
- ----------------------------------------------------------------
- BDS Binary Data Section (Section 4)
- ----------------------------------------------------------------
- */
- bds = is + isLen + pdsLen + gdsLen + bmsLen;
- bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+{
+ T *fphelp = (T*) Malloc((size_t)nsp*sizeof(T));
+ int m, n;
+ int index, inext;
- bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4,
- fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
+ if ( fphelp == NULL ) SysError("No Memory!");
- if ( *iret != 0 ) return;
+ index = inext = 0;
- ISEC4_NumNonMissValues = ISEC4_NumValues;
+ for ( m = 0; m <= pcStart; m++ )
+ for ( n = m; n <= trunc; n++ )
+ {
+ if ( pcStart >= n )
+ {
+ fphelp[index ] = fpdata[inext++];
+ fphelp[index+1] = fpdata[inext++];
+ }
+ index += 2;
+ }
- if ( bitmapSize > 0 )
- {
- if ( dfunc != 'L' && dfunc != 'J' )
- if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+ index = 0;
+ for ( m = 0; m <= trunc; m++ )
+ for ( n = m; n <= trunc; n++ )
+ {
+ if ( n > pcStart )
{
- lmissvalinfo = 0;
- FSEC3_MissVal = (T)GRIB_MISSVAL;
- Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+ fphelp[index ] = fpdata[inext++];
+ fphelp[index+1] = fpdata[inext++];
}
+ index += 2;
+ }
- /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
- ISEC4_NumValues = bitmapSize;
+ for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
- if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
- {
- GRIBPACK bitmap;
- /*
- unsigned char *bitmap;
- bitmap = BMS_Bitmap;
- int j = ISEC4_NumNonMissValues;
- for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
- {
- if ( (bitmap[i/8]>>(7-(i&7)))&1 )
- fsec4[i] = fsec4[--j];
- else
- fsec4[i] = FSEC3_MissVal;
- }
- */
+ Free(fphelp);
+}
- GRIBPACK *imask = (GRIBPACK*) Malloc((size_t)imaskSize*sizeof(GRIBPACK));
-#if defined (VECTORCODE)
- (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
- GRIBPACK *pbitmap = imask;
-#else
- GRIBPACK *pbitmap = BMS_Bitmap;
-#endif
+void TEMPLATE(gather_complex,T)(T *fpdata, size_t pcStart, size_t trunc, size_t nsp)
+{
+ T *restrict fphelp = (T*) Malloc(nsp*sizeof(T));
+ size_t inext = 0;
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( int i = imaskSize/8-1; i >= 0; i-- )
- {
- bitmap = pbitmap[i];
- imask[i*8+0] = 1 & (bitmap >> 7);
- imask[i*8+1] = 1 & (bitmap >> 6);
- imask[i*8+2] = 1 & (bitmap >> 5);
- imask[i*8+3] = 1 & (bitmap >> 4);
- imask[i*8+4] = 1 & (bitmap >> 3);
- imask[i*8+5] = 1 & (bitmap >> 2);
- imask[i*8+6] = 1 & (bitmap >> 1);
- imask[i*8+7] = 1 & (bitmap);
- }
+ for ( size_t m = 0, index = 0; m <= pcStart; m++ )
+ for ( size_t n = m; n <= trunc; n++ )
+ {
+ if ( pcStart >= n )
+ {
+ fphelp[inext++] = fpdata[index];
+ fphelp[inext++] = fpdata[index+1];
+ }
+ index += 2;
+ }
- int j = 0;
- for ( int i = 0; i < ISEC4_NumValues; i++ )
- if ( imask[i] ) j++;
+ for ( size_t m = 0, index = 0; m <= trunc; m++ )
+ for ( size_t n = m; n <= trunc; n++ )
+ {
+ if ( n > pcStart )
+ {
+ fphelp[inext++] = fpdata[index];
+ fphelp[inext++] = fpdata[index+1];
+ }
+ index += 2;
+ }
- if ( ISEC4_NumNonMissValues != j )
- {
- if ( dfunc != 'J' && ISEC4_NumBits != 0 )
- Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
- j, ISEC4_NumNonMissValues);
+ for ( size_t m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
- ISEC4_NumNonMissValues = j;
- }
+ Free(fphelp);
+}
- if ( dfunc != 'J' )
- {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
- fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
- }
- Free(imask);
- }
- }
+void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
+{
+ /* System generated locals */
+ double r_1;
- if ( ISEC2_Reduced )
- {
- int nvalues = 0;
- int nlat = ISEC2_NumLat;
- int nlon = ISEC2_RowLonPtr[0];
- for ( int ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
- for ( int ilat = 1; ilat < nlat; ++ilat )
- if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+ /* Local variables */
+ int jl;
+ double zfac, zeps, zbeta;
+ double zalpha;
- // int dlon = ISEC2_LastLon-ISEC2_FirstLon;
- // if ( dlon < 0 ) dlon += 360000;
-
- if ( nvalues != ISEC4_NumValues ) *iret = -801;
+ /* **** SCM0 - Apply SCM0 limiter to derivative estimates. */
+ /* output: */
+ /* pdl = the limited derivative at the left edge of the interval */
+ /* pdr = the limited derivative at the right edge of the interval */
+ /* inputs */
+ /* pdl = the original derivative at the left edge */
+ /* pdr = the original derivative at the right edge */
+ /* pfl = function value at the left edge of the interval */
+ /* pfr = function value at the right edge of the interval */
+ /* klg = number of intervals where the derivatives are limited */
- //printf("nlat %d nlon %d \n", nlat, nlon);
- //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+ /* define constants */
- if ( dfunc == 'R' && *iret == -801 )
- gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
- ISEC4_NumValues, nvalues);
-
- if ( dfunc == 'R' && *iret != -801 )
- {
- ISEC2_Reduced = 0;
- ISEC2_NumLon = nlon;
- ISEC4_NumValues = nlon*nlat;
+ zeps = 1.0e-12;
+ zfac = (1.0 - zeps) * 3.0;
- lsect3 = bitmapSize > 0;
- int lperio = 1;
- int lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) &&
- ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) ||
- (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30) ||
- (ISEC1_Parameter == 39) || (ISEC1_Parameter == 40) ||
- (ISEC1_Parameter == 41) || (ISEC1_Parameter == 42) ||
- (ISEC1_Parameter == 43));
-
- (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
-
- if ( bitmapSize > 0 )
- {
- int j = 0;
- for ( int i = 0; i < ISEC4_NumValues; i++ )
- if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
-
- ISEC4_NumNonMissValues = j;
- }
+ for ( jl = 0; jl < klg; ++jl )
+ {
+ if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
+ {
+ zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
+ zbeta = pdr[jl] / (pfr[jl] - pfl[jl]);
+ if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
+ if ( zbeta <= 0.0 ) pdr[jl] = 0.0;
+ if ( zalpha > zfac ) pdl[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
+ if ( zbeta > zfac ) pdr[jl] = (T)(zfac * (pfr[jl] - pfl[jl]));
+ }
+ else
+ {
+ pdl[jl] = 0.0;
+ pdr[jl] = 0.0;
}
}
+} /* scm0 */
+static
+int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
+ int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
+{
+ /*
+C---->
+C**** ROWINA3 - Interpolation of row of values.
+C
+C Purpose.
+C --------
+C
+C Interpolate a row of values.
+C
+C
+C** Interface.
+C ----------
+C
+C CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
+C
+C
+C Input Parameters.
+C -----------------
+C
+C P - Row of values to be interpolated.
+C Dimension must be at least KO.
+C
+C KO - Number of values required.
+C
+C KI - Number of values in P on input.
+C
+C PW - Working array.
+C Dimension must be at least (0:KO+2,3).
+C
+C KCODE - Interpolation required.
+C 1 , linear.
+C 3 , cubic.
+C
+C PMSVAL - Value used for missing data indicator.
+C
+C OMISNG - True if missing values are present in field.
+C
+C OPERIO - True if input field is periodic.
+C
+C OVEGGY - True if 'nearest neighbour' processing must be used
+C for interpolation
+C
+C Output Parameters.
+C ------------------
+C
+C P - Now contains KO values.
+C KRET - Return code
+C 0, OK
+C Non-zero, error
+C
+C
+C Method.
+C -------
+C
+C Linear or cubic interpolation performed as required.
+C
+C Comments.
+C ---------
+C
+C This is a version of ROWINA which allows for missing data
+C values and hence for bitmapped fields.
+C
+C
+C Author.
+C -------
+C
+C J.D.Chambers ECMWF 22.07.94
+C
+C
+C Modifications.
+C --------------
+C
+C J.D.Chambers ECMWF 13.09.94
+C Add return code KRET and remove calls to ABORT.
+C
+C J. Clochard, Meteo France, for ECMWF - January 1998.
+C Addition of OMISNG and OPERIO arguments.
+C
+C
+C -----------------------------------------------------------------
+*/
+ /* System generated locals */
+ int pw_dim1, pw_offset, i_1;
- if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
- esLen = 4;
-
- int gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
-
- if ( ISEC0_GRIB_Len )
- if ( ISEC0_GRIB_Len < gribLen )
- Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
+ /* Local variables */
+ int jl, ip;
+ double zwt1, zrdi, zpos;
+ double zdo, zwt;
- ISEC0_GRIB_Len = gribLen;
+ UNUSED(omisng);
- *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
+ /* Parameter adjustments */
+ --p;
+ pw_dim1 = ko + 3;
+ pw_offset = pw_dim1;
+ pw -= pw_offset;
- /*
- ----------------------------------------------------------------
- Section 9 . Abort/return to calling routine.
- ----------------------------------------------------------------
- */
- LABEL900:;
+ *kret = 0;
- if ( ldebug )
+ if ( kcode == 1 )
{
- gprintf(__func__, "Section 9.");
- gprintf(__func__, "Output values set -");
-
- gribPrintSec0(isec0);
- gribPrintSec1(isec0, isec1);
- /*
- Print section 2 if present.
- */
- if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
+ /* Move input values to work array */
+ for ( jl = 1; jl <= ki; ++jl )
+ pw[jl + pw_dim1] = p[jl];
- if ( ! l_iorj )
+ if ( operio )
{
- /*
- Print section 3 if present.
- */
- if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+ /* Arrange wrap-around value in work array */
+ pw[ki + 1 + pw_dim1] = p[1];
- TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
- /*
- Special print for 2D spectra wave field real values in
- section 4
- */
- if ( (isec1[ 0] == 140) &&
- (isec1[ 1] == 98) &&
- (isec1[23] == 1) &&
- ((isec1[39] == 1045) || (isec1[39] == 1081)) &&
- ((isec1[ 5] == 250) || (isec1[ 5] == 251)) )
- gribPrintSec4Wave(isec4);
+ /* Set up constants to be used to figure out weighting for */
+ /* values in interpolation. */
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
}
- }
-}
-
-#endif /* T */
-
-/*
- * Local Variables:
- * mode: c
- * End:
- */
-
-/* GRIB block 0 - indicator block */
-static
-void encodeIS(GRIBPACK *lGrib, long *gribLen)
-{
- long z;
- // z = *gribLen;
-
- lGrib[0] = 'G';
- lGrib[1] = 'R';
- lGrib[2] = 'I';
- lGrib[3] = 'B';
-
- /*
- * lGrib[4]-lGrib[6] contains full length of grib record.
- * included before finished CODEGB
- */
+ else
+ {
+ /* Repeat last value, to cope with "implicit truncation" below */
+ pw[ki + 1 + pw_dim1] = p[ki];
- z = 7;
- Put1Byte(1); /* grib version */
- z = 8;
+ /* Set up constants to be used to figure out weighting for */
+ /* values in interpolation. */
+ zrdi = (double) (ki-1);
+ zdo = 1.0 / (double) (ko-1);
+ }
- *gribLen = z;
-}
+ /* Loop through the output points */
+ for ( jl = 1; jl <= ko; ++jl )
+ {
-/* GRIB block 5 - end block */
-static
-void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
-{
- long z = *gribLen;
+ /* Calculate weight from the start of row */
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
- lGrib[z++] = '7';
- lGrib[z++] = '7';
- lGrib[z++] = '7';
- lGrib[z++] = '7';
+ /* Get the current array position(minus 1) from the weight - */
+ /* note the implicit truncation. */
+ ip = (int) zwt;
+
+ /* Adjust the weight to range (0.0 to 1.0) */
+ zwt -= ip;
- if ( z > JP23SET )
+ /* If 'nearest neighbour' processing must be used */
+ if ( oveggy )
+ {
+ if ( zwt < 0.5 )
+ p[jl] = pw[ip + 1 + pw_dim1];
+ else
+ p[jl] = pw[ip + 2 + pw_dim1];
+ }
+ else
+ {
+ /* If the left value is missing, use the right value */
+ if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 2 + pw_dim1];
+ }
+ /* If the right value is missing, use the left value */
+ else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+ {
+ p[jl] = pw[ip + 1 + pw_dim1];
+ }
+ /* If neither missing, interpolate ... */
+ else
+ {
+ /* Interpolate using the weighted values on either side */
+ /* of the output point position */
+ p[jl] = (T)((1.0 - zwt) * pw[ip+1 + pw_dim1]
+ + zwt * pw[ip+2 + pw_dim1]);
+ }
+ }
+ }
+ }
+ else if ( kcode == 3 )
{
- long itemp;
- long bdslen = z - 4;
- /*
- fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET);
- exit(1);
- */
- /*
- If a very large product, the section 4 length field holds
- the number of bytes in the product after section 4 upto
- the end of the padding bytes.
- This is a fixup to get round the restriction on product lengths
- due to the count being only 24 bits. It is only possible because
- the (default) rounding for GRIB products is 120 bytes.
- */
- while ( z%120 ) lGrib[z++] = 0;
-
- if ( z > JP23SET*120 )
+ /* ******************************* */
+ /* Section 2. Cubic interpolation .. */
+ /* ******************************* */
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
{
- fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET*120);
- exit(1);
+ if ( IS_EQUAL(p[jl], msval) )
+ {
+ fprintf(stderr," ROWINA3: ");
+ fprintf(stderr," Cubic interpolation not supported");
+ fprintf(stderr," for fields containing missing data.\n");
+ *kret = 1;
+ goto L900;
+ }
+ pw[jl + pw_dim1] = p[jl];
+ }
+ pw[pw_dim1] = p[ki];
+ pw[ki + 1 + pw_dim1] = p[1];
+ pw[ki + 2 + pw_dim1] = p[2];
+ i_1 = ki;
+ for ( jl = 1; jl <= i_1; ++jl )
+ {
+ pw[jl + (pw_dim1 << 1)] =
+ (T)(- pw[jl - 1 + pw_dim1] / 3.0 -
+ pw[jl + pw_dim1] * 0.5 +
+ pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0);
+ pw[jl + 1 + pw_dim1 * 3] =
+ (T)(pw[jl - 1 + pw_dim1] / 6.0 -
+ pw[jl + pw_dim1] +
+ pw[jl + 1 + pw_dim1] * 0.5 +
+ pw[jl + 2 + pw_dim1] / 3.0);
}
- itemp = z / (-120);
- itemp = JP23SET - itemp + 1;
+ TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+ &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
- lGrib[4] = (GRIBPACK)(itemp >> 16);
- lGrib[5] = (GRIBPACK)(itemp >> 8);
- lGrib[6] = (GRIBPACK)itemp;
+ zrdi = (double) ki;
+ zdo = 1.0 / (double) ko;
+ for ( jl = 1; jl <= ko; ++jl )
+ {
+ zpos = (jl - 1) * zdo;
+ zwt = zpos * zrdi;
+ ip = (int) zwt + 1;
+ zwt = zwt + 1.0 - ip;
+ zwt1 = 1.0 - zwt;
+ p[jl] = (T)(((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+ zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+ ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+ zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt);
+ }
- bdslen = z - bdslen;
- lGrib[bdsstart ] = (GRIBPACK)(bdslen >> 16);
- lGrib[bdsstart+1] = (GRIBPACK)(bdslen >> 8);
- lGrib[bdsstart+2] = (GRIBPACK)bdslen;
}
else
{
- lGrib[4] = (GRIBPACK)(z >> 16);
- lGrib[5] = (GRIBPACK)(z >> 8);
- lGrib[6] = (GRIBPACK)z;
-
- while ( z%8 ) lGrib[z++] = 0;
+ /* ************************************** */
+ /* Section 3. Invalid interpolation code .. */
+ /* ************************************** */
+ fprintf(stderr," ROWINA3:");
+ fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+ *kret = 2;
}
- *gribLen = z;
-}
-
-/* GRIB block 1 - product definition block. */
+L900:
+ return 0;
+} /* rowina3 */
-#define DWD_extension_253_len 38
-#define DWD_extension_254_len 26
-#define ECMWF_extension_1_len 24
-#define MPIM_extension_1_len 18
-static
-long getLocalExtLen(int *isec1)
+int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
+ T msval, int *kret, int omisng, int operio, int oveggy)
{
- long extlen = 0;
+ /*
+C**** QU2REG3 - Convert quasi-regular grid data to regular.
+C
+C Purpose.
+C --------
+C
+C Convert quasi-regular grid data to regular,
+C using either a linear or cubic interpolation.
+C
+C
+C** Interface.
+C ----------
+C
+C CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
+C X OVEGGY)
+C
+C
+C Input Parameters.
+C -----------------
+C
+C PFIELD - Array containing quasi-regular grid data.
+C
+C KPOINT - Array containing list of the number of
+C points on each latitude (or longitude) of
+C the quasi-regular grid.
+C
+C KLAT - Number of latitude lines
+C
+C KLON - Number of longitude lines
+C
+C KCODE - Interpolation required.
+C 1 , linear - data quasi-regular on latitude lines.
+C 3 , cubic - data quasi-regular on latitude lines.
+C 11, linear - data quasi-regular on longitude lines.
+C 13, cubic - data quasi-regular on longitude lines.
+C
+C PMSVAL - Value used for missing data indicator.
+C
+C OMISNG - True if missing values are present in field.
+C
+C OPERIO - True if input field is periodic.
+C
+C OVEGGY - True if 'nearest neighbour' processing must be used
+C for interpolation
+C
+C
+C Output Parameters.
+C ------------------
+C
+C KRET - return code
+C 0 = OK
+C non-zero indicates fatal error
+C
+C
+C Output Parameters.
+C ------------------
+C
+C PFIELD - Array containing regular grid data.
+C
+C
+C Method.
+C -------
+C
+C Data is interpolated and expanded into a temporary array,
+C which is then copied back into the user's array.
+C Returns an error code if an invalid interpolation is requested
+C or field size exceeds array dimensions.
+C
+C Comments.
+C ---------
+C
+C This routine is an adaptation of QU2REG to allow missing data
+C values, and hence bit mapped fields.
+C
+C
+C Author.
+C -------
+C
+C J.D.Chambers ECMWF 22.07.94
+C
+C
+C Modifications.
+C --------------
+C
+C J.D.Chambers ECMWF 13.09.94
+C Add return code KRET and remove calls to ABORT.
+C
+C J.D.Chambers ECMWF Feb 1997
+C Allow for 64-bit pointers
+C
+C J. Clochard, Meteo France, for ECMWF - January 1998.
+C Addition of OMISNG and OPERIO arguments.
+C Fix message for longitude number out of bounds, and routine
+C name in title and formats.
+C
+*/
+ /* System generated locals */
+ int i_1, i_2;
+ int kcode = 1;
- if ( ISEC1_LocalFLag )
- {
- if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
- {
- if ( isec1[36] == 254 ) extlen = DWD_extension_254_len;
- else if ( isec1[36] == 253 ) extlen = DWD_extension_253_len;
- }
- else if ( ISEC1_CenterID == 98 )
- {
- if ( isec1[36] == 1 ) extlen = ECMWF_extension_1_len;
- }
- else if ( ISEC1_CenterID == 252 )
- {
- if ( isec1[36] == 1 ) extlen = MPIM_extension_1_len;
- }
- }
+ /* Local variables */
+ int ilii, ilio, icode;
+ int iregno, iquano, j210, j220, j230, j240, j225;
+ T *ztemp = NULL;
+ T *zline = NULL;
+ T *zwork = NULL;
- return (extlen);
-}
+ ztemp = (T*) Malloc((size_t)klon*(size_t)klat*sizeof(T));
-static
-long getPdsLen(int *isec1)
-{
- long pdslen = 28;
+ zline = (T*) Malloc(2*(size_t)klon*sizeof(T));
- pdslen += getLocalExtLen(isec1);
+ zwork = (T*) Malloc(3*(2*(size_t)klon+3)*sizeof(T));
- return (pdslen);
-}
+ /* Parameter adjustments */
+ --pfield;
+ --kpoint;
-static
-void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
-{
- int isvn;
- long localextlen, i;
- long z = *zs;
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
- localextlen = getLocalExtLen(isec1);
- for ( i = 0; i < localextlen-2; i++ )
- {
- Put1Byte(isec1[24+i]);
- }
+ *kret = 0;
- isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier */
- Put2Byte(isvn); /* DWD run type (0=main, 2=ass, 3=test) */
+/* Check input parameters. */
- *zs = z;
-}
+ if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+ fprintf(stderr," QU2REG :");
+ fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+ *kret = 1;
+ goto L900;
+ }
-static
-void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
-{
- int isvn;
- long localextlen, i;
- long z = *zs;
+/* Set array indices to 0. */
- localextlen = DWD_extension_254_len;
- for ( i = 0; i < localextlen-2; i++ )
- {
- Put1Byte(isec1[24+i]);
- }
+ ilii = 0;
+ ilio = 0;
- isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier */
- Put2Byte(isvn); /* DWD run type (0=main, 2=ass, 3=test) */
- Put1Byte(isec1[50]); /* 55 User id, specified by table */
- Put2Byte(isec1[51]); /* 56 Experiment identifier */
- Put2Byte(isec1[52]); /* 58 Ensemble identification by table */
- Put2Byte(isec1[53]); /* 60 Number of ensemble members */
- Put2Byte(isec1[54]); /* 62 Actual number of ensemble member */
- Put1Byte(isec1[55]); /* 64 Model major version number */
- Put1Byte(isec1[56]); /* 65 Model minor version number */
- Put1Byte(0); /* 66 Blank for even buffer length */
+/* Establish values of loop parameters. */
- *zs = z;
-}
+ if (kcode > 10) {
-static
-void encodePDS_ECMWF_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
-{
- // int isvn;
- long localextlen, i;
- long z = *zs;
+/* Quasi-regular along longitude lines. */
- localextlen = getLocalExtLen(isec1);
- for ( i = 0; i < localextlen-12; i++ )
- {
- Put1Byte(isec1[24+i]);
- }
- /* 12 bytes explicitly encoded below: */
- Put1Byte(isec1[36]); /* ECMWF local GRIB use definition identifier */
- /* 1=MARS labelling or ensemble fcst. data */
- Put1Byte(isec1[37]); /* Class */
- Put1Byte(isec1[38]); /* Type */
- Put2Byte(isec1[39]); /* Stream */
+ iquano = klon;
+ iregno = klat;
+ icode = kcode - 10;
+ } else {
- /* Version number or experiment identifier */
- Put1Byte(((unsigned char*) &isec1[40])[0]);
- Put1Byte(((unsigned char*) &isec1[40])[1]);
- Put1Byte(((unsigned char*) &isec1[40])[2]);
- Put1Byte(((unsigned char*) &isec1[40])[3]);
+/* Quasi-regular along latitude lines. */
- Put1Byte(isec1[41]); /* Ensemble forecast number */
- Put1Byte(isec1[42]); /* Total number of forecasts in ensemble */
- Put1Byte(0); /* (Spare) */
+ iquano = klat;
+ iregno = klon;
+ icode = kcode;
+ }
- *zs = z;
-}
+/* -------------------------------------------------------- */
+/** Section 2. Interpolate field from quasi to regular grid. */
+/* -------------------------------------------------------- */
-static
-void encodePDS_MPIM_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
-{
- // int isvn;
- long localextlen, i;
- long z = *zs;
+ i_1 = iquano;
+ for (j230 = 1; j230 <= i_1; ++j230) {
- localextlen = getLocalExtLen(isec1);
- for ( i = 0; i < localextlen-6; i++ )
- {
- Put1Byte(isec1[24+i]);
- }
- /* 6 bytes explicitly encoded below: */
- Put1Byte(isec1[36]); /* MPIM local GRIB use definition identifier */
- /* (extension identifier) */
- Put1Byte(isec1[37]); /* type of ensemble forecast */
- Put2Byte(isec1[38]); /* individual ensemble member */
- Put2Byte(isec1[39]); /* number of forecasts in ensemble */
+ if (iregno != kpoint[j230]) {
- *zs = z;
-}
+/* Line contains less values than required,so */
+/* extract quasi-regular grid values for a line */
-/* GRIB BLOCK 1 - PRODUCT DESCRIPTION SECTION */
-static
-void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
-{
- GRIBPACK *lGrib = lpds;
- long z = 0;
- int ival, century, year;
+ i_2 = kpoint[j230];
+ for (j210 = 1; j210 <= i_2; ++j210) {
+ ++ilii;
+ zline[j210 - 1] = pfield[ilii];
+ }
- century = ISEC1_Century;
- year = ISEC1_Year;
+/* and interpolate this line. */
- if ( century < 0 )
- {
- century = -century;
- year = -year;
- }
+ TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
+ if (*kret != 0) goto L900;
- Put3Byte(pdsLen); /* 0 Length of Block 1 */
- Put1Byte(ISEC1_CodeTable); /* 3 Local table number */
- Put1Byte(ISEC1_CenterID); /* 4 Identification of centre */
- Put1Byte(ISEC1_ModelID); /* 5 Identification of model */
- Put1Byte(ISEC1_GridDefinition); /* 6 Grid definition */
- Put1Byte(ISEC1_Sec2Or3Flag); /* 7 Block 2 included */
- Put1Byte(ISEC1_Parameter); /* 8 Parameter Code */
- Put1Byte(ISEC1_LevelType); /* 9 Type of level */
- if ( (ISEC1_LevelType != 20) &&
- (ISEC1_LevelType != GRIB1_LTYPE_99) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE) &&
- (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT) &&
- (ISEC1_LevelType != GRIB1_LTYPE_SIGMA) &&
- (ISEC1_LevelType != GRIB1_LTYPE_HYBRID) &&
- (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) &&
- (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
- (ISEC1_LevelType != 115) &&
- (ISEC1_LevelType != 117) &&
- (ISEC1_LevelType != 125) &&
- (ISEC1_LevelType != 127) &&
- (ISEC1_LevelType != 160) &&
- (ISEC1_LevelType != 210) )
- {
- Put1Byte(ISEC1_Level1);
- Put1Byte(ISEC1_Level2);
- }
- else
- {
- Put2Byte(ISEC1_Level1); /* 10 Level */
- }
+/* Add regular grid values for this line to the
+ temporary array. */
- Put1Int(year); /* 12 Year of Century */
- Put1Byte(ISEC1_Month); /* 13 Month */
- Put1Byte(ISEC1_Day); /* 14 Day */
- Put1Byte(ISEC1_Hour); /* 15 Hour */
- Put1Byte(ISEC1_Minute); /* 16 Minute */
+ i_2 = iregno;
+ for (j220 = 1; j220 <= i_2; ++j220) {
+ ++ilio;
+ ztemp[ilio - 1] = zline[j220 - 1];
+ }
- Put1Byte(ISEC1_TimeUnit); /* 17 Time unit */
- if ( ISEC1_TimeRange == 10 )
- {
- Put1Byte(ISEC1_TimePeriod1);
- Put1Byte(ISEC1_TimePeriod2);
- }
- else if ( ISEC1_TimeRange == 113 || ISEC1_TimeRange == 0 )
- {
- Put1Byte(ISEC1_TimePeriod1);
- Put1Byte(0);
- }
- else if ( ISEC1_TimeRange == 5 || ISEC1_TimeRange == 4 ||
- ISEC1_TimeRange == 3 || ISEC1_TimeRange == 2 )
- {
- Put1Byte(0);
- Put1Byte(ISEC1_TimePeriod2);
- }
- else
- {
- Put1Byte(0);
- Put1Byte(0);
- }
- Put1Byte(ISEC1_TimeRange); /* 20 Timerange flag */
- Put2Byte(ISEC1_AvgNum); /* 21 Average */
+ } else {
- Put1Byte(ISEC1_AvgMiss); /* 23 Missing from averages */
- Put1Byte(century); /* 24 Century */
- Put1Byte(ISEC1_SubCenterID); /* 25 Subcenter */
- Put2Byte(ISEC1_DecScaleFactor); /* 26 Decimal scale factor */
+/* Line contains the required number of values, so add */
+/* this line to the temporary array. */
- if ( ISEC1_LocalFLag )
- {
- if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
- {
- if ( isec1[36] == 254 ) encodePDS_DWD_local_Extension_254(lGrib, &z, isec1);
- else if ( isec1[36] == 253 ) encodePDS_DWD_local_Extension_253(lGrib, &z, isec1);
- }
- else if ( ISEC1_CenterID == 98 )
- {
- if ( isec1[36] == 1 ) encodePDS_ECMWF_local_Extension_1(lGrib, &z, isec1);
- }
- else if ( ISEC1_CenterID == 252 )
- {
- if ( isec1[36] == 1 ) encodePDS_MPIM_local_Extension_1(lGrib, &z, isec1);
- }
- else
- {
- long i, localextlen;
- localextlen = getLocalExtLen(isec1);
- for ( i = 0; i < localextlen; i++ )
- {
- Put1Byte(isec1[24+i]);
- }
- }
- }
-}
+ i_2 = iregno;
+ for (j225 = 1; j225 <= i_2; ++j225) {
+ ++ilio;
+ ++ilii;
+ ztemp[ilio - 1] = pfield[ilii];
+ }
+ }
+ }
+/* Copy temporary array to user array. */
+ i_1 = klon * klat;
+ for (j240 = 1; j240 <= i_1; ++j240) {
+ pfield[j240] = ztemp[j240 - 1];
+ }
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
+L900:
+ Free(zwork);
+ Free(zline);
+ Free(ztemp);
-static
-void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
- const T *data, T zref, T factor, size_t *gz)
+ return 0;
+} /* qu2reg3 */
+
+#endif /* T */
+
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+#include <string.h>
+
+
+
+int gribVersion(unsigned char *is, size_t buffersize)
{
- size_t i, z = *gz;
- unsigned int ival;
- int cbits, jbits;
- unsigned int c;
- static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-
- /* code from gribw routine flist2bitstream */
+ if ( buffersize < 8 )
+ Error("Buffer too small (current size %d)!", (int) buffersize);
- cbits = 8;
- c = 0;
- for ( i = packStart; i < datasize; i++ )
- {
- /* note float -> unsigned int .. truncate */
- ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
- /*
- if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
- if ( ival < 0 ) ival = 0;
- */
- jbits = numBits;
- while ( cbits <= jbits )
- {
- if ( cbits == 8 )
- {
- jbits -= 8;
- lGrib[z++] = (ival >> jbits) & 0xFF;
- }
- else
- {
- jbits -= cbits;
- lGrib[z++] = (GRIBPACK)((c << cbits) + ((ival >> jbits) & mask[cbits]));
- cbits = 8;
- c = 0;
- }
- }
- /* now jbits < cbits */
- if ( jbits )
- {
- c = (c << jbits) + (ival & mask[jbits]);
- cbits -= jbits;
- }
- }
- if ( cbits != 8 ) lGrib[z++] = (GRIBPACK)(c << cbits);
+ return GRIB_EDITION(is);
+}
+
+static
+double GET_Real(unsigned char *grib)
+{
+ int iexp = GET_UINT1(grib[0]);
+ int imant = GET_UINT3(grib[1], grib[2], grib[3]);
- *gz = z;
+ return decfp2(iexp, imant);
}
-
-static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
- const T *restrict data, T zref, T factor, size_t *gz)
+static
+int decodeIS(unsigned char *is, int *isec0, int *iret)
{
- U_BYTEORDER;
- uint16_t *restrict sgrib = (uint16_t *) (lGrib+*gz);
+ // Octets 1 - 4 : The letters G R I B. Four 8 bit fields.
- if ( IS_BIGENDIAN() )
+ // Check letters -> GRIB, BUDG or TIDE.
+
+ // Check that 'GRIB' is found where expected.
+ bool lgrib = GRIB_START(is);
+
+ // ECMWF pseudo-grib data uses 'BUDG' and 'TIDE'.
+ bool lbudg = BUDG_START(is);
+ bool ltide = TIDE_START(is);
+
+ // Data is not GRIB or pseudo-grib.
+ if ( lgrib == false && lbudg == false && ltide == false )
{
- for ( size_t i = 0; i < datasize; i++ )
- {
- sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
- }
+ *iret = 305;
+ gprintf(__func__, "Input data is not GRIB or pseudo-grib.");
+ gprintf(__func__, "Return code = %d", *iret);
}
- else
+ if ( lbudg || ltide )
{
- uint16_t ui16;
- for ( size_t i = 0; i < datasize; i++ )
- {
- ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
- sgrib[i] = gribSwapByteOrder_uint16(ui16);
- }
+ *iret = 305;
+ gprintf(__func__, "Pseudo-grib data unsupported.");
+ gprintf(__func__, "Return code = %d", *iret);
}
- *gz += 2*datasize;
-}
-/*
-static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
- const T *restrict data, T zref, T factor, size_t *gz)
-{
- size_t i, z = *gz;
- uint16_t ui16;
- T tmp;
+ // Octets 5 - 7 : Length of message. One 24 bit field.
+ ISEC0_GRIB_Len = GRIB1_SECLEN(is);
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui16 = (uint16_t) tmp;
- lGrib[z ] = ui16 >> 8;
- lGrib[z+1] = ui16;
- z += 2;
- }
+ // Octet 8 : GRIB Edition Number. One 8 bit field.
+ ISEC0_GRIB_Version = GRIB_EDITION(is);
- *gz = z;
+ if ( ISEC0_GRIB_Version > 1 )
+ Error("GRIB version %d unsupported!", ISEC0_GRIB_Version);
+
+ int grib1offset = ISEC0_GRIB_Version * 4;
+
+ int isLen = 4 + grib1offset;
+
+ return isLen;
}
-*/
-static
-void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
- GRIBPACK *restrict lGrib,
- const T *restrict data,
- T zref, T factor, size_t *gz)
-{
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
- uint64_t start_minmax, end_minmax;
-#endif
- uint32_t ui32;
- size_t i, z = *gz;
- T tmp;
- data += packStart;
- datasize -= packStart;
+static
+void decodePDS_ECMWF_local_Extension_1(unsigned char *pds, int *isec1)
+{
+ isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+ isec1[37] = GET_UINT1(pds[41]); /* Class */
+ isec1[38] = GET_UINT1(pds[42]); /* Type */
+ isec1[39] = GET_UINT2(pds[43],pds[44]); /* Stream */
+ /* isec1[40] = GET_UINT4(pds[45],pds[46],pds[47],pds[48]); */
+ memcpy((char*) &isec1[40], &pds[45], 4);
+ isec1[41] = GET_UINT1(pds[49]); /* Forecast number */
+ isec1[42] = GET_UINT1(pds[50]); /* Total number of forecasts */
+}
- if ( numBits == 8 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(2, "pack 8 bit base");
-#endif
+static
+void decodePDS_DWD_local_Extension_254(unsigned char *pds, int *isec1)
+{
+ isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+ for ( int i = 0; i < 11; i++ )
+ isec1[37+i] = GET_UINT1(pds[41+i]);
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- lGrib[z ] = (GRIBPACK)tmp;
- z++;
- }
+ int isvn = GET_UINT2(pds[52],pds[53]);
+
+ isec1[48] = isvn % 0x8000; /* DWD experiment identifier */
+ isec1[49] = isvn >> 15; /* DWD run type (0=main, 2=ass, 3=test) */
+}
-#ifdef _GET_IBM_COUNTER
- hpmStop(2);
-#endif
- }
- else if ( numBits == 16 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(3, "pack 16 bit base");
-#elif defined _GET_X86_COUNTER
- start_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER
- start_minmax = mach_absolute_time();
-#endif
- if ( sizeof(T) == sizeof(double) )
- {
- grib_encode_array_2byte_double(datasize, lGrib, (const double *) data, zref, factor, &z);
- }
- else
- {
- TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
- }
+static
+void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
+{
+ isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+ for ( int i = 0; i < 11; i++ )
+ isec1[37+i] = GET_UINT1(pds[41+i]);
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER
- end_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER
- end_minmax = mach_absolute_time();
-#endif
-#if defined _ENABLE_AVX
- printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#elif defined _ENABLE_SSE4_1
- printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#else
- printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#endif
-#endif
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(3);
-#endif
- }
- else if ( numBits == 24 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(4, "pack 24 bit base");
-#endif
+ int isvn = GET_UINT2(pds[52],pds[53]);
+
+ isec1[48] = isvn % 0x8000; /* DWD experiment identifier */
+ isec1[49] = isvn >> 15; /* DWD run type (0=main, 2=ass, 3=test) */
+ isec1[50] = GET_UINT1(pds[54]); /* User id, specified by table */
+ isec1[51] = GET_UINT2(pds[55],pds[56]); /* Experiment identifier */
+ isec1[52] = GET_UINT2(pds[57],pds[58]); /* Ensemble identification by table */
+ isec1[53] = GET_UINT2(pds[59],pds[60]); /* Number of ensemble members */
+ isec1[54] = GET_UINT2(pds[61],pds[62]); /* Actual number of ensemble member */
+ isec1[55] = GET_UINT1(pds[63]); /* Model major version number */
+ isec1[56] = GET_UINT1(pds[64]); /* Model minor version number */
+}
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui32 = (uint32_t) tmp;
- lGrib[z ] = (GRIBPACK)(ui32 >> 16);
- lGrib[z+1] = (GRIBPACK)(ui32 >> 8);
- lGrib[z+2] = (GRIBPACK)ui32;
- z += 3;
- }
+static
+void decodePDS_MPIM_local_Extension_1(unsigned char *pds, int *isec1)
+{
+ isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+ isec1[37] = GET_UINT1(pds[41]); /* type of ensemble forecast */
+ isec1[38] = GET_UINT2(pds[42],pds[43]); /* individual ensemble member */
+ isec1[39] = GET_UINT2(pds[44],pds[45]); /* number of forecasts in ensemble */
+}
-#ifdef _GET_IBM_COUNTER
- hpmStop(4);
-#endif
- }
- else if ( numBits == 32 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(5, "pack 32 bit base");
-#endif
+static
+int decodePDS(unsigned char *pds, int *isec0, int *isec1)
+{
+ int pdsLen = PDS_Len;
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui32 = (uint32_t) tmp;
- lGrib[z ] = (GRIBPACK)(ui32 >> 24);
- lGrib[z+1] = (GRIBPACK)(ui32 >> 16);
- lGrib[z+2] = (GRIBPACK)(ui32 >> 8);
- lGrib[z+3] = (GRIBPACK)ui32;
- z += 4;
- }
+ ISEC1_CodeTable = PDS_CodeTable;
+ ISEC1_CenterID = PDS_CenterID;
+ ISEC1_ModelID = PDS_ModelID;
+ ISEC1_GridDefinition = PDS_GridDefinition;
+ ISEC1_Sec2Or3Flag = PDS_Sec2Or3Flag;
+ ISEC1_Parameter = PDS_Parameter;
+ ISEC1_LevelType = PDS_LevelType;
-#ifdef _GET_IBM_COUNTER
- hpmStop(5);
-#endif
- }
- else if ( numBits > 0 && numBits <= 32 )
- {
- TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
- }
- else if ( numBits == 0 )
+ if ( (ISEC1_LevelType != 20) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_99) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC_PA) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_SIGMA) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_HYBRID) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
+ (ISEC1_LevelType != 115) &&
+ (ISEC1_LevelType != 117) &&
+ (ISEC1_LevelType != 125) &&
+ (ISEC1_LevelType != 127) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_SEADEPTH) &&
+ (ISEC1_LevelType != 210) )
{
+ ISEC1_Level1 = PDS_Level1;
+ ISEC1_Level2 = PDS_Level2;
}
else
{
- Error("Unimplemented packing factor %d!", numBits);
+ ISEC1_Level1 = PDS_Level;
+ ISEC1_Level2 = 0;
}
- *gz = z;
-}
-
-static
-void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize,
- GRIBPACK *restrict lGrib,
- const T *restrict data,
- T zref, T factor, size_t *gz)
-{
- U_BYTEORDER;
- size_t i, j, z = *gz;
-#ifdef _ARCH_PWR6
-#define __UNROLL_DEPTH_2 8
-#else
-#define __UNROLL_DEPTH_2 128
-#endif
- size_t residual;
- size_t ofs;
- T dval[__UNROLL_DEPTH_2];
-
- data += packStart;
- datasize -= packStart;
- residual = datasize % __UNROLL_DEPTH_2;
- ofs = datasize - residual;
-
- // reducing FP operations to single FMA is slowing down on pwr6 ...
+ /* ISEC1_Year = PDS_Year; */
+ ISEC1_Month = PDS_Month;
+ ISEC1_Day = PDS_Day;
+ ISEC1_Hour = PDS_Hour;
+ ISEC1_Minute = PDS_Minute;
+ ISEC1_TimeUnit = PDS_TimeUnit;
+ ISEC1_TimePeriod1 = PDS_TimePeriod1;
+ ISEC1_TimePeriod2 = PDS_TimePeriod2;
+ ISEC1_TimeRange = PDS_TimeRange;
+ ISEC1_AvgNum = PDS_AvgNum;
+ ISEC1_AvgMiss = PDS_AvgMiss;
- if ( numBits == 8 )
+ if ( ISEC0_GRIB_Version == 1 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(2, "pack 8 bit unrolled");
-#endif
- unsigned char *cgrib = (unsigned char *) (lGrib + z);
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *cgrib++ = (unsigned long) dval[j];
-#else
- *cgrib++ = (unsigned char) dval[j];
-#endif
- }
- z += __UNROLL_DEPTH_2;
- }
- for (j = 0; j < residual; j++)
- {
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < residual; j++)
- {
-#ifdef _ARCH_PWR6
- *cgrib++ = (unsigned long) dval[j];
-#else
- *cgrib++ = (unsigned char) dval[j];
-#endif
- }
- z += residual;
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(2);
-#endif
+ ISEC1_Year = PDS_Year;
+ ISEC1_Century = PDS_Century;
+ ISEC1_SubCenterID = PDS_Subcenter;
+ ISEC1_DecScaleFactor = PDS_DecimalScale;
}
- else if ( numBits == 16 )
+ else
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(3, "pack 16 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint16_t ival;
-#endif
- uint16_t *sgrib = (uint16_t *) (lGrib+z);
-
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *sgrib++ = (unsigned long) dval[j];
-#else
- *sgrib++ = (uint16_t) dval[j];
-#endif
- }
- z += 2*__UNROLL_DEPTH_2;
- }
- else
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- ival = (uint16_t) dval[j];
- *sgrib++ = gribSwapByteOrder_uint16(ival);
- }
- z += 2*__UNROLL_DEPTH_2;
- }
- }
- for (j = 0; j < residual; j++)
- {
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
+ int year = GET_UINT1(pds[12]);
+ if ( year <= 100 )
{
- for (j = 0; j < residual; j++)
- {
-#ifdef _ARCH_PWR6
- *sgrib++ = (unsigned long) dval[j];
-#else
- *sgrib++ = (uint16_t) dval[j];
-#endif
- }
- z += 2*residual;
+ ISEC1_Year = year;
+ ISEC1_Century = 1;
}
else
{
- for (j = 0; j < residual; j++)
- {
- ival = (uint16_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 8);
- lGrib[z+1] = (GRIBPACK)ival;
- z += 2;
- }
+ ISEC1_Year = year%100;
+ ISEC1_Century = 1 + (year-ISEC1_Year)/100;
}
-#ifdef _GET_IBM_COUNTER
- hpmStop(3);
-#endif
+ ISEC1_SubCenterID = 0;
+ ISEC1_DecScaleFactor = 0;
}
- else if ( numBits == 24 )
+
+ if ( ISEC1_Year < 0 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(4, "pack 24 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint32_t ival;
-#endif
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- ival = (unsigned long) dval[j];
-#else
- ival = (uint32_t) dval[j];
-#endif
- lGrib[z ] = (GRIBPACK)(ival >> 16);
- lGrib[z+1] = (GRIBPACK)(ival >> 8);
- lGrib[z+2] = (GRIBPACK)ival;
- z += 3;
- }
- }
- for (j = 0; j < residual; j++)
+ ISEC1_Year = -ISEC1_Year;
+ ISEC1_Century = -ISEC1_Century;
+ }
+
+ ISEC1_LocalFLag = 0;
+ if ( pdsLen > 28 )
+ {
+ int localextlen = pdsLen-28;
+
+ if ( localextlen > 4000 )
{
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ Warning("PDS larger than 4000 bytes not supported!");
}
- for (j = 0; j < residual; j++)
+ else
{
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 16);
- lGrib[z+1] = (GRIBPACK)(ival >> 8);
- lGrib[z+2] = (GRIBPACK)ival;
- z += 3;
- }
-#ifdef _GET_IBM_COUNTER
- hpmStop(4);
-#endif
- }
- else if ( numBits == 32 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(5, "pack 32 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint32_t ival;
-#endif
- unsigned int *igrib = (unsigned int *) (lGrib + z);
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
+ ISEC1_LocalFLag = 1;
+
+ if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
{
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *igrib = (unsigned long) dval[j];
-#else
- *igrib = (uint32_t) dval[j];
-#endif
- igrib++;
- z += 4;
- }
+ if ( pds[40] == 254 )
+ decodePDS_DWD_local_Extension_254(pds, isec1);
+ else if ( pds[40] == 253 )
+ decodePDS_DWD_local_Extension_253(pds, isec1);
}
- else
+ else if ( (ISEC1_CenterID == 98 && ISEC1_LocalFLag == 1) ||
+ (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag == 1) ||
+ (ISEC1_CenterID == 7 && ISEC1_SubCenterID == 98) )
{
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 24);
- lGrib[z+1] = (GRIBPACK)(ival >> 16);
- lGrib[z+2] = (GRIBPACK)(ival >> 8);
- lGrib[z+3] = (GRIBPACK)ival;
- z += 4;
- }
+ if ( pds[40] == 1 )
+ decodePDS_ECMWF_local_Extension_1(pds, isec1);
}
- }
- for (j = 0; j < residual; j++)
- {
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
- {
- for (j = 0; j < residual; j++)
+ else if ( ISEC1_CenterID == 252 && ISEC1_LocalFLag == 1 )
{
-#ifdef _ARCH_PWR6
- *igrib = (unsigned long) dval[j];
-#else
- *igrib = (uint32_t) dval[j];
-#endif
- igrib++;
- z += 4;
+ if ( pds[40] == 1 )
+ decodePDS_MPIM_local_Extension_1(pds, isec1);
}
- }
- else
- {
- for (j = 0; j < residual; j++)
+ else
{
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 24);
- lGrib[z+1] = (GRIBPACK)(ival >> 16);
- lGrib[z+2] = (GRIBPACK)(ival >> 8);
- lGrib[z+3] = (GRIBPACK)ival;
- z += 4;
+ for ( int i = 0; i < localextlen; i++ )
+ isec1[24+i] = pds[28+i];
}
}
-#ifdef _GET_IBM_COUNTER
- hpmStop(5);
-#endif
- }
- else if ( numBits > 0 && numBits <= 32 )
- {
- TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
- }
- else if ( numBits == 0 )
- {
- }
- else
- {
- Error("Unimplemented packing factor %d!", numBits);
}
- *gz = z;
-#undef __UNROLL_DEPTH_2
+ return pdsLen;
}
-#endif /* T */
-/*
- * Local Variables:
- * mode: c
- * End:
- */
+void gribPrintSec2_double(int *isec0, int *isec2, double *fsec2) {gribPrintSec2DP(isec0, isec2, fsec2);}
+void gribPrintSec3_double(int *isec0, int *isec3, double *fsec3) {gribPrintSec3DP(isec0, isec3, fsec3);}
+void gribPrintSec4_double(int *isec0, int *isec4, double *fsec4) {gribPrintSec4DP(isec0, isec4, fsec4);}
+void gribPrintSec2_float(int *isec0, int *isec2, float *fsec2) {gribPrintSec2SP(isec0, isec2, fsec2);}
+void gribPrintSec3_float(int *isec0, int *isec3, float *fsec3) {gribPrintSec3SP(isec0, isec3, fsec3);}
+void gribPrintSec4_float(int *isec0, int *isec4, float *fsec4) {gribPrintSec4SP(isec0, isec4, fsec4);}
+
#ifdef T
#undef T
#endif
-#define T float
+#define T double
#ifdef T
+#include <inttypes.h>
+
+static
+void TEMPLATE(decode_array_common,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
+ T fmin, T zscale, T *restrict fpdata)
+{
+ /* code from wgrib routine BDS_unpack */
+ const unsigned char *bits = igrib;
+ long i;
+ unsigned int tbits = 0;
+ int n_bits = NumBits;
+ int t_bits = 0;
+
+ unsigned jmask = (1U << n_bits) - 1U;
+ for ( i = 0; i < jlend; i++ )
+ {
+ if (n_bits - t_bits > 8)
+ {
+ tbits = (tbits << 16) | ((unsigned)bits[0] << 8) | ((unsigned)bits[1]);
+ bits += 2;
+ t_bits += 16;
+ }
+
+ while ( t_bits < n_bits )
+ {
+ tbits = (tbits * 256) + *bits++;
+ t_bits += 8;
+ }
+ t_bits -= n_bits;
+ fpdata[i] = (float)((tbits >> t_bits) & jmask);
+ }
+ /* at least this vectorizes :) */
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin + zscale*fpdata[i];
+}
static
-void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
- const T *data, T zref, T factor, size_t *gz)
+void TEMPLATE(decode_array_common2,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
+ T fmin, T zscale, T *restrict fpdata)
{
- size_t i, z = *gz;
- unsigned int ival;
- int cbits, jbits;
- unsigned int c;
- static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-
- /* code from gribw routine flist2bitstream */
+ static const unsigned mask[] = {0,1,3,7,15,31,63,127,255};
+ static const double shift[9]
+ = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
- cbits = 8;
- c = 0;
- for ( i = packStart; i < datasize; i++ )
+ /* code from wgrib routine BDS_unpack */
+ const unsigned char *bits = igrib;
+ long i;
+ int n_bits = NumBits;
+ int c_bits, j_bits;
+
+ /* older unoptimized code, not often used */
+ c_bits = 8;
+ for ( i = 0; i < jlend; i++ )
{
- /* note float -> unsigned int .. truncate */
- ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
- /*
- if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
- if ( ival < 0 ) ival = 0;
- */
- jbits = numBits;
- while ( cbits <= jbits )
+ double jj = 0.0;
+ j_bits = n_bits;
+ while (c_bits <= j_bits)
{
- if ( cbits == 8 )
+ if (c_bits == 8)
{
- jbits -= 8;
- lGrib[z++] = (ival >> jbits) & 0xFF;
+ jj = jj * 256.0 + (double) (*bits++);
+ j_bits -= 8;
}
else
{
- jbits -= cbits;
- lGrib[z++] = (GRIBPACK)((c << cbits) + ((ival >> jbits) & mask[cbits]));
- cbits = 8;
- c = 0;
+ jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+ bits++;
+ j_bits -= c_bits;
+ c_bits = 8;
}
}
- /* now jbits < cbits */
- if ( jbits )
+
+ if (j_bits)
{
- c = (c << jbits) + (ival & mask[jbits]);
- cbits -= jbits;
+ c_bits -= j_bits;
+ jj = (jj * shift[j_bits]) + (double) (((unsigned)*bits >> c_bits) & mask[j_bits]);
}
+ fpdata[i] = (T)(fmin + zscale*jj);
}
- if ( cbits != 8 ) lGrib[z++] = (GRIBPACK)(c << cbits);
-
- *gz = z;
}
-
static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
- const T *restrict data, T zref, T factor, size_t *gz)
+void TEMPLATE(decode_array_2byte,T)(size_t jlend, const unsigned char *restrict igrib,
+ T *fpdata, T fmin, T zscale)
{
U_BYTEORDER;
- uint16_t *restrict sgrib = (uint16_t *) (lGrib+*gz);
+ const uint16_t *restrict sgrib = (uint16_t *) (igrib);
if ( IS_BIGENDIAN() )
{
- for ( size_t i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < jlend; i++ )
{
- sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
+ fpdata[i] = fmin + zscale * sgrib[i];
}
}
else
{
uint16_t ui16;
- for ( size_t i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < jlend; i++ )
{
- ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
- sgrib[i] = gribSwapByteOrder_uint16(ui16);
+ ui16 = gribSwapByteOrder_uint16(sgrib[i]);
+ fpdata[i] = fmin + zscale * ui16;
}
}
-
- *gz += 2*datasize;
}
-/*
-static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
- const T *restrict data, T zref, T factor, size_t *gz)
-{
- size_t i, z = *gz;
- uint16_t ui16;
- T tmp;
-
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui16 = (uint16_t) tmp;
- lGrib[z ] = ui16 >> 8;
- lGrib[z+1] = ui16;
- z += 2;
- }
- *gz = z;
-}
-*/
-static
-void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
- GRIBPACK *restrict lGrib,
- const T *restrict data,
- T zref, T factor, size_t *gz)
+static
+void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits,
+ T fmin, T zscale, T *restrict fpdata)
{
#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
- uint64_t start_minmax, end_minmax;
+ uint64_t start_decode, end_decode;
#endif
- uint32_t ui32;
- size_t i, z = *gz;
- T tmp;
- data += packStart;
- datasize -= packStart;
+ long i;
+#if defined (VECTORCODE)
+ GRIBPACK *lgrib = NULL;
- if ( numBits == 8 )
+ if ( numBits%8 == 0 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(2, "pack 8 bit base");
-#endif
-
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
+ long jlenc = jlend * numBits / 8;
+ if ( jlenc > 0 )
{
- tmp = ((data[i] - zref) * factor + (T)0.5);
- lGrib[z ] = (GRIBPACK)tmp;
- z++;
- }
+ lgrib = (GRIBPACK*) Malloc(jlenc*sizeof(GRIBPACK));
+ if ( lgrib == NULL ) SysError("No Memory!");
-#ifdef _GET_IBM_COUNTER
- hpmStop(2);
-#endif
+ (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+ }
}
- else if ( numBits == 16 )
- {
-#ifdef _GET_IBM_COUNTER
- hpmStart(3, "pack 16 bit base");
-#elif defined _GET_X86_COUNTER
- start_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER
- start_minmax = mach_absolute_time();
-#endif
- if ( sizeof(T) == sizeof(double) )
- {
- grib_encode_array_2byte_double(datasize, lGrib, (const double *) data, zref, factor, &z);
- }
- else
- {
- TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
- }
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER
- end_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER
- end_minmax = mach_absolute_time();
-#endif
-#if defined _ENABLE_AVX
- printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#elif defined _ENABLE_SSE4_1
- printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#else
- printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#endif
-#endif
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(3);
-#endif
- }
- else if ( numBits == 24 )
+ if ( numBits == 0 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(4, "pack 24 bit base");
-#endif
-
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui32 = (uint32_t) tmp;
- lGrib[z ] = (GRIBPACK)(ui32 >> 16);
- lGrib[z+1] = (GRIBPACK)(ui32 >> 8);
- lGrib[z+2] = (GRIBPACK)ui32;
- z += 3;
- }
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(4);
-#endif
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin;
}
+ else if ( numBits == 8 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (int)lgrib[i];
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 16 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((int)lgrib[2*i ] << 8) + (int)lgrib[2*i+1]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 24 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((int)lgrib[3*i ] << 16) + ((int)lgrib[3*i+1] << 8) +
+ (int)lgrib[3*i+2]);
+ fpdata[i] = fmin + zscale * dval;
+ }
else if ( numBits == 32 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((unsigned int)lgrib[4*i ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+ ((unsigned int)lgrib[4*i+2] << 8) + (unsigned int)lgrib[4*i+3]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits <= 25 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(5, "pack 32 bit base");
-#endif
-
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
- for ( i = 0; i < datasize; i++ )
- {
- tmp = ((data[i] - zref) * factor + (T)0.5);
- ui32 = (uint32_t) tmp;
- lGrib[z ] = (GRIBPACK)(ui32 >> 24);
- lGrib[z+1] = (GRIBPACK)(ui32 >> 16);
- lGrib[z+2] = (GRIBPACK)(ui32 >> 8);
- lGrib[z+3] = (GRIBPACK)ui32;
- z += 4;
- }
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(5);
-#endif
- }
- else if ( numBits > 0 && numBits <= 32 )
- {
- TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+ TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
}
- else if ( numBits == 0 )
+ else if ( numBits > 25 && numBits < 32 )
{
+ TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
}
else
{
Error("Unimplemented packing factor %d!", numBits);
}
- *gz = z;
-}
+ if ( lgrib ) Free(lgrib);
-static
-void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize,
- GRIBPACK *restrict lGrib,
- const T *restrict data,
- T zref, T factor, size_t *gz)
-{
- U_BYTEORDER;
- size_t i, j, z = *gz;
-#ifdef _ARCH_PWR6
-#define __UNROLL_DEPTH_2 8
#else
-#define __UNROLL_DEPTH_2 128
-#endif
- size_t residual;
- size_t ofs;
- T dval[__UNROLL_DEPTH_2];
-
- data += packStart;
- datasize -= packStart;
- residual = datasize % __UNROLL_DEPTH_2;
- ofs = datasize - residual;
-
- // reducing FP operations to single FMA is slowing down on pwr6 ...
-
- if ( numBits == 8 )
+ if ( numBits == 0 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(2, "pack 8 bit unrolled");
-#endif
- unsigned char *cgrib = (unsigned char *) (lGrib + z);
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *cgrib++ = (unsigned long) dval[j];
-#else
- *cgrib++ = (unsigned char) dval[j];
-#endif
- }
- z += __UNROLL_DEPTH_2;
- }
- for (j = 0; j < residual; j++)
- {
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < residual; j++)
- {
-#ifdef _ARCH_PWR6
- *cgrib++ = (unsigned long) dval[j];
-#else
- *cgrib++ = (unsigned char) dval[j];
-#endif
- }
- z += residual;
-
-#ifdef _GET_IBM_COUNTER
- hpmStop(2);
-#endif
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin;
}
+ else if ( numBits == 8 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (int)igrib[i];
+ fpdata[i] = fmin + zscale * dval;
+ }
else if ( numBits == 16 )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(3, "pack 16 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint16_t ival;
-#endif
- uint16_t *sgrib = (uint16_t *) (lGrib+z);
-
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *sgrib++ = (unsigned long) dval[j];
-#else
- *sgrib++ = (uint16_t) dval[j];
-#endif
- }
- z += 2*__UNROLL_DEPTH_2;
- }
- else
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- ival = (uint16_t) dval[j];
- *sgrib++ = gribSwapByteOrder_uint16(ival);
- }
- z += 2*__UNROLL_DEPTH_2;
- }
- }
- for (j = 0; j < residual; j++)
- {
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
- {
- for (j = 0; j < residual; j++)
- {
-#ifdef _ARCH_PWR6
- *sgrib++ = (unsigned long) dval[j];
-#else
- *sgrib++ = (uint16_t) dval[j];
-#endif
- }
- z += 2*residual;
- }
- else
- {
- for (j = 0; j < residual; j++)
- {
- ival = (uint16_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 8);
- lGrib[z+1] = (GRIBPACK)ival;
- z += 2;
- }
- }
-#ifdef _GET_IBM_COUNTER
- hpmStop(3);
-#endif
+ TEMPLATE(decode_array_2byte,T)((size_t) jlend, igrib, fpdata, fmin, zscale);
}
else if ( numBits == 24 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (T)(((int)igrib[3*i ] << 16) + ((int)igrib[3*i+1] << 8) +
+ (int)igrib[3*i+2]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 32 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (T)(((unsigned int)igrib[4*i ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+ ((unsigned int)igrib[4*i+2] << 8) + (unsigned int)igrib[4*i+3]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits <= 25 )
+ {
+ TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ }
+ else if ( numBits > 25 && numBits < 32 )
+ {
+ TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ }
+ else
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(4, "pack 24 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint32_t ival;
+ Error("Unimplemented packing factor %d!", numBits);
+ }
#endif
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- ival = (unsigned long) dval[j];
-#else
- ival = (uint32_t) dval[j];
+}
+
+#endif /* T */
+
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#ifdef T
+#undef T
#endif
- lGrib[z ] = (GRIBPACK)(ival >> 16);
- lGrib[z+1] = (GRIBPACK)(ival >> 8);
- lGrib[z+2] = (GRIBPACK)ival;
- z += 3;
- }
- }
- for (j = 0; j < residual; j++)
+#define T float
+#ifdef T
+
+#include <inttypes.h>
+
+static
+void TEMPLATE(decode_array_common,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
+ T fmin, T zscale, T *restrict fpdata)
+{
+ /* code from wgrib routine BDS_unpack */
+ const unsigned char *bits = igrib;
+ long i;
+ unsigned int tbits = 0;
+ int n_bits = NumBits;
+ int t_bits = 0;
+
+ unsigned jmask = (1U << n_bits) - 1U;
+ for ( i = 0; i < jlend; i++ )
+ {
+ if (n_bits - t_bits > 8)
{
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ tbits = (tbits << 16) | ((unsigned)bits[0] << 8) | ((unsigned)bits[1]);
+ bits += 2;
+ t_bits += 16;
}
- for (j = 0; j < residual; j++)
+
+ while ( t_bits < n_bits )
{
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 16);
- lGrib[z+1] = (GRIBPACK)(ival >> 8);
- lGrib[z+2] = (GRIBPACK)ival;
- z += 3;
+ tbits = (tbits * 256) + *bits++;
+ t_bits += 8;
}
-#ifdef _GET_IBM_COUNTER
- hpmStop(4);
-#endif
+ t_bits -= n_bits;
+ fpdata[i] = (float)((tbits >> t_bits) & jmask);
}
- else if ( numBits == 32 )
+ /* at least this vectorizes :) */
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin + zscale*fpdata[i];
+}
+
+static
+void TEMPLATE(decode_array_common2,T)(const unsigned char *restrict igrib, long jlend, int NumBits,
+ T fmin, T zscale, T *restrict fpdata)
+{
+ static const unsigned mask[] = {0,1,3,7,15,31,63,127,255};
+ static const double shift[9]
+ = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+
+ /* code from wgrib routine BDS_unpack */
+ const unsigned char *bits = igrib;
+ long i;
+ int n_bits = NumBits;
+ int c_bits, j_bits;
+
+ /* older unoptimized code, not often used */
+ c_bits = 8;
+ for ( i = 0; i < jlend; i++ )
{
-#ifdef _GET_IBM_COUNTER
- hpmStart(5, "pack 32 bit unrolled");
-#endif
-#ifdef _ARCH_PWR6
- unsigned long ival;
-#else
- uint32_t ival;
-#endif
- unsigned int *igrib = (unsigned int *) (lGrib + z);
- for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 )
- {
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
- }
- if ( IS_BIGENDIAN() )
+ double jj = 0.0;
+ j_bits = n_bits;
+ while (c_bits <= j_bits)
+ {
+ if (c_bits == 8)
{
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
-#ifdef _ARCH_PWR6
- *igrib = (unsigned long) dval[j];
-#else
- *igrib = (uint32_t) dval[j];
-#endif
- igrib++;
- z += 4;
- }
+ jj = jj * 256.0 + (double) (*bits++);
+ j_bits -= 8;
}
else
{
- for (j = 0; j < __UNROLL_DEPTH_2; j++)
- {
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 24);
- lGrib[z+1] = (GRIBPACK)(ival >> 16);
- lGrib[z+2] = (GRIBPACK)(ival >> 8);
- lGrib[z+3] = (GRIBPACK)ival;
- z += 4;
- }
+ jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+ bits++;
+ j_bits -= c_bits;
+ c_bits = 8;
}
}
- for (j = 0; j < residual; j++)
+
+ if (j_bits)
{
- dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ c_bits -= j_bits;
+ jj = (jj * shift[j_bits]) + (double) (((unsigned)*bits >> c_bits) & mask[j_bits]);
}
- if ( IS_BIGENDIAN() )
- {
- for (j = 0; j < residual; j++)
- {
-#ifdef _ARCH_PWR6
- *igrib = (unsigned long) dval[j];
-#else
- *igrib = (uint32_t) dval[j];
+ fpdata[i] = (T)(fmin + zscale*jj);
+ }
+}
+
+static
+void TEMPLATE(decode_array_2byte,T)(size_t jlend, const unsigned char *restrict igrib,
+ T *fpdata, T fmin, T zscale)
+{
+ U_BYTEORDER;
+ const uint16_t *restrict sgrib = (uint16_t *) (igrib);
+
+ if ( IS_BIGENDIAN() )
+ {
+ for ( size_t i = 0; i < jlend; i++ )
+ {
+ fpdata[i] = fmin + zscale * sgrib[i];
+ }
+ }
+ else
+ {
+ uint16_t ui16;
+ for ( size_t i = 0; i < jlend; i++ )
+ {
+ ui16 = gribSwapByteOrder_uint16(sgrib[i]);
+ fpdata[i] = fmin + zscale * ui16;
+ }
+ }
+}
+
+static
+void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits,
+ T fmin, T zscale, T *restrict fpdata)
+{
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+ uint64_t start_decode, end_decode;
#endif
- igrib++;
- z += 4;
- }
- }
- else
+
+ long i;
+#if defined (VECTORCODE)
+ GRIBPACK *lgrib = NULL;
+
+ if ( numBits%8 == 0 )
+ {
+ long jlenc = jlend * numBits / 8;
+ if ( jlenc > 0 )
{
- for (j = 0; j < residual; j++)
- {
- ival = (uint32_t) dval[j];
- lGrib[z ] = (GRIBPACK)(ival >> 24);
- lGrib[z+1] = (GRIBPACK)(ival >> 16);
- lGrib[z+2] = (GRIBPACK)(ival >> 8);
- lGrib[z+3] = (GRIBPACK)ival;
- z += 4;
- }
+ lgrib = (GRIBPACK*) Malloc(jlenc*sizeof(GRIBPACK));
+ if ( lgrib == NULL ) SysError("No Memory!");
+
+ (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
}
-#ifdef _GET_IBM_COUNTER
- hpmStop(5);
-#endif
}
- else if ( numBits > 0 && numBits <= 32 )
+
+ if ( numBits == 0 )
{
- TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin;
}
- else if ( numBits == 0 )
+ else if ( numBits == 8 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (int)lgrib[i];
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 16 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((int)lgrib[2*i ] << 8) + (int)lgrib[2*i+1]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 24 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((int)lgrib[3*i ] << 16) + ((int)lgrib[3*i+1] << 8) +
+ (int)lgrib[3*i+2]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 32 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (((unsigned int)lgrib[4*i ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+ ((unsigned int)lgrib[4*i+2] << 8) + (unsigned int)lgrib[4*i+3]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits <= 25 )
+ {
+ TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ }
+ else if ( numBits > 25 && numBits < 32 )
{
+ TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
}
else
{
Error("Unimplemented packing factor %d!", numBits);
}
- *gz = z;
-#undef __UNROLL_DEPTH_2
+ if ( lgrib ) Free(lgrib);
+
+#else
+ if ( numBits == 0 )
+ {
+ for ( i = 0; i < jlend; i++ )
+ fpdata[i] = fmin;
+ }
+ else if ( numBits == 8 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (int)igrib[i];
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 16 )
+ {
+ TEMPLATE(decode_array_2byte,T)((size_t) jlend, igrib, fpdata, fmin, zscale);
+ }
+ else if ( numBits == 24 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (T)(((int)igrib[3*i ] << 16) + ((int)igrib[3*i+1] << 8) +
+ (int)igrib[3*i+2]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits == 32 )
+ for ( i = 0; i < jlend; i++ )
+ {
+ T dval = (T)(((unsigned int)igrib[4*i ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+ ((unsigned int)igrib[4*i+2] << 8) + (unsigned int)igrib[4*i+3]);
+ fpdata[i] = fmin + zscale * dval;
+ }
+ else if ( numBits <= 25 )
+ {
+ TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ }
+ else if ( numBits > 25 && numBits < 32 )
+ {
+ TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+ }
+ else
+ {
+ Error("Unimplemented packing factor %d!", numBits);
+ }
+#endif
}
#endif /* T */
@@ -18254,599 +15976,818 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
#define T double
#ifdef T
-/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
-static
-void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
+static
+int TEMPLATE(decodeGDS,T)(unsigned char *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
{
- long z = *gribLen;
- int exponent, mantissa;
- long i;
- int ival;
- int pvoffset = 0xFF;
- int gdslen = 32;
- unsigned lonIncr, latIncr;
+ // int imisng = 0;
+ bool ReducedGrid = false, VertCoorTab = false;
+#if defined (VECTORCODE)
+ unsigned char *igrib;
+ GRIBPACK *lgrib = NULL;
+ size_t lGribLen = 0;
+#endif
- if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
+ *numGridVals = 0;
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ) gdslen += 10;
+ memset(isec2, 0, 22*sizeof(int));
- if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
+ unsigned gdsLen = GDS_Len;
- if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
+ unsigned ipvpl = GDS_PVPL;
+ if ( ipvpl == 0 ) ipvpl = 0xFF;
- gdslen += ISEC2_NumVCP * 4;
+ if ( ipvpl != 0xFF )
+ { /* Either vct or reduced grid */
+ if ( GDS_NV != 0 )
+ { /* we have vct */
+ VertCoorTab = true;
+ unsigned ipl = 4*GDS_NV + ipvpl - 1;
+ if ( ipl < gdsLen ) ReducedGrid = true;
+ }
+ else
+ {
+ VertCoorTab = false;
+ ReducedGrid = true;
+ }
+ /* ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+ }
+
+ if ( ISEC0_GRIB_Version == 0 )
+ {
+ VertCoorTab = (gdsLen - 32) > 0;
+ }
+
+ if ( ReducedGrid )
+ {
+ unsigned locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+ unsigned jlenl = (gdsLen - locnl) >> 1;
+ if ( jlenl == GDS_NumLat )
+ {
+ *numGridVals = 0;
+ ISEC2_Reduced = true;
+ for ( unsigned i = 0; i < jlenl; i++ )
+ {
+ ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
+ *numGridVals += ISEC2_RowLon(i);
+ }
+ }
+ else
+ {
+ ReducedGrid = false;
+ }
+ }
- Put3Byte(gdslen); /* 0- 2 Length of Block 2 Byte 0 */
- Put1Byte(ISEC2_NumVCP); /* 3 NV */
- Put1Byte(pvoffset); /* 4 PV */
- Put1Byte(ISEC2_GridType); /* 5 LatLon=0 Gauss=4 Spectral=50 */
+ ISEC2_GridType = GDS_GridType;
- if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+ /*
+ Gaussian grid definition.
+ */
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
{
- Put2Byte(ISEC2_PentaJ); /* 6- 7 Pentagonal resolution J */
- Put2Byte(ISEC2_PentaK); /* 8- 9 Pentagonal resolution K */
- Put2Byte(ISEC2_PentaM); /* 10-11 Pentagonal resolution M */
- Put1Byte(ISEC2_RepType); /* 12 Representation type */
- Put1Byte(ISEC2_RepMode); /* 13 Representation mode */
- PutnZero(18); /* 14-31 reserved */
+ ISEC2_NumLat = GDS_NumLat;
+ if ( ! ReducedGrid )
+ {
+ ISEC2_NumLon = GDS_NumLon;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ }
+ ISEC2_FirstLat = GDS_FirstLat;
+ ISEC2_FirstLon = GDS_FirstLon;
+ ISEC2_ResFlag = GDS_ResFlag;
+ ISEC2_LastLat = GDS_LastLat;
+ ISEC2_LastLon = GDS_LastLon;
+ ISEC2_LonIncr = GDS_LonIncr;
+
+ ISEC2_NumPar = GDS_NumPar;
+ ISEC2_ScanFlag = GDS_ScanFlag;
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ {
+ ISEC2_LatSP = GDS_LatSP;
+ ISEC2_LonSP = GDS_LonSP;
+ FSEC2_RotAngle = (T)GDS_RotAngle;
+ }
+ /*
+ if ( Lons != Longitudes || Lats != Latitudes )
+ Error("Latitude/Longitude Conflict");
+ */
}
- else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
{
- Put2Byte(ISEC2_GME_NI2);
- Put2Byte(ISEC2_GME_NI3);
- Put3Byte(ISEC2_GME_ND);
- Put3Byte(ISEC2_GME_NI);
- Put1Byte(ISEC2_GME_AFlag);
- Put3Int(ISEC2_GME_LatPP);
- Put3Int(ISEC2_GME_LonPP);
- Put3Int(ISEC2_GME_LonMPL);
- Put1Byte(ISEC2_GME_BFlag);
- PutnZero(5);
+ // iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
+ {
+ // iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
}
else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
{
- Put2Byte(ISEC2_NumLon); /* 6- 7 Longitudes */
-
- Put2Byte(ISEC2_NumLat); /* 8- 9 Latitudes */
- Put3Int(ISEC2_FirstLat);
- Put3Int(ISEC2_FirstLon);
- Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
- Put3Int(ISEC2_Lambert_Lov); /* 17-19 */
- Put3Int(ISEC2_Lambert_dx); /* 20-22 */
- Put3Int(ISEC2_Lambert_dy); /* 23-25 */
- Put1Byte(ISEC2_Lambert_ProjFlag);/* 26 Projection flag */
- Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
- Put3Int(ISEC2_Lambert_LatS1); /* 28-30 */
- Put3Int(ISEC2_Lambert_LatS2); /* 31-33 */
- Put3Int(ISEC2_Lambert_LatSP); /* 34-36 */
- Put3Int(ISEC2_Lambert_LonSP); /* 37-39 */
- PutnZero(2); /* 34-41 */
+ ISEC2_NumLon = GDS_NumLon;
+ ISEC2_NumLat = GDS_NumLat;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ ISEC2_FirstLat = GDS_FirstLat;
+ ISEC2_FirstLon = GDS_FirstLon;
+ ISEC2_ResFlag = GDS_ResFlag;
+ ISEC2_Lambert_Lov = GDS_Lambert_Lov;
+ ISEC2_Lambert_dx = GDS_Lambert_dx;
+ ISEC2_Lambert_dy = GDS_Lambert_dy;
+ ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
+ ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
+ ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
+ ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
+ ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
+ ISEC2_ScanFlag = GDS_ScanFlag;
}
- else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
{
- int numlon;
- if ( ISEC2_Reduced )
- numlon = 0xFFFF;
- else
- numlon = ISEC2_NumLon;
+ ISEC2_PentaJ = GDS_PentaJ; /* Truncation */
+ ISEC2_PentaK = GDS_PentaK;
+ ISEC2_PentaM = GDS_PentaM;
+ ISEC2_RepType = GDS_RepType;
+ ISEC2_RepMode = GDS_RepMode;
+ *numGridVals = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
+ isec2[ 6] = 0;
+ isec2[ 7] = 0;
+ isec2[ 8] = 0;
+ isec2[ 9] = 0;
+ isec2[10] = 0;
+ // iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+ {
+ ISEC2_GME_NI2 = GDS_GME_NI2;
+ ISEC2_GME_NI3 = GDS_GME_NI3;
+ ISEC2_GME_ND = GDS_GME_ND;
+ ISEC2_GME_NI = GDS_GME_NI;
+ ISEC2_GME_AFlag = GDS_GME_AFlag;
+ ISEC2_GME_LatPP = GDS_GME_LatPP;
+ ISEC2_GME_LonPP = GDS_GME_LonPP;
+ ISEC2_GME_LonMPL = GDS_GME_LonMPL;
+ ISEC2_GME_BFlag = GDS_GME_BFlag;
+ *numGridVals = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
+ // iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+ }
+ else
+ {
+ static bool lwarn = true;
+ ISEC2_NumLon = GDS_NumLon;
+ ISEC2_NumLat = GDS_NumLat;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ if ( lwarn )
+ {
+ lwarn = false;
+ Message("GRIB gridtype %d unsupported", ISEC2_GridType);
+ }
+ }
- Put2Byte(numlon); /* 6- 7 Number of Longitudes */
+ /* vertical coordinate parameters for hybrid levels. */
+ /* get number of vertical coordinate parameters, if any. */
- Put2Byte(ISEC2_NumLat); /* 8- 9 Number of Latitudes */
- Put3Int(ISEC2_FirstLat);
- Put3Int(ISEC2_FirstLon);
- Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
- Put3Int(ISEC2_LastLat);
- Put3Int(ISEC2_LastLon);
- if ( ISEC2_ResFlag == 0 )
+ ISEC2_NumVCP = 0;
+
+ isec2[17] = 0;
+ isec2[18] = 0;
+
+ if ( VertCoorTab )
+ {
+ int locnv;
+ if ( ISEC0_GRIB_Version == 0 )
{
- lonIncr = 0xFFFF;
- latIncr = 0xFFFF;
+ locnv = 32;
+ ISEC2_NumVCP = (gdsLen - 32) >> 2;
}
else
{
- lonIncr = (unsigned)ISEC2_LonIncr;
- latIncr = (unsigned)ISEC2_LatIncr;
+ locnv = GDS_PVPL - 1;
+ ISEC2_NumVCP = GDS_NV;
}
- Put2Byte(lonIncr); /* 23-24 i - direction increment */
- if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
- Put2Byte(ISEC2_NumPar); /* 25-26 Latitudes Pole->Equator */
- else
- Put2Byte(latIncr); /* 25-26 j - direction increment */
-
- Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
- PutnZero(4); /* 28-31 reserved */
+#if defined (SX)
+ lGribLen = 4*ISEC2_NumVCP;
+ lgrib = (GRIBPACK*) Malloc(lGribLen*sizeof(GRIBPACK));
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ igrib = &gds[locnv];
+ if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
+ for ( int i = 0; i < ISEC2_NumVCP; i++ )
{
- Put3Int(ISEC2_LatSP);
- Put3Int(ISEC2_LonSP);
- Put1Real((double)(FSEC2_RotAngle));
+ int iexp = lgrib[4*i];
+ int imant = GET_UINT3(lgrib[4*i+1], lgrib[4*i+2], lgrib[4*i+3]);
+ fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
}
- }
- else
- {
- Error("Unsupported grid type %d", ISEC2_GridType);
- }
-#if defined (SX)
-#pragma vdir novector /* vectorization gives wrong results on NEC */
+ Free(lgrib);
+#else
+ for ( int i = 0; i < ISEC2_NumVCP; i++ )
+ {
+ int iexp = gds[locnv+4*i];
+ int imant = GET_UINT3(gds[locnv+4*i+1], gds[locnv+4*i+2], gds[locnv+4*i+3]);
+ fsec2[10+i] = (T)decfp2(iexp,imant);
+ }
#endif
- for ( i = 0; i < ISEC2_NumVCP; ++i )
- {
- Put1Real((double)(fsec2[10+i]));
}
- if ( ISEC2_Reduced )
- for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
-
- *gribLen = z;
+ return gdsLen;
}
-/* GRIB BLOCK 3 - BIT MAP SECTION */
+#define ldexp_double ldexp
+#define ldexp_float ldexpf
+
static
-void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
+void TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4,
+ T *fsec4, int fsec4len, int dfunc, int bdsLen, int numGridVals, int *iret)
{
- GRIBPACK *bitmap;
- long bitmapSize;
- long imaskSize;
- long i;
- long bmsLen, bmsUnusedBits;
- long fsec4size;
- long z = *gribLen;
-#if defined (VECTORCODE)
- unsigned int *imask;
-#endif
- static int lmissvalinfo = 1;
- /* unsigned int c, imask; */
+ int ioff = 0;
+ unsigned zoff;
+ unsigned bds_head = 11;
+ T zscale = 0.;
+ T fmin = 0.;
+ T *fpdata = fsec4;
+ extern int CGRIBEX_Fix_ZSE;
- if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
- {
- lmissvalinfo = 0;
- Message("Missing value = NaN is unsupported!");
- }
+ *iret = 0;
+ unsigned char *igrib = bds;
- bitmapSize = ISEC4_NumValues;
- imaskSize = ((bitmapSize+7)>>3)<<3;
- bitmap = &lGrib[z+6];
- fsec4size = 0;
+ memset(isec4, 0, 42*sizeof(int));
-#if defined (VECTORCODE)
- imask = (unsigned int*) Malloc(imaskSize*sizeof(unsigned int));
- memset(imask, 0, imaskSize*sizeof(int));
+ /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0; i < bitmapSize; i++ )
- {
- if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
- {
- data[fsec4size++] = data[i];
- imask[i] = 1;
- }
- }
+ int bds_flag = BDS_Flag;
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0; i < imaskSize/8; i++ )
- {
- bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
- (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
- (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
- (imask[i*8+6] << 1) | (imask[i*8+7]);
- }
+ /* 0------- grid point */
+ /* 1------- spherical harmonics */
- Free(imask);
-#else
- for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
+ bool lspherc = (bds_flag >> 7)&1;
- for ( i = 0; i < bitmapSize; i++ )
- {
- if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
- {
- data[fsec4size++] = data[i];
- bitmap[i/8] |= (GRIBPACK)(1<<(7-(i&7)));
- }
- }
-#endif
+ if ( lspherc ) isec4[2] = 128;
+ else isec4[2] = 0;
- bmsLen = imaskSize/8 + 6;
- bmsUnusedBits = imaskSize - bitmapSize;
+ /* -0------ simple packing */
+ /* -1------ complex packing */
- Put3Byte(bmsLen); /* 0- 2 Length of Block 3 Byte 0 */
- Put1Byte(bmsUnusedBits);
- Put2Byte(0);
+ bool lcomplex = (bds_flag >> 6)&1;
- *gribLen += bmsLen;
+ if ( lcomplex ) isec4[3] = 64;
+ else isec4[3] = 0;
- *datasize = fsec4size;
-}
+ /* ---0---- No additional flags */
+ /* ---1---- No additional flags */
-/* GRIB BLOCK 4 - BINARY DATA SECTION */
-static
-int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
- long *datstart, long *datsize, int code)
-{
- /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
- /* Uwe Schulzweida, 6/05/2003 : Copy result to fpval to prevent integer overflow */
+ bool lcompress = (bds_flag >> 4)&1;
- size_t z = (size_t)*gribLen;
- long i;
- int numBits;
- int ival;
- long PackStart = 0, Flag = 0;
- int binscale = 0;
- int bds_head = 11;
- int bds_ext = 0;
- /* ibits = BitsPerInt; */
- int exponent, mantissa;
- int lspherc = FALSE;
- int isubset = 0, itemp = 0, itrunc = 0;
- T factor = 1, fmin, fmax;
- const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality */
- /* of floating point numbers - needed */
- /* on some platforms (eg vpp700, linux) */
- extern int CGRIBEX_Const; /* 1: Don't pack constant fields on regular grids */
+ if ( lcompress )
+ { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
+ else
+ { isec4[5] = 0; isec4[6] = 0; zoff = 0; }
- if ( isec2 )
- {
- /* If section 2 is present, it says if data is spherical harmonic */
+ /* ----++++ number of unused bits at end of section) */
- lspherc = ( isec2[0] == 50 || isec2[0] == 60 ||
- isec2[0] == 70 || isec2[0] == 80 );
+ int bds_ubits = bds_flag & 0xF;
+
+ /* scale factor (2 bytes) */;
- if ( lspherc )
- isec4[2] = 128;
- else
- isec4[2] = 0;
- }
- else
- {
- /* Section 4 says if it's spherical harmonic data.. */
+ int jscale = BDS_BinScale;
- lspherc = ( isec4[2] == 128 );
- }
+ /* check for missing data indicators. */
- /* Complex packing supported for spherical harmonics. */
+ int iexp = bds[ 6];
+ int imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
- int lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
- ( lspherc && isec2 && ( isec2[5] == 2 ) );
+ int imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
- /* Check input specification is consistent */
+ /* convert reference value and scale factor. */
- if ( lcomplex && isec2 )
+ if ( ! (dfunc == 'J') && imiss == 0 )
{
- if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
- {
- gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
- gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
- return (807);
- }
- else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
- {
- gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
- gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
- return (807);
- }
- else if ( lcomplex )
- {
- /*
- Truncation of full spectrum, which is supposed triangular,
- has to be diagnosed. Define also sub-set truncation.
- */
- isubset = isec4[17];
- /* When encoding, use the total number of data. */
- itemp = isec4[0];
- itrunc = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
- }
+ fmin = (T)BDS_RefValue;
+ zscale = TEMPLATE(ldexp,T)((T)1.0, jscale);
}
- if ( decscale )
- {
- T scale = (T) pow(10.0, (double) decscale);
- for ( i = 0; i < datasize; ++i ) data[i] *= scale;
- }
+ /* get number of bits in each data value. */
+
+ ISEC4_NumBits = BDS_NumBits;
+
+ /* octet number of start of packed data */
+ /* calculated from start of block 4 - 1 */
+
+ unsigned locnd = zoff + bds_head;
+
+ /* if data is in spherical harmonic form, distinguish */
+ /* between simple/complex packing (lcomplex = 0/1) */
if ( lspherc )
{
- if ( lcomplex )
+ if ( !lcomplex )
{
- int jup, ioff;
- jup = isubset;
- ioff = (jup+1)*(jup+2);
- bds_ext = 4 + 3 + 4*ioff;
- PackStart = ioff;
- Flag = 192;
+ /* no unpacked binary data present */
+ /* octet number of start of packed data */
+ /* calculated from start of block 4 - 1 */
+
+ ioff = 1;
+ locnd += 4*ioff; /* RealCoef */
+
+ /* get real (0,0) coefficient in grib format and */
+ /* convert to floating point. */
+
+ if ( dfunc != 'J' )
+ {
+ if ( imiss ) *fpdata++ = 0.0;
+ else *fpdata++ = (T)BDS_RealCoef;
+ }
}
- else
+ else /* complex packed spherical harmonics */
{
- bds_ext = 4;
- PackStart = 1;
- Flag = 128;
- }
- }
+ isec4[15] = BDS_PackData;
+ /* scaling factor */
+ isec4[16] = BDS_Power;
- *datstart = bds_head + bds_ext;
+ /* pentagonal resolution parameters of the */
+ /* unpacked section of data field */
- int nbpv = numBits = ISEC4_NumBits;
+ int jup = bds[zoff+15];
+ int kup = bds[zoff+16];
+ int mup = bds[zoff+17];
- if ( lspherc && lcomplex )
+ isec4[zoff+17] = jup;
+ isec4[zoff+18] = kup;
+ isec4[zoff+19] = mup;
+
+ /* unpacked binary data */
+
+ locnd += 4; /* 2 + power */
+ locnd += 3; /* j, k, m */
+ ioff = (jup+1)*(jup+2);
+
+ if ( dfunc != 'J' )
+ for ( int i = 0; i < ioff; i++ )
+ {
+ if ( imiss )
+ *fpdata++ = 0.0;
+ else
+ {
+ int iexp = (bds[locnd+4*i]);
+ int imant = GET_UINT3(bds[locnd+4*i+1], bds[locnd+4*i+2], bds[locnd+4*i+3]);
+ *fpdata++ = (T)decfp2(iexp,imant);
+ }
+ }
+
+ locnd += 4*ioff; /* RealCoef */
+ }
+ }
+ else
{
- int pcStart, pcScale;
- pcStart = isubset;
- pcScale = isec4[16];
- TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
- TEMPLATE(gather_complex,T)(data, (size_t)pcStart, (size_t)itrunc, (size_t)datasize);
+ if ( lcomplex )
+ {
+ *iret = 1999;
+ gprintf(__func__, " Second order packed grids unsupported!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
+ }
}
- fmin = fmax = data[PackStart];
+ /* Decode data values to floating point and store in fsec4. */
+ /* First calculate the number of data values. */
+ /* Take into account that spherical harmonics can be packed */
+ /* simple (lcomplex = 0) or complex (lcomplex = 1) */
- TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
+ int jlend = bdsLen - locnd;
- double zref = (double)fmin;
+ if ( ISEC4_NumBits == 0 )
+ {
+ if ( jlend > 1 )
+ {
+ *iret = 2001;
+ gprintf(__func__, " Number of bits per data value = 0!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
+ }
+ if ( numGridVals == 0 )
+ {
+ *iret = 2002;
+ gprintf(__func__, " Constant field unsupported for this grid type!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
+ }
- if ( CGRIBEX_Const && !lspherc )
+ jlend = numGridVals;
+ jlend -= ioff;
+ }
+ else
{
- if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
+ jlend = (int) (((long)jlend*8 - bds_ubits) / ISEC4_NumBits);
}
+ ISEC4_NumValues = jlend + ioff;
+ ISEC4_NumNonMissValues = 0;
- long blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
- blockLength += blockLength & 1;
-
- long unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
+ if ( lcompress )
+ {
+ size_t len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
- Flag += unused_bits;
+ ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
+ if ( lspherc ) ISEC4_NumValues += lcomplex ? ioff : 1;
+ }
- /*
- Adjust number of bits per value if full integer length to
- avoid hitting most significant bit (sign bit).
- */
- /* if( nbpv == ibits ) nbpv = nbpv - 1; */
- /*
- Calculate the binary scaling factor to spread the range of
- values over the number of bits per value.
- Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
- as a guideline).
- */
- double range = fabs(fmax - fmin);
+ if ( dfunc == 'J' ) return;
- if ( fabs(fmin) < FLT_MIN ) fmin = 0;
- /*
- Have to allow tolerance in comparisons on some platforms
- (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
- to avoid clipping ranges which are a power of 2.
- */
- if ( range <= jpepsln )
- {
- binscale = 0;
- }
- else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
+ /* check length of output array. */
+
+ if ( ISEC4_NumValues > fsec4len )
{
- binscale = 0;
+ *iret = 710;
+ gprintf(__func__, " Output array too small. Length = %d", fsec4len);
+ gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
}
- else if ( fabs(range-1.0) <= jpepsln )
+
+ if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
+ else
{
- binscale = 1 - nbpv;
+ igrib += locnd;
+
+ TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
}
- else if ( range > 1.0 )
+
+ if ( lspherc && lcomplex )
{
- double rangec = range + jpepsln,
- p2 = 2.0;
- int jloop = 1;
- while ( jloop < 128 && p2 <= rangec )
- {
- p2 *= 2.0;
- ++jloop;
- }
- if (jloop < 128)
- binscale = jloop - nbpv;
- else
- {
- gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
- gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
- return (707);
- }
+ int pcStart = isec4[19], pcScale = isec4[16];
+ TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
+ TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
}
- else
+
+ if ( CGRIBEX_Fix_ZSE ) /* Fix ZeroShiftError of simple packed spherical harmonics */
+ if ( lspherc && !lcomplex )
+ {
+ /* 20100705: Fix ZeroShiftError - Edi Kirk */
+ if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
+ {
+ T zserr = fsec4[1];
+ for ( int i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
+ }
+ }
+
+ if ( decscale )
{
- double rangec = range - jpepsln, p05 = 0.5;
- int jloop = 1;
- while ( jloop < 127 && p05 >= rangec )
- {
- p05 *= 0.5;
- jloop++;
- }
- if ( jloop < 127 )
- {
- binscale = 1 - jloop - nbpv;
- }
- else
- {
- gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
- gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
- return (707);
- }
+ T scale = (T) pow(10.0, (double)-decscale);
+ for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
}
+}
- uint64_t max_nbpv_pow2 = (uint64_t) ((1ULL << nbpv) - 1);
- if ( binscale != 0 )
- {
- while ( (uint64_t)(ldexp(range, -binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+ T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
+ int kleng, int *kword, int dfunc, int *iret)
+{
+ UCHAR *gds = NULL, *bms = NULL;
+ int gdsLen = 0, bmsLen = 0;
+ int bitmapSize = 0;
+ int imaskSize = 0;
+ bool ldebug = false, l_iorj = false;
+ bool lsect2 = false, lsect3 = false;
+ int numGridVals = 0;
+ static bool lmissvalinfo = true;
- factor = (T)intpow2(-binscale);
- }
+ UNUSED(kleng);
- ref2ibm(&zref, BitsPerInt);
+ *iret = 0;
- Put3Byte(blockLength); /* 0-2 Length of Block 4 */
- Put1Byte(Flag); /* 3 Flag & Unused bits */
- if ( binscale < 0 ) binscale = 32768 - binscale;
- Put2Byte(binscale); /* 4-5 Scale factor */
- Put1Real(zref); /* 6-9 Reference value */
- Put1Byte(nbpv); /* 10 Packing size */
+ grsdef();
- if ( lspherc )
- {
- if ( lcomplex )
- {
- int jup = isubset;
- int ioff = (int)z + bds_ext;
- if ( ioff > 0xFFFF ) ioff = 0;
- Put2Byte(ioff);
- Put2Int(isec4[16]);
- Put1Byte(jup);
- Put1Byte(jup);
- Put1Byte(jup);
- for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
- }
- else
- {
- Put1Real((double)(data[0]));
- }
- }
+ ISEC2_Reduced = false;
+
+ // ----------------------------------------------------------------
+ // IS Indicator Section (Section 0)
+ // ----------------------------------------------------------------
+ UCHAR *is = (UCHAR *) &kgrib[0];
+ int isLen = decodeIS(is, isec0, iret);
+
+ int gribLen = ISEC0_GRIB_Len;
+
+ /*
+ When decoding or calculating length, previous editions
+ of the GRIB code must be taken into account.
+
+ In the table below, covering sections 0 and 1 of the GRIB
+ code, octet numbering is from the beginning of the GRIB
+ message;
+ * indicates that the value is not available in the code edition;
+ R indicates reserved, should be set to 0;
+ Experimental edition is considered as edition -1.
+
+ GRIB code edition -1 has fixed length of 20 octets for
+ section 1, the length not included in the message.
+ GRIB code edition 0 has fixed length of 24 octets for
+ section 1, the length being included in the message.
+ GRIB code edition 1 can have different lengths for section
+ 1, the minimum being 28 octets, length being included in
+ the message.
+
+ Octet numbers for code
+ editions
+
+ Contents. -1 0 1
+ --------- ----------------------
+ Letters GRIB 1-4 1-4 1-4
+ Total length of GRIB message. * * 5-7
+ GRIB code edition number * * 8
+ Length of Section 1. * 5-7 9-11
+ Reserved octet (R). * 8(R) *
+ Version no. of Code Table 2. * * 12
+ Identification of centre. 5 9 13
+ Generating process. 6 10 14
+ Grid definition . 7 11 15
+ Flag (Code Table 1). 8 12 16
+ Indicator of parameter. 9 13 17
+ Indicator of type of level. 10 14 18
+ Height, pressure etc of levels. 11-12 15-16 19-20
+ Year of century. 13 17 21
+ Month. 14 18 22
+ Day. 15 19 23
+ Hour. 16 20 24
+ Minute. 17 21 25
+ Indicator of unit of time. 18 22 26
+ P1 - Period of time. 19 23 27
+ P2 - Period of time 20(R) 24 28
+ or reserved octet (R).
+ Time range indicator. 21(R) 25 29
+ or reserved octet (R).
+ Number included in average. 22-23(R) 26-27 30-31
+ or reserved octet (R).
+ Number missing from average. 24(R) 28(R) 32
+ or reserved octet (R).
+ Century of data. * * 33
+ Designates sub-centre if not 0. * * 34
+ Decimal scale factor. * * 35-36
+ Reserved. Set to 0. * * 37-48
+ (Need not be present)
+ For originating centre use only. * * 49-nn
+ (Need not be present)
- *datsize = ((datasize-PackStart)*nbpv + 7)/8;
+ Identify which GRIB code edition is being decoded.
-#if defined (_ARCH_PWR6)
- TEMPLATE(encode_array_unrolled,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
-#else
- TEMPLATE(encode_array,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
-#endif
+ In GRIB edition 1, the edition number is in octet 8.
+ In GRIB edition 0, octet 8 is reserved and set to 0.
+ In GRIB edition -1, octet 8 is a flag field and can have a
+ a valid value of 0, 1, 2 or 3.
- if ( unused_bits >= 8 ) Put1Byte(0); /* Fillbyte */
+ However, GRIB edition number 0 has a fixed
+ length of 24, included in the message, for section 1, so
+ if the value extracted from octets 5-7 is 24 and that from
+ octet 8 is 0, it is safe to assume edition 0 of the code.
- *gribLen = (long)z;
+ */
+ if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
+ {
+ // Set length of GRIB message to missing data value.
+ ISEC0_GRIB_Len = 0;
+ }
- return (0);
-}
+ // ----------------------------------------------------------------
+ // PDS Product Definition Section (Section 1)
+ // ----------------------------------------------------------------
+ UCHAR *pds = is + isLen;
+ int pdsLen = decodePDS(pds, isec0, isec1);
+ // ----------------------------------------------------------------
+ // GDS Grid Description Section (Section 2)
+ // ----------------------------------------------------------------
+ bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ if ( gdsIncluded )
+ {
+ gds = is + isLen + pdsLen;
+ gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
+ }
-void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
- T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int efunc, int *kret)
-{
- long gribLen = 0; /* Counter of GRIB length for output */
- long isLen, pdsLen;
- GRIBPACK *lpds;
- unsigned char *CGrib;
- long fsec4size = 0;
- int bmsIncluded;
- GRIBPACK *lGrib;
- long datstart, datsize, bdsstart;
- int status = 0;
+ // ----------------------------------------------------------------
+ // BMS Bit-Map Section Section (Section 3)
+ // ----------------------------------------------------------------
+ isec3[0] = 0;
+ bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ if ( bmsIncluded )
+ {
+ bms = is + isLen + pdsLen + gdsLen;
+ bmsLen = BMS_Len;
- UNUSED(isec3);
- UNUSED(efunc);
+ imaskSize = (bmsLen - 6)<<3;
+ bitmapSize = imaskSize - BMS_UnusedBits;
+ }
- grsdef();
+ // ----------------------------------------------------------------
+ // BDS Binary Data Section (Section 4)
+ // ----------------------------------------------------------------
+ UCHAR *bds = is + isLen + pdsLen + gdsLen + bmsLen;
+ int bdsLen = BDS_Len;
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ if ( gribLen > JP23SET && bdsLen <= 120 )
+ {
+ gribLen &= JP23SET;
+ gribLen *= 120;
+ ISEC0_GRIB_Len = gribLen;
+ bdsLen = correct_bdslen(bdsLen, gribLen, isLen+pdsLen+gdsLen+bmsLen);
+ }
+ TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4,
+ fsec4, fsec4len, dfunc, bdsLen, numGridVals, iret);
- CGrib = (unsigned char *) kgrib;
+ if ( *iret != 0 ) return;
- bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ ISEC4_NumNonMissValues = ISEC4_NumValues;
- /* set max header len */
- size_t len = 16384;
+ if ( bitmapSize > 0 )
+ {
+ if ( dfunc != 'L' && dfunc != 'J' )
+ if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+ {
+ lmissvalinfo = false;
+ FSEC3_MissVal = (T)GRIB_MISSVAL;
+ Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+ }
- /* add data len */
- size_t numBytes = (size_t)((ISEC4_NumBits+7)>>3);
+ /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
+ ISEC4_NumValues = bitmapSize;
- len += numBytes*(size_t)klenp;
+ if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
+ {
+ GRIBPACK bitmap;
+ /*
+ unsigned char *bitmap;
+ bitmap = BMS_Bitmap;
+ int j = ISEC4_NumNonMissValues;
+ for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
+ {
+ if ( (bitmap[i/8]>>(7-(i&7)))&1 )
+ fsec4[i] = fsec4[--j];
+ else
+ fsec4[i] = FSEC3_MissVal;
+ }
+ */
- /* add bitmap len */
- if ( bmsIncluded ) len += (size_t)((klenp+7)>>3);
+ GRIBPACK *imask = (GRIBPACK*) Malloc((size_t)imaskSize*sizeof(GRIBPACK));
#if defined (VECTORCODE)
- lGrib = (GRIBPACK*) Malloc(len*sizeof(GRIBPACK));
- if ( lGrib == NULL ) SysError("No Memory!");
+ (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
+ GRIBPACK *pbitmap = imask;
#else
- lGrib = CGrib;
+ GRIBPACK *pbitmap = BMS_Bitmap;
#endif
- isLen = 8;
- encodeIS(lGrib, &gribLen);
- lpds = &lGrib[isLen];
- pdsLen = getPdsLen(isec1);
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( int i = imaskSize/8-1; i >= 0; i-- )
+ {
+ bitmap = pbitmap[i];
+ imask[i*8+0] = 1 & (bitmap >> 7);
+ imask[i*8+1] = 1 & (bitmap >> 6);
+ imask[i*8+2] = 1 & (bitmap >> 5);
+ imask[i*8+3] = 1 & (bitmap >> 4);
+ imask[i*8+4] = 1 & (bitmap >> 3);
+ imask[i*8+5] = 1 & (bitmap >> 2);
+ imask[i*8+6] = 1 & (bitmap >> 1);
+ imask[i*8+7] = 1 & (bitmap);
+ }
- encodePDS(lpds, pdsLen, isec1);
- gribLen += pdsLen;
- /*
- if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
- {
- static int lwarn_cplx = TRUE;
+ int j = 0;
+ for ( int i = 0; i < ISEC4_NumValues; i++ )
+ if ( imask[i] ) j++;
- if ( lwarn_cplx )
- Message("Complex packing of spectral data unsupported, using simple packing!");
+ if ( ISEC4_NumNonMissValues != j )
+ {
+ if ( dfunc != 'J' && ISEC4_NumBits != 0 )
+ Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
+ j, ISEC4_NumNonMissValues);
- isec2[5] = 1;
- isec4[3] = 0;
+ ISEC4_NumNonMissValues = j;
+ }
- lwarn_cplx = FALSE;
- }
- */
- TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
- /*
- ----------------------------------------------------------------
- BMS Bit-Map Section Section (Section 3)
- ----------------------------------------------------------------
- */
- if ( bmsIncluded )
- {
- TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
- }
- else
- {
- fsec4size = ISEC4_NumValues;
+ if ( dfunc != 'J' )
+ {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
+ fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
+ }
+
+ Free(imask);
+ }
}
- bdsstart = gribLen;
- status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
- isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
- if ( status )
+ if ( ISEC2_Reduced )
{
- *kret = status;
- return;
+ int nvalues = 0;
+ int nlat = ISEC2_NumLat;
+ int nlon = ISEC2_RowLonPtr[0];
+ for ( int ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
+ for ( int ilat = 1; ilat < nlat; ++ilat )
+ if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+
+ // int dlon = ISEC2_LastLon-ISEC2_FirstLon;
+ // if ( dlon < 0 ) dlon += 360000;
+
+ if ( nvalues != ISEC4_NumValues ) *iret = -801;
+
+ //printf("nlat %d nlon %d \n", nlat, nlon);
+ //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+
+ if ( dfunc == 'R' && *iret == -801 )
+ gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
+ ISEC4_NumValues, nvalues);
+
+ if ( dfunc == 'R' && *iret != -801 )
+ {
+ ISEC2_Reduced = 0;
+ ISEC2_NumLon = nlon;
+ ISEC4_NumValues = nlon*nlat;
+
+ lsect3 = bitmapSize > 0;
+ int lperio = 1;
+ int lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) &&
+ ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) ||
+ (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30) ||
+ (ISEC1_Parameter == 39) || (ISEC1_Parameter == 40) ||
+ (ISEC1_Parameter == 41) || (ISEC1_Parameter == 42) ||
+ (ISEC1_Parameter == 43));
+
+ (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
+
+ if ( bitmapSize > 0 )
+ {
+ int j = 0;
+ for ( int i = 0; i < ISEC4_NumValues; i++ )
+ if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
+
+ ISEC4_NumNonMissValues = j;
+ }
+ }
}
- encodeES(lGrib, &gribLen, bdsstart);
- if ( (size_t) gribLen > (size_t)kleng*sizeof(int) )
- Error("kgrib buffer too small! kleng = %d gribLen = %d", kleng, gribLen);
+ if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
+ int esLen = 4;
+ gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
-#if defined (VECTORCODE)
- if ( (size_t) gribLen > len )
- Error("lGrib buffer too small! len = %d gribLen = %d", len, gribLen);
+ if ( ISEC0_GRIB_Len )
+ if ( ISEC0_GRIB_Len < gribLen )
+ Warning("Inconsistent length of GRIB message (grib_message_size=%d < grib_record_size=%d)!", ISEC0_GRIB_Len, gribLen);
- (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
+ ISEC0_GRIB_Len = gribLen;
- Free(lGrib);
-#endif
+ *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
- ISEC0_GRIB_Len = (int)gribLen;
- ISEC0_GRIB_Version = 1;
+ // ----------------------------------------------------------------
+ // Section 9 . Abort/return to calling routine.
+ // ----------------------------------------------------------------
+ if ( ldebug )
+ {
+ gprintf(__func__, "Section 9.");
+ gprintf(__func__, "Output values set -");
- *kword = (int)((gribLen + (long)sizeof(int) - 1) / (long)sizeof(int));
+ gribPrintSec0(isec0);
+ gribPrintSec1(isec0, isec1);
+ // Print section 2 if present.
+ if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
- *kret = status;
+ if ( ! l_iorj )
+ {
+ // Print section 3 if present.
+ if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+
+ TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
+ // Special print for 2D spectra wave field real values in section 4
+ if ( (isec1[ 0] == 140) &&
+ (isec1[ 1] == 98) &&
+ (isec1[23] == 1) &&
+ ((isec1[39] == 1045) || (isec1[39] == 1081)) &&
+ ((isec1[ 5] == 250) || (isec1[ 5] == 251)) )
+ gribPrintSec4Wave(isec4);
+ }
+ }
}
#endif /* T */
@@ -18863,599 +16804,818 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
#define T float
#ifdef T
-/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
-static
-void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
+static
+int TEMPLATE(decodeGDS,T)(unsigned char *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
{
- long z = *gribLen;
- int exponent, mantissa;
- long i;
- int ival;
- int pvoffset = 0xFF;
- int gdslen = 32;
- unsigned lonIncr, latIncr;
+ // int imisng = 0;
+ bool ReducedGrid = false, VertCoorTab = false;
+#if defined (VECTORCODE)
+ unsigned char *igrib;
+ GRIBPACK *lgrib = NULL;
+ size_t lGribLen = 0;
+#endif
- if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
+ *numGridVals = 0;
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ) gdslen += 10;
+ memset(isec2, 0, 22*sizeof(int));
- if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
+ unsigned gdsLen = GDS_Len;
- if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
+ unsigned ipvpl = GDS_PVPL;
+ if ( ipvpl == 0 ) ipvpl = 0xFF;
- gdslen += ISEC2_NumVCP * 4;
+ if ( ipvpl != 0xFF )
+ { /* Either vct or reduced grid */
+ if ( GDS_NV != 0 )
+ { /* we have vct */
+ VertCoorTab = true;
+ unsigned ipl = 4*GDS_NV + ipvpl - 1;
+ if ( ipl < gdsLen ) ReducedGrid = true;
+ }
+ else
+ {
+ VertCoorTab = false;
+ ReducedGrid = true;
+ }
+ /* ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+ }
+
+ if ( ISEC0_GRIB_Version == 0 )
+ {
+ VertCoorTab = (gdsLen - 32) > 0;
+ }
+
+ if ( ReducedGrid )
+ {
+ unsigned locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+ unsigned jlenl = (gdsLen - locnl) >> 1;
+ if ( jlenl == GDS_NumLat )
+ {
+ *numGridVals = 0;
+ ISEC2_Reduced = true;
+ for ( unsigned i = 0; i < jlenl; i++ )
+ {
+ ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
+ *numGridVals += ISEC2_RowLon(i);
+ }
+ }
+ else
+ {
+ ReducedGrid = false;
+ }
+ }
- Put3Byte(gdslen); /* 0- 2 Length of Block 2 Byte 0 */
- Put1Byte(ISEC2_NumVCP); /* 3 NV */
- Put1Byte(pvoffset); /* 4 PV */
- Put1Byte(ISEC2_GridType); /* 5 LatLon=0 Gauss=4 Spectral=50 */
+ ISEC2_GridType = GDS_GridType;
- if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+ /*
+ Gaussian grid definition.
+ */
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
{
- Put2Byte(ISEC2_PentaJ); /* 6- 7 Pentagonal resolution J */
- Put2Byte(ISEC2_PentaK); /* 8- 9 Pentagonal resolution K */
- Put2Byte(ISEC2_PentaM); /* 10-11 Pentagonal resolution M */
- Put1Byte(ISEC2_RepType); /* 12 Representation type */
- Put1Byte(ISEC2_RepMode); /* 13 Representation mode */
- PutnZero(18); /* 14-31 reserved */
+ ISEC2_NumLat = GDS_NumLat;
+ if ( ! ReducedGrid )
+ {
+ ISEC2_NumLon = GDS_NumLon;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ }
+ ISEC2_FirstLat = GDS_FirstLat;
+ ISEC2_FirstLon = GDS_FirstLon;
+ ISEC2_ResFlag = GDS_ResFlag;
+ ISEC2_LastLat = GDS_LastLat;
+ ISEC2_LastLon = GDS_LastLon;
+ ISEC2_LonIncr = GDS_LonIncr;
+
+ ISEC2_NumPar = GDS_NumPar;
+ ISEC2_ScanFlag = GDS_ScanFlag;
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ {
+ ISEC2_LatSP = GDS_LatSP;
+ ISEC2_LonSP = GDS_LonSP;
+ FSEC2_RotAngle = (T)GDS_RotAngle;
+ }
+ /*
+ if ( Lons != Longitudes || Lats != Latitudes )
+ Error("Latitude/Longitude Conflict");
+ */
}
- else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
{
- Put2Byte(ISEC2_GME_NI2);
- Put2Byte(ISEC2_GME_NI3);
- Put3Byte(ISEC2_GME_ND);
- Put3Byte(ISEC2_GME_NI);
- Put1Byte(ISEC2_GME_AFlag);
- Put3Int(ISEC2_GME_LatPP);
- Put3Int(ISEC2_GME_LonPP);
- Put3Int(ISEC2_GME_LonMPL);
- Put1Byte(ISEC2_GME_BFlag);
- PutnZero(5);
+ // iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
+ {
+ // iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
}
else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
{
- Put2Byte(ISEC2_NumLon); /* 6- 7 Longitudes */
-
- Put2Byte(ISEC2_NumLat); /* 8- 9 Latitudes */
- Put3Int(ISEC2_FirstLat);
- Put3Int(ISEC2_FirstLon);
- Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
- Put3Int(ISEC2_Lambert_Lov); /* 17-19 */
- Put3Int(ISEC2_Lambert_dx); /* 20-22 */
- Put3Int(ISEC2_Lambert_dy); /* 23-25 */
- Put1Byte(ISEC2_Lambert_ProjFlag);/* 26 Projection flag */
- Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
- Put3Int(ISEC2_Lambert_LatS1); /* 28-30 */
- Put3Int(ISEC2_Lambert_LatS2); /* 31-33 */
- Put3Int(ISEC2_Lambert_LatSP); /* 34-36 */
- Put3Int(ISEC2_Lambert_LonSP); /* 37-39 */
- PutnZero(2); /* 34-41 */
+ ISEC2_NumLon = GDS_NumLon;
+ ISEC2_NumLat = GDS_NumLat;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ ISEC2_FirstLat = GDS_FirstLat;
+ ISEC2_FirstLon = GDS_FirstLon;
+ ISEC2_ResFlag = GDS_ResFlag;
+ ISEC2_Lambert_Lov = GDS_Lambert_Lov;
+ ISEC2_Lambert_dx = GDS_Lambert_dx;
+ ISEC2_Lambert_dy = GDS_Lambert_dy;
+ ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
+ ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
+ ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
+ ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
+ ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
+ ISEC2_ScanFlag = GDS_ScanFlag;
}
- else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
- ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
- ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+ {
+ ISEC2_PentaJ = GDS_PentaJ; /* Truncation */
+ ISEC2_PentaK = GDS_PentaK;
+ ISEC2_PentaM = GDS_PentaM;
+ ISEC2_RepType = GDS_RepType;
+ ISEC2_RepMode = GDS_RepMode;
+ *numGridVals = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
+ isec2[ 6] = 0;
+ isec2[ 7] = 0;
+ isec2[ 8] = 0;
+ isec2[ 9] = 0;
+ isec2[10] = 0;
+ // iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+ {
+ ISEC2_GME_NI2 = GDS_GME_NI2;
+ ISEC2_GME_NI3 = GDS_GME_NI3;
+ ISEC2_GME_ND = GDS_GME_ND;
+ ISEC2_GME_NI = GDS_GME_NI;
+ ISEC2_GME_AFlag = GDS_GME_AFlag;
+ ISEC2_GME_LatPP = GDS_GME_LatPP;
+ ISEC2_GME_LonPP = GDS_GME_LonPP;
+ ISEC2_GME_LonMPL = GDS_GME_LonMPL;
+ ISEC2_GME_BFlag = GDS_GME_BFlag;
+ *numGridVals = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
+ // iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+ }
+ else
+ {
+ static bool lwarn = true;
+ ISEC2_NumLon = GDS_NumLon;
+ ISEC2_NumLat = GDS_NumLat;
+ *numGridVals = ISEC2_NumLon*ISEC2_NumLat;
+ if ( lwarn )
+ {
+ lwarn = false;
+ Message("GRIB gridtype %d unsupported", ISEC2_GridType);
+ }
+ }
+
+ /* vertical coordinate parameters for hybrid levels. */
+ /* get number of vertical coordinate parameters, if any. */
+
+ ISEC2_NumVCP = 0;
+
+ isec2[17] = 0;
+ isec2[18] = 0;
+
+ if ( VertCoorTab )
{
- int numlon;
- if ( ISEC2_Reduced )
- numlon = 0xFFFF;
+ int locnv;
+ if ( ISEC0_GRIB_Version == 0 )
+ {
+ locnv = 32;
+ ISEC2_NumVCP = (gdsLen - 32) >> 2;
+ }
else
- numlon = ISEC2_NumLon;
+ {
+ locnv = GDS_PVPL - 1;
+ ISEC2_NumVCP = GDS_NV;
+ }
+#if defined (SX)
+ lGribLen = 4*ISEC2_NumVCP;
+ lgrib = (GRIBPACK*) Malloc(lGribLen*sizeof(GRIBPACK));
+
+ igrib = &gds[locnv];
+ if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
+ for ( int i = 0; i < ISEC2_NumVCP; i++ )
+ {
+ int iexp = lgrib[4*i];
+ int imant = GET_UINT3(lgrib[4*i+1], lgrib[4*i+2], lgrib[4*i+3]);
+ fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
+ }
+
+ Free(lgrib);
+#else
+ for ( int i = 0; i < ISEC2_NumVCP; i++ )
+ {
+ int iexp = gds[locnv+4*i];
+ int imant = GET_UINT3(gds[locnv+4*i+1], gds[locnv+4*i+2], gds[locnv+4*i+3]);
+ fsec2[10+i] = (T)decfp2(iexp,imant);
+ }
+#endif
+ }
+
+ return gdsLen;
+}
+
+#define ldexp_double ldexp
+#define ldexp_float ldexpf
+
+static
+void TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4,
+ T *fsec4, int fsec4len, int dfunc, int bdsLen, int numGridVals, int *iret)
+{
+ int ioff = 0;
+ unsigned zoff;
+ unsigned bds_head = 11;
+ T zscale = 0.;
+ T fmin = 0.;
+ T *fpdata = fsec4;
+ extern int CGRIBEX_Fix_ZSE;
+
+ *iret = 0;
+ unsigned char *igrib = bds;
+
+ memset(isec4, 0, 42*sizeof(int));
+
+ /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
+
+ int bds_flag = BDS_Flag;
+
+ /* 0------- grid point */
+ /* 1------- spherical harmonics */
+
+ bool lspherc = (bds_flag >> 7)&1;
- Put2Byte(numlon); /* 6- 7 Number of Longitudes */
+ if ( lspherc ) isec4[2] = 128;
+ else isec4[2] = 0;
- Put2Byte(ISEC2_NumLat); /* 8- 9 Number of Latitudes */
- Put3Int(ISEC2_FirstLat);
- Put3Int(ISEC2_FirstLon);
- Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
- Put3Int(ISEC2_LastLat);
- Put3Int(ISEC2_LastLon);
- if ( ISEC2_ResFlag == 0 )
- {
- lonIncr = 0xFFFF;
- latIncr = 0xFFFF;
- }
- else
- {
- lonIncr = (unsigned)ISEC2_LonIncr;
- latIncr = (unsigned)ISEC2_LatIncr;
- }
- Put2Byte(lonIncr); /* 23-24 i - direction increment */
- if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
- Put2Byte(ISEC2_NumPar); /* 25-26 Latitudes Pole->Equator */
- else
- Put2Byte(latIncr); /* 25-26 j - direction increment */
+ /* -0------ simple packing */
+ /* -1------ complex packing */
- Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
- PutnZero(4); /* 28-31 reserved */
+ bool lcomplex = (bds_flag >> 6)&1;
- if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
- {
- Put3Int(ISEC2_LatSP);
- Put3Int(ISEC2_LonSP);
- Put1Real((double)(FSEC2_RotAngle));
- }
- }
+ if ( lcomplex ) isec4[3] = 64;
+ else isec4[3] = 0;
+
+ /* ---0---- No additional flags */
+ /* ---1---- No additional flags */
+
+ bool lcompress = (bds_flag >> 4)&1;
+
+ if ( lcompress )
+ { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
else
- {
- Error("Unsupported grid type %d", ISEC2_GridType);
- }
+ { isec4[5] = 0; isec4[6] = 0; zoff = 0; }
-#if defined (SX)
-#pragma vdir novector /* vectorization gives wrong results on NEC */
-#endif
- for ( i = 0; i < ISEC2_NumVCP; ++i )
- {
- Put1Real((double)(fsec2[10+i]));
- }
+ /* ----++++ number of unused bits at end of section) */
- if ( ISEC2_Reduced )
- for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
+ int bds_ubits = bds_flag & 0xF;
+
+ /* scale factor (2 bytes) */;
- *gribLen = z;
-}
+ int jscale = BDS_BinScale;
-/* GRIB BLOCK 3 - BIT MAP SECTION */
-static
-void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
-{
- GRIBPACK *bitmap;
- long bitmapSize;
- long imaskSize;
- long i;
- long bmsLen, bmsUnusedBits;
- long fsec4size;
- long z = *gribLen;
-#if defined (VECTORCODE)
- unsigned int *imask;
-#endif
- static int lmissvalinfo = 1;
- /* unsigned int c, imask; */
+ /* check for missing data indicators. */
- if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
- {
- lmissvalinfo = 0;
- Message("Missing value = NaN is unsupported!");
- }
+ int iexp = bds[ 6];
+ int imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
- bitmapSize = ISEC4_NumValues;
- imaskSize = ((bitmapSize+7)>>3)<<3;
- bitmap = &lGrib[z+6];
- fsec4size = 0;
+ int imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
-#if defined (VECTORCODE)
- imask = (unsigned int*) Malloc(imaskSize*sizeof(unsigned int));
- memset(imask, 0, imaskSize*sizeof(int));
+ /* convert reference value and scale factor. */
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0; i < bitmapSize; i++ )
+ if ( ! (dfunc == 'J') && imiss == 0 )
{
- if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
- {
- data[fsec4size++] = data[i];
- imask[i] = 1;
- }
+ fmin = (T)BDS_RefValue;
+ zscale = TEMPLATE(ldexp,T)((T)1.0, jscale);
}
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
- for ( i = 0; i < imaskSize/8; i++ )
- {
- bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
- (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
- (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
- (imask[i*8+6] << 1) | (imask[i*8+7]);
- }
+ /* get number of bits in each data value. */
- Free(imask);
-#else
- for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
+ ISEC4_NumBits = BDS_NumBits;
+
+ /* octet number of start of packed data */
+ /* calculated from start of block 4 - 1 */
+
+ unsigned locnd = zoff + bds_head;
+
+ /* if data is in spherical harmonic form, distinguish */
+ /* between simple/complex packing (lcomplex = 0/1) */
- for ( i = 0; i < bitmapSize; i++ )
+ if ( lspherc )
{
- if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+ if ( !lcomplex )
{
- data[fsec4size++] = data[i];
- bitmap[i/8] |= (GRIBPACK)(1<<(7-(i&7)));
- }
- }
-#endif
+ /* no unpacked binary data present */
+ /* octet number of start of packed data */
+ /* calculated from start of block 4 - 1 */
- bmsLen = imaskSize/8 + 6;
- bmsUnusedBits = imaskSize - bitmapSize;
+ ioff = 1;
+ locnd += 4*ioff; /* RealCoef */
- Put3Byte(bmsLen); /* 0- 2 Length of Block 3 Byte 0 */
- Put1Byte(bmsUnusedBits);
- Put2Byte(0);
+ /* get real (0,0) coefficient in grib format and */
+ /* convert to floating point. */
- *gribLen += bmsLen;
+ if ( dfunc != 'J' )
+ {
+ if ( imiss ) *fpdata++ = 0.0;
+ else *fpdata++ = (T)BDS_RealCoef;
+ }
+ }
+ else /* complex packed spherical harmonics */
+ {
+ isec4[15] = BDS_PackData;
+ /* scaling factor */
+ isec4[16] = BDS_Power;
- *datasize = fsec4size;
-}
+ /* pentagonal resolution parameters of the */
+ /* unpacked section of data field */
-/* GRIB BLOCK 4 - BINARY DATA SECTION */
-static
-int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
- long *datstart, long *datsize, int code)
-{
- /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
- /* Uwe Schulzweida, 6/05/2003 : Copy result to fpval to prevent integer overflow */
+ int jup = bds[zoff+15];
+ int kup = bds[zoff+16];
+ int mup = bds[zoff+17];
- size_t z = (size_t)*gribLen;
- long i;
- int numBits;
- int ival;
- long PackStart = 0, Flag = 0;
- int binscale = 0;
- int bds_head = 11;
- int bds_ext = 0;
- /* ibits = BitsPerInt; */
- int exponent, mantissa;
- int lspherc = FALSE;
- int isubset = 0, itemp = 0, itrunc = 0;
- T factor = 1, fmin, fmax;
- const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality */
- /* of floating point numbers - needed */
- /* on some platforms (eg vpp700, linux) */
- extern int CGRIBEX_Const; /* 1: Don't pack constant fields on regular grids */
+ isec4[zoff+17] = jup;
+ isec4[zoff+18] = kup;
+ isec4[zoff+19] = mup;
- if ( isec2 )
- {
- /* If section 2 is present, it says if data is spherical harmonic */
+ /* unpacked binary data */
- lspherc = ( isec2[0] == 50 || isec2[0] == 60 ||
- isec2[0] == 70 || isec2[0] == 80 );
+ locnd += 4; /* 2 + power */
+ locnd += 3; /* j, k, m */
+ ioff = (jup+1)*(jup+2);
- if ( lspherc )
- isec4[2] = 128;
- else
- isec4[2] = 0;
+ if ( dfunc != 'J' )
+ for ( int i = 0; i < ioff; i++ )
+ {
+ if ( imiss )
+ *fpdata++ = 0.0;
+ else
+ {
+ int iexp = (bds[locnd+4*i]);
+ int imant = GET_UINT3(bds[locnd+4*i+1], bds[locnd+4*i+2], bds[locnd+4*i+3]);
+ *fpdata++ = (T)decfp2(iexp,imant);
+ }
+ }
+
+ locnd += 4*ioff; /* RealCoef */
+ }
}
else
{
- /* Section 4 says if it's spherical harmonic data.. */
-
- lspherc = ( isec4[2] == 128 );
+ if ( lcomplex )
+ {
+ *iret = 1999;
+ gprintf(__func__, " Second order packed grids unsupported!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
+ }
}
- /* Complex packing supported for spherical harmonics. */
-
- int lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
- ( lspherc && isec2 && ( isec2[5] == 2 ) );
+ /* Decode data values to floating point and store in fsec4. */
+ /* First calculate the number of data values. */
+ /* Take into account that spherical harmonics can be packed */
+ /* simple (lcomplex = 0) or complex (lcomplex = 1) */
- /* Check input specification is consistent */
+ int jlend = bdsLen - locnd;
- if ( lcomplex && isec2 )
+ if ( ISEC4_NumBits == 0 )
{
- if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
+ if ( jlend > 1 )
{
- gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
- gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
- return (807);
+ *iret = 2001;
+ gprintf(__func__, " Number of bits per data value = 0!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
}
- else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
- {
- gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
- gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
- return (807);
- }
- else if ( lcomplex )
+
+ if ( numGridVals == 0 )
{
- /*
- Truncation of full spectrum, which is supposed triangular,
- has to be diagnosed. Define also sub-set truncation.
- */
- isubset = isec4[17];
- /* When encoding, use the total number of data. */
- itemp = isec4[0];
- itrunc = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
+ *iret = 2002;
+ gprintf(__func__, " Constant field unsupported for this grid type!");
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
}
- }
- if ( decscale )
+ jlend = numGridVals;
+ jlend -= ioff;
+ }
+ else
{
- T scale = (T) pow(10.0, (double) decscale);
- for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+ jlend = (int) (((long)jlend*8 - bds_ubits) / ISEC4_NumBits);
}
- if ( lspherc )
+ ISEC4_NumValues = jlend + ioff;
+ ISEC4_NumNonMissValues = 0;
+
+ if ( lcompress )
{
- if ( lcomplex )
- {
- int jup, ioff;
- jup = isubset;
- ioff = (jup+1)*(jup+2);
- bds_ext = 4 + 3 + 4*ioff;
- PackStart = ioff;
- Flag = 192;
- }
- else
- {
- bds_ext = 4;
- PackStart = 1;
- Flag = 128;
- }
- }
+ size_t len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
- *datstart = bds_head + bds_ext;
+ ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
- int nbpv = numBits = ISEC4_NumBits;
+ if ( lspherc ) ISEC4_NumValues += lcomplex ? ioff : 1;
+ }
- if ( lspherc && lcomplex )
+ if ( dfunc == 'J' ) return;
+
+ /* check length of output array. */
+
+ if ( ISEC4_NumValues > fsec4len )
{
- int pcStart, pcScale;
- pcStart = isubset;
- pcScale = isec4[16];
- TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
- TEMPLATE(gather_complex,T)(data, (size_t)pcStart, (size_t)itrunc, (size_t)datasize);
+ *iret = 710;
+ gprintf(__func__, " Output array too small. Length = %d", fsec4len);
+ gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
+ gprintf(__func__, " Return code = %d", *iret);
+ return;
}
- fmin = fmax = data[PackStart];
+ if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
+ else
+ {
+ igrib += locnd;
- TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
+ TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+ }
- double zref = (double)fmin;
+ if ( lspherc && lcomplex )
+ {
+ int pcStart = isec4[19], pcScale = isec4[16];
+ TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
+ TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
+ }
+ if ( CGRIBEX_Fix_ZSE ) /* Fix ZeroShiftError of simple packed spherical harmonics */
+ if ( lspherc && !lcomplex )
+ {
+ /* 20100705: Fix ZeroShiftError - Edi Kirk */
+ if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
+ {
+ T zserr = fsec4[1];
+ for ( int i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
+ }
+ }
- if ( CGRIBEX_Const && !lspherc )
+ if ( decscale )
{
- if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
+ T scale = (T) pow(10.0, (double)-decscale);
+ for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
}
+}
- long blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
- blockLength += blockLength & 1;
+void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+ T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
+ int kleng, int *kword, int dfunc, int *iret)
+{
+ UCHAR *gds = NULL, *bms = NULL;
+ int gdsLen = 0, bmsLen = 0;
+ int bitmapSize = 0;
+ int imaskSize = 0;
+ bool ldebug = false, l_iorj = false;
+ bool lsect2 = false, lsect3 = false;
+ int numGridVals = 0;
+ static bool lmissvalinfo = true;
- long unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
+ UNUSED(kleng);
- Flag += unused_bits;
+ *iret = 0;
+ grsdef();
- /*
- Adjust number of bits per value if full integer length to
- avoid hitting most significant bit (sign bit).
- */
- /* if( nbpv == ibits ) nbpv = nbpv - 1; */
- /*
- Calculate the binary scaling factor to spread the range of
- values over the number of bits per value.
- Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
- as a guideline).
- */
- double range = fabs(fmax - fmin);
+ ISEC2_Reduced = false;
- if ( fabs(fmin) < FLT_MIN ) fmin = 0;
- /*
- Have to allow tolerance in comparisons on some platforms
- (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
- to avoid clipping ranges which are a power of 2.
- */
- if ( range <= jpepsln )
- {
- binscale = 0;
- }
- else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
- {
- binscale = 0;
- }
- else if ( fabs(range-1.0) <= jpepsln )
- {
- binscale = 1 - nbpv;
- }
- else if ( range > 1.0 )
- {
- double rangec = range + jpepsln,
- p2 = 2.0;
- int jloop = 1;
- while ( jloop < 128 && p2 <= rangec )
- {
- p2 *= 2.0;
- ++jloop;
- }
- if (jloop < 128)
- binscale = jloop - nbpv;
- else
- {
- gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
- gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
- return (707);
- }
- }
- else
- {
- double rangec = range - jpepsln, p05 = 0.5;
- int jloop = 1;
- while ( jloop < 127 && p05 >= rangec )
- {
- p05 *= 0.5;
- jloop++;
- }
- if ( jloop < 127 )
- {
- binscale = 1 - jloop - nbpv;
- }
- else
- {
- gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
- gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
- return (707);
- }
- }
+ // ----------------------------------------------------------------
+ // IS Indicator Section (Section 0)
+ // ----------------------------------------------------------------
+ UCHAR *is = (UCHAR *) &kgrib[0];
+ int isLen = decodeIS(is, isec0, iret);
- uint64_t max_nbpv_pow2 = (uint64_t) ((1ULL << nbpv) - 1);
+ int gribLen = ISEC0_GRIB_Len;
- if ( binscale != 0 )
- {
- while ( (uint64_t)(ldexp(range, -binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+ /*
+ When decoding or calculating length, previous editions
+ of the GRIB code must be taken into account.
- factor = (T)intpow2(-binscale);
- }
+ In the table below, covering sections 0 and 1 of the GRIB
+ code, octet numbering is from the beginning of the GRIB
+ message;
+ * indicates that the value is not available in the code edition;
+ R indicates reserved, should be set to 0;
+ Experimental edition is considered as edition -1.
- ref2ibm(&zref, BitsPerInt);
+ GRIB code edition -1 has fixed length of 20 octets for
+ section 1, the length not included in the message.
+ GRIB code edition 0 has fixed length of 24 octets for
+ section 1, the length being included in the message.
+ GRIB code edition 1 can have different lengths for section
+ 1, the minimum being 28 octets, length being included in
+ the message.
- Put3Byte(blockLength); /* 0-2 Length of Block 4 */
- Put1Byte(Flag); /* 3 Flag & Unused bits */
- if ( binscale < 0 ) binscale = 32768 - binscale;
- Put2Byte(binscale); /* 4-5 Scale factor */
- Put1Real(zref); /* 6-9 Reference value */
- Put1Byte(nbpv); /* 10 Packing size */
+ Octet numbers for code
+ editions
- if ( lspherc )
- {
- if ( lcomplex )
- {
- int jup = isubset;
- int ioff = (int)z + bds_ext;
- if ( ioff > 0xFFFF ) ioff = 0;
- Put2Byte(ioff);
- Put2Int(isec4[16]);
- Put1Byte(jup);
- Put1Byte(jup);
- Put1Byte(jup);
- for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
- }
- else
- {
- Put1Real((double)(data[0]));
- }
- }
+ Contents. -1 0 1
+ --------- ----------------------
+ Letters GRIB 1-4 1-4 1-4
+ Total length of GRIB message. * * 5-7
+ GRIB code edition number * * 8
+ Length of Section 1. * 5-7 9-11
+ Reserved octet (R). * 8(R) *
+ Version no. of Code Table 2. * * 12
+ Identification of centre. 5 9 13
+ Generating process. 6 10 14
+ Grid definition . 7 11 15
+ Flag (Code Table 1). 8 12 16
+ Indicator of parameter. 9 13 17
+ Indicator of type of level. 10 14 18
+ Height, pressure etc of levels. 11-12 15-16 19-20
+ Year of century. 13 17 21
+ Month. 14 18 22
+ Day. 15 19 23
+ Hour. 16 20 24
+ Minute. 17 21 25
+ Indicator of unit of time. 18 22 26
+ P1 - Period of time. 19 23 27
+ P2 - Period of time 20(R) 24 28
+ or reserved octet (R).
+ Time range indicator. 21(R) 25 29
+ or reserved octet (R).
+ Number included in average. 22-23(R) 26-27 30-31
+ or reserved octet (R).
+ Number missing from average. 24(R) 28(R) 32
+ or reserved octet (R).
+ Century of data. * * 33
+ Designates sub-centre if not 0. * * 34
+ Decimal scale factor. * * 35-36
+ Reserved. Set to 0. * * 37-48
+ (Need not be present)
+ For originating centre use only. * * 49-nn
+ (Need not be present)
- *datsize = ((datasize-PackStart)*nbpv + 7)/8;
+ Identify which GRIB code edition is being decoded.
-#if defined (_ARCH_PWR6)
- TEMPLATE(encode_array_unrolled,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
-#else
- TEMPLATE(encode_array,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
-#endif
+ In GRIB edition 1, the edition number is in octet 8.
+ In GRIB edition 0, octet 8 is reserved and set to 0.
+ In GRIB edition -1, octet 8 is a flag field and can have a
+ a valid value of 0, 1, 2 or 3.
- if ( unused_bits >= 8 ) Put1Byte(0); /* Fillbyte */
+ However, GRIB edition number 0 has a fixed
+ length of 24, included in the message, for section 1, so
+ if the value extracted from octets 5-7 is 24 and that from
+ octet 8 is 0, it is safe to assume edition 0 of the code.
- *gribLen = (long)z;
+ */
+ if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
+ {
+ // Set length of GRIB message to missing data value.
+ ISEC0_GRIB_Len = 0;
+ }
- return (0);
-}
+ // ----------------------------------------------------------------
+ // PDS Product Definition Section (Section 1)
+ // ----------------------------------------------------------------
+ UCHAR *pds = is + isLen;
+ int pdsLen = decodePDS(pds, isec0, isec1);
+ // ----------------------------------------------------------------
+ // GDS Grid Description Section (Section 2)
+ // ----------------------------------------------------------------
+ bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ if ( gdsIncluded )
+ {
+ gds = is + isLen + pdsLen;
+ gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
+ }
-void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
- T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
- int kleng, int *kword, int efunc, int *kret)
-{
- long gribLen = 0; /* Counter of GRIB length for output */
- long isLen, pdsLen;
- GRIBPACK *lpds;
- unsigned char *CGrib;
- long fsec4size = 0;
- int bmsIncluded;
- GRIBPACK *lGrib;
- long datstart, datsize, bdsstart;
- int status = 0;
+ // ----------------------------------------------------------------
+ // BMS Bit-Map Section Section (Section 3)
+ // ----------------------------------------------------------------
+ isec3[0] = 0;
+ bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ if ( bmsIncluded )
+ {
+ bms = is + isLen + pdsLen + gdsLen;
+ bmsLen = BMS_Len;
- UNUSED(isec3);
- UNUSED(efunc);
+ imaskSize = (bmsLen - 6)<<3;
+ bitmapSize = imaskSize - BMS_UnusedBits;
+ }
- grsdef();
+ // ----------------------------------------------------------------
+ // BDS Binary Data Section (Section 4)
+ // ----------------------------------------------------------------
+ UCHAR *bds = is + isLen + pdsLen + gdsLen + bmsLen;
+ int bdsLen = BDS_Len;
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ if ( gribLen > JP23SET && bdsLen <= 120 )
+ {
+ gribLen &= JP23SET;
+ gribLen *= 120;
+ ISEC0_GRIB_Len = gribLen;
+ bdsLen = correct_bdslen(bdsLen, gribLen, isLen+pdsLen+gdsLen+bmsLen);
+ }
+ TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4,
+ fsec4, fsec4len, dfunc, bdsLen, numGridVals, iret);
- CGrib = (unsigned char *) kgrib;
+ if ( *iret != 0 ) return;
- bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ ISEC4_NumNonMissValues = ISEC4_NumValues;
- /* set max header len */
- size_t len = 16384;
+ if ( bitmapSize > 0 )
+ {
+ if ( dfunc != 'L' && dfunc != 'J' )
+ if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+ {
+ lmissvalinfo = false;
+ FSEC3_MissVal = (T)GRIB_MISSVAL;
+ Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+ }
- /* add data len */
- size_t numBytes = (size_t)((ISEC4_NumBits+7)>>3);
+ /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
+ ISEC4_NumValues = bitmapSize;
- len += numBytes*(size_t)klenp;
+ if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
+ {
+ GRIBPACK bitmap;
+ /*
+ unsigned char *bitmap;
+ bitmap = BMS_Bitmap;
+ int j = ISEC4_NumNonMissValues;
+ for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
+ {
+ if ( (bitmap[i/8]>>(7-(i&7)))&1 )
+ fsec4[i] = fsec4[--j];
+ else
+ fsec4[i] = FSEC3_MissVal;
+ }
+ */
- /* add bitmap len */
- if ( bmsIncluded ) len += (size_t)((klenp+7)>>3);
+ GRIBPACK *imask = (GRIBPACK*) Malloc((size_t)imaskSize*sizeof(GRIBPACK));
#if defined (VECTORCODE)
- lGrib = (GRIBPACK*) Malloc(len*sizeof(GRIBPACK));
- if ( lGrib == NULL ) SysError("No Memory!");
+ (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
+ GRIBPACK *pbitmap = imask;
#else
- lGrib = CGrib;
+ GRIBPACK *pbitmap = BMS_Bitmap;
#endif
- isLen = 8;
- encodeIS(lGrib, &gribLen);
- lpds = &lGrib[isLen];
- pdsLen = getPdsLen(isec1);
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( int i = imaskSize/8-1; i >= 0; i-- )
+ {
+ bitmap = pbitmap[i];
+ imask[i*8+0] = 1 & (bitmap >> 7);
+ imask[i*8+1] = 1 & (bitmap >> 6);
+ imask[i*8+2] = 1 & (bitmap >> 5);
+ imask[i*8+3] = 1 & (bitmap >> 4);
+ imask[i*8+4] = 1 & (bitmap >> 3);
+ imask[i*8+5] = 1 & (bitmap >> 2);
+ imask[i*8+6] = 1 & (bitmap >> 1);
+ imask[i*8+7] = 1 & (bitmap);
+ }
- encodePDS(lpds, pdsLen, isec1);
- gribLen += pdsLen;
- /*
- if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
- {
- static int lwarn_cplx = TRUE;
+ int j = 0;
+ for ( int i = 0; i < ISEC4_NumValues; i++ )
+ if ( imask[i] ) j++;
- if ( lwarn_cplx )
- Message("Complex packing of spectral data unsupported, using simple packing!");
+ if ( ISEC4_NumNonMissValues != j )
+ {
+ if ( dfunc != 'J' && ISEC4_NumBits != 0 )
+ Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
+ j, ISEC4_NumNonMissValues);
- isec2[5] = 1;
- isec4[3] = 0;
+ ISEC4_NumNonMissValues = j;
+ }
- lwarn_cplx = FALSE;
- }
- */
- TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
- /*
- ----------------------------------------------------------------
- BMS Bit-Map Section Section (Section 3)
- ----------------------------------------------------------------
- */
- if ( bmsIncluded )
- {
- TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
- }
- else
- {
- fsec4size = ISEC4_NumValues;
+ if ( dfunc != 'J' )
+ {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( int i = ISEC4_NumValues-1; i >= 0; i-- )
+ fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
+ }
+
+ Free(imask);
+ }
}
- bdsstart = gribLen;
- status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
- isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
- if ( status )
+ if ( ISEC2_Reduced )
{
- *kret = status;
- return;
+ int nvalues = 0;
+ int nlat = ISEC2_NumLat;
+ int nlon = ISEC2_RowLonPtr[0];
+ for ( int ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
+ for ( int ilat = 1; ilat < nlat; ++ilat )
+ if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+
+ // int dlon = ISEC2_LastLon-ISEC2_FirstLon;
+ // if ( dlon < 0 ) dlon += 360000;
+
+ if ( nvalues != ISEC4_NumValues ) *iret = -801;
+
+ //printf("nlat %d nlon %d \n", nlat, nlon);
+ //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+
+ if ( dfunc == 'R' && *iret == -801 )
+ gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
+ ISEC4_NumValues, nvalues);
+
+ if ( dfunc == 'R' && *iret != -801 )
+ {
+ ISEC2_Reduced = 0;
+ ISEC2_NumLon = nlon;
+ ISEC4_NumValues = nlon*nlat;
+
+ lsect3 = bitmapSize > 0;
+ int lperio = 1;
+ int lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) &&
+ ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) ||
+ (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30) ||
+ (ISEC1_Parameter == 39) || (ISEC1_Parameter == 40) ||
+ (ISEC1_Parameter == 41) || (ISEC1_Parameter == 42) ||
+ (ISEC1_Parameter == 43));
+
+ (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
+
+ if ( bitmapSize > 0 )
+ {
+ int j = 0;
+ for ( int i = 0; i < ISEC4_NumValues; i++ )
+ if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
+
+ ISEC4_NumNonMissValues = j;
+ }
+ }
}
- encodeES(lGrib, &gribLen, bdsstart);
- if ( (size_t) gribLen > (size_t)kleng*sizeof(int) )
- Error("kgrib buffer too small! kleng = %d gribLen = %d", kleng, gribLen);
+ if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
+ int esLen = 4;
+ gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
-#if defined (VECTORCODE)
- if ( (size_t) gribLen > len )
- Error("lGrib buffer too small! len = %d gribLen = %d", len, gribLen);
+ if ( ISEC0_GRIB_Len )
+ if ( ISEC0_GRIB_Len < gribLen )
+ Warning("Inconsistent length of GRIB message (grib_message_size=%d < grib_record_size=%d)!", ISEC0_GRIB_Len, gribLen);
- (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
+ ISEC0_GRIB_Len = gribLen;
- Free(lGrib);
-#endif
+ *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
- ISEC0_GRIB_Len = (int)gribLen;
- ISEC0_GRIB_Version = 1;
+ // ----------------------------------------------------------------
+ // Section 9 . Abort/return to calling routine.
+ // ----------------------------------------------------------------
+ if ( ldebug )
+ {
+ gprintf(__func__, "Section 9.");
+ gprintf(__func__, "Output values set -");
- *kword = (int)((gribLen + (long)sizeof(int) - 1) / (long)sizeof(int));
+ gribPrintSec0(isec0);
+ gribPrintSec1(isec0, isec1);
+ // Print section 2 if present.
+ if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
- *kret = status;
+ if ( ! l_iorj )
+ {
+ // Print section 3 if present.
+ if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+
+ TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
+ // Special print for 2D spectra wave field real values in section 4
+ if ( (isec1[ 0] == 140) &&
+ (isec1[ 1] == 98) &&
+ (isec1[23] == 1) &&
+ ((isec1[39] == 1045) || (isec1[39] == 1081)) &&
+ ((isec1[ 5] == 250) || (isec1[ 5] == 251)) )
+ gribPrintSec4Wave(isec4);
+ }
+ }
}
#endif /* T */
@@ -19466,3437 +17626,4090 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
* End:
*/
-void encode_dummy(void)
-{
- (void) encode_array_unrolled_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
- (void) encode_array_unrolled_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
-}
-static const char grb_libvers[] = "1.7.5" " of ""Jun 3 2016"" ""14:44:00";
-const char *
-cgribexLibraryVersion(void)
-{
- return (grb_libvers);
-}
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic pop
-#endif
-
-#ifdef HAVE_CONFIG_H
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef WORDS_BIGENDIAN
-#include <limits.h>
-#endif
-
-
-static const uint32_t crctab[] = {
- 0x00000000,
- 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
- 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
- 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
- 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
- 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
- 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
- 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
- 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
- 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
- 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
- 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
- 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
- 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
- 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
- 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
- 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
- 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
- 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
- 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
- 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
- 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
- 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
- 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
- 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
- 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
- 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
- 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
- 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
- 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
- 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
- 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
- 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
- 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
- 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
- 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
- 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
- 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
- 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
- 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
- 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
- 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
- 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
- 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
- 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
- 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
- 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
- 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
-};
-
-
-uint32_t
-memcrc(const unsigned char *b, size_t n)
+/* GRIB block 0 - indicator block */
+static
+void encodeIS(GRIBPACK *lGrib, long *gribLen)
{
-/* Input arguments:
- * const char* b == byte sequence to checksum
- * size_t n == length of sequence
- */
-
-
- uint32_t s = 0;
+ long z;
+ // z = *gribLen;
- memcrc_r(&s, b, n);
+ lGrib[0] = 'G';
+ lGrib[1] = 'R';
+ lGrib[2] = 'I';
+ lGrib[3] = 'B';
- /* Extend with the length of the string. */
- while (n != 0) {
- register uint32_t c = n & 0377;
- n >>= 8;
- s = (s << 8) ^ crctab[(s >> 24) ^ c];
- }
+ // lGrib[4]-lGrib[6] contains full length of grib record.
+ // included before finished CODEGB
+ z = 7;
+ Put1Byte(1); /* grib version */
+ z = 8;
- return ~s;
+ *gribLen = z;
}
-void
-memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
+/* GRIB block 5 - end block */
+static
+void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
{
-/* Input arguments:
- * const char* b == byte sequence to checksum
- * size_t n == length of sequence
- */
-
-
- register uint32_t c, s = *state;
- register size_t n = block_len;
- register const unsigned char *b = block;
-
- for (; n > 0; --n) {
- c = (uint32_t)(*b++);
- s = (s << 8) ^ crctab[(s >> 24) ^ c];
- }
-
- *state = s;
-}
+ long z = *gribLen;
-#ifdef WORDS_BIGENDIAN
-#define SWAP_CSUM(BITWIDTH,BYTEWIDTH,NACC) \
- do { \
- register const uint##BITWIDTH##_t *b = (uint##BITWIDTH##_t *)elems; \
- for (size_t i = 0; i < num_elems; ++i) { \
- for(size_t aofs = NACC; aofs > 0; --aofs) { \
- uint##BITWIDTH##_t accum = b[i + aofs - 1]; \
- for (size_t j = 0; j < BYTEWIDTH; ++j) { \
- uint32_t c = (uint32_t)(accum & UCHAR_MAX); \
- s = (s << 8) ^ crctab[(s >> 24) ^ c]; \
- accum >>= 8; \
- } \
- } \
- } \
- } while (0)
-#endif
+ lGrib[z++] = '7';
+ lGrib[z++] = '7';
+ lGrib[z++] = '7';
+ lGrib[z++] = '7';
+ if ( z > JP24SET )
+ {
+ long bdslen = z - 4;
+ // fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET);
+ // exit(1);
+ /*
+ If a very large product, the section 4 length field holds
+ the number of bytes in the product after section 4 upto
+ the end of the padding bytes.
+ This is a fixup to get round the restriction on product lengths
+ due to the count being only 24 bits. It is only possible because
+ the (default) rounding for GRIB products is 120 bytes.
+ */
+ while ( z%120 ) lGrib[z++] = 0;
-/**
- * Does endian-swapping prior to checksumming in case platform is big-endian
- *
- * @param elems points to first first element with alignment elem_size
- * @param num_elems number of elements to process
- * @param elem_size size of each element in bytes
- */
-void
-memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
- size_t elem_size)
-{
-#ifdef WORDS_BIGENDIAN
- register uint32_t s = *state;
+ if ( z > JP23SET*120 )
+ {
+ fprintf(stderr, "Abort: GRIB1 record too large (size = %ld; max = %d)!\n", z, JP23SET*120);
+ exit(1);
+ }
- switch (elem_size)
- {
- case 1:
- memcrc_r(state, elems, num_elems * elem_size);
- return;
- case 2:
- SWAP_CSUM(16,2,1);
- break;
- case 4:
- SWAP_CSUM(32,4,1);
- break;
- case 8:
- SWAP_CSUM(64,8,1);
- break;
- case 16:
- SWAP_CSUM(64,8,2);
- break;
- }
- *state = s;
-#else
- memcrc_r(state, elems, num_elems * elem_size);
-#endif
-}
+ long itemp = z / (-120);
+ itemp = JP23SET - itemp + 1;
+ lGrib[4] = (GRIBPACK)(itemp >> 16);
+ lGrib[5] = (GRIBPACK)(itemp >> 8);
+ lGrib[6] = (GRIBPACK)itemp;
-uint32_t
-memcrc_finish(uint32_t *state, off_t total_size)
-{
- register uint32_t c, s = *state;
- register uint64_t n = (uint64_t)total_size;
+ bdslen = z - bdslen;
+ lGrib[bdsstart ] = (GRIBPACK)(bdslen >> 16);
+ lGrib[bdsstart+1] = (GRIBPACK)(bdslen >> 8);
+ lGrib[bdsstart+2] = (GRIBPACK)bdslen;
+ }
+ else
+ {
+ lGrib[4] = (GRIBPACK)(z >> 16);
+ lGrib[5] = (GRIBPACK)(z >> 8);
+ lGrib[6] = (GRIBPACK)z;
- /* Extend with the length of the string. */
- while (n != 0) {
- c = n & 0377;
- n >>= 8;
- s = (s << 8) ^ crctab[(s >> 24) ^ c];
- }
+ while ( z%8 ) lGrib[z++] = 0;
+ }
- return ~s;
+ *gribLen = z;
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined(HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <errno.h>
+/* GRIB block 1 - product definition block. */
-#if !defined(HAVE_CONFIG_H) && !defined(HAVE_MALLOC_H) && defined(SX)
-# define HAVE_MALLOC_H
-#endif
+#define DWD_extension_253_len 38
+#define DWD_extension_254_len 26
+#define ECMWF_extension_1_len 24
+#define MPIM_extension_1_len 18
-#if defined(HAVE_MALLOC_H)
-# include <malloc.h>
-#endif
+static
+long getLocalExtLen(int *isec1)
+{
+ long extlen = 0;
+ if ( ISEC1_LocalFLag )
+ {
+ if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
+ {
+ if ( isec1[36] == 254 ) extlen = DWD_extension_254_len;
+ else if ( isec1[36] == 253 ) extlen = DWD_extension_253_len;
+ }
+ else if ( ISEC1_CenterID == 98 )
+ {
+ if ( isec1[36] == 1 ) extlen = ECMWF_extension_1_len;
+ }
+ else if ( ISEC1_CenterID == 252 )
+ {
+ if ( isec1[36] == 1 ) extlen = MPIM_extension_1_len;
+ }
+ }
-enum {MALLOC_FUNC=0, CALLOC_FUNC, REALLOC_FUNC, FREE_FUNC};
-static const char *memfunc[] = {"Malloc", "Calloc", "Realloc", "Free"};
+ return extlen;
+}
-#undef MEM_UNDEFID
-#define MEM_UNDEFID -1
+static
+long getPdsLen(int *isec1)
+{
+ long pdslen = 28;
-#define MEM_MAXNAME 32 /* Min = 8, for "unknown" ! */
+ pdslen += getLocalExtLen(isec1);
-static int dmemory_ExitOnError = 1;
+ return pdslen;
+}
-typedef struct
+static
+void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
{
- void *ptr;
- size_t size;
- size_t nobj;
- int item;
- int mtype;
- int line;
- char filename[MEM_MAXNAME];
- char functionname[MEM_MAXNAME];
-}
-MemTable_t;
+ long z = *zs;
-static MemTable_t *memTable;
-static size_t memTableSize = 0;
-static long memAccess = 0;
+ long localextlen = getLocalExtLen(isec1);
+ for ( long i = 0; i < localextlen-2; i++ ) Put1Byte(isec1[24+i]);
-static size_t MemObjs = 0;
-static size_t MaxMemObjs = 0;
-static size_t MemUsed = 0;
-static size_t MaxMemUsed = 0;
+ int isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier */
+ Put2Byte(isvn); /* DWD run type (0=main, 2=ass, 3=test) */
-static int MEM_Debug = 0; /* If set to 1, debugging */
-static int MEM_Info = 0; /* If set to 1, print mem table at exit */
+ *zs = z;
+}
static
-const char *get_filename(const char *file)
+void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
{
- const char *fnptr = strrchr(file, '/');
- if ( fnptr ) fnptr++;
- else fnptr = (char *) file;
+ long z = *zs;
- return fnptr;
-}
+ long localextlen = DWD_extension_254_len;
+ for ( long i = 0; i < localextlen-2; i++ ) Put1Byte(isec1[24+i]);
+ int isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier */
+ Put2Byte(isvn); /* DWD run type (0=main, 2=ass, 3=test) */
+ Put1Byte(isec1[50]); /* 55 User id, specified by table */
+ Put2Byte(isec1[51]); /* 56 Experiment identifier */
+ Put2Byte(isec1[52]); /* 58 Ensemble identification by table */
+ Put2Byte(isec1[53]); /* 60 Number of ensemble members */
+ Put2Byte(isec1[54]); /* 62 Actual number of ensemble member */
+ Put1Byte(isec1[55]); /* 64 Model major version number */
+ Put1Byte(isec1[56]); /* 65 Model minor version number */
+ Put1Byte(0); /* 66 Blank for even buffer length */
-void memDebug(int debug)
-{
- MEM_Debug = debug;
+ *zs = z;
}
-/* If we're not using GNU C, elide __attribute__ */
-#if ! defined __GNUC__ && ! defined __attribute__
-# define __attribute__(x) /*NOTHING*/
-#endif
-
-static
-void memInternalProblem(const char *caller, const char *fmt, ...)
- __attribute__((noreturn));
-static
-void memError(const char *caller, const char *file, int line, size_t size)
- __attribute__((noreturn));
-
static
-void memInternalProblem(const char *functionname, const char *fmt, ...)
+void encodePDS_ECMWF_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
{
- va_list args;
+ long z = *zs;
- va_start(args, fmt);
+ long localextlen = getLocalExtLen(isec1);
+ for ( long i = 0; i < localextlen-12; i++ ) Put1Byte(isec1[24+i]);
+ /* 12 bytes explicitly encoded below: */
+ Put1Byte(isec1[36]); /* ECMWF local GRIB use definition identifier */
+ /* 1=MARS labelling or ensemble fcst. data */
+ Put1Byte(isec1[37]); /* Class */
+ Put1Byte(isec1[38]); /* Type */
+ Put2Byte(isec1[39]); /* Stream */
- printf("\n");
- fprintf(stderr, "Internal problem (%s) : ", functionname);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
+ /* Version number or experiment identifier */
+ Put1Byte(((unsigned char*) &isec1[40])[0]);
+ Put1Byte(((unsigned char*) &isec1[40])[1]);
+ Put1Byte(((unsigned char*) &isec1[40])[2]);
+ Put1Byte(((unsigned char*) &isec1[40])[3]);
- va_end(args);
+ Put1Byte(isec1[41]); /* Ensemble forecast number */
+ Put1Byte(isec1[42]); /* Total number of forecasts in ensemble */
+ Put1Byte(0); /* (Spare) */
- exit(EXIT_FAILURE);
+ *zs = z;
}
static
-void memError(const char *functionname, const char *file, int line, size_t size)
+void encodePDS_MPIM_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
{
- fputs("\n", stdout);
- fprintf(stderr, "Error (%s) : Allocation of %zu bytes failed. [ line %d file %s ]\n",
- functionname, size, line, get_filename(file));
+ long z = *zs;
- if ( errno ) perror("System error message ");
+ long localextlen = getLocalExtLen(isec1);
+ for ( long i = 0; i < localextlen-6; i++ ) Put1Byte(isec1[24+i]);
+ /* 6 bytes explicitly encoded below: */
+ Put1Byte(isec1[36]); /* MPIM local GRIB use definition identifier */
+ /* (extension identifier) */
+ Put1Byte(isec1[37]); /* type of ensemble forecast */
+ Put2Byte(isec1[38]); /* individual ensemble member */
+ Put2Byte(isec1[39]); /* number of forecasts in ensemble */
- exit(EXIT_FAILURE);
+ *zs = z;
}
+/* GRIB BLOCK 1 - PRODUCT DESCRIPTION SECTION */
static
-void memListPrintEntry(int mtype, int item, size_t size, void *ptr,
- const char *functionname, const char *file, int line)
+void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
{
- fprintf(stderr, "[%-7s ", memfunc[mtype]);
+ GRIBPACK *lGrib = lpds;
+ long z = 0;
+ int ival;
- fprintf(stderr, "memory item %3d ", item);
- fprintf(stderr, "(%6zu byte) ", size);
- fprintf(stderr, "at %p", ptr);
- if ( file != NULL )
+ int century = ISEC1_Century;
+ int year = ISEC1_Year;
+
+ if ( century < 0 )
{
- fprintf(stderr, " line %4d", line);
- fprintf(stderr, " file %s", get_filename(file));
+ century = -century;
+ year = -year;
}
- if ( functionname != NULL )
- fprintf(stderr, " (%s)", functionname);
- fprintf(stderr, "]\n");
-}
-
-static
-void memListPrintTable(void)
-{
- if ( MemObjs ) fprintf(stderr, "\nMemory table:\n");
- for ( size_t memID = 0; memID < memTableSize; memID++ )
+ Put3Byte(pdsLen); /* 0 Length of Block 1 */
+ Put1Byte(ISEC1_CodeTable); /* 3 Local table number */
+ Put1Byte(ISEC1_CenterID); /* 4 Identification of centre */
+ Put1Byte(ISEC1_ModelID); /* 5 Identification of model */
+ Put1Byte(ISEC1_GridDefinition); /* 6 Grid definition */
+ Put1Byte(ISEC1_Sec2Or3Flag); /* 7 Block 2 included */
+ Put1Byte(ISEC1_Parameter); /* 8 Parameter Code */
+ Put1Byte(ISEC1_LevelType); /* 9 Type of level */
+ if ( (ISEC1_LevelType != 20) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_99) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC_PA) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_SIGMA) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_HYBRID) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) &&
+ (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
+ (ISEC1_LevelType != 115) &&
+ (ISEC1_LevelType != 117) &&
+ (ISEC1_LevelType != 125) &&
+ (ISEC1_LevelType != 127) &&
+ (ISEC1_LevelType != 160) &&
+ (ISEC1_LevelType != 210) )
{
- if ( memTable[memID].item != MEM_UNDEFID )
- memListPrintEntry(memTable[memID].mtype, memTable[memID].item,
- memTable[memID].size*memTable[memID].nobj,
- memTable[memID].ptr, memTable[memID].functionname,
- memTable[memID].filename, memTable[memID].line);
+ Put1Byte(ISEC1_Level1);
+ Put1Byte(ISEC1_Level2);
+ }
+ else
+ {
+ Put2Byte(ISEC1_Level1); /* 10 Level */
}
- if ( MemObjs )
+ Put1Int(year); /* 12 Year of Century */
+ Put1Byte(ISEC1_Month); /* 13 Month */
+ Put1Byte(ISEC1_Day); /* 14 Day */
+ Put1Byte(ISEC1_Hour); /* 15 Hour */
+ Put1Byte(ISEC1_Minute); /* 16 Minute */
+
+ Put1Byte(ISEC1_TimeUnit); /* 17 Time unit */
+ if ( ISEC1_TimeRange == 10 )
{
- fprintf(stderr, " Memory access : %6u\n", (unsigned) memAccess);
- fprintf(stderr, " Maximum objects : %6zu\n", memTableSize);
- fprintf(stderr, " Objects used : %6u\n", (unsigned) MaxMemObjs);
- fprintf(stderr, " Objects in use : %6u\n", (unsigned) MemObjs);
- fprintf(stderr, " Memory allocated : ");
- if (MemUsed > 1024*1024*1024)
- fprintf(stderr, " %5d GB\n", (int) (MemUsed/(1024*1024*1024)));
- else if (MemUsed > 1024*1024)
- fprintf(stderr, " %5d MB\n", (int) (MemUsed/(1024*1024)));
- else if (MemUsed > 1024)
- fprintf(stderr, " %5d KB\n", (int) (MemUsed/(1024)));
- else
- fprintf(stderr, " %5d Byte\n", (int) MemUsed);
+ Put1Byte(ISEC1_TimePeriod1);
+ Put1Byte(ISEC1_TimePeriod2);
+ }
+ else if ( ISEC1_TimeRange == 113 || ISEC1_TimeRange == 0 )
+ {
+ Put1Byte(ISEC1_TimePeriod1);
+ Put1Byte(0);
+ }
+ else if ( ISEC1_TimeRange == 5 || ISEC1_TimeRange == 4 ||
+ ISEC1_TimeRange == 3 || ISEC1_TimeRange == 2 )
+ {
+ Put1Byte(0);
+ Put1Byte(ISEC1_TimePeriod2);
+ }
+ else
+ {
+ Put1Byte(0);
+ Put1Byte(0);
}
+ Put1Byte(ISEC1_TimeRange); /* 20 Timerange flag */
+ Put2Byte(ISEC1_AvgNum); /* 21 Average */
- if ( MaxMemUsed )
+ Put1Byte(ISEC1_AvgMiss); /* 23 Missing from averages */
+ Put1Byte(century); /* 24 Century */
+ Put1Byte(ISEC1_SubCenterID); /* 25 Subcenter */
+ Put2Int(ISEC1_DecScaleFactor); /* 26 Decimal scale factor */
+
+ if ( ISEC1_LocalFLag )
{
- fprintf(stderr, " Maximum memory allocated : ");
- if (MaxMemUsed > 1024*1024*1024)
- fprintf(stderr, " %5d GB\n", (int) (MaxMemUsed/(1024*1024*1024)));
- else if (MaxMemUsed > 1024*1024)
- fprintf(stderr, " %5d MB\n", (int) (MaxMemUsed/(1024*1024)));
- else if (MaxMemUsed > 1024)
- fprintf(stderr, " %5d KB\n", (int) (MaxMemUsed/(1024)));
+ if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
+ {
+ if ( isec1[36] == 254 ) encodePDS_DWD_local_Extension_254(lGrib, &z, isec1);
+ else if ( isec1[36] == 253 ) encodePDS_DWD_local_Extension_253(lGrib, &z, isec1);
+ }
+ else if ( ISEC1_CenterID == 98 )
+ {
+ if ( isec1[36] == 1 ) encodePDS_ECMWF_local_Extension_1(lGrib, &z, isec1);
+ }
+ else if ( ISEC1_CenterID == 252 )
+ {
+ if ( isec1[36] == 1 ) encodePDS_MPIM_local_Extension_1(lGrib, &z, isec1);
+ }
else
- fprintf(stderr, " %5d Byte\n", (int) MaxMemUsed);
+ {
+ long i, localextlen;
+ localextlen = getLocalExtLen(isec1);
+ for ( i = 0; i < localextlen; i++ )
+ {
+ Put1Byte(isec1[24+i]);
+ }
+ }
}
}
-static
-void memGetDebugLevel(void)
-{
- const char *envstr;
- envstr = getenv("MEMORY_INFO");
- if ( envstr && isdigit((int) envstr[0]) ) MEM_Info = atoi(envstr);
- envstr = getenv("MEMORY_DEBUG");
- if ( envstr && isdigit((int) envstr[0]) ) MEM_Debug = atoi(envstr);
- if ( MEM_Debug && !MEM_Info ) MEM_Info = 1;
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
- if ( MEM_Info ) atexit(memListPrintTable);
-}
+
+#define round_float roundf
+#define round_double round
static
-void memInit(void)
+void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
+ const T *data, T zref, T factor, size_t *gz)
{
- static int initDebugLevel = 0;
+ size_t i, z = *gz;
+ unsigned int ival;
+ int cbits, jbits;
+ unsigned int c;
+ static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+
+ /* code from gribw routine flist2bitstream */
- if ( ! initDebugLevel )
+ cbits = 8;
+ c = 0;
+ for ( i = packStart; i < datasize; i++ )
{
- memGetDebugLevel();
- initDebugLevel = 1;
+ /* note float -> unsigned int .. truncate */
+ // ival = (unsigned int)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
+ /*
+ if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
+ if ( ival < 0 ) ival = 0;
+ */
+ jbits = numBits;
+ while ( cbits <= jbits )
+ {
+ if ( cbits == 8 )
+ {
+ jbits -= 8;
+ lGrib[z++] = (ival >> jbits) & 0xFF;
+ }
+ else
+ {
+ jbits -= cbits;
+ lGrib[z++] = (GRIBPACK)((c << cbits) + ((ival >> jbits) & mask[cbits]));
+ cbits = 8;
+ c = 0;
+ }
+ }
+ /* now jbits < cbits */
+ if ( jbits )
+ {
+ c = (c << jbits) + (ival & mask[jbits]);
+ cbits -= jbits;
+ }
}
+ if ( cbits != 8 ) lGrib[z++] = (GRIBPACK)(c << cbits);
+
+ *gz = z;
}
+
static
-int memListDeleteEntry(void *ptr, size_t *size)
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+ const T *restrict data, T zref, T factor, size_t *gz)
{
- int item = MEM_UNDEFID;
- size_t memID;
+ U_BYTEORDER;
+ uint16_t *restrict sgrib = (uint16_t *) (lGrib+*gz);
- for ( memID = 0; memID < memTableSize; memID++ )
+ if ( IS_BIGENDIAN() )
{
- if ( memTable[memID].item == MEM_UNDEFID ) continue;
- if ( memTable[memID].ptr == ptr ) break;
+ for ( size_t i = 0; i < datasize; i++ )
+ {
+ // sgrib[i] = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
+ }
}
-
- if ( memID != memTableSize )
+ else
{
- MemObjs--;
- MemUsed -= memTable[memID].size * memTable[memID].nobj;
- *size = memTable[memID].size * memTable[memID].nobj;
- item = memTable[memID].item;
- memTable[memID].item = MEM_UNDEFID;
+ uint16_t ui16;
+ for ( size_t i = 0; i < datasize; i++ )
+ {
+ // ui16 = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
+ sgrib[i] = gribSwapByteOrder_uint16(ui16);
+ }
}
- return item;
+ *gz += 2*datasize;
}
-
+/*
static
-void memTableInitEntry(size_t memID)
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+ const T *restrict data, T zref, T factor, size_t *gz)
{
- if ( memID >= memTableSize )
- memInternalProblem(__func__, "memID %d undefined!", memID);
+ size_t i, z = *gz;
+ uint16_t ui16;
+ T tmp;
- memTable[memID].ptr = NULL;
- memTable[memID].item = MEM_UNDEFID;
- memTable[memID].size = 0;
- memTable[memID].nobj = 0;
- memTable[memID].mtype = MEM_UNDEFID;
- memTable[memID].line = MEM_UNDEFID;
-}
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui16 = (uint16_t) tmp;
+ lGrib[z ] = ui16 >> 8;
+ lGrib[z+1] = ui16;
+ z += 2;
+ }
+ *gz = z;
+}
+*/
static
-int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
- const char *functionname, const char *file, int line)
+void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
+ GRIBPACK *restrict lGrib,
+ const T *restrict data,
+ T zref, T factor, size_t *gz)
{
- static int item = 0;
- size_t memSize = 0;
- size_t memID = 0;
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+ uint64_t start_minmax, end_minmax;
+#endif
+ uint32_t ui32;
+ size_t i, z = *gz;
+ T tmp;
- /*
- Look for a free slot in memTable.
- (Create the table the first time through).
- */
- if ( memTableSize == 0 )
- {
- memTableSize = 8;
- memSize = memTableSize * sizeof(MemTable_t);
- memTable = (MemTable_t *) malloc(memSize);
- if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
+ data += packStart;
+ datasize -= packStart;
- for ( size_t i = 0; i < memTableSize; i++ )
- memTableInitEntry(i);
- }
- else
+ if ( numBits == 8 )
{
- while ( memID < memTableSize )
+#ifdef _GET_IBM_COUNTER
+ hpmStart(2, "pack 8 bit base");
+#endif
+
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
{
- if ( memTable[memID].item == MEM_UNDEFID ) break;
- memID++;
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ lGrib[z ] = (GRIBPACK)tmp;
+ z++;
}
+
+#ifdef _GET_IBM_COUNTER
+ hpmStop(2);
+#endif
}
- /*
- If the table overflows, double its size.
- */
- if ( memID == memTableSize )
+ else if ( numBits == 16 )
{
- memTableSize = 2*memTableSize;
- memSize = memTableSize*sizeof(MemTable_t);
- memTable = (MemTable_t*) realloc(memTable, memSize);
- if ( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
+#ifdef _GET_IBM_COUNTER
+ hpmStart(3, "pack 16 bit base");
+#elif defined _GET_X86_COUNTER
+ start_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER
+ start_minmax = mach_absolute_time();
+#endif
+ if ( sizeof(T) == sizeof(double) )
+ {
+ grib_encode_array_2byte_double(datasize, lGrib, (const double *) data, zref, factor, &z);
+ }
+ else
+ {
+ TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
+ }
- for ( size_t i = memID; i < memTableSize; i++ )
- memTableInitEntry(i);
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER
+ end_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER
+ end_minmax = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+ printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#elif defined _ENABLE_SSE4_1
+ printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#else
+ printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#endif
+#endif
+
+#ifdef _GET_IBM_COUNTER
+ hpmStop(3);
+#endif
}
+ else if ( numBits == 24 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(4, "pack 24 bit base");
+#endif
- memTable[memID].item = item;
- memTable[memID].ptr = ptr;
- memTable[memID].size = size;
- memTable[memID].nobj = nobj;
- memTable[memID].mtype = mtype;
- memTable[memID].line = line;
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui32 = (uint32_t) tmp;
+ lGrib[z ] = (GRIBPACK)(ui32 >> 16);
+ lGrib[z+1] = (GRIBPACK)(ui32 >> 8);
+ lGrib[z+2] = (GRIBPACK)ui32;
+ z += 3;
+ }
- if ( file )
+#ifdef _GET_IBM_COUNTER
+ hpmStop(4);
+#endif
+ }
+ else if ( numBits == 32 )
{
- const char *filename = get_filename(file);
- size_t len = strlen(filename);
- if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
+#ifdef _GET_IBM_COUNTER
+ hpmStart(5, "pack 32 bit base");
+#endif
- (void) memcpy(memTable[memID].filename, filename, len);
- memTable[memID].filename[len] = '\0';
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui32 = (uint32_t) tmp;
+ lGrib[z ] = (GRIBPACK)(ui32 >> 24);
+ lGrib[z+1] = (GRIBPACK)(ui32 >> 16);
+ lGrib[z+2] = (GRIBPACK)(ui32 >> 8);
+ lGrib[z+3] = (GRIBPACK)ui32;
+ z += 4;
+ }
+
+#ifdef _GET_IBM_COUNTER
+ hpmStop(5);
+#endif
}
- else
+ else if ( numBits > 0 && numBits <= 32 )
{
- (void) strcpy(memTable[memID].filename, "unknown");
+ TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
}
-
- if ( functionname )
+ else if ( numBits == 0 )
{
- size_t len = strlen(functionname);
- if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
-
- (void) memcpy(memTable[memID].functionname, functionname, len);
- memTable[memID].functionname[len] = '\0';
}
else
{
- (void) strcpy(memTable[memID].functionname, "unknown");
+ Error("Unimplemented packing factor %d!", numBits);
}
- MaxMemObjs++;
- MemObjs++;
- MemUsed += size*nobj;
- if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
-
- return item++;
+ *gz = z;
}
static
-int memListChangeEntry(void *ptrold, void *ptr, size_t size,
- const char *functionname, const char *file, int line)
+void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize,
+ GRIBPACK *restrict lGrib,
+ const T *restrict data,
+ T zref, T factor, size_t *gz)
{
- int item = MEM_UNDEFID;
- size_t memID = 0;
+ U_BYTEORDER;
+ size_t i, j, z = *gz;
+#ifdef _ARCH_PWR6
+ enum { CGRIBEX__UNROLL_DEPTH_2 = 8 };
+#else
+ enum { CGRIBEX__UNROLL_DEPTH_2 = 128 };
+#endif
+ size_t residual;
+ size_t ofs;
+ T dval[CGRIBEX__UNROLL_DEPTH_2];
- while( memID < memTableSize )
- {
- if ( memTable[memID].item != MEM_UNDEFID )
- if ( memTable[memID].ptr == ptrold ) break;
- memID++;
- }
+ data += packStart;
+ datasize -= packStart;
+ residual = datasize % CGRIBEX__UNROLL_DEPTH_2;
+ ofs = datasize - residual;
- if ( memID == memTableSize )
+ // reducing FP operations to single FMA is slowing down on pwr6 ...
+
+ if ( numBits == 8 )
{
- if ( ptrold != NULL )
- memInternalProblem(__func__, "Item at %p not found.", ptrold);
+#ifdef _GET_IBM_COUNTER
+ hpmStart(2, "pack 8 bit unrolled");
+#endif
+ unsigned char *cgrib = (unsigned char *) (lGrib + z);
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *cgrib++ = (unsigned long) dval[j];
+#else
+ *cgrib++ = (unsigned char) dval[j];
+#endif
+ }
+ z += CGRIBEX__UNROLL_DEPTH_2;
+ }
+ for (j = 0; j < residual; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < residual; j++)
+ {
+#ifdef _ARCH_PWR6
+ *cgrib++ = (unsigned long) dval[j];
+#else
+ *cgrib++ = (unsigned char) dval[j];
+#endif
+ }
+ z += residual;
+
+#ifdef _GET_IBM_COUNTER
+ hpmStop(2);
+#endif
}
- else
+ else if ( numBits == 16 )
{
- item = memTable[memID].item;
-
- size_t sizeold = memTable[memID].size*memTable[memID].nobj;
-
- memTable[memID].ptr = ptr;
- memTable[memID].size = size;
- memTable[memID].nobj = 1;
- memTable[memID].mtype = REALLOC_FUNC;
- memTable[memID].line = line;
+#ifdef _GET_IBM_COUNTER
+ hpmStart(3, "pack 16 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint16_t ival;
+#endif
+ uint16_t *sgrib = (uint16_t *) (lGrib+z);
- if ( file )
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
{
- const char *filename = get_filename(file);
- size_t len = strlen(filename);
- if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
-
- (void) memcpy(memTable[memID].filename, filename, len);
- memTable[memID].filename[len] = '\0';
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *sgrib++ = (unsigned long) dval[j];
+#else
+ *sgrib++ = (uint16_t) dval[j];
+#endif
+ }
+ z += 2*CGRIBEX__UNROLL_DEPTH_2;
+ }
+ else
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ ival = (uint16_t) dval[j];
+ *sgrib++ = gribSwapByteOrder_uint16(ival);
+ }
+ z += 2*CGRIBEX__UNROLL_DEPTH_2;
+ }
}
- else
+ for (j = 0; j < residual; j++)
{
- (void) strcpy(memTable[memID].filename, "unknown");
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
}
-
- if ( functionname )
+ if ( IS_BIGENDIAN() )
{
- size_t len = strlen(functionname);
- if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
-
- (void) memcpy(memTable[memID].functionname, functionname, len);
- memTable[memID].functionname[len] = '\0';
+ for (j = 0; j < residual; j++)
+ {
+#ifdef _ARCH_PWR6
+ *sgrib++ = (unsigned long) dval[j];
+#else
+ *sgrib++ = (uint16_t) dval[j];
+#endif
+ }
+ z += 2*residual;
}
else
{
- (void) strcpy(memTable[memID].functionname, "unknown");
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint16_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 8);
+ lGrib[z+1] = (GRIBPACK)ival;
+ z += 2;
+ }
}
-
- MemUsed -= sizeold;
- MemUsed += size;
- if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
+#ifdef _GET_IBM_COUNTER
+ hpmStop(3);
+#endif
}
-
- return item;
-}
-
-
-void *memCalloc(size_t nobjs, size_t size, const char *file, const char *functionname, int line)
-{
- void *ptr = NULL;
-
- memInit();
-
- if ( nobjs*size > 0 )
+ else if ( numBits == 24 )
{
- ptr = calloc(nobjs, size);
-
- if ( MEM_Info )
+#ifdef _GET_IBM_COUNTER
+ hpmStart(4, "pack 24 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint32_t ival;
+#endif
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
{
- memAccess++;
-
- int item = MEM_UNDEFID;
- if ( ptr ) item = memListNewEntry(CALLOC_FUNC, ptr, size, nobjs, functionname, file, line);
-
- if ( MEM_Debug ) memListPrintEntry(CALLOC_FUNC, item, size*nobjs, ptr, functionname, file, line);
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ ival = (unsigned long) dval[j];
+#else
+ ival = (uint32_t) dval[j];
+#endif
+ lGrib[z ] = (GRIBPACK)(ival >> 16);
+ lGrib[z+1] = (GRIBPACK)(ival >> 8);
+ lGrib[z+2] = (GRIBPACK)ival;
+ z += 3;
+ }
}
-
- if ( ptr == NULL && dmemory_ExitOnError )
- memError(functionname, file, line, size*nobjs);
- }
- else
- fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, file);
-
- return ptr;
-}
-
-
-void *memMalloc(size_t size, const char *file, const char *functionname, int line)
-{
- void *ptr = NULL;
-
- memInit();
-
- if ( size > 0 )
- {
- ptr = malloc(size);
-
- if ( MEM_Info )
+ for (j = 0; j < residual; j++)
{
- memAccess++;
-
- int item = MEM_UNDEFID;
- if ( ptr ) item = memListNewEntry(MALLOC_FUNC, ptr, size, 1, functionname, file, line);
-
- if ( MEM_Debug ) memListPrintEntry(MALLOC_FUNC, item, size, ptr, functionname, file, line);
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
}
-
- if ( ptr == NULL && dmemory_ExitOnError )
- memError(functionname, file, line, size);
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 16);
+ lGrib[z+1] = (GRIBPACK)(ival >> 8);
+ lGrib[z+2] = (GRIBPACK)ival;
+ z += 3;
+ }
+#ifdef _GET_IBM_COUNTER
+ hpmStop(4);
+#endif
}
- else
- fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, file);
-
- return ptr;
-}
-
-
-void *memRealloc(void *ptrold, size_t size, const char *file, const char *functionname, int line)
-{
- void *ptr = NULL;
-
- memInit();
-
- if ( size > 0 )
+ else if ( numBits == 32 )
{
- ptr = realloc(ptrold, size);
-
- if ( MEM_Info )
- {
- memAccess++;
-
- int item = MEM_UNDEFID;
- if ( ptr )
+#ifdef _GET_IBM_COUNTER
+ hpmStart(5, "pack 32 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint32_t ival;
+#endif
+ unsigned int *igrib = (unsigned int *) (lGrib + z);
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
{
- item = memListChangeEntry(ptrold, ptr, size, functionname, file, line);
-
- if ( item == MEM_UNDEFID ) item = memListNewEntry(REALLOC_FUNC, ptr, size, 1, functionname, file, line);
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *igrib = (unsigned long) dval[j];
+#else
+ *igrib = (uint32_t) dval[j];
+#endif
+ igrib++;
+ z += 4;
+ }
+ }
+ else
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 24);
+ lGrib[z+1] = (GRIBPACK)(ival >> 16);
+ lGrib[z+2] = (GRIBPACK)(ival >> 8);
+ lGrib[z+3] = (GRIBPACK)ival;
+ z += 4;
+ }
}
-
- if ( MEM_Debug ) memListPrintEntry(REALLOC_FUNC, item, size, ptr, functionname, file, line);
}
-
- if ( ptr == NULL && dmemory_ExitOnError )
- memError(functionname, file, line, size);
- }
- else
- fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, get_filename(file));
-
- return ptr;
-}
-
-
-void memFree(void *ptr, const char *file, const char *functionname, int line)
-{
- memInit();
-
- if ( MEM_Info )
- {
- int item;
- size_t size;
-
- if ( (item = memListDeleteEntry(ptr, &size)) >= 0 )
+ for (j = 0; j < residual; j++)
{
- if ( MEM_Debug ) memListPrintEntry(FREE_FUNC, item, size, ptr, functionname, file, line);
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < residual; j++)
+ {
+#ifdef _ARCH_PWR6
+ *igrib = (unsigned long) dval[j];
+#else
+ *igrib = (uint32_t) dval[j];
+#endif
+ igrib++;
+ z += 4;
+ }
}
else
{
- if ( ptr && MEM_Debug )
- fprintf(stderr, "%s info: memory entry at %p not found. [line %4d file %s (%s)]\n",
- __func__, ptr, line, get_filename(file), functionname);
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 24);
+ lGrib[z+1] = (GRIBPACK)(ival >> 16);
+ lGrib[z+2] = (GRIBPACK)(ival >> 8);
+ lGrib[z+3] = (GRIBPACK)ival;
+ z += 4;
+ }
}
+#ifdef _GET_IBM_COUNTER
+ hpmStop(5);
+#endif
}
-
- free(ptr);
-}
-
-
-size_t memTotal(void)
-{
- size_t memtotal = 0;
-#if defined (HAVE_MALLINFO)
- struct mallinfo meminfo = mallinfo();
- if ( MEM_Debug )
+ else if ( numBits > 0 && numBits <= 32 )
{
- fprintf(stderr, "arena %8zu (non-mmapped space allocated from system)\n", (size_t)meminfo.arena);
- fprintf(stderr, "ordblks %8zu (number of free chunks)\n", (size_t)meminfo.ordblks);
- fprintf(stderr, "smblks %8zu (number of fastbin blocks)\n", (size_t) meminfo.smblks);
- fprintf(stderr, "hblks %8zu (number of mmapped regions)\n", (size_t) meminfo.hblks);
- fprintf(stderr, "hblkhd %8zu (space in mmapped regions)\n", (size_t) meminfo.hblkhd);
- fprintf(stderr, "usmblks %8zu (maximum total allocated space)\n", (size_t) meminfo.usmblks);
- fprintf(stderr, "fsmblks %8zu (maximum total allocated space)\n", (size_t) meminfo.fsmblks);
- fprintf(stderr, "uordblks %8zu (total allocated space)\n", (size_t) meminfo.uordblks);
- fprintf(stderr, "fordblks %8zu (total free space)\n", (size_t) meminfo.fordblks);
- fprintf(stderr, "Memory in use: %8zu bytes\n", (size_t) meminfo.usmblks + (size_t)meminfo.uordblks);
- fprintf(stderr, "Total heap size: %8zu bytes\n", (size_t) meminfo.arena);
-
- /* malloc_stats(); */
+ TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
}
- memtotal = (size_t)meminfo.arena;
-#endif
-
- return memtotal;
-}
-
-
-void memExitOnError(void)
-{
- dmemory_ExitOnError = 1;
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#if !defined (NAMESPACE_H)
-#endif
-
-int _ExitOnError = 1; /* If set to 1, exit on error */
-int _Verbose = 1; /* If set to 1, errors are reported */
-int _Debug = 0; /* If set to 1, debugging */
-
-/* If we're not using GNU C, elide __attribute__ */
-#if ! defined __GNUC__ && ! defined __attribute__
-# define __attribute__(x) /*NOTHING*/
-#endif
-
-void SysError_(const char *caller, const char *fmt, ...)
- __attribute__((noreturn));
-
-void SysError_(const char *caller, const char *fmt, ...)
-{
- va_list args;
- int saved_errno = errno;
-
- va_start(args, fmt);
-
- printf("\n");
- fprintf(stderr, "Error (%s) : ", caller);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
-
- va_end(args);
-
- if ( saved_errno )
+ else if ( numBits == 0 )
{
- errno = saved_errno;
- perror("System error message");
+ }
+ else
+ {
+ Error("Unimplemented packing factor %d!", numBits);
}
- exit(EXIT_FAILURE);
-}
-
-
-void Error_(const char *caller, const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
-
- printf("\n");
- fprintf(stderr, "Error (%s) : ", caller);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
-
- va_end(args);
-
- if ( _ExitOnError ) exit(EXIT_FAILURE);
+ *gz = z;
}
-typedef void (*cdiAbortCFunc)(const char * caller, const char * filename,
- const char *functionname, int line,
- const char * errorString, va_list ap)
-#ifdef __GNUC__
- __attribute__((noreturn))
-#endif
-;
+#endif /* T */
-void cdiAbortC(const char * caller, const char * filename,
- const char *functionname, int line,
- const char * errorString, ... )
-{
- va_list ap;
- va_start(ap, errorString);
- cdiAbortCFunc cdiAbortC_p
- = (cdiAbortCFunc)namespaceSwitchGet(NSSWITCH_ABORT).func;
- cdiAbortC_p(caller, filename, functionname, line, errorString, ap);
- va_end(ap);
-}
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
-void
-cdiAbortC_serial(const char *caller, const char *filename,
- const char *functionname, int line,
- const char *errorString, va_list ap)
-{
- fprintf(stderr, "ERROR, %s, %s, line %d%s%s\nerrorString: \"",
- functionname, filename, line, caller?", called from ":"",
- caller?caller:"");
- vfprintf(stderr, errorString, ap);
- fputs("\"\n", stderr);
- exit(EXIT_FAILURE);
-}
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
-typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
- va_list ap);
-void Warning_(const char *caller, const char *fmt, ...)
-{
- va_list args;
+#define round_float roundf
+#define round_double round
- va_start(args, fmt);
+static
+void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
+ const T *data, T zref, T factor, size_t *gz)
+{
+ size_t i, z = *gz;
+ unsigned int ival;
+ int cbits, jbits;
+ unsigned int c;
+ static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+
+ /* code from gribw routine flist2bitstream */
- if ( _Verbose )
+ cbits = 8;
+ c = 0;
+ for ( i = packStart; i < datasize; i++ )
{
- cdiWarningFunc cdiWarning_p
- = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
- cdiWarning_p(caller, fmt, args);
+ /* note float -> unsigned int .. truncate */
+ // ival = (unsigned int)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
+ /*
+ if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
+ if ( ival < 0 ) ival = 0;
+ */
+ jbits = numBits;
+ while ( cbits <= jbits )
+ {
+ if ( cbits == 8 )
+ {
+ jbits -= 8;
+ lGrib[z++] = (ival >> jbits) & 0xFF;
+ }
+ else
+ {
+ jbits -= cbits;
+ lGrib[z++] = (GRIBPACK)((c << cbits) + ((ival >> jbits) & mask[cbits]));
+ cbits = 8;
+ c = 0;
+ }
+ }
+ /* now jbits < cbits */
+ if ( jbits )
+ {
+ c = (c << jbits) + (ival & mask[jbits]);
+ cbits -= jbits;
+ }
}
+ if ( cbits != 8 ) lGrib[z++] = (GRIBPACK)(c << cbits);
- va_end(args);
-}
-
-void cdiWarning(const char *caller, const char *fmt, va_list ap)
-{
- fprintf(stderr, "Warning (%s) : ", caller);
- vfprintf(stderr, fmt, ap);
- fputc('\n', stderr);
+ *gz = z;
}
-void Message_(const char *caller, const char *fmt, ...)
+static
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+ const T *restrict data, T zref, T factor, size_t *gz)
{
- va_list args;
-
- va_start(args, fmt);
+ U_BYTEORDER;
+ uint16_t *restrict sgrib = (uint16_t *) (lGrib+*gz);
- fprintf(stdout, "%-18s : ", caller);
- vfprintf(stdout, fmt, args);
- fprintf(stdout, "\n");
+ if ( IS_BIGENDIAN() )
+ {
+ for ( size_t i = 0; i < datasize; i++ )
+ {
+ // sgrib[i] = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
+ }
+ }
+ else
+ {
+ uint16_t ui16;
+ for ( size_t i = 0; i < datasize; i++ )
+ {
+ // ui16 = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
+ ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
+ sgrib[i] = gribSwapByteOrder_uint16(ui16);
+ }
+ }
- va_end(args);
+ *gz += 2*datasize;
}
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef EXSE_H
-#define EXSE_H
-
-enum {
- EXSE_SINGLE_PRECISION = 4,
- EXSE_DOUBLE_PRECISION = 8,
-};
+static
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+ const T *restrict data, T zref, T factor, size_t *gz)
+{
+ size_t i, z = *gz;
+ uint16_t ui16;
+ T tmp;
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
#endif
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui16 = (uint16_t) tmp;
+ lGrib[z ] = ui16 >> 8;
+ lGrib[z+1] = ui16;
+ z += 2;
+ }
+ *gz = z;
+}
+*/
+static
+void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
+ GRIBPACK *restrict lGrib,
+ const T *restrict data,
+ T zref, T factor, size_t *gz)
+{
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+ uint64_t start_minmax, end_minmax;
+#endif
+ uint32_t ui32;
+ size_t i, z = *gz;
+ T tmp;
+ data += packStart;
+ datasize -= packStart;
-enum {
- EXT_HEADER_LEN = 4,
-};
+ if ( numBits == 8 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(2, "pack 8 bit base");
+#endif
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ lGrib[z ] = (GRIBPACK)tmp;
+ z++;
+ }
-static int initExtLib = 0;
-static int extDefaultPrec = 0;
-static int extDefaultNumber = EXT_REAL;
+#ifdef _GET_IBM_COUNTER
+ hpmStop(2);
+#endif
+ }
+ else if ( numBits == 16 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(3, "pack 16 bit base");
+#elif defined _GET_X86_COUNTER
+ start_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER
+ start_minmax = mach_absolute_time();
+#endif
+ if ( sizeof(T) == sizeof(double) )
+ {
+ grib_encode_array_2byte_double(datasize, lGrib, (const double *) data, zref, factor, &z);
+ }
+ else
+ {
+ TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
+ }
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER
+ end_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER
+ end_minmax = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+ printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#elif defined _ENABLE_SSE4_1
+ printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#else
+ printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#endif
+#endif
+
+#ifdef _GET_IBM_COUNTER
+ hpmStop(3);
+#endif
+ }
+ else if ( numBits == 24 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(4, "pack 24 bit base");
+#endif
-/*
- * A version string.
- */
-#undef LIBVERSION
-#define LIBVERSION 1.4.0
-#define XSTRING(x) #x
-#define STRING(x) XSTRING(x)
-static const char ext_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__ ;
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui32 = (uint32_t) tmp;
+ lGrib[z ] = (GRIBPACK)(ui32 >> 16);
+ lGrib[z+1] = (GRIBPACK)(ui32 >> 8);
+ lGrib[z+2] = (GRIBPACK)ui32;
+ z += 3;
+ }
-const char *extLibraryVersion(void)
-{
- return ext_libvers;
-}
+#ifdef _GET_IBM_COUNTER
+ hpmStop(4);
+#endif
+ }
+ else if ( numBits == 32 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(5, "pack 32 bit base");
+#endif
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+ for ( i = 0; i < datasize; i++ )
+ {
+ // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
+ tmp = ((data[i] - zref) * factor + (T)0.5);
+ ui32 = (uint32_t) tmp;
+ lGrib[z ] = (GRIBPACK)(ui32 >> 24);
+ lGrib[z+1] = (GRIBPACK)(ui32 >> 16);
+ lGrib[z+2] = (GRIBPACK)(ui32 >> 8);
+ lGrib[z+3] = (GRIBPACK)ui32;
+ z += 4;
+ }
-static int EXT_Debug = 0; /* If set to 1, debugging */
+#ifdef _GET_IBM_COUNTER
+ hpmStop(5);
+#endif
+ }
+ else if ( numBits > 0 && numBits <= 32 )
+ {
+ TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+ }
+ else if ( numBits == 0 )
+ {
+ }
+ else
+ {
+ Error("Unimplemented packing factor %d!", numBits);
+ }
+ *gz = z;
+}
-void extDebug(int debug)
+static
+void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize,
+ GRIBPACK *restrict lGrib,
+ const T *restrict data,
+ T zref, T factor, size_t *gz)
{
- EXT_Debug = debug;
+ U_BYTEORDER;
+ size_t i, j, z = *gz;
+#ifdef _ARCH_PWR6
+ enum { CGRIBEX__UNROLL_DEPTH_2 = 8 };
+#else
+ enum { CGRIBEX__UNROLL_DEPTH_2 = 128 };
+#endif
+ size_t residual;
+ size_t ofs;
+ T dval[CGRIBEX__UNROLL_DEPTH_2];
- if ( EXT_Debug )
- Message("debug level %d", debug);
-}
+ data += packStart;
+ datasize -= packStart;
+ residual = datasize % CGRIBEX__UNROLL_DEPTH_2;
+ ofs = datasize - residual;
+ // reducing FP operations to single FMA is slowing down on pwr6 ...
-static
-void extLibInit()
-{
- const char *envName = "EXT_PRECISION";
+ if ( numBits == 8 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(2, "pack 8 bit unrolled");
+#endif
+ unsigned char *cgrib = (unsigned char *) (lGrib + z);
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *cgrib++ = (unsigned long) dval[j];
+#else
+ *cgrib++ = (unsigned char) dval[j];
+#endif
+ }
+ z += CGRIBEX__UNROLL_DEPTH_2;
+ }
+ for (j = 0; j < residual; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < residual; j++)
+ {
+#ifdef _ARCH_PWR6
+ *cgrib++ = (unsigned long) dval[j];
+#else
+ *cgrib++ = (unsigned char) dval[j];
+#endif
+ }
+ z += residual;
- char *envString = getenv(envName);
- if ( envString )
+#ifdef _GET_IBM_COUNTER
+ hpmStop(2);
+#endif
+ }
+ else if ( numBits == 16 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(3, "pack 16 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint16_t ival;
+#endif
+ uint16_t *sgrib = (uint16_t *) (lGrib+z);
+
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *sgrib++ = (unsigned long) dval[j];
+#else
+ *sgrib++ = (uint16_t) dval[j];
+#endif
+ }
+ z += 2*CGRIBEX__UNROLL_DEPTH_2;
+ }
+ else
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ ival = (uint16_t) dval[j];
+ *sgrib++ = gribSwapByteOrder_uint16(ival);
+ }
+ z += 2*CGRIBEX__UNROLL_DEPTH_2;
+ }
+ }
+ for (j = 0; j < residual; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < residual; j++)
+ {
+#ifdef _ARCH_PWR6
+ *sgrib++ = (unsigned long) dval[j];
+#else
+ *sgrib++ = (uint16_t) dval[j];
+#endif
+ }
+ z += 2*residual;
+ }
+ else
+ {
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint16_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 8);
+ lGrib[z+1] = (GRIBPACK)ival;
+ z += 2;
+ }
+ }
+#ifdef _GET_IBM_COUNTER
+ hpmStop(3);
+#endif
+ }
+ else if ( numBits == 24 )
+ {
+#ifdef _GET_IBM_COUNTER
+ hpmStart(4, "pack 24 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint32_t ival;
+#endif
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ ival = (unsigned long) dval[j];
+#else
+ ival = (uint32_t) dval[j];
+#endif
+ lGrib[z ] = (GRIBPACK)(ival >> 16);
+ lGrib[z+1] = (GRIBPACK)(ival >> 8);
+ lGrib[z+2] = (GRIBPACK)ival;
+ z += 3;
+ }
+ }
+ for (j = 0; j < residual; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 16);
+ lGrib[z+1] = (GRIBPACK)(ival >> 8);
+ lGrib[z+2] = (GRIBPACK)ival;
+ z += 3;
+ }
+#ifdef _GET_IBM_COUNTER
+ hpmStop(4);
+#endif
+ }
+ else if ( numBits == 32 )
{
- int pos = 0;
-
- if ( strlen(envString) == 2 )
+#ifdef _GET_IBM_COUNTER
+ hpmStart(5, "pack 32 bit unrolled");
+#endif
+#ifdef _ARCH_PWR6
+ unsigned long ival;
+#else
+ uint32_t ival;
+#endif
+ unsigned int *igrib = (unsigned int *) (lGrib + z);
+ for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
+ dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+#ifdef _ARCH_PWR6
+ *igrib = (unsigned long) dval[j];
+#else
+ *igrib = (uint32_t) dval[j];
+#endif
+ igrib++;
+ z += 4;
+ }
+ }
+ else
+ {
+ for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 24);
+ lGrib[z+1] = (GRIBPACK)(ival >> 16);
+ lGrib[z+2] = (GRIBPACK)(ival >> 8);
+ lGrib[z+3] = (GRIBPACK)ival;
+ z += 4;
+ }
+ }
+ }
+ for (j = 0; j < residual; j++)
{
- switch ( tolower((int) envString[pos]) )
+ // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
+ dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
+ }
+ if ( IS_BIGENDIAN() )
+ {
+ for (j = 0; j < residual; j++)
{
- case 'r':
- {
- extDefaultNumber = EXT_REAL;
- switch ( (int) envString[pos+1] )
- {
- case '4': extDefaultPrec = EXSE_SINGLE_PRECISION; break;
- case '8': extDefaultPrec = EXSE_DOUBLE_PRECISION; break;
- default:
- Message("Invalid digit in %s: %s", envName, envString);
- }
- break;
- }
- case 'c':
- {
- extDefaultNumber = EXT_COMP;
- switch ( (int) envString[pos+1] )
- {
- case '4': extDefaultPrec = EXSE_SINGLE_PRECISION; break;
- case '8': extDefaultPrec = EXSE_DOUBLE_PRECISION; break;
- default:
- Message("Invalid digit in %s: %s", envName, envString);
- }
- break;
- }
- default:
- {
- Message("Invalid character in %s: %s", envName, envString);
- break;
- }
- }
+#ifdef _ARCH_PWR6
+ *igrib = (unsigned long) dval[j];
+#else
+ *igrib = (uint32_t) dval[j];
+#endif
+ igrib++;
+ z += 4;
+ }
+ }
+ else
+ {
+ for (j = 0; j < residual; j++)
+ {
+ ival = (uint32_t) dval[j];
+ lGrib[z ] = (GRIBPACK)(ival >> 24);
+ lGrib[z+1] = (GRIBPACK)(ival >> 16);
+ lGrib[z+2] = (GRIBPACK)(ival >> 8);
+ lGrib[z+3] = (GRIBPACK)ival;
+ z += 4;
+ }
}
+#ifdef _GET_IBM_COUNTER
+ hpmStop(5);
+#endif
+ }
+ else if ( numBits > 0 && numBits <= 32 )
+ {
+ TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+ }
+ else if ( numBits == 0 )
+ {
+ }
+ else
+ {
+ Error("Unimplemented packing factor %d!", numBits);
}
- initExtLib = 1;
-}
-
-static
-void extInit(extrec_t *extp)
-{
- extp->checked = 0;
- extp->byteswap = 0;
- extp->prec = 0;
- extp->number = extDefaultNumber;
- extp->datasize = 0;
- extp->buffersize = 0;
- extp->buffer = NULL;
+ *gz = z;
}
+#endif /* T */
-void *extNew(void)
-{
- if ( ! initExtLib ) extLibInit();
-
- extrec_t *extp = (extrec_t *) Malloc(sizeof(extrec_t));
-
- extInit(extp);
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
- return (void*)extp;
-}
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
-void extDelete(void *ext)
+/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
+static
+void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
{
- extrec_t *extp = (extrec_t *) ext;
+ long z = *gribLen;
+ int exponent, mantissa;
+ int ival;
+ int pvoffset = 0xFF;
+ int gdslen = 32;
- if ( extp )
- {
- if ( extp->buffer ) Free(extp->buffer);
- Free(extp);
- }
-}
+ if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ) gdslen += 10;
-int extCheckFiletype(int fileID, int *swap)
-{
- size_t fact = 0;
- size_t data = 0;
- size_t dimxy = 0;
- int found = 0;
- unsigned char buffer[40], *pbuf;
+ if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
- if ( fileRead(fileID, buffer, 4) != 4 ) return found;
+ if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
- size_t blocklen = (size_t) get_UINT32(buffer);
- size_t sblocklen = (size_t) get_SUINT32(buffer);
+ gdslen += ISEC2_NumVCP * 4;
- if ( EXT_Debug )
- Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+ Put3Byte(gdslen); /* 0- 2 Length of Block 2 Byte 0 */
+ Put1Byte(ISEC2_NumVCP); /* 3 NV */
+ Put1Byte(pvoffset); /* 4 PV */
+ Put1Byte(ISEC2_GridType); /* 5 LatLon=0 Gauss=4 Spectral=50 */
- if ( blocklen == 16 )
+ if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
{
- *swap = 0;
- fact = blocklen/4;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
- pbuf = buffer+3*fact; dimxy = (size_t) get_UINT32(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ Put2Byte(ISEC2_PentaJ); /* 6- 7 Pentagonal resolution J */
+ Put2Byte(ISEC2_PentaK); /* 8- 9 Pentagonal resolution K */
+ Put2Byte(ISEC2_PentaM); /* 10-11 Pentagonal resolution M */
+ Put1Byte(ISEC2_RepType); /* 12 Representation type */
+ Put1Byte(ISEC2_RepMode); /* 13 Representation mode */
+ PutnZero(18); /* 14-31 reserved */
}
- else if ( blocklen == 32 )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
{
- *swap = 0;
- fact = blocklen/4;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
- pbuf = buffer+3*fact; dimxy = (size_t) get_UINT64(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ Put2Byte(ISEC2_GME_NI2);
+ Put2Byte(ISEC2_GME_NI3);
+ Put3Byte(ISEC2_GME_ND);
+ Put3Byte(ISEC2_GME_NI);
+ Put1Byte(ISEC2_GME_AFlag);
+ Put3Int(ISEC2_GME_LatPP);
+ Put3Int(ISEC2_GME_LonPP);
+ Put3Int(ISEC2_GME_LonMPL);
+ Put1Byte(ISEC2_GME_BFlag);
+ PutnZero(5);
}
- else if ( sblocklen == 16 )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
{
- *swap = 1;
- fact = sblocklen/4;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
- pbuf = buffer+3*fact; dimxy = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ Put2Byte(ISEC2_NumLon); /* 6- 7 Longitudes */
+
+ Put2Byte(ISEC2_NumLat); /* 8- 9 Latitudes */
+ Put3Int(ISEC2_FirstLat);
+ Put3Int(ISEC2_FirstLon);
+ Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
+ Put3Int(ISEC2_Lambert_Lov); /* 17-19 */
+ Put3Int(ISEC2_Lambert_dx); /* 20-22 */
+ Put3Int(ISEC2_Lambert_dy); /* 23-25 */
+ Put1Byte(ISEC2_Lambert_ProjFlag);/* 26 Projection flag */
+ Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
+ Put3Int(ISEC2_Lambert_LatS1); /* 28-30 */
+ Put3Int(ISEC2_Lambert_LatS2); /* 31-33 */
+ Put3Int(ISEC2_Lambert_LatSP); /* 34-36 */
+ Put3Int(ISEC2_Lambert_LonSP); /* 37-39 */
+ PutnZero(2); /* 34-41 */
}
- else if ( sblocklen == 32 )
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
{
- *swap = 1;
- fact = sblocklen/4;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
- pbuf = buffer+3*fact; dimxy = (size_t) get_SUINT64(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
- }
+ int numlon = ISEC2_Reduced ? 0xFFFF : ISEC2_NumLon;
+ Put2Byte(numlon); /* 6- 7 Number of Longitudes */
- fileRewind(fileID);
+ Put2Byte(ISEC2_NumLat); /* 8- 9 Number of Latitudes */
+ Put3Int(ISEC2_FirstLat);
+ Put3Int(ISEC2_FirstLon);
+ Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
+ Put3Int(ISEC2_LastLat);
+ Put3Int(ISEC2_LastLon);
+ unsigned lonIncr = (ISEC2_ResFlag == 0) ? 0xFFFF : (unsigned)ISEC2_LonIncr;
+ unsigned latIncr = (ISEC2_ResFlag == 0) ? 0xFFFF : (unsigned)ISEC2_LatIncr;
+ Put2Byte(lonIncr); /* 23-24 i - direction increment */
+ if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
+ Put2Byte(ISEC2_NumPar); /* 25-26 Latitudes Pole->Equator */
+ else
+ Put2Byte(latIncr); /* 25-26 j - direction increment */
- if ( data && dimxy*fact == data ) found = 1;
- else if ( data && dimxy*fact*2 == data ) found = 1;
+ Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
+ PutnZero(4); /* 28-31 reserved */
- if ( EXT_Debug )
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ {
+ Put3Int(ISEC2_LatSP);
+ Put3Int(ISEC2_LonSP);
+ Put1Real((double)(FSEC2_RotAngle));
+ }
+ }
+ else
{
- Message("swap = %d fact = %d", *swap, fact);
- Message("dimxy = %lu data = %lu", dimxy, data);
+ Error("Unsupported grid type %d", ISEC2_GridType);
}
- return found;
-}
-
-
-int extInqHeader(void *ext, int *header)
-{
- extrec_t *extp = (extrec_t *) ext;
-
- for ( size_t i = 0; i < EXT_HEADER_LEN; i++ )
- header[i] = extp->header[i];
+#if defined (SX)
+#pragma vdir novector /* vectorization gives wrong results on NEC */
+#endif
+ for ( long i = 0; i < ISEC2_NumVCP; ++i )
+ {
+ Put1Real((double)(fsec2[10+i]));
+ }
- if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
+ if ( ISEC2_Reduced )
+ for ( long i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
- return 0;
+ *gribLen = z;
}
-
-int extDefHeader(void *ext, const int *header)
+/* GRIB BLOCK 3 - BIT MAP SECTION */
+static
+void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
{
- extrec_t *extp = (extrec_t *) ext;
-
- for ( size_t i = 0; i < EXT_HEADER_LEN; i++ )
- extp->header[i] = header[i];
+ long z = *gribLen;
+ static bool lmissvalinfo = true;
+ // unsigned int c, imask;
- extp->datasize = (size_t)header[3];
- if ( extp->number == EXT_COMP ) extp->datasize *= 2;
+ if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
+ {
+ lmissvalinfo = false;
+ Message("Missing value = NaN is unsupported!");
+ }
- if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
+ long bitmapSize = ISEC4_NumValues;
+ long imaskSize = ((bitmapSize+7)>>3)<<3;
+ GRIBPACK *bitmap = &lGrib[z+6];
+ long fsec4size = 0;
- return 0;
-}
+#if defined (VECTORCODE)
+ unsigned int *imask = (unsigned int*) Malloc(imaskSize*sizeof(unsigned int));
+ memset(imask, 0, imaskSize*sizeof(int));
-static
-int extInqData(extrec_t *extp, int prec, void *data)
-{
- size_t i;
- int ierr = 0;
- int byteswap = extp->byteswap;
- size_t datasize = extp->datasize;
- void *buffer = extp->buffer;
- int rprec = extp->prec;
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( long i = 0; i < bitmapSize; i++ )
+ {
+ if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+ {
+ data[fsec4size++] = data[i];
+ imask[i] = 1;
+ }
+ }
- switch ( rprec )
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( long i = 0; i < imaskSize/8; i++ )
{
- case EXSE_SINGLE_PRECISION:
- {
- if ( sizeof(FLT32) == 4 )
- {
- if ( byteswap ) swap4byte(buffer, datasize);
+ bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
+ (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
+ (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
+ (imask[i*8+6] << 1) | (imask[i*8+7]);
+ }
- if ( rprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT32));
- else
- for ( i = 0; i < datasize; ++i )
- ((double *) data)[i] = (double) ((float *) buffer)[i];
- }
- else
- {
- Error("not implemented for %d byte float", sizeof(FLT32));
- }
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- if ( sizeof(FLT64) == 8 )
- {
- if ( byteswap ) swap8byte(buffer, datasize);
+ Free(imask);
+#else
+ for ( long i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
- if ( rprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT64));
- else
- for ( i = 0; i < datasize; ++i )
- ((float *) data)[i] = (float) ((double *) buffer)[i];
- }
- else
- {
- Error("not implemented for %d byte float", sizeof(FLT64));
- }
- break;
- default:
- {
- Error("unexpected data precision %d", rprec);
- break;
- }
+ for ( long i = 0; i < bitmapSize; i++ )
+ {
+ if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+ {
+ data[fsec4size++] = data[i];
+ bitmap[i/8] |= (GRIBPACK)(1<<(7-(i&7)));
+ }
}
+#endif
- return ierr;
-}
-
+ long bmsLen = imaskSize/8 + 6;
+ long bmsUnusedBits = imaskSize - bitmapSize;
-int extInqDataSP(void *ext, float *data)
-{
- return extInqData((extrec_t *)ext, EXSE_SINGLE_PRECISION, (void *) data);
-}
+ Put3Byte(bmsLen); /* 0- 2 Length of Block 3 Byte 0 */
+ Put1Byte(bmsUnusedBits);
+ Put2Byte(0);
+ *gribLen += bmsLen;
-int extInqDataDP(void *ext, double *data)
-{
- return extInqData((extrec_t *)ext, EXSE_DOUBLE_PRECISION, (void *) data);
+ *datasize = fsec4size;
}
-
-static int extDefData(void *ext, int prec, const void *data)
+/* GRIB BLOCK 4 - BINARY DATA SECTION */
+static
+int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
+ long *datstart, long *datsize, int code)
{
- extrec_t *extp = (extrec_t *) ext;
- size_t i;
- int rprec;
- void *buffer;
-
- if ( extDefaultPrec ) rprec = extDefaultPrec;
- else rprec = extp->prec;
-
- if ( ! rprec ) rprec = prec;
-
- extp->prec = rprec;
-
- int *header = extp->header;
-
- size_t datasize = (size_t)header[3];
- if ( extp->number == EXT_COMP ) datasize *= 2;
- size_t blocklen = datasize * (size_t)rprec;
-
- extp->datasize = datasize;
-
- size_t buffersize = extp->buffersize;
+ /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
+ /* Uwe Schulzweida, 6/05/2003 : Copy result to fpval to prevent integer overflow */
- if ( buffersize != blocklen )
- {
- buffersize = blocklen;
- buffer = extp->buffer;
- buffer = Realloc(buffer, buffersize);
- extp->buffer = buffer;
- extp->buffersize = buffersize;
- }
- else
- buffer = extp->buffer;
+ size_t z = (size_t)*gribLen;
+ long i;
+ int numBits;
+ int ival;
+ long PackStart = 0;
+ int Flag = 0;
+ int binscale = 0;
+ int bds_head = 11;
+ int bds_ext = 0;
+ /* ibits = BitsPerInt; */
+ int exponent, mantissa;
+ bool lspherc = false;
+ int isubset = 0, itemp = 0, itrunc = 0;
+ T factor = 1, fmin, fmax;
+ const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality */
+ /* of floating point numbers - needed */
+ /* on some platforms (eg vpp700, linux) */
+ extern int CGRIBEX_Const; /* 1: Don't pack constant fields on regular grids */
- switch ( rprec )
+ if ( isec2 )
{
- case EXSE_SINGLE_PRECISION:
- {
- if ( rprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT32));
- else
- for ( i = 0; i < datasize; i++ )
- ((float *) buffer)[i] = (float) ((double *) data)[i];
+ /* If section 2 is present, it says if data is spherical harmonic */
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- if ( rprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT64));
- else
- for ( i = 0; i < datasize; i++ )
- ((double *) buffer)[i] = (double) ((float *) data)[i];
+ lspherc = ( isec2[0] == 50 || isec2[0] == 60 ||
+ isec2[0] == 70 || isec2[0] == 80 );
- break;
- }
- default:
- {
- Error("unexpected data precision %d", rprec);
- break;
- }
+ isec4[2] = lspherc ? 128 : 0;
}
+ else
+ {
+ /* Section 4 says if it's spherical harmonic data.. */
- return 0;
-}
-
-
-int extDefDataSP(void *ext, const float *data)
-{
- return extDefData(ext, EXSE_SINGLE_PRECISION, (void *) data);
-}
-
+ lspherc = ( isec4[2] == 128 );
+ }
-int extDefDataDP(void *ext, const double *data)
-{
- return extDefData(ext, EXSE_DOUBLE_PRECISION, (void *) data);
-}
+ /* Complex packing supported for spherical harmonics. */
+ bool lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+ ( lspherc && isec2 && ( isec2[5] == 2 ) );
-int extRead(int fileID, void *ext)
-{
- extrec_t *extp = (extrec_t *) ext;
- size_t i;
- void *buffer;
- int status;
+ /* Check input specification is consistent */
- if ( ! extp->checked )
+ if ( lcomplex && isec2 )
{
- status = extCheckFiletype(fileID, &extp->byteswap);
- if ( status == 0 ) Error("Not a EXTRA file!");
- extp->checked = 1;
+ if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
+ {
+ gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+ gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+ return (807);
+ }
+ else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
+ {
+ gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+ gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+ return (807);
+ }
+ else if ( lcomplex )
+ {
+ /*
+ Truncation of full spectrum, which is supposed triangular,
+ has to be diagnosed. Define also sub-set truncation.
+ */
+ isubset = isec4[17];
+ /* When encoding, use the total number of data. */
+ itemp = isec4[0];
+ itrunc = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
+ }
}
- int byteswap = extp->byteswap;
-
- /* read header record */
- size_t blocklen = binReadF77Block(fileID, byteswap);
-
- if ( fileEOF(fileID) ) return -1;
+ if ( decscale )
+ {
+ T scale = (T) pow(10.0, (double) decscale);
+ for ( long i = 0; i < datasize; ++i ) data[i] *= scale;
+ }
- if ( EXT_Debug )
- Message("blocklen = %lu", blocklen);
+ if ( lspherc )
+ {
+ if ( lcomplex )
+ {
+ int jup = isubset;
+ int ioff = (jup+1)*(jup+2);
+ bds_ext = 4 + 3 + 4*ioff;
+ PackStart = ioff;
+ Flag = 192;
+ }
+ else
+ {
+ bds_ext = 4;
+ PackStart = 1;
+ Flag = 128;
+ }
+ }
- size_t hprec = blocklen / EXT_HEADER_LEN;
+ *datstart = bds_head + bds_ext;
- extp->prec = (int)hprec;
+ int nbpv = numBits = ISEC4_NumBits;
- switch ( hprec )
+ if ( lspherc && lcomplex )
{
- case EXSE_SINGLE_PRECISION:
- {
- INT32 tempheader[4];
- binReadInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader);
-
- for ( i = 0; i < EXT_HEADER_LEN; i++ )
- extp->header[i] = (int)tempheader[i];
+ int pcStart, pcScale;
+ pcStart = isubset;
+ pcScale = isec4[16];
+ TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
+ TEMPLATE(gather_complex,T)(data, (size_t)pcStart, (size_t)itrunc, (size_t)datasize);
+ }
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- INT64 tempheader[4];
- binReadInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader);
+ fmin = fmax = data[PackStart];
- for ( i = 0; i < EXT_HEADER_LEN; i++ )
- extp->header[i] = (int)tempheader[i];
+ TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
- break;
- }
- default:
- {
- Error("Unexpected header precision %d", hprec);
- break;
- }
- }
+ double zref = (double)fmin;
- size_t blocklen2 = binReadF77Block(fileID, byteswap);
- if ( blocklen2 != blocklen )
+ if ( CGRIBEX_Const && !lspherc )
{
- Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
- if ( blocklen2 != 0 ) return -1;
+ if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
}
- extp->datasize = (size_t)extp->header[3];
- if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
+ long blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
+ blockLength += blockLength & 1;
- blocklen = binReadF77Block(fileID, byteswap);
+ long unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
- size_t buffersize = (size_t)extp->buffersize;
+ Flag += unused_bits;
- if ( buffersize < blocklen )
- {
- buffersize = blocklen;
- buffer = extp->buffer;
- buffer = Realloc(buffer, buffersize);
- extp->buffer = buffer;
- extp->buffersize = buffersize;
- }
- else
- buffer = extp->buffer;
- size_t dprec = blocklen / extp->datasize;
+ /*
+ Adjust number of bits per value if full integer length to
+ avoid hitting most significant bit (sign bit).
+ */
+ /* if( nbpv == ibits ) nbpv = nbpv - 1; */
+ /*
+ Calculate the binary scaling factor to spread the range of
+ values over the number of bits per value.
+ Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
+ as a guideline).
+ */
+ double range = fabs(fmax - fmin);
- if ( dprec == hprec )
+ if ( fabs(fmin) < FLT_MIN ) fmin = 0;
+ /*
+ Have to allow tolerance in comparisons on some platforms
+ (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
+ to avoid clipping ranges which are a power of 2.
+ */
+ if ( range <= jpepsln )
{
- extp->number = EXT_REAL;
+ binscale = 0;
}
- else if ( dprec == 2*hprec )
+ else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
{
- dprec /= 2;
- extp->datasize *= 2;
- extp->number = EXT_COMP;
+ binscale = 0;
+ }
+ else if ( fabs(range-1.0) <= jpepsln )
+ {
+ binscale = 1 - nbpv;
+ }
+ else if ( range > 1.0 )
+ {
+ double rangec = range + jpepsln,
+ p2 = 2.0;
+ int jloop = 1;
+ while ( jloop < 128 && p2 <= rangec )
+ {
+ p2 *= 2.0;
+ ++jloop;
+ }
+ if (jloop < 128)
+ binscale = jloop - nbpv;
+ else
+ {
+ gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+ gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+ return (707);
+ }
+ }
+ else
+ {
+ double rangec = range - jpepsln, p05 = 0.5;
+ int jloop = 1;
+ while ( jloop < 127 && p05 >= rangec )
+ {
+ p05 *= 0.5;
+ jloop++;
+ }
+ if ( jloop < 127 )
+ {
+ binscale = 1 - jloop - nbpv;
+ }
+ else
+ {
+ gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+ gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+ return (707);
+ }
}
- if ( dprec != EXSE_SINGLE_PRECISION && dprec != EXSE_DOUBLE_PRECISION )
+ uint64_t max_nbpv_pow2 = (uint64_t) ((1ULL << nbpv) - 1);
+
+ if ( binscale != 0 )
{
- Warning("Unexpected data precision %d", dprec);
- return -1;
+ while ( (uint64_t)(ldexp(range, -binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+
+ factor = (T)intpow2(-binscale);
}
- fileRead(fileID, buffer, blocklen);
+ ref2ibm(&zref, BitsPerInt);
- blocklen2 = binReadF77Block(fileID, byteswap);
+ Put3Byte(blockLength); /* 0-2 Length of Block 4 */
+ Put1Byte(Flag); /* 3 Flag & Unused bits */
+ if ( binscale < 0 ) binscale = 32768 - binscale;
+ Put2Byte(binscale); /* 4-5 Scale factor */
+ Put1Real(zref); /* 6-9 Reference value */
+ Put1Byte(nbpv); /* 10 Packing size */
- if ( blocklen2 != blocklen )
+ if ( lspherc )
{
- Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
- if ( blocklen2 != 0 ) return -1;
+ if ( lcomplex )
+ {
+ int jup = isubset;
+ int ioff = (int)z + bds_ext;
+ if ( ioff > 0xFFFF ) ioff = 0;
+ Put2Byte(ioff);
+ Put2Int(isec4[16]);
+ Put1Byte(jup);
+ Put1Byte(jup);
+ Put1Byte(jup);
+ for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
+ }
+ else
+ {
+ Put1Real((double)(data[0]));
+ }
}
+ *datsize = ((datasize-PackStart)*nbpv + 7)/8;
+
+#if defined (_ARCH_PWR6)
+ TEMPLATE(encode_array_unrolled,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
+#else
+ TEMPLATE(encode_array,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
+#endif
+
+ if ( unused_bits >= 8 ) Put1Byte(0); /* Fillbyte */
+
+ *gribLen = (long)z;
+
return 0;
}
-int extWrite(int fileID, void *ext)
+void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+ T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int efunc, int *kret)
{
- extrec_t *extp = (extrec_t *) ext;
- size_t i;
- union { INT32 i32[EXT_HEADER_LEN]; INT64 i64[EXT_HEADER_LEN]; } tempheader;
- int byteswap = extp->byteswap;
- int rprec = extp->prec;
- int number = extp->number;
- int *header = extp->header;
+ long gribLen = 0; // Counter of GRIB length for output
+ long fsec4size = 0;
+ long datstart, datsize;
- /* write header record */
- size_t blocklen = EXT_HEADER_LEN * (size_t)rprec;
+ UNUSED(isec3);
+ UNUSED(efunc);
- binWriteF77Block(fileID, byteswap, blocklen);
+ grsdef();
- switch ( rprec )
- {
- case EXSE_SINGLE_PRECISION:
- {
- for ( i = 0; i < EXT_HEADER_LEN; i++ )
- tempheader.i32[i] = (INT32) header[i];
+ unsigned char *CGrib = (unsigned char *) kgrib;
- binWriteInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader.i32);
+ bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- for ( i = 0; i < EXT_HEADER_LEN; i++ )
- tempheader.i64[i] = (INT64) header[i];
+ // set max header len
+ size_t len = 16384;
- binWriteInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader.i64);
+ // add data len
+ size_t numBytes = (size_t)((ISEC4_NumBits+7)>>3);
- break;
- }
- default:
- {
- Error("unexpected header precision %d", rprec);
- break;
- }
- }
+ len += numBytes*(size_t)klenp;
- binWriteF77Block(fileID, byteswap, blocklen);
+ // add bitmap len
+ if ( bmsIncluded ) len += (size_t)((klenp+7)>>3);
- size_t datasize = (size_t)header[3];
- if ( number == EXT_COMP ) datasize *= 2;
- blocklen = datasize * (size_t)rprec;
+#if defined (VECTORCODE)
+ GRIBPACK *lGrib = (GRIBPACK*) Malloc(len*sizeof(GRIBPACK));
+ if ( lGrib == NULL ) SysError("No Memory!");
+#else
+ GRIBPACK *lGrib = CGrib;
+#endif
- binWriteF77Block(fileID, byteswap, blocklen);
+ long isLen = 8;
+ encodeIS(lGrib, &gribLen);
+ GRIBPACK *lpds = &lGrib[isLen];
+ long pdsLen = getPdsLen(isec1);
- extp->datasize = datasize;
+ encodePDS(lpds, pdsLen, isec1);
+ gribLen += pdsLen;
+ /*
+ if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
+ {
+ static bool lwarn_cplx = true;
- void *buffer = extp->buffer;
+ if ( lwarn_cplx )
+ Message("Complex packing of spectral data unsupported, using simple packing!");
- switch ( rprec )
+ isec2[5] = 1;
+ isec4[3] = 0;
+
+ lwarn_cplx = false;
+ }
+ */
+ if ( gdsIncluded ) TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
+ /*
+ ----------------------------------------------------------------
+ BMS Bit-Map Section Section (Section 3)
+ ----------------------------------------------------------------
+ */
+ if ( bmsIncluded )
{
- case EXSE_SINGLE_PRECISION:
- {
- binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
- break;
- }
- default:
- {
- Error("unexpected data precision %d", rprec);
- break;
- }
+ TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
+ }
+ else
+ {
+ fsec4size = ISEC4_NumValues;
}
- binWriteF77Block(fileID, byteswap, blocklen);
+ long bdsstart = gribLen;
+ int status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
+ isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
+ if ( status )
+ {
+ *kret = status;
+ return;
+ }
- return 0;
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ encodeES(lGrib, &gribLen, bdsstart);
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h> // gettimeofday()
+ if ( (size_t) gribLen > (size_t)kleng*sizeof(int) )
+ Error("kgrib buffer too small! kleng = %d gribLen = %d", kleng, gribLen);
+#if defined (VECTORCODE)
+ if ( (size_t) gribLen > len )
+ Error("lGrib buffer too small! len = %d gribLen = %d", len, gribLen);
+ (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
-#if ! defined (O_BINARY)
-#define O_BINARY 0
+ Free(lGrib);
#endif
-#ifndef strdupx
-#ifndef strdup
-char *strdup(const char *s);
-#endif
-#define strdupx strdup
-/*
-#define strdupx(s) \
-({ \
- const char *__old = (s); \
- size_t __len = strlen(__old) + 1; \
- char *__new = (char *) Malloc(__len); \
- (char *) memcpy(__new, __old, __len); \
-})
-*/
-#endif
+ ISEC0_GRIB_Len = (int)gribLen;
+ ISEC0_GRIB_Version = 1;
+ *kword = (int)((gribLen + (long)sizeof(int) - 1) / (long)sizeof(int));
-#if defined (HAVE_MMAP)
-# include <sys/mman.h> /* mmap() is defined in this header */
-#endif
+ *kret = status;
+}
+#endif /* T */
-#if ! defined (FALSE)
-# define FALSE 0
-#endif
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
-#if ! defined (TRUE)
-# define TRUE 1
+#ifdef T
+#undef T
#endif
+#define T float
+#ifdef T
-/* #define MAX_FILES FOPEN_MAX */
-#define MAX_FILES 4096
+/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
+static
+void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
+{
+ long z = *gribLen;
+ int exponent, mantissa;
+ int ival;
+ int pvoffset = 0xFF;
+ int gdslen = 32;
-static int _file_max = MAX_FILES;
+ if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
-static void file_initialize(void);
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ) gdslen += 10;
-static int _file_init = FALSE;
+ if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
-#if defined (HAVE_LIBPTHREAD)
-#include <pthread.h>
+ if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
-static pthread_once_t _file_init_thread = PTHREAD_ONCE_INIT;
-static pthread_mutex_t _file_mutex;
+ gdslen += ISEC2_NumVCP * 4;
-# define FILE_LOCK() pthread_mutex_lock(&_file_mutex)
-# define FILE_UNLOCK() pthread_mutex_unlock(&_file_mutex)
-# define FILE_INIT() \
- if ( _file_init == FALSE ) pthread_once(&_file_init_thread, file_initialize)
+ Put3Byte(gdslen); /* 0- 2 Length of Block 2 Byte 0 */
+ Put1Byte(ISEC2_NumVCP); /* 3 NV */
+ Put1Byte(pvoffset); /* 4 PV */
+ Put1Byte(ISEC2_GridType); /* 5 LatLon=0 Gauss=4 Spectral=50 */
+
+ if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+ {
+ Put2Byte(ISEC2_PentaJ); /* 6- 7 Pentagonal resolution J */
+ Put2Byte(ISEC2_PentaK); /* 8- 9 Pentagonal resolution K */
+ Put2Byte(ISEC2_PentaM); /* 10-11 Pentagonal resolution M */
+ Put1Byte(ISEC2_RepType); /* 12 Representation type */
+ Put1Byte(ISEC2_RepMode); /* 13 Representation mode */
+ PutnZero(18); /* 14-31 reserved */
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+ {
+ Put2Byte(ISEC2_GME_NI2);
+ Put2Byte(ISEC2_GME_NI3);
+ Put3Byte(ISEC2_GME_ND);
+ Put3Byte(ISEC2_GME_NI);
+ Put1Byte(ISEC2_GME_AFlag);
+ Put3Int(ISEC2_GME_LatPP);
+ Put3Int(ISEC2_GME_LonPP);
+ Put3Int(ISEC2_GME_LonMPL);
+ Put1Byte(ISEC2_GME_BFlag);
+ PutnZero(5);
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
+ {
+ Put2Byte(ISEC2_NumLon); /* 6- 7 Longitudes */
+
+ Put2Byte(ISEC2_NumLat); /* 8- 9 Latitudes */
+ Put3Int(ISEC2_FirstLat);
+ Put3Int(ISEC2_FirstLon);
+ Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
+ Put3Int(ISEC2_Lambert_Lov); /* 17-19 */
+ Put3Int(ISEC2_Lambert_dx); /* 20-22 */
+ Put3Int(ISEC2_Lambert_dy); /* 23-25 */
+ Put1Byte(ISEC2_Lambert_ProjFlag);/* 26 Projection flag */
+ Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
+ Put3Int(ISEC2_Lambert_LatS1); /* 28-30 */
+ Put3Int(ISEC2_Lambert_LatS2); /* 31-33 */
+ Put3Int(ISEC2_Lambert_LatSP); /* 34-36 */
+ Put3Int(ISEC2_Lambert_LonSP); /* 37-39 */
+ PutnZero(2); /* 34-41 */
+ }
+ else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON ||
+ ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN ||
+ ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ {
+ int numlon = ISEC2_Reduced ? 0xFFFF : ISEC2_NumLon;
+ Put2Byte(numlon); /* 6- 7 Number of Longitudes */
+
+ Put2Byte(ISEC2_NumLat); /* 8- 9 Number of Latitudes */
+ Put3Int(ISEC2_FirstLat);
+ Put3Int(ISEC2_FirstLon);
+ Put1Byte(ISEC2_ResFlag); /* 16 Resolution flag */
+ Put3Int(ISEC2_LastLat);
+ Put3Int(ISEC2_LastLon);
+ unsigned lonIncr = (ISEC2_ResFlag == 0) ? 0xFFFF : (unsigned)ISEC2_LonIncr;
+ unsigned latIncr = (ISEC2_ResFlag == 0) ? 0xFFFF : (unsigned)ISEC2_LatIncr;
+ Put2Byte(lonIncr); /* 23-24 i - direction increment */
+ if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
+ Put2Byte(ISEC2_NumPar); /* 25-26 Latitudes Pole->Equator */
+ else
+ Put2Byte(latIncr); /* 25-26 j - direction increment */
-#else
+ Put1Byte(ISEC2_ScanFlag); /* 27 Scanning mode */
+ PutnZero(4); /* 28-31 reserved */
-# define FILE_LOCK()
-# define FILE_UNLOCK()
-# define FILE_INIT() \
- if ( _file_init == FALSE ) file_initialize()
+ if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ {
+ Put3Int(ISEC2_LatSP);
+ Put3Int(ISEC2_LonSP);
+ Put1Real((double)(FSEC2_RotAngle));
+ }
+ }
+ else
+ {
+ Error("Unsupported grid type %d", ISEC2_GridType);
+ }
+#if defined (SX)
+#pragma vdir novector /* vectorization gives wrong results on NEC */
#endif
+ for ( long i = 0; i < ISEC2_NumVCP; ++i )
+ {
+ Put1Real((double)(fsec2[10+i]));
+ }
+ if ( ISEC2_Reduced )
+ for ( long i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
-typedef struct
-{
- int self;
- int flag; /* access and error flag */
- int eof; /* end of file flag */
- int fd; /* file descriptor used for read */
- FILE *fp; /* FILE pointer used for write */
- char *name; /* file name */
- off_t size; /* file size */
- off_t position; /* file position */
- long access; /* file access */
- off_t byteTrans; /* */
- size_t blockSize; /* file block size */
- int mode; /* file access mode */
- short type; /* file type ( 1:open 2:fopen ) */
- short bufferType; /* buffer type ( 1:std 2:mmap ) */
- size_t bufferSize; /* file buffer size */
- size_t mappedSize; /* mmap buffer size */
- char *buffer; /* file buffer */
- long bufferNumFill; /* number of buffer fill */
- char *bufferPtr; /* file buffer pointer */
- off_t bufferPos;
- off_t bufferStart;
- off_t bufferEnd;
- size_t bufferCnt;
- double time_in_sec;
+ *gribLen = z;
}
-bfile_t;
+/* GRIB BLOCK 3 - BIT MAP SECTION */
+static
+void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
+{
+ long z = *gribLen;
+ static bool lmissvalinfo = true;
+ // unsigned int c, imask;
-enum F_I_L_E_Flags
- {
- FILE_READ = 01,
- FILE_WRITE = 02,
- FILE_UNBUF = 04,
- FILE_EOF = 010,
- FILE_ERROR = 020
- };
-
+ if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
+ {
+ lmissvalinfo = false;
+ Message("Missing value = NaN is unsupported!");
+ }
-static int FileInfo = FALSE;
+ long bitmapSize = ISEC4_NumValues;
+ long imaskSize = ((bitmapSize+7)>>3)<<3;
+ GRIBPACK *bitmap = &lGrib[z+6];
+ long fsec4size = 0;
+#if defined (VECTORCODE)
+ unsigned int *imask = (unsigned int*) Malloc(imaskSize*sizeof(unsigned int));
+ memset(imask, 0, imaskSize*sizeof(int));
-#if ! defined (MIN_BUF_SIZE)
-# define MIN_BUF_SIZE 131072L
+#if defined (CRAY)
+#pragma _CRI ivdep
#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( long i = 0; i < bitmapSize; i++ )
+ {
+ if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+ {
+ data[fsec4size++] = data[i];
+ imask[i] = 1;
+ }
+ }
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+ for ( long i = 0; i < imaskSize/8; i++ )
+ {
+ bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
+ (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
+ (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
+ (imask[i*8+6] << 1) | (imask[i*8+7]);
+ }
-static size_t FileBufferSizeMin = MIN_BUF_SIZE;
-static long FileBufferSizeEnv = -1;
-static short FileBufferTypeEnv = 0;
-
-static short FileTypeRead = FILE_TYPE_OPEN;
-static short FileTypeWrite = FILE_TYPE_FOPEN;
-static int FileFlagWrite = 0;
-
-static int FILE_Debug = 0; /* If set to 1, debugging */
-
-
-static void file_table_print(void);
-
-/*
- * A version string.
- */
-#undef LIBVERSION
-#define LIBVERSION 1.8.2
-#define XSTRING(x) #x
-#define STRING(x) XSTRING(x)
-static const char file_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__;
+ Free(imask);
+#else
+ for ( long i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
-/*
- 21/05/2004 1.3.2 set min I/O Buffersize to 128k
- 31/05/2005 1.4.0 replace fileTable by _fileList
- 26/08/2005 1.4.1 fileClose with return value
- checks for all fileptr
- 01/09/2005 1.5.0 thread safe version
- 06/11/2005 1.5.1 add filePtrEOF, filePtr, filePtrGetc
- 03/02/2006 1.5.2 ansi C: define getpagesize and strdupx
- 27/12/2007 1.6.0 add FILE_TYPE_FOPEN
- 24/03/2008 1.6.1 add O_BINARY if available
- remove default HAVE_MMAP
- use HAVE_STRUCT_STAT_ST_BLKSIZE
- 22/08/2010 1.7.0 refactor
- 11/11/2010 1.7.1 update for changed interface of error.h
- 02/02/2012 1.8.0 cleanup
- 16/11/2012 1.8.1 added support for unbuffered write
- 27/06/2013 1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
- */
+ for ( long i = 0; i < bitmapSize; i++ )
+ {
+ if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+ {
+ data[fsec4size++] = data[i];
+ bitmap[i/8] |= (GRIBPACK)(1<<(7-(i&7)));
+ }
+ }
+#endif
+ long bmsLen = imaskSize/8 + 6;
+ long bmsUnusedBits = imaskSize - bitmapSize;
-typedef struct _filePtrToIdx {
- int idx;
- bfile_t *ptr;
- struct _filePtrToIdx *next;
-} filePtrToIdx;
+ Put3Byte(bmsLen); /* 0- 2 Length of Block 3 Byte 0 */
+ Put1Byte(bmsUnusedBits);
+ Put2Byte(0);
+ *gribLen += bmsLen;
-static filePtrToIdx *_fileList = NULL;
-static filePtrToIdx *_fileAvail = NULL;
+ *datasize = fsec4size;
+}
+/* GRIB BLOCK 4 - BINARY DATA SECTION */
static
-void file_list_new(void)
+int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
+ long *datstart, long *datsize, int code)
{
- assert(_fileList == NULL);
+ /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
+ /* Uwe Schulzweida, 6/05/2003 : Copy result to fpval to prevent integer overflow */
- _fileList = (filePtrToIdx *) Malloc((size_t)_file_max * sizeof (filePtrToIdx));
-}
+ size_t z = (size_t)*gribLen;
+ long i;
+ int numBits;
+ int ival;
+ long PackStart = 0;
+ int Flag = 0;
+ int binscale = 0;
+ int bds_head = 11;
+ int bds_ext = 0;
+ /* ibits = BitsPerInt; */
+ int exponent, mantissa;
+ bool lspherc = false;
+ int isubset = 0, itemp = 0, itrunc = 0;
+ T factor = 1, fmin, fmax;
+ const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality */
+ /* of floating point numbers - needed */
+ /* on some platforms (eg vpp700, linux) */
+ extern int CGRIBEX_Const; /* 1: Don't pack constant fields on regular grids */
-static
-void file_list_delete(void)
-{
- if ( _fileList )
+ if ( isec2 )
{
- Free(_fileList);
- _fileList = NULL;
- }
-}
+ /* If section 2 is present, it says if data is spherical harmonic */
-static
-void file_init_pointer(void)
-{
- int i;
+ lspherc = ( isec2[0] == 50 || isec2[0] == 60 ||
+ isec2[0] == 70 || isec2[0] == 80 );
- for ( i = 0; i < _file_max; i++ )
- {
- _fileList[i].next = _fileList + i + 1;
- _fileList[i].idx = i;
- _fileList[i].ptr = 0;
+ isec4[2] = lspherc ? 128 : 0;
}
+ else
+ {
+ /* Section 4 says if it's spherical harmonic data.. */
- _fileList[_file_max-1].next = 0;
+ lspherc = ( isec4[2] == 128 );
+ }
- _fileAvail = _fileList;
-}
+ /* Complex packing supported for spherical harmonics. */
-static
-bfile_t *file_to_pointer(int idx)
-{
- bfile_t *fileptr = NULL;
+ bool lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+ ( lspherc && isec2 && ( isec2[5] == 2 ) );
- FILE_INIT();
+ /* Check input specification is consistent */
- if ( idx >= 0 && idx < _file_max )
+ if ( lcomplex && isec2 )
{
- FILE_LOCK();
-
- fileptr = _fileList[idx].ptr;
-
- FILE_UNLOCK();
+ if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
+ {
+ gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+ gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+ return (807);
+ }
+ else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
+ {
+ gprintf(__func__, " COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+ gprintf(__func__, " COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+ return (807);
+ }
+ else if ( lcomplex )
+ {
+ /*
+ Truncation of full spectrum, which is supposed triangular,
+ has to be diagnosed. Define also sub-set truncation.
+ */
+ isubset = isec4[17];
+ /* When encoding, use the total number of data. */
+ itemp = isec4[0];
+ itrunc = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
+ }
}
- else
- Error("file index %d undefined!", idx);
-
- return (fileptr);
-}
-
-/* Create an index from a pointer */
-static
-int file_from_pointer(bfile_t *ptr)
-{
- int idx = -1;
- filePtrToIdx *newptr;
- if ( ptr )
+ if ( decscale )
{
- FILE_LOCK();
+ T scale = (T) pow(10.0, (double) decscale);
+ for ( long i = 0; i < datasize; ++i ) data[i] *= scale;
+ }
- if ( _fileAvail )
+ if ( lspherc )
+ {
+ if ( lcomplex )
{
- newptr = _fileAvail;
- _fileAvail = _fileAvail->next;
- newptr->next = 0;
- idx = newptr->idx;
- newptr->ptr = ptr;
-
- if ( FILE_Debug )
- Message("Pointer %p has idx %d from file list", ptr, idx);
+ int jup = isubset;
+ int ioff = (jup+1)*(jup+2);
+ bds_ext = 4 + 3 + 4*ioff;
+ PackStart = ioff;
+ Flag = 192;
}
else
- Warning("Too many open files (limit is %d)!", _file_max);
-
- FILE_UNLOCK();
+ {
+ bds_ext = 4;
+ PackStart = 1;
+ Flag = 128;
+ }
}
- else
- Error("Internal problem (pointer %p undefined)", ptr);
- return (idx);
-}
+ *datstart = bds_head + bds_ext;
-static
-void file_init_entry(bfile_t *fileptr)
-{
- fileptr->self = file_from_pointer(fileptr);
+ int nbpv = numBits = ISEC4_NumBits;
- fileptr->flag = 0;
- fileptr->fd = -1;
- fileptr->fp = NULL;
- fileptr->mode = 0;
- fileptr->size = 0;
- fileptr->name = NULL;
- fileptr->access = 0;
- fileptr->position = 0;
- fileptr->byteTrans = 0;
- fileptr->type = 0;
- fileptr->bufferType = 0;
- fileptr->bufferSize = 0;
- fileptr->mappedSize = 0;
- fileptr->buffer = NULL;
- fileptr->bufferNumFill = 0;
- fileptr->bufferStart = 0;
- fileptr->bufferEnd = -1;
- fileptr->bufferPos = 0;
- fileptr->bufferCnt = 0;
- fileptr->bufferPtr = NULL;
- fileptr->time_in_sec = 0.0;
-}
+ if ( lspherc && lcomplex )
+ {
+ int pcStart, pcScale;
+ pcStart = isubset;
+ pcScale = isec4[16];
+ TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
+ TEMPLATE(gather_complex,T)(data, (size_t)pcStart, (size_t)itrunc, (size_t)datasize);
+ }
-static
-bfile_t *file_new_entry(void)
-{
- bfile_t *fileptr;
+ fmin = fmax = data[PackStart];
- fileptr = (bfile_t *) Malloc(sizeof(bfile_t));
+ TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
- if ( fileptr ) file_init_entry(fileptr);
+ double zref = (double)fmin;
- return (fileptr);
-}
-static
-void file_delete_entry(bfile_t *fileptr)
-{
- int idx;
+ if ( CGRIBEX_Const && !lspherc )
+ {
+ if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
+ }
- idx = fileptr->self;
- FILE_LOCK();
+ long blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
+ blockLength += blockLength & 1;
- Free(fileptr);
+ long unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
- _fileList[idx].next = _fileAvail;
- _fileList[idx].ptr = 0;
- _fileAvail = &_fileList[idx];
+ Flag += unused_bits;
- FILE_UNLOCK();
- if ( FILE_Debug )
- Message("Removed idx %d from file list", idx);
-}
+ /*
+ Adjust number of bits per value if full integer length to
+ avoid hitting most significant bit (sign bit).
+ */
+ /* if( nbpv == ibits ) nbpv = nbpv - 1; */
+ /*
+ Calculate the binary scaling factor to spread the range of
+ values over the number of bits per value.
+ Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
+ as a guideline).
+ */
+ double range = fabs(fmax - fmin);
+
+ if ( fabs(fmin) < FLT_MIN ) fmin = 0;
+ /*
+ Have to allow tolerance in comparisons on some platforms
+ (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
+ to avoid clipping ranges which are a power of 2.
+ */
+ if ( range <= jpepsln )
+ {
+ binscale = 0;
+ }
+ else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
+ {
+ binscale = 0;
+ }
+ else if ( fabs(range-1.0) <= jpepsln )
+ {
+ binscale = 1 - nbpv;
+ }
+ else if ( range > 1.0 )
+ {
+ double rangec = range + jpepsln,
+ p2 = 2.0;
+ int jloop = 1;
+ while ( jloop < 128 && p2 <= rangec )
+ {
+ p2 *= 2.0;
+ ++jloop;
+ }
+ if (jloop < 128)
+ binscale = jloop - nbpv;
+ else
+ {
+ gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+ gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+ return (707);
+ }
+ }
+ else
+ {
+ double rangec = range - jpepsln, p05 = 0.5;
+ int jloop = 1;
+ while ( jloop < 127 && p05 >= rangec )
+ {
+ p05 *= 0.5;
+ jloop++;
+ }
+ if ( jloop < 127 )
+ {
+ binscale = 1 - jloop - nbpv;
+ }
+ else
+ {
+ gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+ gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+ return (707);
+ }
+ }
+ uint64_t max_nbpv_pow2 = (uint64_t) ((1ULL << nbpv) - 1);
-const char *fileLibraryVersion(void)
-{
- return (file_libvers);
-}
+ if ( binscale != 0 )
+ {
+ while ( (uint64_t)(ldexp(range, -binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+ factor = (T)intpow2(-binscale);
+ }
-static
-int pagesize(void)
-{
-#if defined(_SC_PAGESIZE)
- return ((int) sysconf(_SC_PAGESIZE));
-#else
-#ifndef POSIXIO_DEFAULT_PAGESIZE
-#define POSIXIO_DEFAULT_PAGESIZE 4096
-#endif
- return ((int) POSIXIO_DEFAULT_PAGESIZE);
-#endif
-}
+ ref2ibm(&zref, BitsPerInt);
-static
-double file_time()
-{
- double tseconds = 0.0;
- struct timeval mytime;
- gettimeofday(&mytime, NULL);
- tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
- return (tseconds);
-}
+ Put3Byte(blockLength); /* 0-2 Length of Block 4 */
+ Put1Byte(Flag); /* 3 Flag & Unused bits */
+ if ( binscale < 0 ) binscale = 32768 - binscale;
+ Put2Byte(binscale); /* 4-5 Scale factor */
+ Put1Real(zref); /* 6-9 Reference value */
+ Put1Byte(nbpv); /* 10 Packing size */
-void fileDebug(int debug)
-{
- FILE_Debug = debug;
+ if ( lspherc )
+ {
+ if ( lcomplex )
+ {
+ int jup = isubset;
+ int ioff = (int)z + bds_ext;
+ if ( ioff > 0xFFFF ) ioff = 0;
+ Put2Byte(ioff);
+ Put2Int(isec4[16]);
+ Put1Byte(jup);
+ Put1Byte(jup);
+ Put1Byte(jup);
+ for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
+ }
+ else
+ {
+ Put1Real((double)(data[0]));
+ }
+ }
- if ( FILE_Debug )
- Message("Debug level %d", debug);
-}
+ *datsize = ((datasize-PackStart)*nbpv + 7)/8;
+#if defined (_ARCH_PWR6)
+ TEMPLATE(encode_array_unrolled,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
+#else
+ TEMPLATE(encode_array,T)(nbpv, (size_t)PackStart, (size_t)datasize, lGrib, data, (T)zref, factor, &z);
+#endif
-void *filePtr(int fileID)
-{
- bfile_t *fileptr;
+ if ( unused_bits >= 8 ) Put1Byte(0); /* Fillbyte */
- fileptr = file_to_pointer(fileID);
+ *gribLen = (long)z;
- return (fileptr);
+ return 0;
}
-static
-void file_pointer_info(const char *caller, int fileID)
-{
- if ( FILE_Debug )
- {
- fprintf(stdout, "%-18s : ", caller);
- fprintf(stdout, "The fileID %d underlying pointer is not valid!", fileID);
- fprintf(stdout, "\n");
- }
-}
+void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+ T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
+ int kleng, int *kword, int efunc, int *kret)
+{
+ long gribLen = 0; // Counter of GRIB length for output
+ long fsec4size = 0;
+ long datstart, datsize;
+
+ UNUSED(isec3);
+ UNUSED(efunc);
-int fileSetBufferType(int fileID, int type)
-{
- int ret = 0;
- bfile_t *fileptr;
+ grsdef();
- fileptr = file_to_pointer(fileID);
+ unsigned char *CGrib = (unsigned char *) kgrib;
- if ( fileptr )
- {
- switch (type)
- {
- case FILE_BUFTYPE_STD:
- case FILE_BUFTYPE_MMAP:
- fileptr->bufferType = (short)type;
- break;
- default:
- Error("File type %d not implemented!", type);
- }
- }
+ bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
-#if ! defined (HAVE_MMAP)
- if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
-#endif
+ // set max header len
+ size_t len = 16384;
- return (ret);
-}
+ // add data len
+ size_t numBytes = (size_t)((ISEC4_NumBits+7)>>3);
-int fileFlush(int fileID)
-{
- bfile_t *fileptr;
- int retval = 0;
+ len += numBytes*(size_t)klenp;
- fileptr = file_to_pointer(fileID);
+ // add bitmap len
+ if ( bmsIncluded ) len += (size_t)((klenp+7)>>3);
- if ( fileptr ) retval = fflush(fileptr->fp);
+#if defined (VECTORCODE)
+ GRIBPACK *lGrib = (GRIBPACK*) Malloc(len*sizeof(GRIBPACK));
+ if ( lGrib == NULL ) SysError("No Memory!");
+#else
+ GRIBPACK *lGrib = CGrib;
+#endif
- return (retval);
-}
+ long isLen = 8;
+ encodeIS(lGrib, &gribLen);
+ GRIBPACK *lpds = &lGrib[isLen];
+ long pdsLen = getPdsLen(isec1);
+ encodePDS(lpds, pdsLen, isec1);
+ gribLen += pdsLen;
+ /*
+ if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
+ {
+ static bool lwarn_cplx = true;
-void fileClearerr(int fileID)
-{
- bfile_t *fileptr;
+ if ( lwarn_cplx )
+ Message("Complex packing of spectral data unsupported, using simple packing!");
- fileptr = file_to_pointer(fileID);
+ isec2[5] = 1;
+ isec4[3] = 0;
- if ( fileptr )
+ lwarn_cplx = false;
+ }
+ */
+ if ( gdsIncluded ) TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
+ /*
+ ----------------------------------------------------------------
+ BMS Bit-Map Section Section (Section 3)
+ ----------------------------------------------------------------
+ */
+ if ( bmsIncluded )
{
- if ( fileptr->mode != 'r' )
- clearerr(fileptr->fp);
+ TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
+ }
+ else
+ {
+ fsec4size = ISEC4_NumValues;
}
-}
+ long bdsstart = gribLen;
+ int status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
+ isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
+ if ( status )
+ {
+ *kret = status;
+ return;
+ }
-int filePtrEOF(void *vfileptr)
-{
- bfile_t *fileptr = (bfile_t *) vfileptr;
- int retval = 0;
+ encodeES(lGrib, &gribLen, bdsstart);
- if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
+ if ( (size_t) gribLen > (size_t)kleng*sizeof(int) )
+ Error("kgrib buffer too small! kleng = %d gribLen = %d", kleng, gribLen);
- return (retval);
-}
+#if defined (VECTORCODE)
+ if ( (size_t) gribLen > len )
+ Error("lGrib buffer too small! len = %d gribLen = %d", len, gribLen);
+ (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
-int fileEOF(int fileID)
-{
- bfile_t *fileptr;
- int retval = 0;
+ Free(lGrib);
+#endif
- fileptr = file_to_pointer(fileID);
+ ISEC0_GRIB_Len = (int)gribLen;
+ ISEC0_GRIB_Version = 1;
- if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
+ *kword = (int)((gribLen + (long)sizeof(int) - 1) / (long)sizeof(int));
- return (retval);
+ *kret = status;
}
-void fileRewind(int fileID)
-{
- fileSetPos(fileID, (off_t) 0, SEEK_SET);
- fileClearerr(fileID);
-}
+#endif /* T */
+/*
+ * Local Variables:
+ * mode: c
+ * End:
+ */
-off_t fileGetPos(int fileID)
+void encode_dummy(void)
{
- off_t filepos = 0;
- bfile_t *fileptr;
+ (void) encode_array_unrolled_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
+ (void) encode_array_unrolled_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
+}
+static const char grb_libvers[] = "1.9.0" " of ""Sep 29 2017"" ""10:16:02";
+const char *
+cgribexLibraryVersion(void)
+{
+ return (grb_libvers);
+}
- fileptr = file_to_pointer(fileID);
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic pop
+#endif
- if ( fileptr )
- {
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- filepos = fileptr->position;
- else
- filepos = ftell(fileptr->fp);
- }
+#ifdef HAVE_CONFIG_H
+#endif
- if ( FILE_Debug ) Message("Position %ld", filepos);
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#ifdef WORDS_BIGENDIAN
+#include <limits.h>
+#endif
- return (filepos);
-}
+
+static const uint32_t crctab[] = {
+ 0x00000000,
+ 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+ 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
+ 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
+ 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
+ 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
+ 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
+ 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
+ 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
+ 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
+ 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+ 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
+ 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
+ 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
+ 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
+ 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
+ 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
+ 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
+ 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
+ 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+ 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
+ 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
+ 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
+ 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
+ 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
+ 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
+ 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
+ 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
+ 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+ 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
+ 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
+ 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
+ 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
+ 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
+ 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
+ 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
+ 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
+ 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+ 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
+ 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
-int fileSetPos(int fileID, off_t offset, int whence)
+uint32_t
+memcrc(const unsigned char *b, size_t n)
{
- int status = 0;
- bfile_t *fileptr;
+/* Input arguments:
+ * const char* b == byte sequence to checksum
+ * size_t n == length of sequence
+ */
- fileptr = file_to_pointer(fileID);
- if ( FILE_Debug ) Message("Offset %8ld Whence %3d", (long) offset, whence);
+ uint32_t s = 0;
- if ( fileptr == 0 )
- {
- file_pointer_info(__func__, fileID);
- return (1);
- }
+ memcrc_r(&s, b, n);
- switch (whence)
- {
- case SEEK_SET:
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- {
- off_t position = offset;
- fileptr->position = position;
- if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
- {
- if ( fileptr->bufferType == FILE_BUFTYPE_STD )
- fileptr->bufferPos = position;
- else
- fileptr->bufferPos = position - position % pagesize();
+ /* Extend with the length of the string. */
+ while (n != 0) {
+ register uint32_t c = n & 0377;
+ n >>= 8;
+ s = (s << 8) ^ crctab[(s >> 24) ^ c];
+ }
- fileptr->bufferCnt = 0;
- fileptr->bufferPtr = NULL;
- }
- else
- {
- if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
- {
- if ( FILE_Debug )
- Message("Reset buffer pos from %ld to %ld",
- fileptr->bufferPos, fileptr->bufferEnd + 1);
- fileptr->bufferPos = fileptr->bufferEnd + 1;
- }
- fileptr->bufferCnt = (size_t)(fileptr->bufferEnd - position) + 1;
- fileptr->bufferPtr = fileptr->buffer + position - fileptr->bufferStart;
- }
- }
- else
- {
- status = fseek(fileptr->fp, offset, whence);
- }
- break;
- case SEEK_CUR:
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- {
- fileptr->position += offset;
- off_t position = fileptr->position;
- if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
- {
- if ( fileptr->bufferType == FILE_BUFTYPE_STD )
- fileptr->bufferPos = position;
- else
- fileptr->bufferPos = position - position % pagesize();
+ return ~s;
+}
- fileptr->bufferCnt = 0;
- fileptr->bufferPtr = NULL;
- }
- else
- {
- if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
- {
- if ( FILE_Debug )
- Message("Reset buffer pos from %ld to %ld",
- fileptr->bufferPos, fileptr->bufferEnd + 1);
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
+{
+/* Input arguments:
+ * const char* b == byte sequence to checksum
+ * size_t n == length of sequence
+ */
- fileptr->bufferPos = fileptr->bufferEnd + 1;
- }
- fileptr->bufferCnt -= (size_t)offset;
- fileptr->bufferPtr += offset;
- }
- }
- else
- {
- status = fseek(fileptr->fp, offset, whence);
- }
- break;
- default:
- Error("Whence = %d not implemented", whence);
- }
- if ( fileptr->position < fileptr->size )
- if ( (fileptr->flag & FILE_EOF) != 0 )
- fileptr->flag -= FILE_EOF;
+ register uint32_t c, s = *state;
+ register size_t n = block_len;
+ register const unsigned char *b = block;
- return (status);
+ for (; n > 0; --n) {
+ c = (uint32_t)(*b++);
+ s = (s << 8) ^ crctab[(s >> 24) ^ c];
+ }
+
+ *state = s;
}
-static
-void file_table_print(void)
-{
- int fileID;
- int lprintHeader = 1;
- bfile_t *fileptr;
+#ifdef WORDS_BIGENDIAN
+#define SWAP_CSUM(BITWIDTH,BYTEWIDTH,NACC) \
+ do { \
+ register const uint##BITWIDTH##_t *b = (uint##BITWIDTH##_t *)elems; \
+ for (size_t i = 0; i < num_elems; ++i) { \
+ for(size_t aofs = NACC; aofs > 0; --aofs) { \
+ uint##BITWIDTH##_t accum = b[i + aofs - 1]; \
+ for (size_t j = 0; j < BYTEWIDTH; ++j) { \
+ uint32_t c = (uint32_t)(accum & UCHAR_MAX); \
+ s = (s << 8) ^ crctab[(s >> 24) ^ c]; \
+ accum >>= 8; \
+ } \
+ } \
+ } \
+ } while (0)
+#endif
- for ( fileID = 0; fileID < _file_max; fileID++ )
- {
- fileptr = file_to_pointer(fileID);
- if ( fileptr )
- {
- if ( lprintHeader )
- {
- fprintf(stderr, "\nFile table:\n");
- fprintf(stderr, "+-----+---------+");
- fprintf(stderr, "----------------------------------------------------+\n");
- fprintf(stderr, "| ID | Mode |");
- fprintf(stderr, " Name |\n");
- fprintf(stderr, "+-----+---------+");
- fprintf(stderr, "----------------------------------------------------+\n");
- lprintHeader = 0;
- }
+/**
+ * Does endian-swapping prior to checksumming in case platform is big-endian
+ *
+ * @param elems points to first first element with alignment elem_size
+ * @param num_elems number of elements to process
+ * @param elem_size size of each element in bytes
+ */
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+ size_t elem_size)
+{
+#ifdef WORDS_BIGENDIAN
+ register uint32_t s = *state;
- fprintf(stderr, "| %3d | ", fileID);
+ switch (elem_size)
+ {
+ case 1:
+ memcrc_r(state, elems, num_elems * elem_size);
+ return;
+ case 2:
+ SWAP_CSUM(16,2,1);
+ break;
+ case 4:
+ SWAP_CSUM(32,4,1);
+ break;
+ case 8:
+ SWAP_CSUM(64,8,1);
+ break;
+ case 16:
+ SWAP_CSUM(64,8,2);
+ break;
+ }
+ *state = s;
+#else
+ memcrc_r(state, elems, num_elems * elem_size);
+#endif
+}
- switch ( fileptr->mode )
- {
- case 'r':
- fprintf(stderr, "read ");
- break;
- case 'w':
- fprintf(stderr, "write ");
- break;
- case 'a':
- fprintf(stderr, "append ");
- break;
- default:
- fprintf(stderr, "unknown");
- }
- fprintf(stderr, " | %-51s|\n", fileptr->name);
- }
- }
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size)
+{
+ register uint32_t c, s = *state;
+ register uint64_t n = (uint64_t)total_size;
- if ( lprintHeader == 0 )
- {
- fprintf(stderr, "+-----+---------+");
- fprintf(stderr, "----------------------------------------------------+\n");
- }
+ /* Extend with the length of the string. */
+ while (n != 0) {
+ c = n & 0377;
+ n >>= 8;
+ s = (s << 8) ^ crctab[(s >> 24) ^ c];
+ }
+
+ return ~s;
}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined(HAVE_CONFIG_H)
+#endif
-char *fileInqName(int fileID)
-{
- bfile_t *fileptr;
- char *name = NULL;
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
- fileptr = file_to_pointer(fileID);
+#if !defined(HAVE_CONFIG_H) && !defined(HAVE_MALLOC_H) && defined(SX)
+# define HAVE_MALLOC_H
+#endif
- if ( fileptr ) name = fileptr->name;
+#if defined(HAVE_MALLOC_H)
+# include <malloc.h>
+#endif
- return (name);
-}
+enum {MALLOC_FUNC=0, CALLOC_FUNC, REALLOC_FUNC, FREE_FUNC};
+static const char *memfunc[] = {"Malloc", "Calloc", "Realloc", "Free"};
-int fileInqMode(int fileID)
-{
- bfile_t *fileptr;
- int mode = 0;
+#undef MEM_UNDEFID
+#define MEM_UNDEFID -1
- fileptr = file_to_pointer(fileID);
+#define MEM_MAXNAME 32 /* Min = 8, for "unknown" ! */
- if ( fileptr ) mode = fileptr->mode;
+static int dmemory_ExitOnError = 1;
- return (mode);
+typedef struct
+{
+ void *ptr;
+ size_t size;
+ size_t nobj;
+ int item;
+ int mtype;
+ int line;
+ char filename[MEM_MAXNAME];
+ char functionname[MEM_MAXNAME];
}
+MemTable_t;
+
+static MemTable_t *memTable;
+static size_t memTableSize = 0;
+static long memAccess = 0;
+
+static size_t MemObjs = 0;
+static size_t MaxMemObjs = 0;
+static size_t MemUsed = 0;
+static size_t MaxMemUsed = 0;
+
+static int MEM_Debug = 0; /* If set to 1, debugging */
+static int MEM_Info = 0; /* If set to 1, print mem table at exit */
static
-long file_getenv(const char *envName)
+const char *get_filename(const char *file)
{
- char *envString;
- long envValue = -1;
- long fact = 1;
+ const char *fnptr = strrchr(file, '/');
+ if ( fnptr ) fnptr++;
+ else fnptr = (char *) file;
+
+ return fnptr;
+}
- envString = getenv(envName);
- if ( envString )
- {
- int loop;
+void memDebug(int debug)
+{
+ MEM_Debug = debug;
+}
- for ( loop = 0; loop < (int) strlen(envString); loop++ )
- {
- if ( ! isdigit((int) envString[loop]) )
- {
- switch ( tolower((int) envString[loop]) )
- {
- case 'k': fact = 1024; break;
- case 'm': fact = 1048576; break;
- case 'g': fact = 1073741824; break;
- default:
- fact = 0;
- Message("Invalid number string in %s: %s", envName, envString);
- Warning("%s must comprise only digits [0-9].",envName);
- }
- break;
- }
- }
+/* If we're not using GNU C, elide __attribute__ */
+#if ! defined __GNUC__ && ! defined __attribute__
+# define __attribute__(x) /*NOTHING*/
+#endif
+
+static
+void memInternalProblem(const char *caller, const char *fmt, ...)
+ __attribute__((noreturn));
+static
+void memError(const char *caller, const char *file, int line, size_t size)
+ __attribute__((noreturn));
- if ( fact ) envValue = fact*atol(envString);
+static
+void memInternalProblem(const char *functionname, const char *fmt, ...)
+{
+ va_list args;
- if ( FILE_Debug ) Message("Set %s to %ld", envName, envValue);
- }
+ va_start(args, fmt);
+
+ printf("\n");
+ fprintf(stderr, "Internal problem (%s) : ", functionname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
- return (envValue);
+ va_end(args);
+
+ exit(EXIT_FAILURE);
}
static
-void file_initialize(void)
+void memError(const char *functionname, const char *file, int line, size_t size)
{
- long value;
- char *envString;
-
-#if defined (HAVE_LIBPTHREAD)
- /* initialize global API mutex lock */
- pthread_mutex_init(&_file_mutex, NULL);
-#endif
-
- value = file_getenv("FILE_DEBUG");
- if ( value >= 0 ) FILE_Debug = (int) value;
+ fputs("\n", stdout);
+ fprintf(stderr, "Error (%s) : Allocation of %zu bytes failed. [ line %d file %s ]\n",
+ functionname, size, line, get_filename(file));
- value = file_getenv("FILE_MAX");
- if ( value >= 0 ) _file_max = (int) value;
+ if ( errno ) perror("System error message ");
- if ( FILE_Debug )
- Message("FILE_MAX = %d", _file_max);
+ exit(EXIT_FAILURE);
+}
- FileInfo = (int) file_getenv("FILE_INFO");
+static
+void memListPrintEntry(int mtype, int item, size_t size, void *ptr,
+ const char *functionname, const char *file, int line)
+{
+ fprintf(stderr, "[%-7s ", memfunc[mtype]);
- value = file_getenv("FILE_BUFSIZE");
- if ( value >= 0 ) FileBufferSizeEnv = value;
- else
+ fprintf(stderr, "memory item %3d ", item);
+ fprintf(stderr, "(%6zu byte) ", size);
+ fprintf(stderr, "at %p", ptr);
+ if ( file != NULL )
{
- value = file_getenv("GRIB_API_IO_BUFFER_SIZE");
- if ( value >= 0 ) FileBufferSizeEnv = value;
+ fprintf(stderr, " line %4d", line);
+ fprintf(stderr, " file %s", get_filename(file));
}
+ if ( functionname != NULL )
+ fprintf(stderr, " (%s)", functionname);
+ fprintf(stderr, "]\n");
+}
- value = file_getenv("FILE_TYPE_READ");
- if ( value > 0 )
- {
- switch (value)
- {
- case FILE_TYPE_OPEN:
- case FILE_TYPE_FOPEN:
- FileTypeRead = (short)value;
- break;
- default:
- Warning("File type %d not implemented!", value);
- }
- }
+static
+void memListPrintTable(void)
+{
+ if ( MemObjs ) fprintf(stderr, "\nMemory table:\n");
- value = file_getenv("FILE_TYPE_WRITE");
- if ( value > 0 )
+ for ( size_t memID = 0; memID < memTableSize; memID++ )
{
- switch (value)
- {
- case FILE_TYPE_OPEN:
- case FILE_TYPE_FOPEN:
- FileTypeWrite = (short)value;
- break;
- default:
- Warning("File type %d not implemented!", value);
- }
+ if ( memTable[memID].item != MEM_UNDEFID )
+ memListPrintEntry(memTable[memID].mtype, memTable[memID].item,
+ memTable[memID].size*memTable[memID].nobj,
+ memTable[memID].ptr, memTable[memID].functionname,
+ memTable[memID].filename, memTable[memID].line);
}
-#if defined (O_NONBLOCK)
- FileFlagWrite = O_NONBLOCK;
-#endif
- envString = getenv("FILE_FLAG_WRITE");
- if ( envString )
+ if ( MemObjs )
{
-#if defined (O_NONBLOCK)
- if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
-#endif
+ fprintf(stderr, " Memory access : %6u\n", (unsigned) memAccess);
+ fprintf(stderr, " Maximum objects : %6zu\n", memTableSize);
+ fprintf(stderr, " Objects used : %6u\n", (unsigned) MaxMemObjs);
+ fprintf(stderr, " Objects in use : %6u\n", (unsigned) MemObjs);
+ fprintf(stderr, " Memory allocated : ");
+ if (MemUsed > 1024*1024*1024)
+ fprintf(stderr, " %5d GB\n", (int) (MemUsed/(1024*1024*1024)));
+ else if (MemUsed > 1024*1024)
+ fprintf(stderr, " %5d MB\n", (int) (MemUsed/(1024*1024)));
+ else if (MemUsed > 1024)
+ fprintf(stderr, " %5d KB\n", (int) (MemUsed/(1024)));
+ else
+ fprintf(stderr, " %5d Byte\n", (int) MemUsed);
}
- value = file_getenv("FILE_BUFTYPE");
-#if ! defined (HAVE_MMAP)
- if ( value == FILE_BUFTYPE_MMAP )
- {
- Warning("MMAP not available!");
- value = 0;
- }
-#endif
- if ( value > 0 )
+ if ( MaxMemUsed )
{
- switch (value)
- {
- case FILE_BUFTYPE_STD:
- case FILE_BUFTYPE_MMAP:
- FileBufferTypeEnv = (short)value;
- break;
- default:
- Warning("File buffer type %d not implemented!", value);
- }
+ fprintf(stderr, " Maximum memory allocated : ");
+ if (MaxMemUsed > 1024*1024*1024)
+ fprintf(stderr, " %5d GB\n", (int) (MaxMemUsed/(1024*1024*1024)));
+ else if (MaxMemUsed > 1024*1024)
+ fprintf(stderr, " %5d MB\n", (int) (MaxMemUsed/(1024*1024)));
+ else if (MaxMemUsed > 1024)
+ fprintf(stderr, " %5d KB\n", (int) (MaxMemUsed/(1024)));
+ else
+ fprintf(stderr, " %5d Byte\n", (int) MaxMemUsed);
}
+}
- file_list_new();
- atexit(file_list_delete);
-
- FILE_LOCK();
+static
+void memGetDebugLevel(void)
+{
+ const char *envstr;
- file_init_pointer();
+ envstr = getenv("MEMORY_INFO");
+ if ( envstr && isdigit((int) envstr[0]) ) MEM_Info = atoi(envstr);
- FILE_UNLOCK();
+ envstr = getenv("MEMORY_DEBUG");
+ if ( envstr && isdigit((int) envstr[0]) ) MEM_Debug = atoi(envstr);
- if ( FILE_Debug ) atexit(file_table_print);
+ if ( MEM_Debug && !MEM_Info ) MEM_Info = 1;
- _file_init = TRUE;
+ if ( MEM_Info ) atexit(memListPrintTable);
}
static
-void file_set_buffer(bfile_t *fileptr)
+void memInit(void)
{
- size_t buffersize = 0;
+ static int initDebugLevel = 0;
- if ( fileptr->mode == 'r' )
+ if ( ! initDebugLevel )
{
- if ( FileBufferTypeEnv )
- fileptr->bufferType = FileBufferTypeEnv;
- else if ( fileptr->bufferType == 0 )
- fileptr->bufferType = FILE_BUFTYPE_STD;
-
- if ( FileBufferSizeEnv >= 0 )
- buffersize = (size_t) FileBufferSizeEnv;
- else if ( fileptr->bufferSize > 0 )
- buffersize = fileptr->bufferSize;
- else
- {
- buffersize = fileptr->blockSize * 4;
- if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
- }
-
- if ( (size_t) fileptr->size < buffersize )
- buffersize = (size_t) fileptr->size;
-
- if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
- {
- size_t blocksize = (size_t) pagesize();
- size_t minblocksize = 4 * blocksize;
- buffersize = buffersize - buffersize % minblocksize;
+ memGetDebugLevel();
+ initDebugLevel = 1;
+ }
+}
- if ( buffersize < (size_t) fileptr->size && buffersize < minblocksize )
- buffersize = minblocksize;
- }
+static
+int memListDeleteEntry(void *ptr, size_t *size)
+{
+ int item = MEM_UNDEFID;
+ size_t memID;
- if ( buffersize == 0 ) buffersize = 1;
- }
- else
+ for ( memID = 0; memID < memTableSize; memID++ )
{
- fileptr->bufferType = FILE_BUFTYPE_STD;
-
- if ( FileBufferSizeEnv >= 0 )
- buffersize = (size_t) FileBufferSizeEnv;
- else if ( fileptr->bufferSize > 0 )
- buffersize = fileptr->bufferSize;
- else
- {
- buffersize = fileptr->blockSize * 4;
- if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
- }
+ if ( memTable[memID].item == MEM_UNDEFID ) continue;
+ if ( memTable[memID].ptr == ptr ) break;
}
- if ( fileptr->bufferType == FILE_BUFTYPE_STD || fileptr->type == FILE_TYPE_FOPEN )
+ if ( memID != memTableSize )
{
- if ( buffersize > 0 )
- {
- fileptr->buffer = (char *) Malloc(buffersize);
- if ( fileptr->buffer == NULL )
- SysError("Allocation of file buffer failed!");
- }
+ MemObjs--;
+ MemUsed -= memTable[memID].size * memTable[memID].nobj;
+ *size = memTable[memID].size * memTable[memID].nobj;
+ item = memTable[memID].item;
+ memTable[memID].item = MEM_UNDEFID;
}
- if ( fileptr->type == FILE_TYPE_FOPEN )
- if ( setvbuf(fileptr->fp, fileptr->buffer, fileptr->buffer ? _IOFBF : _IONBF, buffersize) )
- SysError("setvbuf failed!");
-
- fileptr->bufferSize = buffersize;
+ return item;
}
static
-int file_fill_buffer(bfile_t *fileptr)
+void memTableInitEntry(size_t memID)
{
- ssize_t nread;
- int fd;
- long offset = 0;
- off_t retseek;
-
- if ( FILE_Debug )
- Message("file ptr = %p Cnt = %ld", fileptr, fileptr->bufferCnt);
-
- if ( (fileptr->flag & FILE_EOF) != 0 ) return (EOF);
-
- if ( fileptr->buffer == NULL ) file_set_buffer(fileptr);
+ if ( memID >= memTableSize )
+ memInternalProblem(__func__, "memID %d undefined!", memID);
- if ( fileptr->bufferSize == 0 ) return (EOF);
+ memTable[memID].ptr = NULL;
+ memTable[memID].item = MEM_UNDEFID;
+ memTable[memID].size = 0;
+ memTable[memID].nobj = 0;
+ memTable[memID].mtype = MEM_UNDEFID;
+ memTable[memID].line = MEM_UNDEFID;
+}
- fd = fileptr->fd;
+static
+int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
+ const char *functionname, const char *file, int line)
+{
+ static int item = 0;
+ size_t memSize = 0;
+ size_t memID = 0;
-#if defined (HAVE_MMAP)
- if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
+ /*
+ Look for a free slot in memTable.
+ (Create the table the first time through).
+ */
+ if ( memTableSize == 0 )
{
- if ( fileptr->bufferPos >= fileptr->size )
- {
- nread = 0;
- }
- else
- {
- xassert(fileptr->bufferSize <= SSIZE_MAX);
- nread = (ssize_t)fileptr->bufferSize;
- if ( (nread + fileptr->bufferPos) > fileptr->size )
- nread = fileptr->size - fileptr->bufferPos;
-
- if ( fileptr->buffer )
- {
- int ret;
- ret = munmap(fileptr->buffer, fileptr->mappedSize);
- if ( ret == -1 ) SysError("munmap error for read %s", fileptr->name);
- fileptr->buffer = NULL;
- }
-
- fileptr->mappedSize = (size_t)nread;
-
- fileptr->buffer = (char*) mmap(NULL, (size_t) nread, PROT_READ, MAP_PRIVATE, fd, fileptr->bufferPos);
-
- if ( fileptr->buffer == MAP_FAILED ) SysError("mmap error for read %s", fileptr->name);
+ memTableSize = 8;
+ memSize = memTableSize * sizeof(MemTable_t);
+ memTable = (MemTable_t *) malloc(memSize);
+ if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
- offset = fileptr->position - fileptr->bufferPos;
- }
+ for ( size_t i = 0; i < memTableSize; i++ )
+ memTableInitEntry(i);
}
else
-#endif
{
- retseek = lseek(fileptr->fd, fileptr->bufferPos, SEEK_SET);
- if ( retseek == (off_t)-1 )
- SysError("lseek error at pos %ld file %s", (long) fileptr->bufferPos, fileptr->name);
-
- nread = read(fd, fileptr->buffer, fileptr->bufferSize);
+ while ( memID < memTableSize )
+ {
+ if ( memTable[memID].item == MEM_UNDEFID ) break;
+ memID++;
+ }
}
-
- if ( nread <= 0 )
+ /*
+ If the table overflows, double its size.
+ */
+ if ( memID == memTableSize )
{
- if ( nread == 0 )
- fileptr->flag |= FILE_EOF;
- else
- fileptr->flag |= FILE_ERROR;
+ memTableSize = 2*memTableSize;
+ memSize = memTableSize*sizeof(MemTable_t);
+ memTable = (MemTable_t*) realloc(memTable, memSize);
+ if ( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
- fileptr->bufferCnt = 0;
- return (EOF);
+ for ( size_t i = memID; i < memTableSize; i++ )
+ memTableInitEntry(i);
}
- fileptr->bufferPtr = fileptr->buffer;
- fileptr->bufferCnt = (size_t)nread;
+ memTable[memID].item = item;
+ memTable[memID].ptr = ptr;
+ memTable[memID].size = size;
+ memTable[memID].nobj = nobj;
+ memTable[memID].mtype = mtype;
+ memTable[memID].line = line;
- fileptr->bufferStart = fileptr->bufferPos;
- fileptr->bufferPos += nread;
- fileptr->bufferEnd = fileptr->bufferPos - 1;
+ if ( file )
+ {
+ const char *filename = get_filename(file);
+ size_t len = strlen(filename);
+ if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
- if ( FILE_Debug )
+ (void) memcpy(memTable[memID].filename, filename, len);
+ memTable[memID].filename[len] = '\0';
+ }
+ else
{
- Message("fileID = %d Val = %d", fileptr->self, (int) fileptr->buffer[0]);
- Message("fileID = %d Start = %ld", fileptr->self, fileptr->bufferStart);
- Message("fileID = %d End = %ld", fileptr->self, fileptr->bufferEnd);
- Message("fileID = %d nread = %ld", fileptr->self, nread);
- Message("fileID = %d offset = %ld", fileptr->self, offset);
- Message("fileID = %d Pos = %ld", fileptr->self, fileptr->bufferPos);
- Message("fileID = %d postion = %ld", fileptr->self, fileptr->position);
+ (void) strcpy(memTable[memID].filename, "unknown");
}
- if ( offset > 0 )
+ if ( functionname )
{
- if ( offset > nread )
- Error("Internal problem with buffer handling. nread = %d offset = %d", nread, offset);
+ size_t len = strlen(functionname);
+ if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
- fileptr->bufferPtr += offset;
- fileptr->bufferCnt -= (size_t)offset;
+ (void) memcpy(memTable[memID].functionname, functionname, len);
+ memTable[memID].functionname[len] = '\0';
+ }
+ else
+ {
+ (void) strcpy(memTable[memID].functionname, "unknown");
}
- fileptr->bufferNumFill++;
+ MaxMemObjs++;
+ MemObjs++;
+ MemUsed += size*nobj;
+ if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
- return ((unsigned char) *fileptr->bufferPtr);
+ return item++;
}
static
-void file_copy_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
+int memListChangeEntry(void *ptrold, void *ptr, size_t size,
+ const char *functionname, const char *file, int line)
{
- if ( FILE_Debug )
- Message("size = %ld Cnt = %ld", size, fileptr->bufferCnt);
-
- if ( fileptr->bufferCnt < size )
- Error("Buffer too small. bufferCnt = %d", fileptr->bufferCnt);
+ int item = MEM_UNDEFID;
+ size_t memID = 0;
- if ( size == 1 )
+ while( memID < memTableSize )
{
- ((char *)ptr)[0] = fileptr->bufferPtr[0];
+ if ( memTable[memID].item != MEM_UNDEFID )
+ if ( memTable[memID].ptr == ptrold ) break;
+ memID++;
+ }
- fileptr->bufferPtr++;
- fileptr->bufferCnt--;
+ if ( memID == memTableSize )
+ {
+ if ( ptrold != NULL )
+ memInternalProblem(__func__, "Item at %p not found.", ptrold);
}
else
{
- memcpy(ptr, fileptr->bufferPtr, size);
+ item = memTable[memID].item;
- fileptr->bufferPtr += size;
- fileptr->bufferCnt -= size;
- }
-}
+ size_t sizeold = memTable[memID].size*memTable[memID].nobj;
-static
-size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
-{
- size_t nread, rsize;
- size_t offset = 0;
+ memTable[memID].ptr = ptr;
+ memTable[memID].size = size;
+ memTable[memID].nobj = 1;
+ memTable[memID].mtype = REALLOC_FUNC;
+ memTable[memID].line = line;
- if ( FILE_Debug )
- Message("size = %ld Cnt = %ld", size, (long) fileptr->bufferCnt);
+ if ( file )
+ {
+ const char *filename = get_filename(file);
+ size_t len = strlen(filename);
+ if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
- if ( ((long)fileptr->bufferCnt) < 0L )
- Error("Internal problem. bufferCnt = %ld", (long) fileptr->bufferCnt);
+ (void) memcpy(memTable[memID].filename, filename, len);
+ memTable[memID].filename[len] = '\0';
+ }
+ else
+ {
+ (void) strcpy(memTable[memID].filename, "unknown");
+ }
- rsize = size;
+ if ( functionname )
+ {
+ size_t len = strlen(functionname);
+ if ( len > MEM_MAXNAME-1 ) len = MEM_MAXNAME-1;
- while ( fileptr->bufferCnt < rsize )
- {
- nread = fileptr->bufferCnt;
- /*
- fprintf(stderr, "rsize = %d nread = %d\n", (int) rsize, (int) nread);
- */
- if ( nread > (size_t) 0 )
- file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
- offset += nread;
- if ( nread < rsize )
- rsize -= nread;
+ (void) memcpy(memTable[memID].functionname, functionname, len);
+ memTable[memID].functionname[len] = '\0';
+ }
else
- rsize = 0;
+ {
+ (void) strcpy(memTable[memID].functionname, "unknown");
+ }
- if ( file_fill_buffer(fileptr) == EOF ) break;
+ MemUsed -= sizeold;
+ MemUsed += size;
+ if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
}
- nread = size - offset;
-
- if ( fileptr->bufferCnt < nread ) nread = fileptr->bufferCnt;
-
- if ( nread > (unsigned) 0 )
- file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
-
- return (nread+offset);
-}
-
-
-void fileSetBufferSize(int fileID, long buffersize)
-{
- bfile_t *fileptr = file_to_pointer(fileID);
- xassert(buffersize >= 0);
- if ( fileptr ) fileptr->bufferSize = (size_t)buffersize;
-}
-
-/*
- * Open a file. Returns file ID, or -1 on error
- */
-int fileOpen(const char *filename, const char *mode)
-{
- int (*myFileOpen)(const char *filename, const char *mode)
- = (int (*)(const char *, const char *))
- namespaceSwitchGet(NSSWITCH_FILE_OPEN).func;
- return myFileOpen(filename, mode);
+ return item;
}
-int fileOpen_serial(const char *filename, const char *mode)
-{
- FILE *fp = NULL; /* file pointer (used for write) */
- int fd = -1; /* file descriptor (used for read) */
- int fileID = FILE_UNDEFID;
- int fmode = 0;
- struct stat filestat;
- bfile_t *fileptr = NULL;
-
- FILE_INIT();
-
- fmode = tolower((int) mode[0]);
- switch ( fmode )
- {
- case 'r':
- if ( FileTypeRead == FILE_TYPE_FOPEN )
- fp = fopen(filename, "rb");
- else
- fd = open(filename, O_RDONLY | O_BINARY);
- break;
- case 'x': fp = fopen(filename, "rb"); break;
- case 'w':
- if ( FileTypeWrite == FILE_TYPE_FOPEN )
- fp = fopen(filename, "wb");
- else
- fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
- break;
- case 'a': fp = fopen(filename, "ab"); break;
- default: Error("Mode %c unexpected!", fmode);
- }
+void *memCalloc(size_t nobjs, size_t size, const char *file, const char *functionname, int line)
+{
+ void *ptr = NULL;
- if ( FILE_Debug )
- if ( fp == NULL && fd == -1 )
- Message("Open failed on %s mode %c errno %d", filename, fmode, errno);
+ memInit();
- if ( fp )
+ if ( nobjs*size > 0 )
{
- if ( stat(filename, &filestat) != 0 ) return (fileID);
+ ptr = calloc(nobjs, size);
- fileptr = file_new_entry();
- if ( fileptr )
+ if ( MEM_Info )
{
- fileID = fileptr->self;
- fileptr->fp = fp;
- }
- }
- else if ( fd >= 0 )
- {
- if ( fstat(fd, &filestat) != 0 ) return (fileID);
+ memAccess++;
- fileptr = file_new_entry();
- if ( fileptr )
- {
- fileID = fileptr->self;
- fileptr->fd = fd;
+ int item = MEM_UNDEFID;
+ if ( ptr ) item = memListNewEntry(CALLOC_FUNC, ptr, size, nobjs, functionname, file, line);
+
+ if ( MEM_Debug ) memListPrintEntry(CALLOC_FUNC, item, size*nobjs, ptr, functionname, file, line);
}
+
+ if ( ptr == NULL && dmemory_ExitOnError )
+ memError(functionname, file, line, size*nobjs);
}
+ else
+ fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, file);
- if ( fileID >= 0 )
- {
- fileptr->mode = fmode;
- fileptr->name = strdupx(filename);
+ return ptr;
+}
-#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
- fileptr->blockSize = (size_t) filestat.st_blksize;
-#else
- fileptr->blockSize = (size_t) 4096;
-#endif
- if ( fmode == 'r' )
- fileptr->type = FileTypeRead;
- else if ( fmode == 'w' )
- fileptr->type = FileTypeWrite;
- else
- fileptr->type = FILE_TYPE_FOPEN;
+void *memMalloc(size_t size, const char *file, const char *functionname, int line)
+{
+ void *ptr = NULL;
- if ( fmode == 'r' ) fileptr->size = filestat.st_size;
+ memInit();
- if ( fileptr->type == FILE_TYPE_FOPEN ) file_set_buffer(fileptr);
+ if ( size > 0 )
+ {
+ ptr = malloc(size);
- if ( FILE_Debug )
- Message("File %s opened with ID %d", filename, fileID);
+ if ( MEM_Info )
+ {
+ memAccess++;
+
+ int item = MEM_UNDEFID;
+ if ( ptr ) item = memListNewEntry(MALLOC_FUNC, ptr, size, 1, functionname, file, line);
+
+ if ( MEM_Debug ) memListPrintEntry(MALLOC_FUNC, item, size, ptr, functionname, file, line);
+ }
+
+ if ( ptr == NULL && dmemory_ExitOnError )
+ memError(functionname, file, line, size);
}
+ else
+ fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, file);
- return (fileID);
+ return ptr;
}
-/*
- * Close a file.
- */
-int fileClose(int fileID)
-{
- int (*myFileClose)(int fileID)
- = (int (*)(int))namespaceSwitchGet(NSSWITCH_FILE_CLOSE).func;
- return myFileClose(fileID);
-}
-int fileClose_serial(int fileID)
+void *memRealloc(void *ptrold, size_t size, const char *file, const char *functionname, int line)
{
- char *name;
- int ret;
- const char *fbtname[] = {"unknown", "standard", "mmap"};
- const char *ftname[] = {"unknown", "open", "fopen"};
- bfile_t *fileptr = file_to_pointer(fileID);
- double rout = 0;
+ void *ptr = NULL;
- if ( fileptr == NULL )
+ memInit();
+
+ if ( size > 0 )
{
- file_pointer_info(__func__, fileID);
- return (1);
+ ptr = realloc(ptrold, size);
+
+ if ( MEM_Info )
+ {
+ memAccess++;
+
+ int item = MEM_UNDEFID;
+ if ( ptr )
+ {
+ item = memListChangeEntry(ptrold, ptr, size, functionname, file, line);
+
+ if ( item == MEM_UNDEFID ) item = memListNewEntry(REALLOC_FUNC, ptr, size, 1, functionname, file, line);
+ }
+
+ if ( MEM_Debug ) memListPrintEntry(REALLOC_FUNC, item, size, ptr, functionname, file, line);
+ }
+
+ if ( ptr == NULL && dmemory_ExitOnError )
+ memError(functionname, file, line, size);
}
+ else
+ fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", functionname, line, get_filename(file));
- name = fileptr->name;
+ return ptr;
+}
- if ( FILE_Debug )
- Message("fileID = %d filename = %s", fileID, name);
- if ( FileInfo > 0 )
- {
- fprintf(stderr, "____________________________________________\n");
- fprintf(stderr, " file ID : %d\n", fileID);
- fprintf(stderr, " file name : %s\n", fileptr->name);
- fprintf(stderr, " file type : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
+void memFree(void *ptr, const char *file, const char *functionname, int line)
+{
+ memInit();
- if ( fileptr->type == FILE_TYPE_FOPEN )
- fprintf(stderr, " file pointer : %p\n", (void *) fileptr->fp);
- else
- {
- fprintf(stderr, " file descriptor : %d\n", fileptr->fd);
- fprintf(stderr, " file flag : %d\n", FileFlagWrite);
- }
- fprintf(stderr, " file mode : %c\n", fileptr->mode);
+ if ( MEM_Info )
+ {
+ int item;
+ size_t size;
- if ( sizeof(off_t) > sizeof(long) )
+ if ( (item = memListDeleteEntry(ptr, &size)) >= 0 )
{
-#if defined (_WIN32)
- fprintf(stderr, " file size : %I64d\n", (long long) fileptr->size);
- if ( fileptr->type == FILE_TYPE_OPEN )
- fprintf(stderr, " file position : %I64d\n", (long long) fileptr->position);
- fprintf(stderr, " bytes transfered : %I64d\n", (long long) fileptr->byteTrans);
-#else
- fprintf(stderr, " file size : %lld\n", (long long) fileptr->size);
- if ( fileptr->type == FILE_TYPE_OPEN )
- fprintf(stderr, " file position : %lld\n", (long long) fileptr->position);
- fprintf(stderr, " bytes transfered : %lld\n", (long long) fileptr->byteTrans);
-#endif
+ if ( MEM_Debug ) memListPrintEntry(FREE_FUNC, item, size, ptr, functionname, file, line);
}
else
{
- fprintf(stderr, " file size : %ld\n", (long) fileptr->size);
- if ( fileptr->type == FILE_TYPE_OPEN )
- fprintf(stderr, " file position : %ld\n", (long) fileptr->position);
- fprintf(stderr, " bytes transfered : %ld\n", (long) fileptr->byteTrans);
+ if ( ptr && MEM_Debug )
+ fprintf(stderr, "%s info: memory entry at %p not found. [line %4d file %s (%s)]\n",
+ __func__, ptr, line, get_filename(file), functionname);
}
+ }
- if ( fileptr->time_in_sec > 0 )
- {
- rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
- }
-
- fprintf(stderr, " wall time [s] : %.2f\n", fileptr->time_in_sec);
- fprintf(stderr, " data rate [MB/s] : %.1f\n", rout);
+ free(ptr);
+}
- fprintf(stderr, " file access : %ld\n", fileptr->access);
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- {
- fprintf(stderr, " buffer type : %d (%s)\n", fileptr->bufferType, fbtname[fileptr->bufferType]);
- fprintf(stderr, " num buffer fill : %ld\n", fileptr->bufferNumFill);
- }
- fprintf(stderr, " buffer size : %lu\n", (unsigned long) fileptr->bufferSize);
- fprintf(stderr, " block size : %lu\n", (unsigned long) fileptr->blockSize);
- fprintf(stderr, " page size : %d\n", pagesize());
- fprintf(stderr, "--------------------------------------------\n");
- }
- if ( fileptr->type == FILE_TYPE_FOPEN )
+size_t memTotal(void)
+{
+ size_t memtotal = 0;
+#if defined (HAVE_MALLINFO)
+ struct mallinfo meminfo = mallinfo();
+ if ( MEM_Debug )
{
- ret = fclose(fileptr->fp);
- if ( ret == EOF )
- SysError("EOF returned for close of %s!", name);
+ fprintf(stderr, "arena %8zu (non-mmapped space allocated from system)\n", (size_t)meminfo.arena);
+ fprintf(stderr, "ordblks %8zu (number of free chunks)\n", (size_t)meminfo.ordblks);
+ fprintf(stderr, "smblks %8zu (number of fastbin blocks)\n", (size_t) meminfo.smblks);
+ fprintf(stderr, "hblks %8zu (number of mmapped regions)\n", (size_t) meminfo.hblks);
+ fprintf(stderr, "hblkhd %8zu (space in mmapped regions)\n", (size_t) meminfo.hblkhd);
+ fprintf(stderr, "usmblks %8zu (maximum total allocated space)\n", (size_t) meminfo.usmblks);
+ fprintf(stderr, "fsmblks %8zu (maximum total allocated space)\n", (size_t) meminfo.fsmblks);
+ fprintf(stderr, "uordblks %8zu (total allocated space)\n", (size_t) meminfo.uordblks);
+ fprintf(stderr, "fordblks %8zu (total free space)\n", (size_t) meminfo.fordblks);
+ fprintf(stderr, "Memory in use: %8zu bytes\n", (size_t) meminfo.usmblks + (size_t)meminfo.uordblks);
+ fprintf(stderr, "Total heap size: %8zu bytes\n", (size_t) meminfo.arena);
+
+ /* malloc_stats(); */
}
- else
- {
-#if defined (HAVE_MMAP)
- if ( fileptr->buffer && fileptr->mappedSize )
- {
- ret = munmap(fileptr->buffer, fileptr->mappedSize);
- if ( ret == -1 ) SysError("munmap error for close %s", fileptr->name);
- fileptr->buffer = NULL;
- }
+ memtotal = (size_t)meminfo.arena;
#endif
- ret = close(fileptr->fd);
- if ( ret == -1 )
- SysError("EOF returned for close of %s!", name);
- }
- if ( fileptr->name ) Free((void*) fileptr->name);
- if ( fileptr->buffer ) Free((void*) fileptr->buffer);
+ return memtotal;
+}
- file_delete_entry(fileptr);
- return (0);
+void memExitOnError(void)
+{
+ dmemory_ExitOnError = 1;
}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
-int filePtrGetc(void *vfileptr)
+#if !defined (NAMESPACE_H)
+#endif
+
+int _ExitOnError = 1; /* If set to 1, exit on error */
+int _Verbose = 1; /* If set to 1, errors are reported */
+int _Debug = 0; /* If set to 1, debugging */
+
+/* If we're not using GNU C, elide __attribute__ */
+#if ! defined __GNUC__ && ! defined __attribute__
+# define __attribute__(x) /*NOTHING*/
+#endif
+
+void SysError_(const char *caller, const char *fmt, ...)
+ __attribute__((noreturn));
+
+void SysError_(const char *caller, const char *fmt, ...)
{
- int ivalue = EOF;
- int fillret = 0;
- bfile_t *fileptr = (bfile_t *) vfileptr;
+ va_list args;
+ int saved_errno = errno;
- if ( fileptr )
- {
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- {
- if ( fileptr->bufferCnt == 0 ) fillret = file_fill_buffer(fileptr);
+ va_start(args, fmt);
- if ( fillret >= 0 )
- {
- ivalue = (unsigned char) *fileptr->bufferPtr++;
- fileptr->bufferCnt--;
- fileptr->position++;
+ printf("\n");
+ fprintf(stderr, "Error (%s) : ", caller);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
- fileptr->byteTrans++;
- fileptr->access++;
- }
- }
- else
- {
- ivalue = fgetc(fileptr->fp);
- if ( ivalue >= 0 )
- {
- fileptr->byteTrans++;
- fileptr->access++;
- }
- else
- fileptr->flag |= FILE_EOF;
- }
+ va_end(args);
+
+ if ( saved_errno )
+ {
+ errno = saved_errno;
+ perror("System error message");
}
- return (ivalue);
+ exit(EXIT_FAILURE);
}
-int fileGetc(int fileID)
+void Error_(const char *caller, const char *fmt, ...)
{
- int ivalue;
- bfile_t *fileptr;
+ va_list args;
+
+ va_start(args, fmt);
+
+ printf("\n");
+ fprintf(stderr, "Error (%s) : ", caller);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+
+ va_end(args);
- fileptr = file_to_pointer(fileID);
+ if ( _ExitOnError ) exit(EXIT_FAILURE);
+}
+
+typedef void (*cdiAbortCFunc)(const char * caller, const char * filename,
+ const char *functionname, int line,
+ const char * errorString, va_list ap)
+#ifdef __GNUC__
+ __attribute__((noreturn))
+#endif
+;
- ivalue = filePtrGetc((void *)fileptr);
+void cdiAbortC(const char * caller, const char * filename,
+ const char *functionname, int line,
+ const char * errorString, ... )
+{
+ va_list ap;
+ va_start(ap, errorString);
+ cdiAbortCFunc cdiAbortC_p
+ = (cdiAbortCFunc)namespaceSwitchGet(NSSWITCH_ABORT).func;
+ cdiAbortC_p(caller, filename, functionname, line, errorString, ap);
+ va_end(ap);
+}
- return (ivalue);
+void
+cdiAbortC_serial(const char *caller, const char *filename,
+ const char *functionname, int line,
+ const char *errorString, va_list ap)
+{
+ fprintf(stderr, "ERROR, %s, %s, line %d%s%s\nerrorString: \"",
+ functionname, filename, line, caller?", called from ":"",
+ caller?caller:"");
+ vfprintf(stderr, errorString, ap);
+ fputs("\"\n", stderr);
+ exit(EXIT_FAILURE);
}
+typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
+ va_list ap);
-size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
+void Warning_(const char *caller, const char *fmt, ...)
{
- size_t nread = 0;
- bfile_t *fileptr = (bfile_t *) vfileptr;
+ va_list args;
- if ( fileptr )
- {
- if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
- nread = file_read_from_buffer(fileptr, ptr, size);
- else
- {
- nread = fread(ptr, 1, size, fileptr->fp);
- if ( nread != size )
- {
- if ( nread == 0 )
- fileptr->flag |= FILE_EOF;
- else
- fileptr->flag |= FILE_ERROR;
- }
- }
+ va_start(args, fmt);
- fileptr->position += (off_t)nread;
- fileptr->byteTrans += (off_t)nread;
- fileptr->access++;
+ if ( _Verbose )
+ {
+ cdiWarningFunc cdiWarning_p
+ = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
+ cdiWarning_p(caller, fmt, args);
}
- if ( FILE_Debug ) Message("size %ld nread %ld", size, nread);
+ va_end(args);
+}
- return (nread);
+void cdiWarning(const char *caller, const char *fmt, va_list ap)
+{
+ fprintf(stderr, "Warning (%s) : ", caller);
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
}
-size_t fileRead(int fileID, void *restrict ptr, size_t size)
+void Message_(const char *caller, const char *fmt, ...)
{
- size_t nread = 0;
- bfile_t *fileptr;
+ va_list args;
- fileptr = file_to_pointer(fileID);
+ va_start(args, fmt);
- if ( fileptr )
- {
- double t_begin = 0.0;
+ fprintf(stdout, "%-18s : ", caller);
+ vfprintf(stdout, fmt, args);
+ fprintf(stdout, "\n");
- if ( FileInfo ) t_begin = file_time();
+ va_end(args);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef EXSE_H
+#define EXSE_H
- if ( fileptr->type == FILE_TYPE_OPEN )
- nread = file_read_from_buffer(fileptr, ptr, size);
- else
- {
- nread = fread(ptr, 1, size, fileptr->fp);
- if ( nread != size )
- {
- if ( nread == 0 )
- fileptr->flag |= FILE_EOF;
- else
- fileptr->flag |= FILE_ERROR;
- }
- }
+enum {
+ EXSE_SINGLE_PRECISION = 4,
+ EXSE_DOUBLE_PRECISION = 8,
+};
- if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
+#endif
+#if defined (HAVE_CONFIG_H)
+#endif
- fileptr->position += (off_t)nread;
- fileptr->byteTrans += (off_t)nread;
- fileptr->access++;
- }
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
- if ( FILE_Debug ) Message("size %ld nread %ld", size, nread);
- return (nread);
+
+enum {
+ EXT_HEADER_LEN = 4,
+};
+
+
+static int initExtLib = 0;
+static int extDefaultPrec = 0;
+static int extDefaultNumber = EXT_REAL;
+
+
+/*
+ * A version string.
+ */
+#undef LIBVERSION
+#define LIBVERSION 1.4.0
+#define XSTRING(x) #x
+#define STRING(x) XSTRING(x)
+static const char ext_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__ ;
+
+const char *extLibraryVersion(void)
+{
+ return ext_libvers;
}
-size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
+static int EXT_Debug = 0; /* If set to 1, debugging */
+
+
+void extDebug(int debug)
{
- size_t nwrite = 0;
- bfile_t *fileptr;
+ EXT_Debug = debug;
- fileptr = file_to_pointer(fileID);
+ if ( EXT_Debug )
+ Message("debug level %d", debug);
+}
- if ( fileptr )
- {
- double t_begin = 0.0;
- /* if ( fileptr->buffer == NULL ) file_set_buffer(fileptr); */
+static
+void extLibInit()
+{
+ const char *envName = "EXT_PRECISION";
- if ( FileInfo ) t_begin = file_time();
+ char *envString = getenv(envName);
+ if ( envString )
+ {
+ int pos = 0;
- if ( fileptr->type == FILE_TYPE_FOPEN )
- nwrite = fwrite(ptr, 1, size, fileptr->fp);
- else
- {
- ssize_t temp = write(fileptr->fd, ptr, size);
- if (temp == -1)
- {
- perror("error writing to file");
- nwrite = 0;
+ if ( strlen(envString) == 2 )
+ {
+ switch ( tolower((int) envString[pos]) )
+ {
+ case 'r':
+ {
+ extDefaultNumber = EXT_REAL;
+ switch ( (int) envString[pos+1] )
+ {
+ case '4': extDefaultPrec = EXSE_SINGLE_PRECISION; break;
+ case '8': extDefaultPrec = EXSE_DOUBLE_PRECISION; break;
+ default:
+ Message("Invalid digit in %s: %s", envName, envString);
+ }
+ break;
+ }
+ case 'c':
+ {
+ extDefaultNumber = EXT_COMP;
+ switch ( (int) envString[pos+1] )
+ {
+ case '4': extDefaultPrec = EXSE_SINGLE_PRECISION; break;
+ case '8': extDefaultPrec = EXSE_DOUBLE_PRECISION; break;
+ default:
+ Message("Invalid digit in %s: %s", envName, envString);
+ }
+ break;
+ }
+ default:
+ {
+ Message("Invalid character in %s: %s", envName, envString);
+ break;
+ }
}
- else
- nwrite = (size_t)temp;
- }
-
- if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
-
- fileptr->position += (off_t)nwrite;
- fileptr->byteTrans += (off_t)nwrite;
- fileptr->access++;
+ }
}
- return (nwrite);
+ initExtLib = 1;
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _GAUSSGRID_H
-#define _GAUSSGRID_H
-#ifdef __cplusplus
-extern "C" {
-#endif
+static
+void extInit(extrec_t *extp)
+{
+ extp->checked = 0;
+ extp->byteswap = 0;
+ extp->prec = 0;
+ extp->number = extDefaultNumber;
+ extp->datasize = 0;
+ extp->buffersize = 0;
+ extp->buffer = NULL;
+}
-void gaussaw(double *restrict pa, double *restrict pw, size_t nlat);
-#if defined (__cplusplus)
-}
-#endif
+void *extNew(void)
+{
+ if ( ! initExtLib ) extLibInit();
-#endif /* _GAUSSGRID_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
+ extrec_t *extp = (extrec_t *) Malloc(sizeof(extrec_t));
-#include <math.h>
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
+ extInit(extp);
+ return (void*)extp;
+}
-#ifndef M_PI
-#define M_PI 3.14159265358979323846 /* pi */
-#endif
+void extDelete(void *ext)
+{
+ extrec_t *extp = (extrec_t *) ext;
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
+ if ( extp )
+ {
+ if ( extp->buffer ) Free(extp->buffer);
+ Free(extp);
+ }
+}
-static
-void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag,
- double *pw, double *pdxn, double *pxmod)
+int extCheckFiletype(int fileID, int *swap)
{
- double zdlk;
- double zdlldn;
- double zdlx;
- double zdlmod;
- double zdlxn;
+ size_t fact = 0;
+ size_t data = 0;
+ size_t dimxy = 0;
+ int found = 0;
+ unsigned char buffer[40], *pbuf;
- size_t ik;
+ if ( fileRead(fileID, buffer, 4) != 4 ) return found;
- /* 1.0 Newton iteration step */
+ size_t blocklen = (size_t) get_UINT32(buffer);
+ size_t sblocklen = (size_t) get_SUINT32(buffer);
+
+ if ( EXT_Debug )
+ Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
- zdlx = pdx;
- zdlk = 0.0;
- if (kodd == 0)
+ if ( blocklen == 16 )
{
- zdlk = 0.5*pfn[0];
+ *swap = 0;
+ fact = blocklen/4;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
+ pbuf = buffer+3*fact; dimxy = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
}
- zdlxn = 0.0;
- zdlldn = 0.0;
-
- ik = 1;
-
- if (kflag == 0)
+ else if ( blocklen == 32 )
{
- for(size_t jn = 2-kodd; jn <= kn; jn += 2)
- {
- /* normalised ordinary Legendre polynomial == \overbar{p_n}^0 */
- zdlk = zdlk + pfn[ik]*cos((double)(jn)*zdlx);
- /* normalised derivative == d/d\theta(\overbar{p_n}^0) */
- zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
- ik++;
- }
- /* Newton method */
- zdlmod = -(zdlk/zdlldn);
- zdlxn = zdlx + zdlmod;
- *pdxn = zdlxn;
- *pxmod = zdlmod;
+ *swap = 0;
+ fact = blocklen/4;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
+ pbuf = buffer+3*fact; dimxy = (size_t) get_UINT64(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ }
+ else if ( sblocklen == 16 )
+ {
+ *swap = 1;
+ fact = sblocklen/4;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
+ pbuf = buffer+3*fact; dimxy = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ }
+ else if ( sblocklen == 32 )
+ {
+ *swap = 1;
+ fact = sblocklen/4;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
+ pbuf = buffer+3*fact; dimxy = (size_t) get_SUINT64(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
}
- /* 2.0 Compute weights */
+ fileRewind(fileID);
- if (kflag == 1)
+ if ( data && dimxy*fact == data ) found = 1;
+ else if ( data && dimxy*fact*2 == data ) found = 1;
+
+ if ( EXT_Debug )
{
- for(size_t jn = 2-kodd; jn <= kn; jn += 2)
- {
- /* normalised derivative */
- zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
- ik++;
- }
- *pw = (double)(2*kn+1)/(zdlldn*zdlldn);
+ Message("swap = %d fact = %d", *swap, fact);
+ Message("dimxy = %lu data = %lu", dimxy, data);
}
- return;
+ return found;
}
-static
-void gawl(double *pfn, double *pl, double *pw, size_t kn)
+
+int extInqHeader(void *ext, int *header)
{
- double pmod = 0;
- int iflag;
- int itemax;
- double zw = 0;
- double zdlx;
- double zdlxn = 0;
+ extrec_t *extp = (extrec_t *) ext;
- /* 1.0 Initizialization */
+ for ( size_t i = 0; i < EXT_HEADER_LEN; i++ )
+ header[i] = extp->header[i];
- iflag = 0;
- itemax = 20;
+ if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
- size_t iodd = (kn % 2);
+ return 0;
+}
- zdlx = *pl;
- /* 2.0 Newton iteration */
+int extDefHeader(void *ext, const int *header)
+{
+ extrec_t *extp = (extrec_t *) ext;
- for (int jter = 1; jter <= itemax+1; jter++)
- {
- cpledn(kn, iodd, pfn, zdlx, iflag, &zw, &zdlxn, &pmod);
- zdlx = zdlxn;
- if (iflag == 1) break;
- if (fabs(pmod) <= DBL_EPSILON*1000.0) iflag = 1;
- }
+ for ( size_t i = 0; i < EXT_HEADER_LEN; i++ )
+ extp->header[i] = header[i];
- *pl = zdlxn;
- *pw = zw;
+ extp->datasize = (size_t)header[3];
+ if ( extp->number == EXT_COMP ) extp->datasize *= 2;
- return;
+ if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
+
+ return 0;
}
static
-void gauaw(size_t kn, double *__restrict__ pl, double *__restrict__ pw)
+int extInqData(extrec_t *extp, int prec, void *data)
{
- /*
- * 1.0 Initialize Fourier coefficients for ordinary Legendre polynomials
- *
- * Belousov, Swarztrauber, and ECHAM use zfn(0,0) = sqrt(2)
- * IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 (zfn(0,0) = 2.0)
- */
- double *zfn, *zfnlat;
-
- double z, zfnn;
-
- zfn = (double *) Malloc((kn+1) * (kn+1) * sizeof(double));
- zfnlat = (double *) Malloc((kn/2+1+1)*sizeof(double));
+ size_t i;
+ int ierr = 0;
+ int byteswap = extp->byteswap;
+ size_t datasize = extp->datasize;
+ void *buffer = extp->buffer;
+ int rprec = extp->prec;
- zfn[0] = M_SQRT2;
- for (size_t jn = 1; jn <= kn; jn++)
+ switch ( rprec )
{
- zfnn = zfn[0];
- for (size_t jgl = 1; jgl <= jn; jgl++)
- {
- zfnn *= sqrt(1.0-0.25/((double)(jgl*jgl)));
- }
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( sizeof(FLT32) == 4 )
+ {
+ if ( byteswap ) swap4byte(buffer, datasize);
- zfn[jn*(kn+1)+jn] = zfnn;
+ if ( rprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT32));
+ else
+ for ( i = 0; i < datasize; ++i )
+ ((double *) data)[i] = (double) ((float *) buffer)[i];
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT32));
+ }
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ if ( sizeof(FLT64) == 8 )
+ {
+ if ( byteswap ) swap8byte(buffer, datasize);
- size_t iodd = jn % 2;
- for (size_t jgl = 2; jgl <= jn-iodd; jgl += 2)
- {
- zfn[jn*(kn+1)+jn-jgl] = zfn[jn*(kn+1)+jn-jgl+2]
- *((double)((jgl-1)*(2*jn-jgl+2)))/((double)(jgl*(2*jn-jgl+1)));
- }
+ if ( rprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT64));
+ else
+ for ( i = 0; i < datasize; ++i )
+ ((float *) data)[i] = (float) ((double *) buffer)[i];
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT64));
+ }
+ break;
+ default:
+ {
+ Error("unexpected data precision %d", rprec);
+ break;
+ }
}
+ return ierr;
+}
- /* 2.0 Gaussian latitudes and weights */
- size_t iodd = kn % 2;
- size_t ik = iodd;
- for (size_t jgl = iodd; jgl <= kn; jgl += 2)
- {
- zfnlat[ik] = zfn[kn*(kn+1)+jgl];
- ik++;
- }
+int extInqDataSP(void *ext, float *data)
+{
+ return extInqData((extrec_t *)ext, EXSE_SINGLE_PRECISION, (void *) data);
+}
- /*
- * 2.1 Find first approximation of the roots of the
- * Legendre polynomial of degree kn.
- */
- size_t ins2 = kn/2+(kn % 2);
+int extInqDataDP(void *ext, double *data)
+{
+ return extInqData((extrec_t *)ext, EXSE_DOUBLE_PRECISION, (void *) data);
+}
- for (size_t jgl = 1; jgl <= ins2; jgl++)
- {
- z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2));
- pl[jgl-1] = z+1.0/(tan(z)*((double)(8*kn*kn)));
- }
- /* 2.2 Computes roots and weights for transformed theta */
+static int extDefData(void *ext, int prec, const void *data)
+{
+ extrec_t *extp = (extrec_t *) ext;
+ size_t i;
+ int rprec;
+ void *buffer;
- for (size_t jgl = ins2; jgl >= 1 ; jgl--)
- {
- size_t jglm1 = jgl-1;
- gawl(zfnlat, &(pl[jglm1]), &(pw[jglm1]), kn);
- }
+ if ( extDefaultPrec ) rprec = extDefaultPrec;
+ else rprec = extp->prec;
- /* convert to physical latitude */
+ if ( ! rprec ) rprec = prec;
- for (size_t jgl = 0; jgl < ins2; jgl++)
+ extp->prec = rprec;
+
+ int *header = extp->header;
+
+ size_t datasize = (size_t)header[3];
+ if ( extp->number == EXT_COMP ) datasize *= 2;
+ size_t blocklen = datasize * (size_t)rprec;
+
+ extp->datasize = datasize;
+
+ size_t buffersize = extp->buffersize;
+
+ if ( buffersize != blocklen )
{
- pl[jgl] = cos(pl[jgl]);
+ buffersize = blocklen;
+ buffer = extp->buffer;
+ buffer = Realloc(buffer, buffersize);
+ extp->buffer = buffer;
+ extp->buffersize = buffersize;
}
+ else
+ buffer = extp->buffer;
- for (size_t jgl = 1; jgl <= kn/2; jgl++)
+ switch ( rprec )
{
- size_t jglm1 = jgl-1;
- size_t isym = kn-jgl;
- pl[isym] = -pl[jglm1];
- pw[isym] = pw[jglm1];
- }
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( rprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT32));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((float *) buffer)[i] = (float) ((double *) data)[i];
- Free(zfnlat);
- Free(zfn);
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ if ( rprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT64));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((double *) buffer)[i] = (double) ((float *) data)[i];
- return;
+ break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", rprec);
+ break;
+ }
+ }
+
+ return 0;
}
-#if 0
-static
-void gauaw_old(double *pa, double *pw, int nlat)
+
+int extDefDataSP(void *ext, const float *data)
{
- /*
- * Compute Gaussian latitudes. On return pa contains the
- * sine of the latitudes starting closest to the north pole and going
- * toward the south
- *
- */
+ return extDefData(ext, EXSE_SINGLE_PRECISION, (void *) data);
+}
- const int itemax = 20;
- int isym, iter, ins2, jn, j;
- double za, zw, zan;
- double z, zk, zkm1, zkm2, zx, zxn, zldn, zmod;
+int extDefDataDP(void *ext, const double *data)
+{
+ return extDefData(ext, EXSE_DOUBLE_PRECISION, (void *) data);
+}
- /*
- * Perform the Newton loop
- * Find 0 of Legendre polynomial with Newton loop
- */
- ins2 = nlat/2 + nlat%2;
+int extRead(int fileID, void *ext)
+{
+ extrec_t *extp = (extrec_t *) ext;
+ size_t i;
+ void *buffer;
+ int status;
- for ( j = 0; j < ins2; j++ )
+ if ( ! extp->checked )
{
- z = (double) (4*(j+1)-1)*M_PI / (double) (4*nlat+2);
- pa[j] = cos(z + 1.0/(tan(z)*(double)(8*nlat*nlat)));
+ status = extCheckFiletype(fileID, &extp->byteswap);
+ if ( status == 0 ) Error("Not a EXTRA file!");
+ extp->checked = 1;
}
- for ( j = 0; j < ins2; j++ )
- {
+ int byteswap = extp->byteswap;
- za = pa[j];
+ /* read header record */
+ size_t blocklen = binReadF77Block(fileID, byteswap);
- iter = 0;
- do
- {
- iter++;
- zk = 0.0;
+ if ( fileEOF(fileID) ) return -1;
- /* Newton iteration step */
+ if ( EXT_Debug )
+ Message("blocklen = %lu", blocklen);
- zkm2 = 1.0;
- zkm1 = za;
- zx = za;
- for ( jn = 2; jn <= nlat; jn++ )
- {
- zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double)(jn);
- zkm2 = zkm1;
- zkm1 = zk;
- }
- zkm1 = zkm2;
- zldn = ((double) (nlat)*(zkm1-zx*zk)) / (1.-zx*zx);
- zmod = -zk/zldn;
- zxn = zx+zmod;
- zan = zxn;
-
- /* computes weight */
-
- zkm2 = 1.0;
- zkm1 = zxn;
- zx = zxn;
- for ( jn = 2; jn <= nlat; jn++ )
- {
- zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double) (jn);
- zkm2 = zkm1;
- zkm1 = zk;
- }
- zkm1 = zkm2;
- zw = (1.0-zx*zx) / ((double) (nlat*nlat)*zkm1*zkm1);
- za = zan;
- }
- while ( iter <= itemax && fabs(zmod) >= DBL_EPSILON );
+ size_t hprec = blocklen / EXT_HEADER_LEN;
- pa[j] = zan;
- pw[j] = 2.0*zw;
- }
+ extp->prec = (int)hprec;
-#if defined (SX)
-#pragma vdir nodep
-#endif
- for (j = 0; j < nlat/2; j++)
+ switch ( hprec )
{
- isym = nlat-(j+1);
- pa[isym] = -pa[j];
- pw[isym] = pw[j];
- }
-
- return;
-}
-#endif
-
-void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
-{
- //gauaw_old(pa, pw, nlat);
- gauaw(nlat, pa, pw);
-}
+ case EXSE_SINGLE_PRECISION:
+ {
+ INT32 tempheader[4];
+ binReadInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader);
-/*
-#define NGL 48
+ for ( i = 0; i < EXT_HEADER_LEN; i++ )
+ extp->header[i] = (int)tempheader[i];
-int main (int rgc, char *argv[])
-{
- int ngl = NGL;
- double plo[NGL], pwo[NGL];
- double pl[NGL], pw[NGL];
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ INT64 tempheader[4];
+ binReadInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader);
- int i;
+ for ( i = 0; i < EXT_HEADER_LEN; i++ )
+ extp->header[i] = (int)tempheader[i];
- gauaw(ngl, pl, pw);
- gauaw_old(plo, pwo, ngl);
- for (i = 0; i < ngl; i++)
- {
- pl[i] = asin(pl[i])/M_PI*180.0;
- plo[i] = asin(plo[i])/M_PI*180.0;
+ break;
+ }
+ default:
+ {
+ Error("Unexpected header precision %d", hprec);
+ break;
+ }
}
- for (i = 0; i < ngl; i++)
+ size_t blocklen2 = binReadF77Block(fileID, byteswap);
+
+ if ( blocklen2 != blocklen )
{
- fprintf(stderr, "%4d%25.18f%25.18f%25.18f%25.18f\n", i+1, pl[i], pw[i], pl[i]-plo[i], pw[i]-pwo[i]);
+ Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+ if ( blocklen2 != 0 ) return -1;
}
- return 0;
-}
-*/
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ extp->datasize = (size_t)extp->header[3];
-#if defined (HAVE_LIBGRIB_API)
-# include <grib_api.h>
-#endif
+ if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
-#include <stdio.h>
+ blocklen = binReadF77Block(fileID, byteswap);
+ size_t buffersize = (size_t)extp->buffersize;
-static char gribapi_libvers[64] = "";
-#if defined (HAVE_LIBGRIB_API)
-static int gribapi_libvers_init;
-#endif
+ if ( buffersize < blocklen )
+ {
+ buffersize = blocklen;
+ buffer = extp->buffer;
+ buffer = Realloc(buffer, buffersize);
+ extp->buffer = buffer;
+ extp->buffersize = buffersize;
+ }
+ else
+ buffer = extp->buffer;
+ size_t dprec = blocklen / extp->datasize;
-void gribapiLibraryVersion(int* major_version, int* minor_version, int* revision_version)
-{
-#if defined (HAVE_LIBGRIB_API)
- long version = grib_get_api_version();
- (*major_version) = (int)(version/10000);
- (*minor_version) = (int)((version-(*major_version)*10000)/100);
- (*revision_version) = (int)(version-(*major_version)*10000-(*minor_version)*100);
-#else
- (*major_version) = 0;
- (*minor_version) = 0;
- (*revision_version) = 0;
-#endif
-}
+ if ( dprec == hprec )
+ {
+ extp->number = EXT_REAL;
+ }
+ else if ( dprec == 2*hprec )
+ {
+ dprec /= 2;
+ extp->datasize *= 2;
+ extp->number = EXT_COMP;
+ }
-const char *gribapiLibraryVersionString(void)
-{
-#if defined (HAVE_LIBGRIB_API)
- if (!gribapi_libvers_init)
+ if ( dprec != EXSE_SINGLE_PRECISION && dprec != EXSE_DOUBLE_PRECISION )
{
- int major_version, minor_version, revision_version;
+ Warning("Unexpected data precision %d", dprec);
+ return -1;
+ }
- gribapiLibraryVersion(&major_version, &minor_version, &revision_version);
+ fileRead(fileID, buffer, blocklen);
- sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version);
- gribapi_libvers_init = 1;
+ blocklen2 = binReadF77Block(fileID, byteswap);
+
+ if ( blocklen2 != blocklen )
+ {
+ Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+ if ( blocklen2 != 0 ) return -1;
}
-#endif
- return (gribapi_libvers);
+ return 0;
}
-void gribContainersNew(stream_t * streamptr)
+int extWrite(int fileID, void *ext)
{
- int editionNumber = 2;
+ extrec_t *extp = (extrec_t *) ext;
+ size_t i;
+ union { INT32 i32[EXT_HEADER_LEN]; INT64 i64[EXT_HEADER_LEN]; } tempheader;
+ int byteswap = extp->byteswap;
+ int rprec = extp->prec;
+ int number = extp->number;
+ int *header = extp->header;
- if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
- (void)editionNumber;
-#if defined (HAVE_LIBCGRIBEX)
- if ( streamptr->filetype == FILETYPE_GRB )
- {
- }
- else
-#endif
- {
- int nvars = streamptr->nvars;
+ /* write header record */
+ size_t blocklen = EXT_HEADER_LEN * (size_t)rprec;
-#if defined (GRIBCONTAINER2D)
- gribContainer_t **gribContainers;
- gribContainers = (gribContainer_t **) Malloc(nvars*sizeof(gribContainer_t *));
+ binWriteF77Block(fileID, byteswap, blocklen);
- for ( int varID = 0; varID < nvars; ++varID )
- {
- int nlevs = streamptr->vars[varID].nlevs;
- gribContainers[varID] = (gribContainer_t *) Malloc(nlevs*sizeof(gribContainer_t));
+ switch ( rprec )
+ {
+ case EXSE_SINGLE_PRECISION:
+ {
+ for ( i = 0; i < EXT_HEADER_LEN; i++ )
+ tempheader.i32[i] = (INT32) header[i];
- for ( int levelID = 0; levelID < nlevs; ++levelID )
- {
- gribContainers[varID][levelID].gribHandle = gribHandleNew(editionNumber);
- gribContainers[varID][levelID].init = FALSE;
- }
- }
+ binWriteInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader.i32);
- streamptr->gribContainers = (void **) gribContainers;
-#else
- gribContainer_t *gribContainers
- = (gribContainer_t *) Malloc((size_t)nvars*sizeof(gribContainer_t));
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ for ( i = 0; i < EXT_HEADER_LEN; i++ )
+ tempheader.i64[i] = (INT64) header[i];
- for ( int varID = 0; varID < nvars; ++varID )
- {
- gribContainers[varID].gribHandle = gribHandleNew(editionNumber);
- gribContainers[varID].init = FALSE;
- }
+ binWriteInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader.i64);
- streamptr->gribContainers = (void *) gribContainers;
-#endif
+ break;
+ }
+ default:
+ {
+ Error("unexpected header precision %d", rprec);
+ break;
+ }
}
-}
+ binWriteF77Block(fileID, byteswap, blocklen);
-void gribContainersDelete(stream_t * streamptr)
-{
- if ( streamptr->gribContainers )
- {
- int nvars = streamptr->nvars;
-
-#if defined (GRIBCONTAINER2D)
- gribContainer_t **gribContainers = (gribContainer_t **) streamptr->gribContainers;
+ size_t datasize = (size_t)header[3];
+ if ( number == EXT_COMP ) datasize *= 2;
+ blocklen = datasize * (size_t)rprec;
- for ( int varID = 0; varID < nvars; ++varID )
- {
- int nlevs = streamptr->vars[varID].nlevs;
- for ( int levelID = 0; levelID < nlevs; ++levelID )
- {
- gribHandleDelete(gribContainers[varID][levelID].gribHandle);
- }
- Free(gribContainers[varID]);
- }
-#else
- gribContainer_t *gribContainers = (gribContainer_t *) streamptr->gribContainers;
+ binWriteF77Block(fileID, byteswap, blocklen);
- for ( int varID = 0; varID < nvars; ++varID )
- {
- gribHandleDelete(gribContainers[varID].gribHandle);
- }
-#endif
+ extp->datasize = datasize;
- Free(gribContainers);
+ void *buffer = extp->buffer;
- streamptr->gribContainers = NULL;
+ switch ( rprec )
+ {
+ case EXSE_SINGLE_PRECISION:
+ {
+ binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
+ break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", rprec);
+ break;
+ }
}
+
+ binWriteF77Block(fileID, byteswap, blocklen);
+
+ return 0;
}
/*
* Local Variables:
@@ -22907,7390 +21720,7862 @@ void gribContainersDelete(stream_t * streamptr)
* require-trailing-newline: t
* End:
*/
-#ifndef _GRID_H
-#define _GRID_H
+#if defined (HAVE_CONFIG_H)
+#endif
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h> // gettimeofday()
-typedef unsigned char mask_t;
-typedef struct grid_t grid_t;
-struct gridVirtTable
-{
- void (*destroy)(grid_t *gridptr);
- grid_t *(*copy)(grid_t *gridptr);
- void (*copyScalarFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
- void (*copyArrayFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
- void (*defXVals)(grid_t *gridptr, const double *xvals);
- void (*defYVals)(grid_t *gridptr, const double *yvals);
- void (*defMask)(grid_t *gridptr, const int *mask);
- void (*defMaskGME)(grid_t *gridptr, const int *mask);
- void (*defXBounds)(grid_t *gridptr, const double *xbounds);
- void (*defYBounds)(grid_t *gridptr, const double *ybounds);
- void (*defArea)(grid_t *gridptr, const double *area);
- double (*inqXVal)(grid_t *gridptr, int index);
- double (*inqYVal)(grid_t *gridptr, int index);
- int (*inqXVals)(grid_t *gridptr, double *xvals);
- int (*inqYVals)(grid_t *gridptr, double *yvals);
- const double *(*inqXValsPtr)(grid_t *gridptr);
- const double *(*inqYValsPtr)(grid_t *gridptr);
- /* return if for both grids, all xval and all yval are equal */
- bool (*compareXYFull)(grid_t *gridRef, grid_t *gridTest);
- /* return if for both grids, x[0], y[0], x[size-1] and y[size-1] are
- * respectively equal */
- bool (*compareXYAO)(grid_t *gridRef, grid_t *gridTest);
- void (*inqArea)(grid_t *gridptr, double *area);
- const double *(*inqAreaPtr)(grid_t *gridptr);
- int (*hasArea)(grid_t *gridptr);
- int (*inqMask)(grid_t *gridptr, int *mask);
- int (*inqMaskGME)(grid_t *gridptr, int *mask_gme);
- int (*inqXBounds)(grid_t *gridptr, double *xbounds);
- int (*inqYBounds)(grid_t *gridptr, double *ybounds);
- const double *(*inqXBoundsPtr)(grid_t *gridptr);
- const double *(*inqYBoundsPtr)(grid_t *gridptr);
-};
+#if ! defined (O_BINARY)
+#define O_BINARY 0
+#endif
-struct grid_t {
- int self;
- int type; /* grid type */
- int prec; /* grid precision */
- int proj; /* grid projection */
- mask_t *mask;
- mask_t *mask_gme;
- double *xvals;
- double *yvals;
- double *area;
- double *xbounds;
- double *ybounds;
- double xfirst, yfirst;
- double xlast, ylast;
- double xinc, yinc;
- double lcc_originLon; /* Lambert Conformal Conic */
- double lcc_originLat;
- double lcc_lonParY;
- double lcc_lat1;
- double lcc_lat2;
- double lcc_xinc;
- double lcc_yinc;
- int lcc_projflag;
- int lcc_scanflag;
- short lcc_defined;
- short lcc2_defined;
- int laea_defined;
- double lcc2_lon_0; /* Lambert Conformal Conic 2 */
- double lcc2_lat_0;
- double lcc2_lat_1;
- double lcc2_lat_2;
- double lcc2_a;
- double laea_lon_0; /* Lambert Azimuthal Equal Area */
- double laea_lat_0;
- double laea_a;
- double xpole, ypole, angle; /* rotated north pole */
- short isCyclic; /* TRUE for global cyclic grids */
- short isRotated; /* TRUE for rotated grids */
- short xdef; /* 0: undefined 1:xvals 2:x0+xinc */
- short ydef; /* 0: undefined 1:yvals 2:y0+yinc */
- int nd, ni, ni2, ni3; /* parameter for GRID_GME */
- int number, position; /* parameter for GRID_REFERENCE */
- int trunc; /* parameter for GRID_SPECTEAL */
- int nvertex;
- char *reference;
- unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference */
- int *rowlon;
- int nrowlon;
- int size;
- int xsize; /* number of values along X */
- int ysize; /* number of values along Y */
- int np; /* number of parallels between a pole and the equator */
- short lcomplex;
- short hasdims;
- const char *xstdname;
- const char *ystdname;
- char xdimname[CDI_MAX_NAME];
- char ydimname[CDI_MAX_NAME];
- char vdimname[CDI_MAX_NAME];
- char xname[CDI_MAX_NAME];
- char yname[CDI_MAX_NAME];
- char xlongname[CDI_MAX_NAME];
- char ylongname[CDI_MAX_NAME];
- char xunits[CDI_MAX_NAME];
- char yunits[CDI_MAX_NAME];
- char *name;
- const struct gridVirtTable *vtable;
- void *extraData;
-};
+#ifndef strdupx
+#ifndef strdup
+char *strdup(const char *s);
+#endif
+#define strdupx strdup
+/*
+#define strdupx(s) \
+({ \
+ const char *__old = (s); \
+ size_t __len = strlen(__old) + 1; \
+ char *__new = (char *) Malloc(__len); \
+ (char *) memcpy(__new, __old, __len); \
+})
+*/
+#endif
-void grid_init(grid_t *gridptr);
-void
-cdiGridTypeInit(grid_t *gridptr, int gridtype, int size);
-void grid_free(grid_t *gridptr);
-grid_t *gridID2Ptr(int gridID);
-extern const struct gridVirtTable cdiGridVtable;
+#if defined (HAVE_MMAP)
+# include <sys/mman.h> /* mmap() is defined in this header */
+#endif
-unsigned cdiGridCount(void);
-const double *gridInqXvalsPtr(int gridID);
-const double *gridInqYvalsPtr(int gridID);
+/* #define MAX_FILES FOPEN_MAX */
+#define MAX_FILES 4096
-const double *gridInqXboundsPtr(int gridID);
-const double *gridInqYboundsPtr(int gridID);
-const double *gridInqAreaPtr(int gridID);
+static int _file_max = MAX_FILES;
-const char *gridInqXnamePtr(int gridID);
-const char *gridInqYnamePtr(int gridID);
+static void file_initialize(void);
-const char *gridInqReferencePtr(int gridID);
+static bool _file_init = false;
-int gridGenerate(const grid_t *grid);
+#if defined (HAVE_LIBPTHREAD)
+#include <pthread.h>
-void cdiGridGetIndexList(unsigned, int * );
+static pthread_once_t _file_init_thread = PTHREAD_ONCE_INIT;
+static pthread_mutex_t _file_mutex;
-void
-gridUnpack(char * unpackBuffer, int unpackBufferSize,
- int * unpackBufferPos, int originNamespace, void *context,
- int force_id);
+# define FILE_LOCK() pthread_mutex_lock(&_file_mutex)
+# define FILE_UNLOCK() pthread_mutex_unlock(&_file_mutex)
+# define FILE_INIT() \
+ if ( _file_init == false ) pthread_once(&_file_init_thread, file_initialize)
-struct addIffNewRes
-{
- int Id;
- int isNew;
-};
+#else
-struct addIffNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode);
+# define FILE_LOCK()
+# define FILE_UNLOCK()
+# define FILE_INIT() \
+ if ( _file_init == false ) file_initialize()
#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
-#define INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
-#ifdef HAVE_LIBGRIB_API
+typedef struct
+{
+ int self;
+ int flag; /* access and error flag */
+ int eof; /* end of file flag */
+ int fd; /* file descriptor used for read */
+ FILE *fp; /* FILE pointer used for write */
+ char *name; /* file name */
+ off_t size; /* file size */
+ off_t position; /* file position */
+ long access; /* file access */
+ off_t byteTrans; /* */
+ size_t blockSize; /* file block size */
+ int mode; /* file access mode */
+ short type; /* file type ( 1:open 2:fopen ) */
+ short bufferType; /* buffer type ( 1:std 2:mmap ) */
+ size_t bufferSize; /* file buffer size */
+ size_t mappedSize; /* mmap buffer size */
+ char *buffer; /* file buffer */
+ long bufferNumFill; /* number of buffer fill */
+ char *bufferPtr; /* file buffer pointer */
+ off_t bufferPos;
+ off_t bufferStart;
+ off_t bufferEnd;
+ size_t bufferCnt;
+ double time_in_sec;
+}
+bfile_t;
-#include <grib_api.h>
-#include <stdbool.h>
+enum F_I_L_E_Flags
+ {
+ FILE_READ = 01,
+ FILE_WRITE = 02,
+ FILE_UNBUF = 04,
+ FILE_EOF = 010,
+ FILE_ERROR = 020
+ };
-char* gribCopyString(grib_handle* gribHandle, const char* key);
-bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue);
-bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue);
-long gribGetLong(grib_handle* gh, const char* key);
-long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue);
+static bool FileInfo = false;
-double gribGetDouble(grib_handle* gh, const char* key);
-double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue);
-size_t gribGetArraySize(grib_handle* gribHandle, const char* key);
-void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array); //The caller is responsible to ensure a sufficiently large buffer.
-void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array); //The caller is responsible to ensure a sufficiently large buffer.
+#if ! defined (MIN_BUF_SIZE)
+# define MIN_BUF_SIZE 131072L
+#endif
-long gribEditionNumber(grib_handle* gh);
-char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType); //Returns NULL if timeType is kCdiTimeType_endTime and the field does not have an integration period (statistical data).
-int gribapiTimeIsFC(grib_handle *gh);
-int gribapiGetTsteptype(grib_handle *gh);
-int gribGetDatatype(grib_handle* gribHandle);
-int gribapiGetParam(grib_handle *gh);
-int gribapiGetGridType(grib_handle *gh);
-void gribapiGetGrid(grib_handle *gh, grid_t *grid);
-#endif
+static size_t FileBufferSizeMin = MIN_BUF_SIZE;
+static long FileBufferSizeEnv = -1;
+static short FileBufferTypeEnv = 0;
-#endif
+static short FileTypeRead = FILE_TYPE_OPEN;
+static short FileTypeWrite = FILE_TYPE_FOPEN;
+static int FileFlagWrite = 0;
+
+static int FILE_Debug = 0; /* If set to 1, debugging */
+
+
+static void file_table_print(void);
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
+ * A version string.
*/
-#if defined (HAVE_CONFIG_H)
-#endif
+#undef LIBVERSION
+#define LIBVERSION 1.8.3
+#define XSTRING(x) #x
+#define STRING(x) XSTRING(x)
+static const char file_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__;
-#ifdef HAVE_LIBGRIB_API
+/*
+ 21/05/2004 1.3.2 set min I/O Buffersize to 128k
+ 31/05/2005 1.4.0 replace fileTable by _fileList
+ 26/08/2005 1.4.1 fileClose with return value
+ checks for all fileptr
+ 01/09/2005 1.5.0 thread safe version
+ 06/11/2005 1.5.1 add filePtrEOF, filePtr, filePtrGetc
+ 03/02/2006 1.5.2 ansi C: define getpagesize and strdupx
+ 27/12/2007 1.6.0 add FILE_TYPE_FOPEN
+ 24/03/2008 1.6.1 add O_BINARY if available
+ remove default HAVE_MMAP
+ use HAVE_STRUCT_STAT_ST_BLKSIZE
+ 22/08/2010 1.7.0 refactor
+ 11/11/2010 1.7.1 update for changed interface of error.h
+ 02/02/2012 1.8.0 cleanup
+ 16/11/2012 1.8.1 added support for unbuffered write
+ 27/06/2013 1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
+ */
+
+
+typedef struct _filePtrToIdx {
+ int idx;
+ bfile_t *ptr;
+ struct _filePtrToIdx *next;
+} filePtrToIdx;
+static filePtrToIdx *_fileList = NULL;
+static filePtrToIdx *_fileAvail = NULL;
-#include <assert.h>
-#include <time.h>
+static
+void file_list_new(void)
+{
+ assert(_fileList == NULL);
-#define FAIL_ON_GRIB_ERROR(function, gribHandle, key, ...) do\
-{\
- int errorCode = (int)function(gribHandle, key, __VA_ARGS__); \
- if(errorCode)\
- {\
- fprintf(stderr, "%s:%d: Error in function `%s`: `%s` returned error code %d for key \"%s\"", __FILE__, __LINE__, __func__, #function, errorCode, key);\
- exit(errorCode);\
- }\
-} while(0)
+ _fileList = (filePtrToIdx *) Malloc((size_t)_file_max*sizeof(filePtrToIdx));
+}
-//A simple wrapper for grib_get_string() that returns a newly allocated string.
-char* gribCopyString(grib_handle* gribHandle, const char* key)
+static
+void file_list_delete(void)
{
- char* result = NULL;
- size_t length;
-#ifdef HAVE_GRIB_GET_LENGTH
- if(!grib_get_length(gribHandle, key, &length))
+ if ( _fileList )
{
- char* result = (char *) Malloc(length);
- if(!grib_get_string(gribHandle, key, result, &length))
- result = (char *) Realloc(result, length);
-
- else
- {
- Free(result);
- result = NULL;
- }
+ Free(_fileList);
+ _fileList = NULL;
}
-#else
- length = 1024; /* there's an implementation limit
- * that makes strings longer than
- * this unlikely in grib_api versions
- * not providing grib_get_length */
- int rc;
- result = (char *) Malloc(length);
- while ((rc = grib_get_string(gribHandle, key, result, &length))
- == GRIB_BUFFER_TOO_SMALL || rc == GRIB_ARRAY_TOO_SMALL)
+}
+
+static
+void file_init_pointer(void)
+{
+ for ( int i = 0; i < _file_max; i++ )
{
- if (length <= 1024UL * 1024UL)
- {
- length *= 2;
- result = Realloc(result, length);
- }
- else
- break;
+ _fileList[i].next = _fileList + i + 1;
+ _fileList[i].idx = i;
+ _fileList[i].ptr = 0;
}
- if (!rc)
- result = Realloc(result, length);
- else
+
+ _fileList[_file_max-1].next = 0;
+
+ _fileAvail = _fileList;
+}
+
+static
+bfile_t *file_to_pointer(int idx)
+{
+ bfile_t *fileptr = NULL;
+
+ FILE_INIT();
+
+ if ( idx >= 0 && idx < _file_max )
{
- Free(result);
- result = NULL;
+ FILE_LOCK();
+
+ fileptr = _fileList[idx].ptr;
+
+ FILE_UNLOCK();
}
-#endif
- return result;
+ else
+ Error("file index %d undefined!", idx);
+
+ return fileptr;
}
-//A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
-//Returns true if the key exists and the value is equal to the given string.
-bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue)
+/* Create an index from a pointer */
+static
+int file_from_pointer(bfile_t *ptr)
{
- size_t expectedLength = strlen(expectedValue) + 1;
-#ifdef HAVE_GRIB_GET_LENGTH
- size_t length;
- if(grib_get_length(gribHandle, key, &length)) return false;
- if(length != expectedLength) return false;
- char *value = (char *) Malloc(length);
- if(grib_get_string(gribHandle, key, value, &length)) return false;
- int rc = !strcmp(value, expectedValue);
- Free(value);
-#else
- char *value = gribCopyString(gribHandle, key);
- int rc;
- if (value)
- {
- rc = strlen(value) + 1 == expectedLength ?
- !strcmp(value, expectedValue)
- : false;
- }
+ int idx = -1;
+ filePtrToIdx *newptr;
+
+ if ( ptr )
+ {
+ FILE_LOCK();
+
+ if ( _fileAvail )
+ {
+ newptr = _fileAvail;
+ _fileAvail = _fileAvail->next;
+ newptr->next = 0;
+ idx = newptr->idx;
+ newptr->ptr = ptr;
+
+ if ( FILE_Debug )
+ Message("Pointer %p has idx %d from file list", ptr, idx);
+ }
+ else
+ Warning("Too many open files (limit is %d)!", _file_max);
+
+ FILE_UNLOCK();
+ }
else
- rc = false;
- Free(value);
-#endif
- return rc;
-}
+ Error("Internal problem (pointer %p undefined)", ptr);
-//A simple wrapper for grib_get_long() for the usecase that the result is only compared to a given constant value.
-//Returns true if the key exists and the value is equal to the given one.
-bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue)
-{
- long value;
- if(grib_get_long(gribHandle, key, &value)) return false;
- return value == expectedValue;
+ return idx;
}
-//A simple wrapper for grib_get_long() for the usecase that failure to fetch the value is fatal.
-long gribGetLong(grib_handle* gh, const char* key)
+static
+void file_init_entry(bfile_t *fileptr)
{
- long result;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, key, &result);
- return result;
-}
+ fileptr->self = file_from_pointer(fileptr);
-//A simple wrapper for grib_get_long() for the usecase that a default value is used in the case that the operation fails.
-long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
-{
- long result;
- if(grib_get_long(gribHandle, key, &result)) return defaultValue;
- if(result == GRIB_MISSING_LONG) return defaultValue;
- return result;
+ fileptr->flag = 0;
+ fileptr->fd = -1;
+ fileptr->fp = NULL;
+ fileptr->mode = 0;
+ fileptr->size = 0;
+ fileptr->name = NULL;
+ fileptr->access = 0;
+ fileptr->position = 0;
+ fileptr->byteTrans = 0;
+ fileptr->type = 0;
+ fileptr->bufferType = 0;
+ fileptr->bufferSize = 0;
+ fileptr->mappedSize = 0;
+ fileptr->buffer = NULL;
+ fileptr->bufferNumFill = 0;
+ fileptr->bufferStart = 0;
+ fileptr->bufferEnd = -1;
+ fileptr->bufferPos = 0;
+ fileptr->bufferCnt = 0;
+ fileptr->bufferPtr = NULL;
+ fileptr->time_in_sec = 0.0;
}
-//A simple wrapper for grib_get_double() for the usecase that failure to fetch the value is fatal.
-double gribGetDouble(grib_handle* gh, const char* key)
+static
+bfile_t *file_new_entry(void)
{
- double result;
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, key, &result);
- return result;
-}
+ bfile_t *fileptr = (bfile_t *) Malloc(sizeof(bfile_t));
+ if ( fileptr ) file_init_entry(fileptr);
-//A sample wrapper for grib_get_double() for the usecase that a default value is used in the case that the operation fails.
-double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
-{
- double result;
- if(grib_get_double(gribHandle, key, &result)) return defaultValue;
- if(IS_EQUAL(result, GRIB_MISSING_DOUBLE)) return defaultValue;
- return result;
+ return fileptr;
}
-//A simple wrapper for grib_get_size() for the usecase that failure to fetch the value is fatal.
-size_t gribGetArraySize(grib_handle* gribHandle, const char* key)
+static
+void file_delete_entry(bfile_t *fileptr)
{
- size_t result;
- FAIL_ON_GRIB_ERROR(grib_get_size, gribHandle, key, &result);
- return result;
-}
+ int idx = fileptr->self;
-//A simple wrapper for grib_get_double_array() for the usecase that failure to fetch the data is fatal.
-void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array)
-{
- size_t valueCount = gribGetArraySize(gribHandle, key);
- FAIL_ON_GRIB_ERROR(grib_get_double_array, gribHandle, key, array, &valueCount);
-}
+ FILE_LOCK();
-//A simple wrapper for grib_get_long_array() for the usecase that failure to fetch the data is fatal.
-void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array)
-{
- size_t valueCount = gribGetArraySize(gribHandle, key);
- FAIL_ON_GRIB_ERROR(grib_get_long_array, gribHandle, key, array, &valueCount);
-}
+ Free(fileptr);
+
+ _fileList[idx].next = _fileAvail;
+ _fileList[idx].ptr = 0;
+ _fileAvail = &_fileList[idx];
+ FILE_UNLOCK();
-//We need the edition number so frequently, that it's convenient to give it its own function.
-long gribEditionNumber(grib_handle* gh)
-{
- return gribGetLong(gh, "editionNumber");
+ if ( FILE_Debug )
+ Message("Removed idx %d from file list", idx);
}
-//This return value of this should be passed to a call to resetTz(), it is a malloc'ed string with the content of the TZ environment variable before the call (or NULL if that was not set).
-static char* setUtc()
+
+const char *fileLibraryVersion(void)
{
- char* temp = getenv("TZ"), *result = NULL;
- if(temp) result = strdup(temp);
- setenv("TZ", "UTC", 1);
- return result;
+ return file_libvers;
}
-//Undoes the effect of setUtc(), pass to it the return value of the corresponding setUtc() call, it will free the string.
-static void resetTz(char* savedTz)
+static
+int pagesize(void)
{
- if(savedTz)
- {
- setenv("TZ", savedTz, 1);
- Free(savedTz);
- }
- else
- {
- unsetenv("TZ");
- }
+#if defined(_SC_PAGESIZE)
+ return (int) sysconf(_SC_PAGESIZE);
+#else
+#ifndef POSIXIO_DEFAULT_PAGESIZE
+#define POSIXIO_DEFAULT_PAGESIZE 4096
+#endif
+ return (int) POSIXIO_DEFAULT_PAGESIZE;
+#endif
}
-//This function uses the system functions to normalize the date representation according to the gregorian calendar.
-//Returns zero on success.
-static int normalizeDays(struct tm* me)
+static
+double file_time()
{
- char* savedTz = setUtc(); //Ensure that mktime() does not interprete the date according to our local time zone.
-
- int result = mktime(me) == (time_t)-1; //This does all the heavy lifting.
-
- resetTz(savedTz);
- return result;
+ struct timeval mytime;
+ gettimeofday(&mytime, NULL);
+ double tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
+ return tseconds;
}
-//Returns zero on success.
-static int addSecondsToDate(struct tm* me, long long amount)
+void fileDebug(int debug)
{
- //It is irrelevant here whether days are zero or one based, the correction would have be undone again so that it is effectless.
- long long seconds = ((me->tm_mday*24ll + me->tm_hour)*60 + me->tm_min)*60 + me->tm_sec; //The portion of the date that uses fixed increments.
- seconds += amount;
- me->tm_mday = (int)(seconds / 24 / 60 / 60);
- seconds -= (long long)me->tm_mday * 24 * 60 * 60;
- me->tm_hour = (int)(seconds / 60 / 60);
- seconds -= (long long)me->tm_hour * 60 * 60;
- me->tm_min = (int)(seconds / 60);
- seconds -= (long long)(me->tm_min * 60);
- me->tm_sec = (int)seconds;
- return normalizeDays(me);
+ FILE_Debug = debug;
+ if ( FILE_Debug ) Message("Debug level %d", debug);
}
-static void addMonthsToDate(struct tm* me, long long amount)
+
+void *filePtr(int fileID)
{
- long long months = me->tm_year*12ll + me->tm_mon;
- months += amount;
- me->tm_year = (int)(months/12);
- months -= (long long)me->tm_year*12;
- me->tm_mon = (int)months;
+ return (void*)file_to_pointer(fileID);
}
-//unit is a value according to code table 4.4 of the GRIB2 specification, returns non-zero on error
-static int addToDate(struct tm* me, long long amount, long unit)
+static
+void file_pointer_info(const char *caller, int fileID)
{
- switch(unit)
+ if ( FILE_Debug )
{
- case 0: return addSecondsToDate(me, 60*amount); // minute
- case 1: return addSecondsToDate(me, 60*60*amount); // hour
- case 2: return addSecondsToDate(me, 24*60*60*amount); // day
-
- case 3: addMonthsToDate(me, amount); return 0; // month
- case 4: addMonthsToDate(me, 12*amount); return 0; // year
- case 5: addMonthsToDate(me, 10*12*amount); return 0; // decade
- case 6: addMonthsToDate(me, 30*12*amount); return 0; // normal
- case 7: addMonthsToDate(me, 100*12*amount); return 0; // century
-
- case 10: return addSecondsToDate(me, 3*60*60*amount); // eighth of a day
- case 11: return addSecondsToDate(me, 6*60*60*amount); // quarter day
- case 12: return addSecondsToDate(me, 12*60*60*amount); // half day
- case 13: return addSecondsToDate(me, amount); // second
-
- default: return 1; //reserved, unknown, or missing
+ fprintf(stdout, "%-18s : ", caller);
+ fprintf(stdout, "The fileID %d underlying pointer is not valid!", fileID);
+ fprintf(stdout, "\n");
}
}
-static char* makeDateString(struct tm* me)
-{
- char *result
- = (char *) Malloc( 4+1+ 2+1+ 2+1+ 2+1+ 2+1+ 2+ 4+ 1);
- sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec);
- return result;
-}
-//FIXME: This ignores any calendar definition that might be present.
-//XXX: Identification templates are not implemented in grib_api-1.12.3, so even if I implemented the other calendars now, it wouldn't be possible to use them.
-static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecastTime, bool* outHaveTimeRange)
+int fileSetBufferType(int fileID, int type)
{
- switch(gribGetLong(gh, "productDefinitionTemplateNumber"))
+ int ret = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
+
+ if ( fileptr )
{
- case 20: case 30: case 31: case 254: case 311: case 2000:
- *outHaveForecastTime = false, *outHaveTimeRange = false;
- return 0;
+ switch (type)
+ {
+ case FILE_BUFTYPE_STD:
+ case FILE_BUFTYPE_MMAP:
+ fileptr->bufferType = (short)type;
+ break;
+ default:
+ Error("File type %d not implemented!", type);
+ }
+ }
- //case 55 and case 40455 are the same: 55 is the proposed standard value, 40455 is the value in the local use range that is used by the dwd until the standard is updated.
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 55: case 60: case 1000: case 1002: case 1100: case 40033: case 40455:
- *outHaveForecastTime = true, *outHaveTimeRange = false;
- return 0;
+#if ! defined (HAVE_MMAP)
+ if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
+#endif
- case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 34: case 42: case 43: case 46: case 47: case 61: case 91: case 1001: case 1101: case 40034:
- *outHaveForecastTime = true, *outHaveTimeRange = true;
- return 0;
+ return ret;
+}
- default:
- return 1;
- }
+int fileFlush(int fileID)
+{
+ int retval = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
+ if ( fileptr ) retval = fflush(fileptr->fp);
+
+ return retval;
}
-char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType)
+
+void fileClearerr(int fileID)
{
- //Get the parts of the reference date.
- struct tm date;
- date.tm_mon = (int)gribGetLong(gh, "month") - 1; //months are zero based in struct tm and one based in GRIB
- date.tm_mday = (int)gribGetLong(gh, "day");
- date.tm_hour = (int)gribGetLong(gh, "hour");
- date.tm_min = (int)gribGetLong(gh, "minute");
+ bfile_t *fileptr = file_to_pointer(fileID);
- if(gribEditionNumber(gh) == 1)
+ if ( fileptr )
{
- date.tm_year = (int)gribGetLong(gh, "yearOfCentury"); //years are -1900 based both in struct tm and GRIB1
+ if ( fileptr->mode != 'r' )
+ clearerr(fileptr->fp);
}
- else
- {
- date.tm_year = (int)gribGetLong(gh, "year") - 1900; //years are -1900 based in struct tm and zero based in GRIB2
- date.tm_sec = (int)gribGetLong(gh, "second");
+}
- //If the start or end time are requested, we need to take the relative times into account.
- if(timeType != kCdiTimeType_referenceTime)
- {
- //Determine whether we have a forecast time and a time range.
- bool haveForecastTime, haveTimeRange;
- if(getAvailabilityOfRelativeTimes(gh, &haveForecastTime, &haveTimeRange)) return NULL;
- if(timeType == kCdiTimeType_endTime && !haveTimeRange) return NULL; //tell the caller that the requested time does not exist
- //If we have relative times, apply the relative times to the date
- if(haveForecastTime)
- {
- long offset = gribGetLongDefault(gh, "forecastTime", 0); //if(stepUnits == indicatorOfUnitOfTimeRange) assert(startStep == forecastTime)
- long offsetUnit = gribGetLongDefault(gh, "indicatorOfUnitOfTimeRange", 255);
- if(addToDate(&date, offset, offsetUnit)) return NULL;
- if(timeType == kCdiTimeType_endTime)
- {
- assert(haveTimeRange);
- long range = gribGetLongDefault(gh, "lengthOfTimeRange", 0); //if(stepUnits == indicatorOfUnitForTimeRange) assert(endStep == startStep + lengthOfTimeRange)
- long rangeUnit = gribGetLongDefault(gh, "indicatorOfUnitForTimeRange", 255);
- if(addToDate(&date, range, rangeUnit)) return NULL;
- }
- }
- }
- }
+int filePtrEOF(void *vfileptr)
+{
+ int retval = 0;
+ bfile_t *fileptr = (bfile_t *) vfileptr;
+ if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
- //Bake the date into a string.
- return makeDateString(&date);
+ return retval;
}
-int gribapiTimeIsFC(grib_handle *gh)
+
+int fileEOF(int fileID)
{
- if(gribEditionNumber(gh) <= 1) return true;
+ int retval = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
+ if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
- long sigofrtime;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
- return sigofrtime != 3;
+ return retval;
}
-//Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
-int gribapiGetTsteptype(grib_handle *gh)
+void fileRewind(int fileID)
{
- int tsteptype = TSTEP_INSTANT;
- static bool lprint = true;
+ fileSetPos(fileID, (off_t) 0, SEEK_SET);
+ fileClearerr(fileID);
+}
- if ( gribapiTimeIsFC(gh) )
- {
- int status;
- size_t len = 256;
- char stepType[256];
- status = grib_get_string(gh, "stepType", stepType, &len);
- if ( status == 0 && len > 1 && len < 256 )
- {
- if ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
- else if ( strncmp("avg", stepType, len) == 0 ) tsteptype = TSTEP_AVG;
- else if ( strncmp("accum", stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
- else if ( strncmp("max", stepType, len) == 0 ) tsteptype = TSTEP_MAX;
- else if ( strncmp("min", stepType, len) == 0 ) tsteptype = TSTEP_MIN;
- else if ( strncmp("diff", stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
- else if ( strncmp("rms", stepType, len) == 0 ) tsteptype = TSTEP_RMS;
- else if ( strncmp("sd", stepType, len) == 0 ) tsteptype = TSTEP_SD;
- else if ( strncmp("cov", stepType, len) == 0 ) tsteptype = TSTEP_COV;
- else if ( strncmp("ratio", stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
- else if ( lprint )
- {
- Message("Time stepType %s unsupported, set to instant!", stepType);
- lprint = false;
- }
+off_t fileGetPos(int fileID)
+{
+ off_t filepos = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
- // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
- }
+ if ( fileptr )
+ {
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ filepos = fileptr->position;
+ else
+ filepos = ftell(fileptr->fp);
}
- return (tsteptype);
-}
+ if ( FILE_Debug ) Message("Position %ld", filepos);
-int gribGetDatatype(grib_handle* gribHandle)
-{
- int datatype;
- if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
- {
- datatype = gribCheckLong(gribHandle, "precision", 1) ? DATATYPE_FLT32 : DATATYPE_FLT64;
- }
- else
- {
- long bitsPerValue;
- datatype = (!grib_get_long(gribHandle, "bitsPerValue", &bitsPerValue) && bitsPerValue > 0 && bitsPerValue <= 32) ? (int)bitsPerValue : DATATYPE_PACK;
- }
- return datatype;
+ return filepos;
}
-int gribapiGetParam(grib_handle *gh)
+
+int fileSetPos(int fileID, off_t offset, int whence)
{
- long pdis, pcat, pnum;
- if ( gribEditionNumber(gh) <= 1 )
- {
- pdis = 255;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "table2Version", &pcat);
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "indicatorOfParameter", &pnum);
- }
- else
+ int status = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
+
+ if ( FILE_Debug ) Message("Offset %8ld Whence %3d", (long) offset, whence);
+
+ if ( fileptr == 0 )
{
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "discipline", &pdis);
- if(grib_get_long(gh, "parameterCategory", &pcat)) pcat = 0;
- if(grib_get_long(gh, "parameterNumber", &pnum)) pnum = 0;
+ file_pointer_info(__func__, fileID);
+ return 1;
}
- return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
-}
-int gribapiGetGridType(grib_handle *gh)
-{
- int gridtype = GRID_GENERIC;
- switch (gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1))
+ switch (whence)
{
- case GRIB2_GTYPE_LATLON:
- gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GENERIC : GRID_LONLAT;
- break;
+ case SEEK_SET:
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ {
+ off_t position = offset;
+ fileptr->position = position;
+ if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
+ {
+ if ( fileptr->bufferType == FILE_BUFTYPE_STD )
+ fileptr->bufferPos = position;
+ else
+ fileptr->bufferPos = position - position % pagesize();
- case GRIB2_GTYPE_GAUSSIAN:
- gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN;
- break;
+ fileptr->bufferCnt = 0;
+ fileptr->bufferPtr = NULL;
+ }
+ else
+ {
+ if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
+ {
+ if ( FILE_Debug )
+ Message("Reset buffer pos from %ld to %ld",
+ fileptr->bufferPos, fileptr->bufferEnd + 1);
- case GRIB2_GTYPE_LATLON_ROT: gridtype = GRID_LONLAT; break;
- case GRIB2_GTYPE_LCC: gridtype = GRID_LCC; break;
- case GRIB2_GTYPE_SPECTRAL: gridtype = GRID_SPECTRAL; break;
- case GRIB2_GTYPE_GME: gridtype = GRID_GME; break;
- case GRIB2_GTYPE_UNSTRUCTURED: gridtype = GRID_UNSTRUCTURED; break;
+ fileptr->bufferPos = fileptr->bufferEnd + 1;
+ }
+ fileptr->bufferCnt = (size_t)(fileptr->bufferEnd - position) + 1;
+ fileptr->bufferPtr = fileptr->buffer + position - fileptr->bufferStart;
+ }
+ }
+ else
+ {
+ status = fseek(fileptr->fp, offset, whence);
+ }
+ break;
+ case SEEK_CUR:
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ {
+ fileptr->position += offset;
+ off_t position = fileptr->position;
+ if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
+ {
+ if ( fileptr->bufferType == FILE_BUFTYPE_STD )
+ fileptr->bufferPos = position;
+ else
+ fileptr->bufferPos = position - position % pagesize();
+
+ fileptr->bufferCnt = 0;
+ fileptr->bufferPtr = NULL;
+ }
+ else
+ {
+ if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
+ {
+ if ( FILE_Debug )
+ Message("Reset buffer pos from %ld to %ld",
+ fileptr->bufferPos, fileptr->bufferEnd + 1);
+
+ fileptr->bufferPos = fileptr->bufferEnd + 1;
+ }
+ fileptr->bufferCnt -= (size_t)offset;
+ fileptr->bufferPtr += offset;
+ }
+ }
+ else
+ {
+ status = fseek(fileptr->fp, offset, whence);
+ }
+ break;
+ default:
+ Error("Whence = %d not implemented", whence);
}
- return gridtype;
+ if ( fileptr->position < fileptr->size )
+ if ( (fileptr->flag & FILE_EOF) != 0 )
+ fileptr->flag -= FILE_EOF;
+
+ return status;
}
static
-int gribapiGetIsRotated(grib_handle *gh)
+void file_table_print(void)
{
- return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
-}
+ int lprintHeader = 1;
-//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
-void gribapiGetGrid(grib_handle *gh, grid_t *grid)
-{
- long editionNumber = gribEditionNumber(gh);
- int gridtype = gribapiGetGridType(gh);
- /*
- if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
+ for ( int fileID = 0; fileID < _file_max; fileID++ )
{
- gridtype = GRID_GAUSSIAN;
- ISEC2_NumLon = 2*ISEC2_NumLat;
- ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
- }
- */
- grid_init(grid);
- cdiGridTypeInit(grid, gridtype, 0);
+ bfile_t *fileptr = file_to_pointer(fileID);
- size_t datasize;
- FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
- long numberOfPoints;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
+ if ( fileptr )
+ {
+ if ( lprintHeader )
+ {
+ fprintf(stderr, "\nFile table:\n");
+ fprintf(stderr, "+-----+---------+");
+ fprintf(stderr, "----------------------------------------------------+\n");
+ fprintf(stderr, "| ID | Mode |");
+ fprintf(stderr, " Name |\n");
+ fprintf(stderr, "+-----+---------+");
+ fprintf(stderr, "----------------------------------------------------+\n");
+ lprintHeader = 0;
+ }
+
+ fprintf(stderr, "| %3d | ", fileID);
+
+ switch ( fileptr->mode )
+ {
+ case 'r':
+ fprintf(stderr, "read ");
+ break;
+ case 'w':
+ fprintf(stderr, "write ");
+ break;
+ case 'a':
+ fprintf(stderr, "append ");
+ break;
+ default:
+ fprintf(stderr, "unknown");
+ }
- switch (gridtype)
+ fprintf(stderr, " | %-51s|\n", fileptr->name);
+ }
+ }
+
+ if ( lprintHeader == 0 )
{
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- {
- long nlon, nlat;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &nlon);
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &nlat);
+ fprintf(stderr, "+-----+---------+");
+ fprintf(stderr, "----------------------------------------------------+\n");
+ }
+}
- if ( gridtype == GRID_GAUSSIAN )
- {
- long lpar;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
- grid->np = (int)lpar;
- }
- if ( numberOfPoints != nlon*nlat )
- Error("numberOfPoints (%ld) and gridSize (%ld) differ!", numberOfPoints, nlon*nlat);
-
- /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
- grid->size = (int)numberOfPoints;
- grid->xsize = (int)nlon;
- grid->ysize = (int)nlat;
- grid->xinc = 0;
- grid->yinc = 0;
- grid->xdef = 0;
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees", &grid->xlast);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->yfirst);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees", &grid->ylast);
- if ( nlon > 1 )
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
- if ( gridtype == GRID_LONLAT && nlat > 1 )
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->yinc);
-
- if ( grid->xinc < -999 || grid->xinc > 999 ) grid->xinc = 0;
- if ( grid->yinc < -999 || grid->yinc > 999 ) grid->yinc = 0;
-
- if ( grid->yinc > 0 && grid->yfirst > grid->ylast ) grid->yinc = -grid->yinc;
-
- /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
- {
- if ( grid->xsize > 1 )
- {
- if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+char *fileInqName(int fileID)
+{
+ char *name = NULL;
+ bfile_t *fileptr = file_to_pointer(fileID);
+ if ( fileptr ) name = fileptr->name;
- if ( editionNumber <= 1 )
- {
- /* correct xinc if necessary */
- if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
- {
- double xinc = 360. / grid->xsize;
+ return name;
+}
- if ( fabs(grid->xinc-xinc) > 0.0 )
- {
- grid->xinc = xinc;
- if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
- }
- }
- }
- }
- grid->xdef = 2;
- }
- grid->ydef = 0;
- /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
- {
- if ( grid->ysize > 1 )
- {
- if ( editionNumber <= 1 )
- {
- }
- }
- grid->ydef = 2;
- }
- break;
- }
- case GRID_GAUSSIAN_REDUCED:
- {
- long lpar;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- grid->np = (int)lpar;
-
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- int nlat = (int)lpar;
-
- /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
- grid->size = (int)numberOfPoints;
-
- grid->nrowlon = nlat;
- grid->rowlon = (int *) Malloc((size_t)nlat * sizeof (int));
- long *pl = (long *) Malloc((size_t)nlat * sizeof (long));
- size_t dummy = (size_t)nlat;
- FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
- /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
- for ( int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
- Free(pl);
-
- grid->ysize = nlat;
- grid->xinc = 0;
- grid->yinc = 0;
- grid->xdef = 0;
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees", &grid->xlast);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->yfirst);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees", &grid->ylast);
-
- // FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
- // if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
-
- /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
- {
- if ( grid->xsize > 1 )
- {
- if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
- if ( editionNumber <= 1 )
- {
- /* correct xinc if necessary */
- if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
- {
- double xinc = 360. / grid->xsize;
+int fileInqMode(int fileID)
+{
+ int mode = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
+ if ( fileptr ) mode = fileptr->mode;
- if ( fabs(grid->xinc-xinc) > 0.0 )
- {
- grid->xinc = xinc;
- if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
- }
- }
- }
- }
- grid->xdef = 2;
- }
- grid->ydef = 0;
- /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
- {
- if ( grid->ysize > 1 )
- {
- if ( editionNumber <= 1 )
- {
- }
- }
- grid->ydef = 2;
- }
- break;
- }
- case GRID_LCC:
- {
- int nlon, nlat;
- long lpar;
+ return mode;
+}
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
- nlon = (int)lpar;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
- nlat = (int)lpar;
+static
+long file_getenv(const char *envName)
+{
+ long envValue = -1;
+ long fact = 1;
- if ( numberOfPoints != nlon*nlat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+ char *envString = getenv(envName);
- grid->size = (int)numberOfPoints;
- grid->xsize = nlon;
- grid->ysize = nlat;
+ if ( envString )
+ {
+ for ( int loop = 0; loop < (int) strlen(envString); loop++ )
+ {
+ if ( ! isdigit((int) envString[loop]) )
+ {
+ switch ( tolower((int) envString[loop]) )
+ {
+ case 'k': fact = 1024; break;
+ case 'm': fact = 1048576; break;
+ case 'g': fact = 1073741824; break;
+ default:
+ fact = 0;
+ Message("Invalid number string in %s: %s", envName, envString);
+ Warning("%s must comprise only digits [0-9].",envName);
+ }
+ break;
+ }
+ }
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &grid->lcc_xinc);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &grid->lcc_yinc);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "LoVInDegrees", &grid->lcc_lonParY);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin1InDegrees", &grid->lcc_lat1);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin2InDegrees", &grid->lcc_lat2);
+ if ( fact ) envValue = fact*atol(envString);
- if ( editionNumber <= 1 )
- {
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "projectionCenterFlag", &lpar);
- grid->lcc_projflag = (int) lpar;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "scanningMode", &lpar);
- grid->lcc_scanflag = (int) lpar;
- }
+ if ( FILE_Debug ) Message("Set %s to %ld", envName, envValue);
+ }
- grid->xdef = 0;
- grid->ydef = 0;
+ return envValue;
+}
- break;
- }
- case GRID_SPECTRAL:
- {
- size_t len = 256;
- char typeOfPacking[256];
- FAIL_ON_GRIB_ERROR(grib_get_string, gh, "packingType", typeOfPacking, &len);
- grid->lcomplex = 0;
- if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
-
- /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
- grid->size = (int)datasize;
- long lpar;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
- /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
- grid->trunc = (int)lpar;
+static
+void file_initialize(void)
+{
+ long value;
- break;
- }
- case GRID_GME:
- {
- /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
- grid->size = (int)numberOfPoints;
- long lpar;
- /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
- if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd = (int)lpar;
- /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
- if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni = (int)lpar;
- /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
- if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
- /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
- if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
+#if defined (HAVE_LIBPTHREAD)
+ /* initialize global API mutex lock */
+ pthread_mutex_init(&_file_mutex, NULL);
+#endif
- break;
- }
- case GRID_UNSTRUCTURED:
- {
- unsigned char uuid[CDI_UUID_SIZE];
- /*
- char reference_link[8192];
- size_t len = sizeof(reference_link);
- reference_link[0] = 0;
- */
+ value = file_getenv("FILE_DEBUG");
+ if ( value >= 0 ) FILE_Debug = (int) value;
- /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
- grid->size = (int)numberOfPoints;
- long lpar;
- if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
- {
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- grid->number = (int)lpar;
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
- grid->position = (int)lpar;
- /*
- if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
- {
- if ( strncmp(reference_link, "file://", 7) == 0 )
- grid->reference = strdupx(reference_link);
- }
- */
- size_t len = (size_t)CDI_UUID_SIZE;
- if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
- {
- memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
- }
- }
- break;
- }
- case GRID_GENERIC:
- {
- int nlon = 0, nlat = 0;
- long lpar;
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
- /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
- if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+ value = file_getenv("FILE_MAX");
+ if ( value >= 0 ) _file_max = (int) value;
- /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
- grid->size = (int)numberOfPoints;
+ if ( FILE_Debug )
+ Message("FILE_MAX = %d", _file_max);
- if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
- {
- grid->xsize = nlon;
- grid->ysize = nlat;
- }
- else
- {
- grid->xsize = 0;
- grid->ysize = 0;
- }
+ FileInfo = file_getenv("FILE_INFO") > 0;
- break;
- }
- default:
- {
- Error("Unsupported grid type: %s", gridNamePtr(gridtype));
- break;
- }
+ value = file_getenv("FILE_BUFSIZE");
+ if ( value >= 0 ) FileBufferSizeEnv = value;
+ else
+ {
+ value = file_getenv("GRIB_API_IO_BUFFER_SIZE");
+ if ( value >= 0 ) FileBufferSizeEnv = value;
}
- grid->isRotated = FALSE;
- if ( gribapiGetIsRotated(gh) )
+ value = file_getenv("FILE_TYPE_READ");
+ if ( value > 0 )
{
- grid->isRotated = TRUE;
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfSouthernPoleInDegrees", &grid->ypole);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole);
- FAIL_ON_GRIB_ERROR(grib_get_double, gh, "angleOfRotation", &grid->angle);
- /* change from south to north pole */
- if ( fabs(grid->ypole) > 0 ) grid->ypole = -grid->ypole;
- grid->xpole = grid->xpole - 180;
- if ( fabs(grid->angle) > 0 ) grid->angle = -grid->angle;
+ switch (value)
+ {
+ case FILE_TYPE_OPEN:
+ case FILE_TYPE_FOPEN:
+ FileTypeRead = (short)value;
+ break;
+ default:
+ Warning("File type %d not implemented!", value);
+ }
}
- grid->xvals = NULL;
- grid->yvals = NULL;
- grid->type = gridtype;
-}
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef CDI_UUID_H
-#define CDI_UUID_H
+ value = file_getenv("FILE_TYPE_WRITE");
+ if ( value > 0 )
+ {
+ switch (value)
+ {
+ case FILE_TYPE_OPEN:
+ case FILE_TYPE_FOPEN:
+ FileTypeWrite = (short)value;
+ break;
+ default:
+ Warning("File type %d not implemented!", value);
+ }
+ }
-#if defined (HAVE_CONFIG_H)
+#if defined (O_NONBLOCK)
+ FileFlagWrite = O_NONBLOCK;
#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
+ char *envString = getenv("FILE_FLAG_WRITE");
+ if ( envString )
+ {
+#if defined (O_NONBLOCK)
+ if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
#endif
+ }
-static inline int cdiUUIDIsNull(const unsigned char uuid[])
-{
- int isNull = 1;
- for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
- isNull &= (uuid[i] == 0);
- return isNull;
-}
-
-void cdiCreateUUID(unsigned char uuid[CDI_UUID_SIZE]);
-
-void cdiUUID2Str(const unsigned char uuid[], char uuidstr[]);
-int cdiStr2UUID(const char *uuidstr, unsigned char uuid[]);
-
-#if defined (__cplusplus)
-}
+ value = file_getenv("FILE_BUFTYPE");
+#if ! defined (HAVE_MMAP)
+ if ( value == FILE_BUFTYPE_MMAP )
+ {
+ Warning("MMAP not available!");
+ value = 0;
+ }
#endif
+ if ( value > 0 )
+ {
+ switch (value)
+ {
+ case FILE_BUFTYPE_STD:
+ case FILE_BUFTYPE_MMAP:
+ FileBufferTypeEnv = (short)value;
+ break;
+ default:
+ Warning("File buffer type %d not implemented!", value);
+ }
+ }
-#endif
+ file_list_new();
+ atexit(file_list_delete);
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef RESOURCE_UNPACK_H
-#define RESOURCE_UNPACK_H
+ FILE_LOCK();
-#ifdef HAVE_CONFIG_H
-#endif
+ file_init_pointer();
-enum
-{ GRID = 1,
- ZAXIS = 2,
- TAXIS = 3,
- INSTITUTE = 4,
- MODEL = 5,
- STREAM = 6,
- VLIST = 7,
- RESH_DELETE,
- START = 55555555,
- END = 99999999
-};
+ FILE_UNLOCK();
-int reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
- void *context);
+ if ( FILE_Debug ) atexit(file_table_print);
-#endif
+ _file_init = true;
+}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _VLIST_H
-#define _VLIST_H
+static
+void file_set_buffer(bfile_t *fileptr)
+{
+ size_t buffersize = 0;
-#ifdef HAVE_CONFIG_H
-#endif
+ if ( fileptr->mode == 'r' )
+ {
+ if ( FileBufferTypeEnv )
+ fileptr->bufferType = FileBufferTypeEnv;
+ else if ( fileptr->bufferType == 0 )
+ fileptr->bufferType = FILE_BUFTYPE_STD;
-#ifndef _ERROR_H
-#endif
+ if ( FileBufferSizeEnv >= 0 )
+ buffersize = (size_t) FileBufferSizeEnv;
+ else if ( fileptr->bufferSize > 0 )
+ buffersize = fileptr->bufferSize;
+ else
+ {
+ buffersize = fileptr->blockSize * 4;
+ if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
+ }
-#include <stddef.h> /* size_t */
+ if ( (size_t) fileptr->size < buffersize )
+ buffersize = (size_t) fileptr->size;
-#ifndef _CDI_LIMITS_H
-#endif
+ if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
+ {
+ size_t blocksize = (size_t) pagesize();
+ size_t minblocksize = 4 * blocksize;
+ buffersize = buffersize - buffersize % minblocksize;
-#define VALIDMISS 1.e+303
+ if ( buffersize < (size_t) fileptr->size && buffersize < minblocksize )
+ buffersize = minblocksize;
+ }
-/*
- * CDI attribute
- */
-typedef struct {
- size_t xsz; /* amount of space at xvalue */
- size_t namesz; /* size of name */
- char *name; /* attribute name */
- int indtype; /* internal data type of xvalue (INT, FLT or TXT) */
- int exdtype; /* external data type */
- /* indtype exdtype */
- /* TXT TXT */
- /* INT INT16, INT32 */
- /* FLT FLT32, FLT64 */
- size_t nelems; /* number of elements */
- void *xvalue; /* the actual data */
-} cdi_att_t;
+ if ( buffersize == 0 ) buffersize = 1;
+ }
+ else
+ {
+ fileptr->bufferType = FILE_BUFTYPE_STD;
+ if ( FileBufferSizeEnv >= 0 )
+ buffersize = (size_t) FileBufferSizeEnv;
+ else if ( fileptr->bufferSize > 0 )
+ buffersize = fileptr->bufferSize;
+ else
+ {
+ buffersize = fileptr->blockSize * 4;
+ if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
+ }
+ }
-typedef struct {
- size_t nalloc; /* number allocated >= nelems */
- size_t nelems; /* length of the array */
- cdi_att_t value[MAX_ATTRIBUTES];
-} cdi_atts_t;
+ if ( fileptr->bufferType == FILE_BUFTYPE_STD || fileptr->type == FILE_TYPE_FOPEN )
+ {
+ if ( buffersize > 0 )
+ {
+ fileptr->buffer = (char *) Malloc(buffersize);
+ if ( fileptr->buffer == NULL )
+ SysError("Allocation of file buffer failed!");
+ }
+ }
+ if ( fileptr->type == FILE_TYPE_FOPEN )
+ if ( setvbuf(fileptr->fp, fileptr->buffer, fileptr->buffer ? _IOFBF : _IONBF, buffersize) )
+ SysError("setvbuf failed!");
-typedef struct
-{
- int flag;
- int index;
- int mlevelID;
- int flevelID;
+ fileptr->bufferSize = buffersize;
}
-levinfo_t;
-#define DEFAULT_LEVINFO(levID) \
- (levinfo_t){ 0, -1, levID, levID}
-/*
-#define DEFAULT_LEVINFO(levID) \
- (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
-*/
-typedef struct
+static
+int file_fill_buffer(bfile_t *fileptr)
{
- int ens_index;
- int ens_count;
- int forecast_init_type;
-}
-ensinfo_t;
-
-
+ ssize_t nread;
+ long offset = 0;
-typedef struct
-{
- int flag;
- int isUsed;
- int mvarID;
- int fvarID;
- int param;
- int gridID;
- int zaxisID;
- int tsteptype; /* TSTEP_* */
- int datatype; /* DATATYPE_PACKX for GRIB data, else DATATYPE_FLT32 or DATATYPE_FLT64 */
- int instID;
- int modelID;
- int tableID;
- int timave;
- int timaccu;
- int typeOfGeneratingProcess;
- int productDefinitionTemplate;
- int chunktype;
- int xyz;
- int missvalused; /* TRUE if missval is defined */
- int lvalidrange;
- char *name;
- char *longname;
- char *stdname;
- char *units;
- char *extra;
- double missval;
- double scalefactor;
- double addoffset;
- double validrange[2];
- levinfo_t *levinfo;
- int comptype; // compression type
- int complevel; // compression level
- ensinfo_t *ensdata; /* Ensemble information */
- cdi_atts_t atts;
- int iorank;
+ if ( FILE_Debug )
+ Message("file ptr = %p Cnt = %ld", fileptr, fileptr->bufferCnt);
- int subtypeID; /* subtype ID for tile-related meta-data, currently for GRIB-API only. */
+ if ( (fileptr->flag & FILE_EOF) != 0 ) return EOF;
- int opt_grib_nentries; /* current no. key-value pairs */
- int opt_grib_kvpair_size; /* current allocated size */
- opt_key_val_pair_t *opt_grib_kvpair; /* (optional) list of keyword/value pairs */
-}
-var_t;
+ if ( fileptr->buffer == NULL ) file_set_buffer(fileptr);
+ if ( fileptr->bufferSize == 0 ) return EOF;
-typedef struct
-{
- //set when a vlist is passed to streamDefVlist() to safeguard against modifications of the wrong vlist object
- bool immutable;
- //set if this vlist has been created by CDI itself, and must not be destroyed by the user, consequently
- bool internal;
- int self;
- int nvars; /* number of variables */
- int ngrids;
- int nzaxis;
- int nsubtypes; /* no. of variable subtypes (e.g. sets of tiles) */
- long ntsteps;
- int taxisID;
- int tableID;
- int instID;
- int modelID;
- int varsAllocated;
- int gridIDs[MAX_GRIDS_PS];
- int zaxisIDs[MAX_ZAXES_PS];
- int subtypeIDs[MAX_SUBTYPES_PS];
- var_t *vars;
- cdi_atts_t atts;
-}
-vlist_t;
+ int fd = fileptr->fd;
+#if defined (HAVE_MMAP)
+ if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
+ {
+ if ( fileptr->bufferPos >= fileptr->size )
+ {
+ nread = 0;
+ }
+ else
+ {
+ xassert(fileptr->bufferSize <= SSIZE_MAX);
+ nread = (ssize_t)fileptr->bufferSize;
+ if ( (nread + fileptr->bufferPos) > fileptr->size )
+ nread = fileptr->size - fileptr->bufferPos;
-vlist_t *vlist_to_pointer(int vlistID);
-void cdiVlistMakeInternal(int vlistID);
-void cdiVlistMakeImmutable(int vlistID);
-void vlistCheckVarID(const char *caller, int vlistID, int varID);
-const char *vlistInqVarStdnamePtr(int vlistID, int varID);
-void vlistDestroyVarName(int vlistID, int varID);
-void vlistDestroyVarLongname(int vlistID, int varID);
-void vlistDestroyVarStdname(int vlistID, int varID);
-void vlistDestroyVarUnits(int vlistID, int varID);
-void cdiVlistDestroy_(int vlistID);
-void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
-int vlistInqVarMissvalUsed(int vlistID, int varID);
-int vlistHasTime(int vlistID);
+ if ( fileptr->buffer )
+ {
+ int ret = munmap(fileptr->buffer, fileptr->mappedSize);
+ if ( ret == -1 ) SysError("munmap error for read %s", fileptr->name);
+ fileptr->buffer = NULL;
+ }
-int vlistDelAtts(int vlistID, int varID);
-int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2);
+ fileptr->mappedSize = (size_t)nread;
-void vlistUnpack(char * buffer, int bufferSize, int * pos,
- int originNamespace, void *context, int force_id);
+ fileptr->buffer = (char*) mmap(NULL, (size_t) nread, PROT_READ, MAP_PRIVATE, fd, fileptr->bufferPos);
-/* vlistDefVarValidrange: Define the valid range of a Variable */
-void vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
+ if ( fileptr->buffer == MAP_FAILED ) SysError("mmap error for read %s", fileptr->name);
-/* vlistInqVarValidrange: Get the valid range of a Variable */
-int vlistInqVarValidrange(int vlistID, int varID, double *validrange);
+ offset = fileptr->position - fileptr->bufferPos;
+ }
+ }
+ else
+#endif
+ {
+ off_t retseek = lseek(fileptr->fd, fileptr->bufferPos, SEEK_SET);
+ if ( retseek == (off_t)-1 )
+ SysError("lseek error at pos %ld file %s", (long) fileptr->bufferPos, fileptr->name);
-void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3]);
+ nread = read(fd, fileptr->buffer, fileptr->bufferSize);
+ if ( nread > 0 ) offset = fileptr->position - fileptr->bufferPos;
+ }
-int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
+ if ( nread <= 0 )
+ {
+ fileptr->flag |= (nread == 0) ? FILE_EOF : FILE_ERROR;
+ fileptr->bufferCnt = 0;
+ return EOF;
+ }
-void resize_opt_grib_entries(var_t *var, int nentries);
+ fileptr->bufferPtr = fileptr->buffer;
+ fileptr->bufferCnt = (size_t)nread;
+ fileptr->bufferStart = fileptr->bufferPos;
+ fileptr->bufferPos += nread;
+ fileptr->bufferEnd = fileptr->bufferPos - 1;
+ if ( FILE_Debug )
+ {
+ Message("fileID = %d Val = %d", fileptr->self, (int) fileptr->buffer[0]);
+ Message("fileID = %d Start = %ld", fileptr->self, fileptr->bufferStart);
+ Message("fileID = %d End = %ld", fileptr->self, fileptr->bufferEnd);
+ Message("fileID = %d nread = %ld", fileptr->self, nread);
+ Message("fileID = %d offset = %ld", fileptr->self, offset);
+ Message("fileID = %d Pos = %ld", fileptr->self, fileptr->bufferPos);
+ Message("fileID = %d postion = %ld", fileptr->self, fileptr->position);
+ }
-static inline void
-vlistAdd2GridIDs(vlist_t *vlistptr, int gridID)
-{
- int index, ngrids = vlistptr->ngrids;
- for ( index = 0; index < ngrids; index++ )
- if (vlistptr->gridIDs[index] == gridID ) break;
- if ( index == ngrids )
+ if ( offset > 0 )
{
- if (ngrids >= MAX_GRIDS_PS)
- Error("Internal limit exceeded: more than %d grids.", MAX_GRIDS_PS);
- ++(vlistptr->ngrids);
- vlistptr->gridIDs[ngrids] = gridID;
+ if ( offset > nread )
+ Error("Internal problem with buffer handling. nread = %d offset = %d", nread, offset);
+
+ fileptr->bufferPtr += offset;
+ fileptr->bufferCnt -= (size_t)offset;
}
+
+ fileptr->bufferNumFill++;
+
+ return (unsigned char) *fileptr->bufferPtr;
}
-static inline void
-vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
+static
+void file_copy_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
{
- int index, nzaxis = vlistptr->nzaxis;
- for ( index = 0; index < nzaxis; index++ )
- if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
+ if ( FILE_Debug )
+ Message("size = %ld Cnt = %ld", size, fileptr->bufferCnt);
- if ( index == nzaxis )
+ if ( fileptr->bufferCnt < size )
+ Error("Buffer too small. bufferCnt = %d", fileptr->bufferCnt);
+
+ if ( size == 1 )
{
- if ( nzaxis >= MAX_ZAXES_PS )
- Error("Internal limit exceeded: more than %d zaxis.", MAX_ZAXES_PS);
- vlistptr->zaxisIDs[nzaxis] = zaxisID;
- vlistptr->nzaxis++;
+ ((char *)ptr)[0] = fileptr->bufferPtr[0];
+
+ fileptr->bufferPtr++;
+ fileptr->bufferCnt--;
+ }
+ else
+ {
+ memcpy(ptr, fileptr->bufferPtr, size);
+
+ fileptr->bufferPtr += size;
+ fileptr->bufferCnt -= size;
}
}
-static inline void
-vlistAdd2SubtypeIDs(vlist_t *vlistptr, int subtypeID)
+static
+size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
{
- if ( subtypeID == CDI_UNDEFID ) return;
+ size_t nread;
+ size_t offset = 0;
- int index, nsubs = vlistptr->nsubtypes;
- for ( index = 0; index < nsubs; index++ )
- if (vlistptr->subtypeIDs[index] == subtypeID ) break;
- if ( index == nsubs )
+ if ( FILE_Debug )
+ Message("size = %ld Cnt = %ld", size, (long) fileptr->bufferCnt);
+
+ if ( ((long)fileptr->bufferCnt) < 0L )
+ Error("Internal problem. bufferCnt = %ld", (long) fileptr->bufferCnt);
+
+ size_t rsize = size;
+
+ while ( fileptr->bufferCnt < rsize )
{
- if (nsubs >= MAX_SUBTYPES_PS)
- Error("Internal limit exceeded: more than %d subs.", MAX_SUBTYPES_PS);
- ++(vlistptr->nsubtypes);
- vlistptr->subtypeIDs[nsubs] = subtypeID;
+ nread = fileptr->bufferCnt;
+ /*
+ fprintf(stderr, "rsize = %d nread = %d\n", (int) rsize, (int) nread);
+ */
+ if ( nread > (size_t) 0 )
+ file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
+ offset += nread;
+ if ( nread < rsize )
+ rsize -= nread;
+ else
+ rsize = 0;
+
+ if ( file_fill_buffer(fileptr) == EOF ) break;
}
-}
+ nread = size - offset;
+ if ( fileptr->bufferCnt < nread ) nread = fileptr->bufferCnt;
-#if defined (HAVE_LIBGRIB_API)
-extern int cdiNAdditionalGRIBKeys;
-extern char* cdiAdditionalGRIBKeys[];
-#endif
+ if ( nread > (unsigned) 0 )
+ file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
-extern
-#ifndef __cplusplus
-const
-#endif
-resOps vlistOps;
+ return (nread+offset);
+}
+
+
+void fileSetBufferSize(int fileID, long buffersize)
+{
+ bfile_t *fileptr = file_to_pointer(fileID);
+ xassert(buffersize >= 0);
+ if ( fileptr ) fileptr->bufferSize = (size_t)buffersize;
+}
-#endif /* _VLIST_H */
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
+ * Open a file. Returns file ID, or -1 on error
*/
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <assert.h>
-#include <string.h>
-#include <float.h> /* FLT_EPSILON */
-#include <limits.h> /* INT_MAX */
+int fileOpen(const char *filename, const char *mode)
+{
+ int (*myFileOpen)(const char *filename, const char *mode)
+ = (int (*)(const char *, const char *))
+ namespaceSwitchGet(NSSWITCH_FILE_OPEN).func;
+ return myFileOpen(filename, mode);
+}
+int fileOpen_serial(const char *filename, const char *mode)
+{
+ FILE *fp = NULL; /* file pointer (used for write) */
+ int fd = -1; /* file descriptor (used for read) */
+ int fileID = FILE_UNDEFID;
+ struct stat filestat;
+ bfile_t *fileptr = NULL;
-#undef UNDEFID
-#define UNDEFID -1
+ FILE_INIT();
-/* the value in the second pair of brackets must match the length of
- * the longest string (including terminating NUL) */
-static const char Grids[][17] = {
- /* 0 */ "undefined",
- /* 1 */ "generic",
- /* 2 */ "gaussian",
- /* 3 */ "gaussian reduced",
- /* 4 */ "lonlat",
- /* 5 */ "spectral",
- /* 6 */ "fourier",
- /* 7 */ "gme",
- /* 8 */ "trajectory",
- /* 9 */ "unstructured",
- /* 10 */ "curvilinear",
- /* 11 */ "lcc",
- /* 12 */ "lcc2",
- /* 13 */ "laea",
- /* 14 */ "sinusoidal",
- /* 15 */ "projection",
-};
+ int fmode = tolower((int) mode[0]);
-/* must match table below */
-enum xystdname_idx {
- grid_xystdname_grid_latlon,
- grid_xystdname_latlon,
- grid_xystdname_projection,
-};
-static const char xystdname_tab[][2][24] = {
- [grid_xystdname_grid_latlon] = { "grid_longitude",
- "grid_latitude" },
- [grid_xystdname_latlon] = { "longitude",
- "latitude" },
- [grid_xystdname_projection] = { "projection_x_coordinate",
- "projection_y_coordinate" },
+ switch ( fmode )
+ {
+ case 'r':
+ if ( FileTypeRead == FILE_TYPE_FOPEN )
+ fp = fopen(filename, "rb");
+ else
+ fd = open(filename, O_RDONLY | O_BINARY);
+ break;
+ case 'x': fp = fopen(filename, "rb"); break;
+ case 'w':
+ if ( FileTypeWrite == FILE_TYPE_FOPEN )
+ fp = fopen(filename, "wb");
+ else
+ fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
+ break;
+ case 'a': fp = fopen(filename, "ab"); break;
+ default: Error("Mode %c unexpected!", fmode);
+ }
-};
+ if ( FILE_Debug )
+ if ( fp == NULL && fd == -1 )
+ Message("Open failed on %s mode %c errno %d", filename, fmode, errno);
+ if ( fp )
+ {
+ if ( stat(filename, &filestat) != 0 ) return fileID;
+ fileptr = file_new_entry();
+ if ( fileptr )
+ {
+ fileID = fileptr->self;
+ fileptr->fp = fp;
+ }
+ }
+ else if ( fd >= 0 )
+ {
+ if ( fstat(fd, &filestat) != 0 ) return fileID;
-static int gridCompareP ( void * gridptr1, void * gridptr2 );
-static void gridDestroyP ( void * gridptr );
-static void gridPrintP ( void * gridptr, FILE * fp );
-static int gridGetPackSize ( void * gridptr, void *context);
-static void gridPack ( void * gridptr, void * buff, int size,
- int *position, void *context);
-static int gridTxCode ( void );
+ fileptr = file_new_entry();
+ if ( fileptr )
+ {
+ fileID = fileptr->self;
+ fileptr->fd = fd;
+ }
+ }
-static const resOps gridOps = {
- gridCompareP,
- gridDestroyP,
- gridPrintP,
- gridGetPackSize,
- gridPack,
- gridTxCode
-};
+ if ( fileID >= 0 )
+ {
+ fileptr->mode = fmode;
+ fileptr->name = strdupx(filename);
-static int GRID_Debug = 0; /* If set to 1, debugging */
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+ fileptr->blockSize = (size_t) filestat.st_blksize;
+#else
+ fileptr->blockSize = (size_t) 4096;
+#endif
-grid_t *gridID2Ptr(int gridID)
-{
- return (grid_t *)reshGetVal(gridID, &gridOps);
-}
-#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
-#define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
+ if ( fmode == 'r' )
+ fileptr->type = FileTypeRead;
+ else if ( fmode == 'w' )
+ fileptr->type = FileTypeWrite;
+ else
+ fileptr->type = FILE_TYPE_FOPEN;
+ if ( fmode == 'r' ) fileptr->size = filestat.st_size;
-void grid_init(grid_t *gridptr)
-{
- gridptr->self = CDI_UNDEFID;
- gridptr->type = CDI_UNDEFID;
- gridptr->proj = CDI_UNDEFID;
- gridptr->mask = NULL;
- gridptr->mask_gme = NULL;
- gridptr->xvals = NULL;
- gridptr->yvals = NULL;
- gridptr->area = NULL;
- gridptr->xbounds = NULL;
- gridptr->ybounds = NULL;
- gridptr->rowlon = NULL;
- gridptr->nrowlon = 0;
- gridptr->xfirst = 0.0;
- gridptr->xlast = 0.0;
- gridptr->xinc = 0.0;
- gridptr->yfirst = 0.0;
- gridptr->ylast = 0.0;
- gridptr->yinc = 0.0;
- gridptr->lcc_originLon = 0.0;
- gridptr->lcc_originLat = 0.0;
- gridptr->lcc_lonParY = 0.0;
- gridptr->lcc_lat1 = 0.0;
- gridptr->lcc_lat2 = 0.0;
- gridptr->lcc_xinc = 0.0;
- gridptr->lcc_yinc = 0.0;
- gridptr->lcc_projflag = 0;
- gridptr->lcc_scanflag = 0;
- gridptr->lcc_defined = FALSE;
- gridptr->lcc2_lon_0 = 0.0;
- gridptr->lcc2_lat_0 = 0.0;
- gridptr->lcc2_lat_1 = 0.0;
- gridptr->lcc2_lat_2 = 0.0;
- gridptr->lcc2_a = 0.0;
- gridptr->lcc2_defined = FALSE;
- gridptr->laea_lon_0 = 0.0;
- gridptr->laea_lat_0 = 0.0;
- gridptr->laea_a = 0.0;
- gridptr->laea_defined = FALSE;
- gridptr->trunc = 0;
- gridptr->nvertex = 0;
- gridptr->nd = 0;
- gridptr->ni = 0;
- gridptr->ni2 = 0;
- gridptr->ni3 = 0;
- gridptr->number = 0;
- gridptr->position = 0;
- gridptr->reference = NULL;
- gridptr->prec = 0;
- gridptr->size = 0;
- gridptr->xsize = 0;
- gridptr->ysize = 0;
- gridptr->np = 0;
- gridptr->xdef = 0;
- gridptr->ydef = 0;
- gridptr->isCyclic = CDI_UNDEFID;
- gridptr->isRotated = FALSE;
- gridptr->xpole = 0.0;
- gridptr->ypole = 0.0;
- gridptr->angle = 0.0;
- gridptr->lcomplex = 0;
- gridptr->hasdims = TRUE;
- gridptr->xdimname[0] = 0;
- gridptr->ydimname[0] = 0;
- gridptr->vdimname[0] = 0;
- gridptr->xname[0] = 0;
- gridptr->yname[0] = 0;
- gridptr->xlongname[0] = 0;
- gridptr->ylongname[0] = 0;
- gridptr->xunits[0] = 0;
- gridptr->yunits[0] = 0;
- gridptr->xstdname = NULL;
- gridptr->ystdname = NULL;
- memset(gridptr->uuid, 0, CDI_UUID_SIZE);
- gridptr->name = NULL;
- gridptr->vtable = &cdiGridVtable;
- gridptr->extraData = NULL;
-}
+ if ( fileptr->type == FILE_TYPE_FOPEN ) file_set_buffer(fileptr);
+ if ( FILE_Debug )
+ Message("File %s opened with ID %d", filename, fileID);
+ }
-static void
-grid_free_components(grid_t *gridptr)
-{
- void *p2free[] = { gridptr->mask, gridptr->mask_gme,
- gridptr->xvals, gridptr->yvals,
- gridptr->xbounds, gridptr->ybounds,
- gridptr->rowlon, gridptr->area,
- gridptr->reference, gridptr->name };
- for (size_t i = 0; i < sizeof (p2free) / sizeof (p2free[0]); ++i)
- if (p2free[i]) Free(p2free[i]);
+ return fileID;
}
-void grid_free(grid_t *gridptr)
+/*
+ * Close a file.
+ */
+int fileClose(int fileID)
{
- grid_free_components(gridptr);
- grid_init(gridptr);
+ int (*myFileClose)(int fileID)
+ = (int (*)(int))namespaceSwitchGet(NSSWITCH_FILE_CLOSE).func;
+ return myFileClose(fileID);
}
-static grid_t *
-gridNewEntry(cdiResH resH)
+int fileClose_serial(int fileID)
{
- grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
- grid_init(gridptr);
- if (resH == CDI_UNDEFID)
- gridptr->self = reshPut(gridptr, &gridOps);
- else
+ int ret;
+ const char *fbtname[] = {"unknown", "standard", "mmap"};
+ const char *ftname[] = {"unknown", "open", "fopen"};
+ bfile_t *fileptr = file_to_pointer(fileID);
+ double rout = 0;
+
+ if ( fileptr == NULL )
{
- gridptr->self = resH;
- reshReplace(resH, gridptr, &gridOps);
+ file_pointer_info(__func__, fileID);
+ return 1;
}
- return gridptr;
-}
-static
-void gridInit(void)
-{
- static int gridInitialized = 0;
+ char *name = fileptr->name;
- if ( gridInitialized ) return;
+ if ( FILE_Debug )
+ Message("fileID = %d filename = %s", fileID, name);
- gridInitialized = 1;
+ if ( FileInfo )
+ {
+ fprintf(stderr, "____________________________________________\n");
+ fprintf(stderr, " file ID : %d\n", fileID);
+ fprintf(stderr, " file name : %s\n", fileptr->name);
+ fprintf(stderr, " file type : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
- const char *env = getenv("GRID_DEBUG");
- if ( env ) GRID_Debug = atoi(env);
-}
+ if ( fileptr->type == FILE_TYPE_FOPEN )
+ fprintf(stderr, " file pointer : %p\n", (void *) fileptr->fp);
+ else
+ {
+ fprintf(stderr, " file descriptor : %d\n", fileptr->fd);
+ fprintf(stderr, " file flag : %d\n", FileFlagWrite);
+ }
+ fprintf(stderr, " file mode : %c\n", fileptr->mode);
-static void
-grid_copy_base_scalar_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
-{
- memcpy(gridptrDup, gridptrOrig, sizeof(grid_t));
- gridptrDup->self = CDI_UNDEFID;
- if (gridptrOrig->reference)
- gridptrDup->reference = strdupx(gridptrOrig->reference);
-}
+ if ( sizeof(off_t) > sizeof(long) )
+ {
+#if defined (_WIN32)
+ fprintf(stderr, " file size : %I64d\n", (long long) fileptr->size);
+ if ( fileptr->type == FILE_TYPE_OPEN )
+ fprintf(stderr, " file position : %I64d\n", (long long) fileptr->position);
+ fprintf(stderr, " bytes transfered : %I64d\n", (long long) fileptr->byteTrans);
+#else
+ fprintf(stderr, " file size : %lld\n", (long long) fileptr->size);
+ if ( fileptr->type == FILE_TYPE_OPEN )
+ fprintf(stderr, " file position : %lld\n", (long long) fileptr->position);
+ fprintf(stderr, " bytes transfered : %lld\n", (long long) fileptr->byteTrans);
+#endif
+ }
+ else
+ {
+ fprintf(stderr, " file size : %ld\n", (long) fileptr->size);
+ if ( fileptr->type == FILE_TYPE_OPEN )
+ fprintf(stderr, " file position : %ld\n", (long) fileptr->position);
+ fprintf(stderr, " bytes transfered : %ld\n", (long) fileptr->byteTrans);
+ }
+ if ( fileptr->time_in_sec > 0 )
+ rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
-static grid_t *
-grid_copy_base(grid_t *gridptrOrig)
-{
- grid_t *gridptrDup = (grid_t *)Malloc(sizeof (*gridptrDup));
- gridptrOrig->vtable->copyScalarFields(gridptrOrig, gridptrDup);
- gridptrOrig->vtable->copyArrayFields(gridptrOrig, gridptrDup);
- return gridptrDup;
-}
+ fprintf(stderr, " wall time [s] : %.2f\n", fileptr->time_in_sec);
+ fprintf(stderr, " data rate [MB/s] : %.1f\n", rout);
-unsigned cdiGridCount(void)
-{
- return reshCountType(&gridOps);
-}
+ fprintf(stderr, " file access : %ld\n", fileptr->access);
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ {
+ fprintf(stderr, " buffer type : %d (%s)\n", fileptr->bufferType, fbtname[fileptr->bufferType]);
+ fprintf(stderr, " num buffer fill : %ld\n", fileptr->bufferNumFill);
+ }
+ fprintf(stderr, " buffer size : %lu\n", (unsigned long) fileptr->bufferSize);
+ fprintf(stderr, " block size : %lu\n", (unsigned long) fileptr->blockSize);
+ fprintf(stderr, " page size : %d\n", pagesize());
+ fprintf(stderr, "--------------------------------------------\n");
+ }
-static inline
-void gridSetString(char *gridstrname, const char *name, size_t len)
-{
- if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
- strncpy(gridstrname, name, len);
- gridstrname[len - 1] = 0;
-}
+ if ( fileptr->type == FILE_TYPE_FOPEN )
+ {
+ ret = fclose(fileptr->fp);
+ if ( ret == EOF )
+ SysError("EOF returned for close of %s!", name);
+ }
+ else
+ {
+#if defined (HAVE_MMAP)
+ if ( fileptr->buffer && fileptr->mappedSize )
+ {
+ ret = munmap(fileptr->buffer, fileptr->mappedSize);
+ if ( ret == -1 ) SysError("munmap error for close %s", fileptr->name);
+ fileptr->buffer = NULL;
+ }
+#endif
+ ret = close(fileptr->fd);
+ if ( ret == -1 )
+ SysError("EOF returned for close of %s!", name);
+ }
-static inline
-void gridGetString(char *name, const char *gridstrname, size_t len)
-{
- if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
- strncpy(name, gridstrname, len);
- name[len - 1] = 0;
-}
+ if ( fileptr->name ) Free((void*) fileptr->name);
+ if ( fileptr->buffer ) Free((void*) fileptr->buffer);
-static inline void
-gridSetName(char *gridstrname, const char *name)
-{
- strncpy(gridstrname, name, CDI_MAX_NAME);
- gridstrname[CDI_MAX_NAME - 1] = 0;
+ file_delete_entry(fileptr);
+
+ return 0;
}
-void
-cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
+
+int filePtrGetc(void *vfileptr)
{
- gridptr->type = gridtype;
- gridptr->size = size;
+ int ivalue = EOF;
+ bfile_t *fileptr = (bfile_t *) vfileptr;
- switch (gridtype)
+ if ( fileptr )
{
- case GRID_CURVILINEAR:
- gridptr->nvertex = 4;
- /* Fall through */
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- case GRID_GAUSSIAN_REDUCED:
- case GRID_TRAJECTORY:
- {
- if ( gridtype == GRID_TRAJECTORY )
- {
- if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "tlon");
- if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "tlat");
- }
- else
- {
- if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "lon");
- if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "lat");
- }
- gridSetName(gridptr->xlongname, "longitude");
- gridSetName(gridptr->ylongname, "latitude");
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ {
+ int fillret = (fileptr->bufferCnt == 0) ? file_fill_buffer(fileptr) : 0;
+ if ( fillret >= 0 )
+ {
+ ivalue = (unsigned char) *fileptr->bufferPtr++;
+ fileptr->bufferCnt--;
+ fileptr->position++;
- /*
- if ( gridtype == GRID_CURVILINEAR )
- {
- gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
- gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
- gridDefXunits(gridID, "degrees");
- gridDefYunits(gridID, "degrees");
- }
- else
- */
- {
- gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
- gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
- gridSetName(gridptr->xunits, "degrees_east");
- gridSetName(gridptr->yunits, "degrees_north");
- }
+ fileptr->byteTrans++;
+ fileptr->access++;
+ }
+ }
+ else
+ {
+ ivalue = fgetc(fileptr->fp);
+ if ( ivalue >= 0 )
+ {
+ fileptr->byteTrans++;
+ fileptr->access++;
+ }
+ else
+ fileptr->flag |= FILE_EOF;
+ }
+ }
- break;
- }
- case GRID_UNSTRUCTURED:
- gridptr->xsize = size;
- /* Fall through */
- case GRID_GME:
- {
- if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "lon");
- if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "lat");
- gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
- gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
- gridSetName(gridptr->xunits, "degrees_east");
- gridSetName(gridptr->yunits, "degrees_north");
- break;
- }
- case GRID_GENERIC:
- {
+ return ivalue;
+}
- /* gridptr->xsize = size; */
- if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "x");
- if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "y");
- /*
- strcpy(gridptr->xstdname, "grid_longitude");
- strcpy(gridptr->ystdname, "grid_latitude");
- gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
- gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
- gridDefXunits(gridID, "degrees");
- gridDefYunits(gridID, "degrees");
- */
- break;
- }
- case GRID_LCC2:
- case GRID_SINUSOIDAL:
- case GRID_LAEA:
- {
- if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "x");
- if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "y");
- gridptr->xstdname = xystdname_tab[grid_xystdname_projection][0];
- gridptr->ystdname = xystdname_tab[grid_xystdname_projection][1];
- gridSetName(gridptr->xunits, "m");
- gridSetName(gridptr->yunits, "m");
- break;
- }
- }
+
+int fileGetc(int fileID)
+{
+ bfile_t *fileptr = file_to_pointer(fileID);
+ return filePtrGetc((void *)fileptr);
}
-// used also in CDO
-void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *restrict xvals)
+size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
{
- if ( (! (fabs(xinc) > 0)) && xsize > 1 )
+ size_t nread = 0;
+ bfile_t *fileptr = (bfile_t *) vfileptr;
+
+ if ( fileptr )
{
- if ( xfirst >= xlast )
- {
- while ( xfirst >= xlast ) xlast += 360;
- xinc = (xlast-xfirst)/(xsize);
- }
+ if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+ nread = file_read_from_buffer(fileptr, ptr, size);
else
- {
- xinc = (xlast-xfirst)/(xsize-1);
- }
+ {
+ nread = fread(ptr, 1, size, fileptr->fp);
+ if ( nread != size )
+ fileptr->flag |= (nread == 0) ? FILE_EOF : FILE_ERROR;
+ }
+
+ fileptr->position += (off_t)nread;
+ fileptr->byteTrans += (off_t)nread;
+ fileptr->access++;
}
- for ( int i = 0; i < xsize; ++i )
- xvals[i] = xfirst + i*xinc;
+ if ( FILE_Debug ) Message("size %ld nread %ld", size, nread);
+
+ return nread;
}
-static
-void calc_gaussgrid(double *restrict yvals, int ysize, double yfirst, double ylast)
+
+size_t fileRead(int fileID, void *restrict ptr, size_t size)
{
- double *restrict yw = (double *) Malloc((size_t)ysize * sizeof(double));
- gaussaw(yvals, yw, (size_t)ysize);
- Free(yw);
- for (int i = 0; i < ysize; i++ )
- yvals[i] = asin(yvals[i])/M_PI*180.0;
+ size_t nread = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
- if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
+ if ( fileptr )
{
- int yhsize = ysize/2;
- for (int i = 0; i < yhsize; i++ )
- {
- double ytmp = yvals[i];
- yvals[i] = yvals[ysize-i-1];
- yvals[ysize-i-1] = ytmp;
- }
+ double t_begin = 0.0;
+
+ if ( FileInfo ) t_begin = file_time();
+
+ if ( fileptr->type == FILE_TYPE_OPEN )
+ nread = file_read_from_buffer(fileptr, ptr, size);
+ else
+ {
+ nread = fread(ptr, 1, size, fileptr->fp);
+ if ( nread != size )
+ {
+ if ( nread == 0 )
+ fileptr->flag |= FILE_EOF;
+ else
+ fileptr->flag |= FILE_ERROR;
+ }
+ }
+
+ if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
+
+ fileptr->position += (off_t)nread;
+ fileptr->byteTrans += (off_t)nread;
+ fileptr->access++;
}
+
+ if ( FILE_Debug ) Message("size %ld nread %ld", size, nread);
+
+ return nread;
}
-// used also in CDO
-void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
+
+size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
{
- const double deleps = 0.002;
+ size_t nwrite = 0;
+ bfile_t *fileptr = file_to_pointer(fileID);
- if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
+ if ( fileptr )
{
- if ( ysize > 2 )
- {
- calc_gaussgrid(yvals, ysize, yfirst, ylast);
-
- if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
- if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
- {
- double *restrict ytmp = NULL;
- int nstart, lfound = 0;
- int ny = (int) (180./(fabs(ylast-yfirst)/(ysize-1)) + 0.5);
- ny -= ny%2;
- if ( ny > ysize && ny < 4096 )
- {
- ytmp = (double *) Malloc((size_t)ny * sizeof (double));
- calc_gaussgrid(ytmp, ny, yfirst, ylast);
- {
- int i;
- for ( i = 0; i < (ny-ysize); i++ )
- if ( fabs(ytmp[i] - yfirst) < deleps ) break;
- nstart = i;
- }
-
- lfound = (nstart+ysize-1) < ny
- && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
- if ( lfound )
- {
- for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
- }
- }
+ double t_begin = 0.0;
- if ( !lfound )
- {
- Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
- for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
- yvals[0] = yfirst;
- yvals[ysize-1] = ylast;
- }
+ if ( FileInfo ) t_begin = file_time();
- if ( ytmp ) Free(ytmp);
- }
- }
+ if ( fileptr->type == FILE_TYPE_FOPEN )
+ nwrite = fwrite(ptr, 1, size, fileptr->fp);
else
{
- yvals[0] = yfirst;
- yvals[ysize-1] = ylast;
- }
- }
- /* else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
- else
- {
- if ( (! (fabs(yinc) > 0)) && ysize > 1 )
- {
- if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
-
- if ( yfirst > ylast )
- yinc = (yfirst-ylast)/(ysize-1);
- else if ( yfirst < ylast )
- yinc = (ylast-yfirst)/(ysize-1);
- else
+ ssize_t temp = write(fileptr->fd, ptr, size);
+ if (temp == -1)
{
- if ( ysize%2 != 0 )
- {
- yinc = 180.0/(ysize-1);
- yfirst = -90;
- }
- else
- {
- yinc = 180.0/ysize;
- yfirst = -90 + yinc/2;
- }
+ perror("error writing to file");
+ nwrite = 0;
}
+ else
+ nwrite = (size_t)temp;
}
- if ( yfirst > ylast && yinc > 0 ) yinc = -yinc;
+ if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
- for (int i = 0; i < ysize; i++ )
- yvals[i] = yfirst + i*yinc;
+ fileptr->position += (off_t)nwrite;
+ fileptr->byteTrans += (off_t)nwrite;
+ fileptr->access++;
}
- /*
- else
- Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
- */
+
+ return nwrite;
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _GAUSSGRID_H
+#define _GAUSSGRID_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gaussaw(double *restrict pa, double *restrict pw, size_t nlat);
+bool isGaussGrid(size_t ysize, double yinc, const double *yvals);
+
+#if defined (__cplusplus)
}
+#endif
+#endif /* _GAUSSGRID_H */
/*
- at Function gridCreate
- at Title Create a horizontal Grid
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
+#endif
- at Prototype int gridCreate(int gridtype, int size)
- at Parameter
- @Item gridtype The type of the grid, one of the set of predefined CDI grid types.
- The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
- @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
- @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
- @Item size Number of gridpoints.
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+#include <stdlib.h>
- at Description
-The function @func{gridCreate} creates a horizontal Grid.
- at Result
- at func{gridCreate} returns an identifier to the Grid.
- at Example
-Here is an example using @func{gridCreate} to create a regular lon/lat Grid:
- at Source
- ...
-#define nlon 12
-#define nlat 6
- ...
-double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
-double lats[nlat] = {-75, -45, -15, 15, 45, 75};
-int gridID;
- ...
-gridID = gridCreate(GRID_LONLAT, nlon*nlat);
-gridDefXsize(gridID, nlon);
-gridDefYsize(gridID, nlat);
-gridDefXvals(gridID, lons);
-gridDefYvals(gridID, lats);
- ...
- at EndSource
- at EndFunction
-*/
-int gridCreate(int gridtype, int size)
+static
+void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag,
+ double *pw, double *pdxn, double *pxmod)
{
- if ( CDI_Debug ) Message("gridtype=%s size=%d", gridNamePtr(gridtype), size);
-
- if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
+ /* 1.0 Newton iteration step */
- gridInit();
+ double zdlx = pdx;
+ double zdlk = 0.0;
+ if ( kodd == 0 ) zdlk = 0.5*pfn[0];
+ double zdlxn = 0.0;
+ double zdlldn = 0.0;
- grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
- if ( ! gridptr ) Error("No memory");
+ size_t ik = 1;
- int gridID = gridptr->self;
+ if ( kflag == 0 )
+ {
+ for ( size_t jn = 2-kodd; jn <= kn; jn += 2 )
+ {
+ /* normalised ordinary Legendre polynomial == \overbar{p_n}^0 */
+ zdlk = zdlk + pfn[ik]*cos((double)(jn)*zdlx);
+ /* normalised derivative == d/d\theta(\overbar{p_n}^0) */
+ zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
+ ik++;
+ }
+ /* Newton method */
+ double zdlmod = -(zdlk/zdlldn);
+ zdlxn = zdlx + zdlmod;
+ *pdxn = zdlxn;
+ *pxmod = zdlmod;
+ }
- if ( CDI_Debug ) Message("gridID: %d", gridID);
+ /* 2.0 Compute weights */
- cdiGridTypeInit(gridptr, gridtype, size);
+ if ( kflag == 1 )
+ {
+ for ( size_t jn = 2-kodd; jn <= kn; jn += 2 )
+ {
+ /* normalised derivative */
+ zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
+ ik++;
+ }
+ *pw = (double)(2*kn+1)/(zdlldn*zdlldn);
+ }
- return gridID;
+ return;
}
static
-void gridDestroyKernel( grid_t * gridptr )
+void gawl(double *pfn, double *pl, double *pw, size_t kn)
{
- int id;
+ double pmod = 0;
+ double zw = 0;
+ double zdlxn = 0;
- xassert ( gridptr );
+ /* 1.0 Initizialization */
- id = gridptr->self;
+ int iflag = 0;
+ int itemax = 20;
- grid_free_components(gridptr);
- Free( gridptr );
+ size_t iodd = (kn % 2);
- reshRemove ( id, &gridOps );
-}
+ double zdlx = *pl;
-/*
- at Function gridDestroy
- at Title Destroy a horizontal Grid
+ /* 2.0 Newton iteration */
- at Prototype void gridDestroy(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ for ( int jter = 1; jter <= itemax+1; jter++ )
+ {
+ cpledn(kn, iodd, pfn, zdlx, iflag, &zw, &zdlxn, &pmod);
+ zdlx = zdlxn;
+ if (iflag == 1) break;
+ if (fabs(pmod) <= DBL_EPSILON*1000.0) iflag = 1;
+ }
- at EndFunction
-*/
-void gridDestroy(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->destroy(gridptr);
-}
+ *pl = zdlxn;
+ *pw = zw;
-void gridDestroyP ( void * gridptr )
-{
- ((grid_t *)gridptr)->vtable->destroy((grid_t *)gridptr);
+ return;
}
-
-const char *gridNamePtr(int gridtype)
+static
+void gauaw(size_t kn, double *restrict pl, double *restrict pw)
{
- int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
+ /*
+ * 1.0 Initialize Fourier coefficients for ordinary Legendre polynomials
+ *
+ * Belousov, Swarztrauber, and ECHAM use zfn(0,0) = sqrt(2)
+ * IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 (zfn(0,0) = 2.0)
+ */
+ double *zfn = (double *) Malloc((kn+1) * (kn+1) * sizeof(double));
+ double *zfnlat = (double *) Malloc((kn/2+1+1)*sizeof(double));
- const char *name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
+ zfn[0] = M_SQRT2;
+ for ( size_t jn = 1; jn <= kn; jn++ )
+ {
+ double zfnn = zfn[0];
+ for (size_t jgl = 1; jgl <= jn; jgl++)
+ {
+ zfnn *= sqrt(1.0-0.25/((double)(jgl*jgl)));
+ }
- return name;
-}
+ zfn[jn*(kn+1)+jn] = zfnn;
+ size_t iodd = jn % 2;
+ for ( size_t jgl = 2; jgl <= jn-iodd; jgl += 2 )
+ {
+ zfn[jn*(kn+1)+jn-jgl] = zfn[jn*(kn+1)+jn-jgl+2]
+ *((double)((jgl-1)*(2*jn-jgl+2)))/((double)(jgl*(2*jn-jgl+1)));
+ }
+ }
-void gridName(int gridtype, char *gridname)
-{
- strcpy(gridname, gridNamePtr(gridtype));
-}
-static
-char *grid_key_to_string(grid_t *gridptr, int key)
-{
- char *gridstring = NULL;
+ /* 2.0 Gaussian latitudes and weights */
- switch (key)
+ size_t iodd = kn % 2;
+ size_t ik = iodd;
+ for ( size_t jgl = iodd; jgl <= kn; jgl += 2 )
{
- case CDI_GRID_XDIMNAME: gridstring = gridptr->xdimname; break;
- case CDI_GRID_YDIMNAME: gridstring = gridptr->ydimname; break;
- case CDI_GRID_VDIMNAME: gridstring = gridptr->vdimname; break;
+ zfnlat[ik] = zfn[kn*(kn+1)+jgl];
+ ik++;
}
- return gridstring;
-}
+ /*
+ * 2.1 Find first approximation of the roots of the
+ * Legendre polynomial of degree kn.
+ */
-/*
- at Function cdiGridDefString
- at Title Define a CDI grid string value from a key
+ size_t ins2 = kn/2+(kn % 2);
+ double z;
- at Prototype int cdiGridDefString(int gridID, int key, int size, const char *mesg)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item key The key to be searched
- @Item size The allocated length of the string on input
- @Item mesg The address of a string where the data will be read
+ for ( size_t jgl = 1; jgl <= ins2; jgl++ )
+ {
+ z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2));
+ pl[jgl-1] = z+1.0/(tan(z)*((double)(8*kn*kn)));
+ }
- at Description
-The function @func{cdiGridDefString} defines a CDI grid string value from a key.
+ /* 2.2 Computes roots and weights for transformed theta */
- at Result
- at func{cdiGridDefString} returns 0 if OK and integer value on error.
+ for ( size_t jgl = ins2; jgl >= 1 ; jgl-- )
+ {
+ size_t jglm1 = jgl-1;
+ gawl(zfnlat, &(pl[jglm1]), &(pw[jglm1]), kn);
+ }
- at EndFunction
-*/
-int cdiGridDefString(int gridID, int key, int size, const char *mesg)
-{
- if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
+ /* convert to physical latitude */
- grid_t *gridptr = gridID2Ptr(gridID);
+ for ( size_t jgl = 0; jgl < ins2; jgl++ )
+ {
+ pl[jgl] = cos(pl[jgl]);
+ }
- char *gridstring = grid_key_to_string(gridptr, key);
- if ( gridstring == NULL )
+ for ( size_t jgl = 1; jgl <= kn/2; jgl++ )
{
- Warning("CDI grid string key %d not supported!", key);
- return -1;
+ size_t jglm1 = jgl-1;
+ size_t isym = kn-jgl;
+ pl[isym] = -pl[jglm1];
+ pw[isym] = pw[jglm1];
}
- gridSetString(gridstring, mesg, (size_t)size);
- gridMark4Update(gridID);
+ Free(zfnlat);
+ Free(zfn);
- return 0;
+ return;
}
-/*
- at Function cdiGridInqString
- at Title Get a CDI grid string value from a key
-
- at Prototype int cdiGridInqString(int gridID, int key, int size, char *mesg)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item key The key to be searched.
- @Item size The allocated length of the string on input.
- @Item mesg The address of a string where the data will be retrieved.
- The caller must allocate space for the returned string.
- The maximum possible length, in characters, of the string
- is given by the predefined constant @func{CDI_MAX_NAME}.
- at Description
-The function @func{cdiGridInqString} return a CDI grid string value from a key.
+void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
+{
+ //gauaw_old(pa, pw, nlat);
+ gauaw(nlat, pa, pw);
+}
- at Result
- at func{cdiGridInqString} returns 0 if OK and integer value on error.
- at EndFunction
-*/
-int cdiGridInqString(int gridID, int key, int size, char *mesg)
+bool isGaussGrid(size_t ysize, double yinc, const double *yvals)
{
- if ( size < 1 || mesg == NULL ) return -1;
+ bool lgauss = false;
- grid_t *gridptr = gridID2Ptr(gridID);
- const char *gridstring = grid_key_to_string(gridptr, key);
- if ( gridstring == NULL)
+ if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
{
- Warning("CDI grid string key %d not supported!", key);
- return -1;
- }
+ size_t i;
+ double *yv = (double *) Malloc(ysize*sizeof(double));
+ double *yw = (double *) Malloc(ysize*sizeof(double));
+ gaussaw(yv, yw, ysize);
+ Free(yw);
+ for ( i = 0; i < ysize; i++ )
+ yv[i] = asin(yv[i])/M_PI*180.0;
+
+ for ( i = 0; i < ysize; i++ )
+ if ( fabs(yv[i] - yvals[i]) >
+ ((yv[0] - yv[1])/500) ) break;
- gridGetString(mesg, gridstring, (size_t)size);
+ if ( i == ysize ) lgauss = true;
- return 0;
+ /* check S->N */
+ if ( lgauss == false )
+ {
+ for ( i = 0; i < ysize; i++ )
+ if ( fabs(yv[i] - yvals[ysize-i-1]) >
+ ((yv[0] - yv[1])/500) ) break;
+
+ if ( i == ysize ) lgauss = true;
+ }
+
+ Free(yv);
+ }
+
+ return lgauss;
}
/*
- at Function gridDefXname
- at Title Define the name of a X-axis
+#define NGL 48
- at Prototype void gridDefXname(int gridID, const char *name)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item name Name of the X-axis.
+int main (int rgc, char *argv[])
+{
+ int ngl = NGL;
+ double plo[NGL], pwo[NGL];
+ double pl[NGL], pw[NGL];
- at Description
-The function @func{gridDefXname} defines the name of a X-axis.
+ int i;
- at EndFunction
-*/
-void gridDefXname(int gridID, const char *xname)
-{
- if ( xname && *xname )
+ gauaw(ngl, pl, pw);
+ for (i = 0; i < ngl; i++)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->xname, xname);
- gridMark4Update(gridID);
+ pl[i] = asin(pl[i])/M_PI*180.0;
+ plo[i] = asin(plo[i])/M_PI*180.0;
+ }
+
+ for (i = 0; i < ngl; i++)
+ {
+ fprintf(stderr, "%4d%25.18f%25.18f%25.18f%25.18f\n", i+1, pl[i], pw[i], pl[i]-plo[i], pw[i]-pwo[i]);
}
-}
+ return 0;
+}
+*/
/*
- at Function gridDefXlongname
- at Title Define the longname of a X-axis
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- at Prototype void gridDefXlongname(int gridID, const char *longname)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item longname Longname of the X-axis.
+#if defined (HAVE_LIBGRIB_API)
+# include <grib_api.h>
+#endif
- at Description
-The function @func{gridDefXlongname} defines the longname of a X-axis.
+#include <stdio.h>
- at EndFunction
-*/
-void gridDefXlongname(int gridID, const char *xlongname)
+
+static char gribapi_libvers[64] = "";
+#if defined (HAVE_LIBGRIB_API)
+static bool gribapi_libvers_init;
+#endif
+
+
+void gribapiLibraryVersion(int* major_version, int* minor_version, int* revision_version)
{
- if ( xlongname )
- {
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->xlongname, xlongname);
- gridMark4Update(gridID);
- }
+#if defined (HAVE_LIBGRIB_API)
+ long version = grib_get_api_version();
+ (*major_version) = (int)(version/10000);
+ (*minor_version) = (int)((version-(*major_version)*10000)/100);
+ (*revision_version) = (int)(version-(*major_version)*10000-(*minor_version)*100);
+#else
+ (*major_version) = 0;
+ (*minor_version) = 0;
+ (*revision_version) = 0;
+#endif
}
-/*
- at Function gridDefXunits
- at Title Define the units of a X-axis
+const char *gribapiLibraryVersionString(void)
+{
+#if defined (HAVE_LIBGRIB_API)
+ if (!gribapi_libvers_init)
+ {
+ int major_version, minor_version, revision_version;
+
+ gribapiLibraryVersion(&major_version, &minor_version, &revision_version);
- at Prototype void gridDefXunits(int gridID, const char *units)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item units Units of the X-axis.
+ sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version);
+ gribapi_libvers_init = true;
+ }
+#endif
- at Description
-The function @func{gridDefXunits} defines the units of a X-axis.
+ return (gribapi_libvers);
+}
- at EndFunction
-*/
-void gridDefXunits(int gridID, const char *xunits)
+
+void gribContainersNew(stream_t * streamptr)
{
- if ( xunits )
+ int editionNumber = (streamptr->filetype == CDI_FILETYPE_GRB) ? 1 : 2;
+
+#if defined (HAVE_LIBCGRIBEX)
+ if ( editionNumber == 1 )
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->xunits, xunits);
- gridMark4Update(gridID);
}
-}
+ else
+#endif
+ {
+ int nvars = streamptr->nvars;
-/*
- at Function gridDefYname
- at Title Define the name of a Y-axis
+#if defined (GRIBCONTAINER2D)
+ gribContainer_t **gribContainers;
+ gribContainers = (gribContainer_t **) Malloc(nvars*sizeof(gribContainer_t *));
- at Prototype void gridDefYname(int gridID, const char *name)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item name Name of the Y-axis.
+ for ( int varID = 0; varID < nvars; ++varID )
+ {
+ int nlevs = streamptr->vars[varID].nlevs;
+ gribContainers[varID] = (gribContainer_t *) Malloc(nlevs*sizeof(gribContainer_t));
- at Description
-The function @func{gridDefYname} defines the name of a Y-axis.
+ for ( int levelID = 0; levelID < nlevs; ++levelID )
+ {
+ gribContainers[varID][levelID].gribHandle = gribHandleNew(editionNumber);
+ gribContainers[varID][levelID].init = false;
+ }
+ }
- at EndFunction
-*/
-void gridDefYname(int gridID, const char *yname)
-{
- if ( yname && *yname )
- {
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->yname, yname);
- gridMark4Update(gridID);
- }
-}
+ streamptr->gribContainers = (void **) gribContainers;
+#else
+ gribContainer_t *gribContainers
+ = (gribContainer_t *) Malloc((size_t)nvars*sizeof(gribContainer_t));
-/*
- at Function gridDefYlongname
- at Title Define the longname of a Y-axis
+ for ( int varID = 0; varID < nvars; ++varID )
+ {
+ gribContainers[varID].gribHandle = gribHandleNew(editionNumber);
+ gribContainers[varID].init = false;
+ }
- at Prototype void gridDefYlongname(int gridID, const char *longname)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item longname Longname of the Y-axis.
+ streamptr->gribContainers = (void *) gribContainers;
+#endif
+ }
+}
- at Description
-The function @func{gridDefYlongname} defines the longname of a Y-axis.
- at EndFunction
-*/
-void gridDefYlongname(int gridID, const char *ylongname)
+void gribContainersDelete(stream_t * streamptr)
{
- if ( ylongname )
+ if ( streamptr->gribContainers )
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->ylongname, ylongname);
- gridMark4Update(gridID);
- }
-}
+ int nvars = streamptr->nvars;
-/*
- at Function gridDefYunits
- at Title Define the units of a Y-axis
+#if defined (GRIBCONTAINER2D)
+ gribContainer_t **gribContainers = (gribContainer_t **) streamptr->gribContainers;
- at Prototype void gridDefYunits(int gridID, const char *units)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item units Units of the Y-axis.
+ for ( int varID = 0; varID < nvars; ++varID )
+ {
+ int nlevs = streamptr->vars[varID].nlevs;
+ for ( int levelID = 0; levelID < nlevs; ++levelID )
+ {
+ gribHandleDelete(gribContainers[varID][levelID].gribHandle);
+ }
+ Free(gribContainers[varID]);
+ }
+#else
+ gribContainer_t *gribContainers = (gribContainer_t *) streamptr->gribContainers;
- at Description
-The function @func{gridDefYunits} defines the units of a Y-axis.
+ for ( int varID = 0; varID < nvars; ++varID )
+ {
+ gribHandleDelete(gribContainers[varID].gribHandle);
+ }
+#endif
- at EndFunction
-*/
-void gridDefYunits(int gridID, const char *yunits)
-{
- if ( yunits )
- {
- grid_t *gridptr = gridID2Ptr(gridID);
- gridSetName(gridptr->yunits, yunits);
- gridMark4Update(gridID);
+ Free(gribContainers);
+
+ streamptr->gribContainers = NULL;
}
}
-
/*
- at Function gridInqXname
- at Title Get the name of a X-axis
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+#define INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
- at Prototype void gridInqXname(int gridID, char *name)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item name Name of the X-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
+#ifdef HAVE_LIBGRIB_API
- at Description
-The function @func{gridInqXname} returns the name of a X-axis.
- at Result
- at func{gridInqXname} returns the name of the X-axis to the parameter name.
+#include <grib_api.h>
- at EndFunction
-*/
-void gridInqXname(int gridID, char *xname)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+#include <stdbool.h>
- strcpy(xname, gridptr->xname);
-}
+char* gribCopyString(grib_handle* gribHandle, const char* key);
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue);
-const char *gridInqXnamePtr(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->xname;
-}
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue);
+long gribGetLong(grib_handle* gh, const char* key);
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue);
-/*
- at Function gridInqXlongname
- at Title Get the longname of a X-axis
+double gribGetDouble(grib_handle* gh, const char* key);
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue);
- at Prototype void gridInqXlongname(int gridID, char *longname)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item longname Longname of the X-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key);
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array); //The caller is responsible to ensure a sufficiently large buffer.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array); //The caller is responsible to ensure a sufficiently large buffer.
- at Description
-The function @func{gridInqXlongname} returns the longname of a X-axis.
+long gribEditionNumber(grib_handle* gh);
+char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType); //Returns NULL if timeType is kCdiTimeType_endTime and the field does not have an integration period (statistical data).
+int gribapiTimeIsFC(grib_handle *gh);
+int gribapiGetTsteptype(grib_handle *gh);
+int gribGetDatatype(grib_handle* gribHandle);
+int gribapiGetParam(grib_handle *gh);
+int gribapiGetGridType(grib_handle *gh);
+void gribapiGetGrid(grib_handle *gh, grid_t *grid);
- at Result
- at func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
+#ifdef HIRLAM_EXTENSIONS
+void gribapiSetDataTimeRangeIndicator(grib_handle *gh, int timeRangeIndicator);
+void gribapiGetDataTimeRangeIndicator(grib_handle *gh, int *timeRangeIndicator);
+#endif // #ifdef HIRLAM_EXTENSIONS
- at EndFunction
-*/
-void gridInqXlongname(int gridID, char *xlongname)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+extern struct cdiGribAPI_ts_str_map_elem {
+ long productionTemplate;
+ const char sname[8];
+} cdiGribAPI_ts_str_map[];
- strcpy(xlongname, gridptr->xlongname);
-}
+#endif
-/*
- at Function gridInqXunits
- at Title Get the units of a X-axis
+#endif
- at Prototype void gridInqXunits(int gridID, char *units)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item units Units of the X-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- at Description
-The function @func{gridInqXunits} returns the units of a X-axis.
+#ifdef HAVE_LIBGRIB_API
- at Result
- at func{gridInqXunits} returns the units of the X-axis to the parameter units.
- at EndFunction
-*/
-void gridInqXunits(int gridID, char *xunits)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- strcpy(xunits, gridptr->xunits);
-}
+#include <assert.h>
+#include <time.h>
+#define FAIL_ON_GRIB_ERROR(function, gribHandle, key, ...) do\
+{\
+ int errorCode = (int)function(gribHandle, key, __VA_ARGS__); \
+ if(errorCode)\
+ {\
+ fprintf(stderr, "%s:%d: Error in function `%s`: `%s` returned error code %d for key \"%s\"", __FILE__, __LINE__, __func__, #function, errorCode, key);\
+ exit(errorCode);\
+ }\
+} while(0)
-void gridInqXstdname(int gridID, char *xstdname)
+//A simple wrapper for grib_get_string() that returns a newly allocated string.
+char* gribCopyString(grib_handle* gribHandle, const char* key)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- if ( gridptr->xstdname )
- strcpy(xstdname, gridptr->xstdname);
+ size_t length;
+#ifdef HAVE_GRIB_GET_LENGTH
+ if (!grib_get_length(gribHandle, key, &length))
+ {
+ char *result = (char *)Malloc(length);
+ if (!grib_get_string(gribHandle, key, result, &length))
+ result = (char *) Realloc(result, length);
+ else
+ {
+ Free(result);
+ result = NULL;
+ }
+ return result;
+ }
+ else
+ return NULL;
+#else
+ length = 1024; /* there's an implementation limit
+ * that makes strings longer than
+ * this unlikely in grib_api versions
+ * not providing grib_get_length */
+ int rc;
+ char *result = (char *) Malloc(length);
+ while ((rc = grib_get_string(gribHandle, key, result, &length))
+ == GRIB_BUFFER_TOO_SMALL || rc == GRIB_ARRAY_TOO_SMALL)
+ {
+ if (length <= 1024UL * 1024UL)
+ {
+ length *= 2;
+ result = Realloc(result, length);
+ }
+ else
+ break;
+ }
+ if (!rc)
+ result = Realloc(result, length);
else
- xstdname[0] = 0;
+ {
+ Free(result);
+ result = NULL;
+ }
+ return result;
+#endif
}
-/*
- at Function gridInqYname
- at Title Get the name of a Y-axis
-
- at Prototype void gridInqYname(int gridID, char *name)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item name Name of the Y-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
-
- at Description
-The function @func{gridInqYname} returns the name of a Y-axis.
-
- at Result
- at func{gridInqYname} returns the name of the Y-axis to the parameter name.
-
- at EndFunction
-*/
-void gridInqYname(int gridID, char *yname)
+//A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
+//Returns true if the key exists and the value is equal to the given string.
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- strcpy(yname, gridptr->yname);
+ size_t expectedLength = strlen(expectedValue) + 1;
+#ifdef HAVE_GRIB_GET_LENGTH
+ size_t length;
+ if(grib_get_length(gribHandle, key, &length)) return false;
+ if(length != expectedLength) return false;
+ char *value = (char *) Malloc(length);
+ if(grib_get_string(gribHandle, key, value, &length)) return false;
+ int rc = !strcmp(value, expectedValue);
+ Free(value);
+#else
+ char *value = gribCopyString(gribHandle, key);
+ int rc;
+ if (value)
+ {
+ rc = strlen(value) + 1 == expectedLength ?
+ !strcmp(value, expectedValue)
+ : false;
+ }
+ else
+ rc = false;
+ Free(value);
+#endif
+ return rc;
}
-const char *gridInqYnamePtr(int gridID)
+//A simple wrapper for grib_get_long() for the usecase that the result is only compared to a given constant value.
+//Returns true if the key exists and the value is equal to the given one.
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->yname;
+ long value;
+ if(grib_get_long(gribHandle, key, &value)) return false;
+ return value == expectedValue;
}
-/*
- at Function gridInqYlongname
- at Title Get the longname of a Y-axis
-
- at Prototype void gridInqXlongname(int gridID, char *longname)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item longname Longname of the Y-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
-
- at Description
-The function @func{gridInqYlongname} returns the longname of a Y-axis.
+//A simple wrapper for grib_get_long() for the usecase that failure to fetch the value is fatal.
+long gribGetLong(grib_handle* gh, const char* key)
+{
+ long result;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, key, &result);
+ return result;
+}
- at Result
- at func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
+//A simple wrapper for grib_get_long() for the usecase that a default value is used in the case that the operation fails.
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
+{
+ long result;
+ if ( grib_get_long(gribHandle, key, &result) || result == GRIB_MISSING_LONG )
+ result = defaultValue;
+ return result;
+}
- at EndFunction
-*/
-void gridInqYlongname(int gridID, char *ylongname)
+//A simple wrapper for grib_get_double() for the usecase that failure to fetch the value is fatal.
+double gribGetDouble(grib_handle* gh, const char* key)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ double result;
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, key, &result);
+ return result;
+}
- strcpy(ylongname, gridptr->ylongname);
+//A sample wrapper for grib_get_double() for the usecase that a default value is used in the case that the operation fails.
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
+{
+ double result;
+ if ( grib_get_double(gribHandle, key, &result)
+ || IS_EQUAL(result, GRIB_MISSING_DOUBLE) )
+ result = defaultValue;
+ return result;
}
-/*
- at Function gridInqYunits
- at Title Get the units of a Y-axis
+//A simple wrapper for grib_get_size() for the usecase that failure to fetch the value is fatal.
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key)
+{
+ size_t result;
+ FAIL_ON_GRIB_ERROR(grib_get_size, gribHandle, key, &result);
+ return result;
+}
- at Prototype void gridInqYunits(int gridID, char *units)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item units Units of the Y-axis. The caller must allocate space for the
- returned string. The maximum possible length, in characters, of
- the string is given by the predefined constant @func{CDI_MAX_NAME}.
+//A simple wrapper for grib_get_double_array() for the usecase that failure to fetch the data is fatal.
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array)
+{
+ size_t valueCount = gribGetArraySize(gribHandle, key);
+ FAIL_ON_GRIB_ERROR(grib_get_double_array, gribHandle, key, array, &valueCount);
+}
- at Description
-The function @func{gridInqYunits} returns the units of a Y-axis.
+//A simple wrapper for grib_get_long_array() for the usecase that failure to fetch the data is fatal.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array)
+{
+ size_t valueCount = gribGetArraySize(gribHandle, key);
+ FAIL_ON_GRIB_ERROR(grib_get_long_array, gribHandle, key, array, &valueCount);
+}
- at Result
- at func{gridInqYunits} returns the units of the Y-axis to the parameter units.
- at EndFunction
-*/
-void gridInqYunits(int gridID, char *yunits)
+//We need the edition number so frequently, that it's convenient to give it its own function.
+long gribEditionNumber(grib_handle* gh)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ return gribGetLong(gh, "editionNumber");
+}
- strcpy(yunits, gridptr->yunits);
+//This return value of this should be passed to a call to resetTz(), it is a malloc'ed string with the content of the TZ environment variable before the call (or NULL if that was not set).
+static char* setUtc()
+{
+ char* temp = getenv("TZ"), *result = NULL;
+ if(temp) result = strdup(temp);
+ setenv("TZ", "UTC", 1);
+ return result;
}
-void gridInqYstdname(int gridID, char *ystdname)
+//Undoes the effect of setUtc(), pass to it the return value of the corresponding setUtc() call, it will free the string.
+static void resetTz(char* savedTz)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- if ( gridptr->ystdname )
- strcpy(ystdname, gridptr->ystdname);
+ if(savedTz)
+ {
+ setenv("TZ", savedTz, 1);
+ Free(savedTz);
+ }
else
- ystdname[0] = 0;
+ {
+ unsetenv("TZ");
+ }
}
-/*
- at Function gridInqType
- at Title Get the type of a Grid
-
- at Prototype int gridInqType(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+//This function uses the system functions to normalize the date representation according to the gregorian calendar.
+//Returns zero on success.
+static int normalizeDays(struct tm* me)
+{
+ char* savedTz = setUtc(); //Ensure that mktime() does not interprete the date according to our local time zone.
- at Description
-The function @func{gridInqType} returns the type of a Grid.
+ int result = mktime(me) == (time_t)-1; //This does all the heavy lifting.
- at Result
- at func{gridInqType} returns the type of the grid,
-one of the set of predefined CDI grid types.
-The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
- at func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
- at func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
+ resetTz(savedTz);
+ return result;
+}
- at EndFunction
-*/
-int gridInqType(int gridID)
+//Returns zero on success.
+static int addSecondsToDate(struct tm* me, long long amount)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- return gridptr->type;
+ //It is irrelevant here whether days are zero or one based, the correction would have be undone again so that it is effectless.
+ long long seconds = ((me->tm_mday*24ll + me->tm_hour)*60 + me->tm_min)*60 + me->tm_sec; //The portion of the date that uses fixed increments.
+ seconds += amount;
+ me->tm_mday = (int)(seconds / 24 / 60 / 60);
+ seconds -= (long long)me->tm_mday * 24 * 60 * 60;
+ me->tm_hour = (int)(seconds / 60 / 60);
+ seconds -= (long long)me->tm_hour * 60 * 60;
+ me->tm_min = (int)(seconds / 60);
+ seconds -= (long long)(me->tm_min * 60);
+ me->tm_sec = (int)seconds;
+ return normalizeDays(me);
}
-
-/*
- at Function gridInqSize
- at Title Get the size of a Grid
-
- at Prototype int gridInqSize(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqSize} returns the size of a Grid.
-
- at Result
- at func{gridInqSize} returns the number of grid points of a Grid.
-
- at EndFunction
-*/
-int gridInqSize(int gridID)
+static void addMonthsToDate(struct tm* me, long long amount)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- int size = gridptr->size;
+ long long months = me->tm_year*12ll + me->tm_mon;
+ months += amount;
+ me->tm_year = (int)(months/12);
+ months -= (long long)me->tm_year*12;
+ me->tm_mon = (int)months;
+}
- if ( size == 0 )
+//unit is a value according to code table 4.4 of the GRIB2 specification, returns non-zero on error
+static int addToDate(struct tm* me, long long amount, long unit)
+{
+ switch(unit)
{
- int xsize = gridptr->xsize;
- int ysize = gridptr->ysize;
+ case 0: return addSecondsToDate(me, 60*amount); // minute
+ case 1: return addSecondsToDate(me, 60*60*amount); // hour
+ case 2: return addSecondsToDate(me, 24*60*60*amount); // day
- if ( ysize )
- size = xsize * ysize;
- else
- size = xsize;
+ case 3: addMonthsToDate(me, amount); return 0; // month
+ case 4: addMonthsToDate(me, 12*amount); return 0; // year
+ case 5: addMonthsToDate(me, 10*12*amount); return 0; // decade
+ case 6: addMonthsToDate(me, 30*12*amount); return 0; // normal
+ case 7: addMonthsToDate(me, 100*12*amount); return 0; // century
+
+ case 10: return addSecondsToDate(me, 3*60*60*amount); // eighth of a day
+ case 11: return addSecondsToDate(me, 6*60*60*amount); // quarter day
+ case 12: return addSecondsToDate(me, 12*60*60*amount); // half day
+ case 13: return addSecondsToDate(me, amount); // second
- gridptr->size = size;
+ default: return 1; //reserved, unknown, or missing
}
-
- return size;
}
-static
-int nsp2trunc(int nsp)
+static char* makeDateString(struct tm* me)
{
- /* nsp = (trunc+1)*(trunc+1) */
- /* => trunc^2 + 3*trunc - (x-2) = 0 */
- /* */
- /* with: y^2 + p*y + q = 0 */
- /* y = -p/2 +- sqrt((p/2)^2 - q) */
- /* p = 3 and q = - (x-2) */
- int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
- return trunc;
+ char *result
+ = (char *) Malloc( 4+1+ 2+1+ 2+1+ 2+1+ 2+1+ 2+ 4+ 1);
+ sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec);
+ return result;
}
-
-int gridInqTrunc(int gridID)
+//FIXME: This ignores any calendar definition that might be present.
+//XXX: Identification templates are not implemented in grib_api-1.12.3, so even if I implemented the other calendars now, it wouldn't be possible to use them.
+static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecastTime, bool* outHaveTimeRange)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- if ( gridptr->trunc == 0 )
+ switch(gribGetLong(gh, "productDefinitionTemplateNumber"))
{
- if ( gridptr->type == GRID_SPECTRAL )
- gridptr->trunc = nsp2trunc(gridptr->size);
- /*
- else if ( gridptr->type == GRID_GAUSSIAN )
- gridptr->trunc = nlat2trunc(gridptr->ysize);
- */
- }
-
- return gridptr->trunc;
-}
+ case 20: case 30: case 31: case 254: case 311: case 2000:
+ *outHaveForecastTime = false, *outHaveTimeRange = false;
+ return 0;
+ //case 55 and case 40455 are the same: 55 is the proposed standard value, 40455 is the value in the local use range that is used by the dwd until the standard is updated.
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 55: case 56: case 60: case 1000: case 1002: case 1100: case 40033: case 40455: case 40456:
+ *outHaveForecastTime = true, *outHaveTimeRange = false;
+ return 0;
-void gridDefTrunc(int gridID, int trunc)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 34: case 42: case 43: case 46: case 47: case 61: case 91: case 1001: case 1101: case 40034:
+ *outHaveForecastTime = true, *outHaveTimeRange = true;
+ return 0;
- if ( gridptr->trunc != trunc )
- {
- gridMark4Update(gridID);
- gridptr->trunc = trunc;
+ default:
+ return 1;
}
}
-/*
- at Function gridDefXsize
- at Title Define the number of values of a X-axis
-
- at Prototype void gridDefXsize(int gridID, int xsize)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item xsize Number of values of a X-axis.
-
- at Description
-The function @func{gridDefXsize} defines the number of values of a X-axis.
- at EndFunction
-*/
-void gridDefXsize(int gridID, int xsize)
+char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- int gridSize = gridInqSize(gridID);
- if ( xsize > gridSize )
- Error("xsize %d is greater then gridsize %d", xsize, gridSize);
-
- int gridType = gridInqType(gridID);
- if ( gridType == GRID_UNSTRUCTURED && xsize != gridSize )
- Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
+ //Get the parts of the reference date.
+ struct tm date;
+ date.tm_mon = (int)gribGetLong(gh, "month") - 1; //months are zero based in struct tm and one based in GRIB
+ date.tm_mday = (int)gribGetLong(gh, "day");
+ date.tm_hour = (int)gribGetLong(gh, "hour");
+ date.tm_min = (int)gribGetLong(gh, "minute");
- if ( gridptr->xsize != xsize )
+ if(gribEditionNumber(gh) == 1)
{
- gridMark4Update(gridID);
- gridptr->xsize = xsize;
+ date.tm_year = (int)gribGetLong(gh, "yearOfCentury"); //years are -1900 based both in struct tm and GRIB1
}
-
- if ( gridType != GRID_UNSTRUCTURED )
+ else
{
- long axisproduct = gridptr->xsize*gridptr->ysize;
- if ( axisproduct > 0 && axisproduct != gridSize )
- Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
- gridptr->xsize, gridptr->ysize, gridSize);
- }
-}
-
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
- @Item Grid identifier
+ date.tm_year = (int)gribGetLong(gh, "year") - 1900; //years are -1900 based in struct tm and zero based in GRIB2
+ date.tm_sec = (int)gribGetLong(gh, "second");
- at EndFunction
-*/
-void gridDefPrec(int gridID, int prec)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ //If the start or end time are requested, we need to take the relative times into account.
+ if(timeType != kCdiTimeType_referenceTime)
+ {
+ //Determine whether we have a forecast time and a time range.
+ bool haveForecastTime, haveTimeRange;
+ if(getAvailabilityOfRelativeTimes(gh, &haveForecastTime, &haveTimeRange)) return NULL;
+ if(timeType == kCdiTimeType_endTime && !haveTimeRange) return NULL; //tell the caller that the requested time does not exist
- if ( gridptr->prec != prec )
- {
- gridMark4Update(gridID);
- gridptr->prec = prec;
+ //If we have relative times, apply the relative times to the date
+ if(haveForecastTime)
+ {
+ long offset = gribGetLongDefault(gh, "forecastTime", 0); //if(stepUnits == indicatorOfUnitOfTimeRange) assert(startStep == forecastTime)
+ long offsetUnit = gribGetLongDefault(gh, "indicatorOfUnitOfTimeRange", 255);
+ if(addToDate(&date, offset, offsetUnit)) return NULL;
+ if(timeType == kCdiTimeType_endTime)
+ {
+ assert(haveTimeRange);
+ long range = gribGetLongDefault(gh, "lengthOfTimeRange", 0); //if(stepUnits == indicatorOfUnitForTimeRange) assert(endStep == startStep + lengthOfTimeRange)
+ long rangeUnit = gribGetLongDefault(gh, "indicatorOfUnitForTimeRange", 255);
+ if(addToDate(&date, range, rangeUnit)) return NULL;
+ }
+ }
+ }
}
-}
-/*
- at Function
- at Title
+ //Bake the date into a string.
+ return makeDateString(&date);
+}
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-int gridInqPrec(int gridID)
+int gribapiTimeIsFC(grib_handle *gh)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if (gribEditionNumber(gh) <= 1) return true;
- return gridptr->prec;
+ long sigofrtime;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
+ return sigofrtime != 3;
}
-/*
- at Function gridInqXsize
- at Title Get the number of values of a X-axis
-
- at Prototype int gridInqXsize(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqXsize} returns the number of values of a X-axis.
+struct cdiGribAPI_ts_str_map_elem cdiGribAPI_ts_str_map[] = {
+ [TSTEP_INSTANT] = { 0, "instant" },
+ [TSTEP_AVG] = { 8, "avg" },
+ [TSTEP_ACCUM] = { 8, "accum" },
+ [TSTEP_MAX] = { 8, "max" },
+ [TSTEP_MIN] = { 8, "min" },
+ [TSTEP_DIFF] = { 8, "diff" },
+ [TSTEP_RMS] = { 8, "rms" },
+ [TSTEP_SD] = { 8, "sd" },
+ [TSTEP_COV] = { 8, "cov" },
+ [TSTEP_RATIO] = { 8, "ratio" },
+ { 0, "" }
+};
- at Result
- at func{gridInqXsize} returns the number of values of a X-axis.
- at EndFunction
-*/
-int gridInqXsize(int gridID)
+//Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
+int gribapiGetTsteptype(grib_handle *gh)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ int tsteptype = TSTEP_INSTANT;
+ static bool lprint = true;
- return gridptr->xsize;
-}
+ if ( gribapiTimeIsFC(gh) )
+ {
+ int status;
+ size_t len = 256;
+ char stepType[256];
-/*
- at Function gridDefYsize
- at Title Define the number of values of a Y-axis
+ status = grib_get_string(gh, "stepType", stepType, &len);
+ if ( status == 0 && len > 1 && len < 256 )
+ {
+ for (int i = TSTEP_INSTANT; cdiGribAPI_ts_str_map[i].sname[0]; ++i)
+ if ( strncmp(cdiGribAPI_ts_str_map[i].sname, stepType, len) == 0 )
+ {
+ tsteptype = i;
+ goto tsteptypeFound;
+ }
- at Prototype void gridDefYsize(int gridID, int ysize)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item ysize Number of values of a Y-axis.
+ if ( lprint )
+ {
+ Message("Time stepType %s unsupported, set to instant!", stepType);
+ lprint = false;
+ }
+ // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
+ }
+#ifdef HIRLAM_EXTENSIONS
+ {
+ // Normaly cdo looks in grib for attribute called "stepType", see above.
+ // BUT NWP models such as Hirlam and Harmonie 37h1.2, use "timeRangeIndicator" instead!
+ // Where for example: 0: for instanteneous fields; 4: for accumulated fields
+ // 0: Forecast product valid at reference time + P1
+ // 2: Product with a valid time ranging between reference time + P1 and reference time + P2
+ // 4: Accumulation (reference time + P1 to reference time + P2)
+ // 5: Difference(reference time + P2 minus reference time + P1) product considered valid at reference time + P2
+ // More details on WMO standards:
+ // http://www.wmo.int/pages/prog/www/WDM/Guides/Guide-binary-2.html
+ //tsteptype = TSTEP_INSTANT; // default value for any case
+ long timeRangeIND = 0; // typically 0: for instanteneous fields; 4: for accumulated fields
+ int rc = grib_get_long(gh, "timeRangeIndicator", &timeRangeIND);
+ if (rc != 0) {
+ //if ( lprint )
+ Warning("Could not get 'stepType' either 'timeRangeIndicator'. Using defualt!");
+ return (tsteptype);
+ }
+ extern int cdiGribUseTimeRangeIndicator;
+ cdiGribUseTimeRangeIndicator = 1;
+ switch ( timeRangeIND )
+ {
+ case 0: tsteptype = TSTEP_INSTANT; break;
+ case 2: tsteptype = TSTEP_INSTANT2;
+ strcpy(stepType, "instant2"); // was incorrectly set before into accum
+ break;
+ case 4: tsteptype = TSTEP_ACCUM; break;
+ case 5: tsteptype = TSTEP_DIFF; break;
+ default:
+ if ( lprint )
+ {
+ if (CDI_Debug)
+ Warning("timeRangeIND = %d; stepType= %s; tsteptype=%d unsupported timeRangeIND at the moment, set to instant!", timeRangeIND, stepType, tsteptype);
+ lprint = false;
+ }
+ break;
+ }
+ if (CDI_Debug)
+ Warning("timeRangeIND = %d; stepType= %s; tsteptype=%d", timeRangeIND, stepType, tsteptype);
+ }
+#endif // HIRLAM_EXTENSIONS
+ }
+ tsteptypeFound:
+ return tsteptype;
+}
- at Description
-The function @func{gridDefYsize} defines the number of values of a Y-axis.
- at EndFunction
-*/
-void gridDefYsize(int gridID, int ysize)
+int gribGetDatatype(grib_handle* gribHandle)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- int gridSize = gridInqSize(gridID);
-
- if ( ysize > gridSize )
- Error("ysize %d is greater then gridsize %d", ysize, gridSize);
-
- if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridSize )
- Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridSize);
-
- if ( gridptr->ysize != ysize )
+ int datatype;
+ if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
{
- gridMark4Update(gridID);
- gridptr->ysize = ysize;
+ datatype = gribCheckLong(gribHandle, "precision", 1) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
}
-
- if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
+ else
{
- long axisproduct = gridptr->xsize*gridptr->ysize;
- if ( axisproduct > 0 && axisproduct != gridSize )
- Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
- gridptr->xsize, gridptr->ysize, gridSize);
+ long bitsPerValue;
+ datatype = (!grib_get_long(gribHandle, "bitsPerValue", &bitsPerValue) && bitsPerValue > 0 && bitsPerValue <= 32) ? (int)bitsPerValue : CDI_DATATYPE_PACK;
}
+ return datatype;
}
-/*
- at Function gridInqYsize
- at Title Get the number of values of a Y-axis
-
- at Prototype int gridInqYsize(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqYsize} returns the number of values of a Y-axis.
-
- at Result
- at func{gridInqYsize} returns the number of values of a Y-axis.
- at EndFunction
-*/
-int gridInqYsize(int gridID)
+int gribapiGetParam(grib_handle *gh)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- return gridptr->ysize;
+ long pdis, pcat, pnum;
+ if ( gribEditionNumber(gh) <= 1 )
+ {
+ pdis = 255;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "table2Version", &pcat);
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "indicatorOfParameter", &pnum);
+ }
+ else
+ {
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "discipline", &pdis);
+ if(grib_get_long(gh, "parameterCategory", &pcat)) pcat = 0;
+ if(grib_get_long(gh, "parameterNumber", &pnum)) pnum = 0;
+ }
+ return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
}
-/*
- at Function gridDefNP
- at Title Define the number of parallels between a pole and the equator
- at Prototype void gridDefNP(int gridID, int np)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item np Number of parallels between a pole and the equator.
+int gribapiGetGridType(grib_handle *gh)
+{
+ int gridtype = GRID_GENERIC;
+ switch (gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1))
+ {
+ case GRIB2_GTYPE_LATLON:
+ gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GENERIC : GRID_LONLAT;
+ break;
+ case GRIB2_GTYPE_GAUSSIAN:
+ gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN;
+ break;
+ case GRIB2_GTYPE_LATLON_ROT: gridtype = GRID_PROJECTION; break;
+ case GRIB2_GTYPE_LCC: gridtype = GRID_LCC; break;
+ case GRIB2_GTYPE_SPECTRAL: gridtype = GRID_SPECTRAL; break;
+ case GRIB2_GTYPE_GME: gridtype = GRID_GME; break;
+ case GRIB2_GTYPE_UNSTRUCTURED: gridtype = GRID_UNSTRUCTURED; break;
+ }
- at Description
-The function @func{gridDefNP} defines the number of parallels between a pole and the equator
-of a Gaussian grid.
+ return gridtype;
+}
- at EndFunction
-*/
-void gridDefNP(int gridID, int np)
+static
+int gribapiGetIsRotated(grib_handle *gh)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
+}
- if ( gridptr->np != np )
+//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
+void gribapiGetGrid(grib_handle *gh, grid_t *grid)
+{
+ long editionNumber = gribEditionNumber(gh);
+ int gridtype = gribapiGetGridType(gh);
+ int projtype = (gridtype == GRID_PROJECTION && gribapiGetIsRotated(gh)) ? CDI_PROJ_RLL : CDI_UNDEFID;
+ if ( gridtype == GRID_LCC )
{
- gridMark4Update(gridID);
- gridptr->np = np;
+ gridtype = GRID_PROJECTION;
+ projtype = CDI_PROJ_LCC;
}
-}
+ /*
+ if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
+ {
+ gridtype = GRID_GAUSSIAN;
+ ISEC2_NumLon = 2*ISEC2_NumLat;
+ ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
+ }
+ */
+ grid_init(grid);
+ cdiGridTypeInit(grid, gridtype, 0);
-/*
- at Function gridInqNP
- at Title Get the number of parallels between a pole and the equator
+ size_t datasize;
+ FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
+ long lpar;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &lpar);
+ size_t numberOfPoints = (size_t) lpar;
- at Prototype int gridInqNP(int gridID)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- at Description
-The function @func{gridInqNP} returns the number of parallels between a pole and the equator
-of a Gaussian grid.
+ if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
+ {
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &lpar);
+ size_t nlon = (size_t) lpar;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+ size_t nlat = (size_t) lpar;
- at Result
- at func{gridInqNP} returns the number of parallels between a pole and the equator.
+ if ( gridtype == GRID_GAUSSIAN )
+ {
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+ grid->np = (int)lpar;
+ }
- at EndFunction
-*/
-int gridInqNP(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( numberOfPoints != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", numberOfPoints, nlon*nlat);
+
+ grid->size = numberOfPoints;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
+ grid->x.inc = 0;
+ grid->y.inc = 0;
+ grid->x.flag = 0;
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->x.first);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees", &grid->x.last);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->y.first);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees", &grid->y.last);
+ if ( nlon > 1 )
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->x.inc);
+ if ( gridtype == GRID_LONLAT && nlat > 1 )
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->y.inc);
+
+ long iscan, jscan;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "iScansNegatively", &iscan);
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "jScansPositively", &jscan);
+ if ( iscan ) grid->x.inc = - grid->x.inc;
+ if ( !jscan ) grid->y.inc = - grid->y.inc;
+
+ if ( grid->x.inc < -999 || grid->x.inc > 999 ) grid->x.inc = 0;
+ if ( grid->y.inc < -999 || grid->y.inc > 999 ) grid->y.inc = 0;
+
+ /* if ( IS_NOT_EQUAL(grid->x.first, 0) || IS_NOT_EQUAL(grid->x.last, 0) ) */
+ {
+ if ( grid->x.size > 1 )
+ {
+ if ( editionNumber <= 1 )
+ {
+ /* correct xinc if necessary */
+ if ( IS_EQUAL(grid->x.first, 0) && grid->x.last > 354 )
+ {
+ double xinc = 360. / grid->x.size;
+ if ( fabs(grid->x.inc-xinc) > 0.0 )
+ {
+ grid->x.inc = xinc;
+ if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+ }
+ }
+ }
+ }
+ grid->x.flag = 2;
+ }
+ grid->y.flag = 0;
+ /* if ( IS_NOT_EQUAL(grid->y.first, 0) || IS_NOT_EQUAL(grid->y.last, 0) ) */
+ {
+ if ( grid->y.size > 1 )
+ {
+ if ( editionNumber <= 1 )
+ {
+ }
+ }
+ grid->y.flag = 2;
+ }
+ }
+ else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+ {
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+ grid->np = (int)lpar;
- return gridptr->np;
-}
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+ int nlat = (int)lpar;
-/*
- at Function
- at Title
+ grid->size = numberOfPoints;
- at Prototype
- at Parameter
- @Item Grid identifier
+ grid->nrowlon = nlat;
+ grid->rowlon = (int *) Malloc((size_t)nlat * sizeof (int));
+ long *pl = (long *) Malloc((size_t)nlat * sizeof (long));
+ size_t dummy = (size_t)nlat;
+ FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
+ for ( int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
+ Free(pl);
- at EndFunction
-*/
-void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid->y.size = (size_t)nlat;
+ grid->x.inc = 0;
+ grid->y.inc = 0;
+ grid->x.flag = 0;
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->x.first);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees", &grid->x.last);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->y.first);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees", &grid->y.last);
- gridptr->rowlon = (int *) Malloc((size_t)nrowlon * sizeof(int));
- gridptr->nrowlon = nrowlon;
- memcpy(gridptr->rowlon, rowlon, (size_t)nrowlon * sizeof(int));
- gridMark4Update(gridID);
-}
+ // FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->x.inc);
+ // if ( IS_EQUAL(grid->x.inc, GRIB_MISSING_DOUBLE) ) grid->x.inc = 0;
-/*
- at Function
- at Title
+ /* if ( IS_NOT_EQUAL(grid->x.first, 0) || IS_NOT_EQUAL(grid->x.last, 0) ) */
+ {
+ if ( grid->x.size > 1 )
+ {
+ if ( (grid->x.first > grid->x.last) && (grid->x.first >= 180) ) grid->x.first -= 360;
- at Prototype
- at Parameter
- @Item Grid identifier
+ if ( editionNumber <= 1 )
+ {
+ /* correct xinc if necessary */
+ if ( IS_EQUAL(grid->x.first, 0) && grid->x.last > 354 )
+ {
+ double xinc = 360. / grid->x.size;
+ if ( fabs(grid->x.inc-xinc) > 0.0 )
+ {
+ grid->x.inc = xinc;
+ if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+ }
+ }
+ }
+ }
+ grid->x.flag = 2;
+ }
+ grid->y.flag = 0;
+ /* if ( IS_NOT_EQUAL(grid->y.first, 0) || IS_NOT_EQUAL(grid->y.last, 0) ) */
+ {
+ if ( grid->y.size > 1 )
+ {
+ if ( editionNumber <= 1 )
+ {
+ }
+ }
+ grid->y.flag = 2;
+ }
+ }
+ else if ( projtype == CDI_PROJ_LCC )
+ {
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
+ size_t nlon = (size_t)lpar;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
+ size_t nlat = (size_t)lpar;
- at EndFunction
-*/
-void gridInqRowlon(int gridID, int *rowlon)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( numberOfPoints != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", numberOfPoints, nlon*nlat);
- if ( gridptr->rowlon == 0 ) Error("undefined pointer!");
+ grid->size = numberOfPoints;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
- memcpy(rowlon, gridptr->rowlon, (size_t)gridptr->nrowlon * sizeof(int));
-}
+ double xinc, yinc;
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &xinc);
+ FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &yinc);
-static int
-gridInqMaskSerialGeneric(grid_t *gridptr, mask_t **internalMask,
- int *restrict mask)
-{
- long size = gridptr->size;
+ grid->x.first = 0;
+ grid->x.last = 0;
+ grid->x.inc = xinc;
+ grid->y.first = 0;
+ grid->y.last = 0;
+ grid->y.inc = yinc;
+ grid->x.flag = 2;
+ grid->y.flag = 2;
+ }
+ else if ( gridtype == GRID_SPECTRAL )
+ {
+ size_t len = 256;
+ char typeOfPacking[256];
+ FAIL_ON_GRIB_ERROR(grib_get_string, gh, "packingType", typeOfPacking, &len);
+ grid->lcomplex = 0;
+ if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
- if ( CDI_Debug && size == 0 )
- Warning("Size undefined for gridID = %d", gridptr->self);
+ grid->size = datasize;
- const mask_t *restrict mask_src = *internalMask;
- if ( mask_src )
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
+ grid->trunc = (int)lpar;
+ }
+ else if ( gridtype == GRID_GME )
{
- if (mask && size > 0)
- for (size_t i = 0; i < (size_t)size; ++i)
- mask[i] = (int)mask_src[i];
+ grid->size = numberOfPoints;
+ if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->gme.nd = (int)lpar;
+ if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->gme.ni = (int)lpar;
+ if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->gme.ni2 = (int)lpar;
+ if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->gme.ni3 = (int)lpar;
}
- else
- size = 0;
-
- return (int)size;
-}
-
-static int
-gridInqMaskSerial(grid_t *gridptr, int *mask)
-{
- return gridInqMaskSerialGeneric(gridptr, &gridptr->mask, mask);
-}
-
-
-int gridInqMask(int gridID, int *mask)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqMask(gridptr, mask);
-}
+ else if ( gridtype == GRID_UNSTRUCTURED )
+ {
+ unsigned char uuid[CDI_UUID_SIZE];
+ /*
+ char reference_link[8192];
+ size_t len = sizeof(reference_link);
+ reference_link[0] = 0;
+ */
+ grid->size = numberOfPoints;
-static void
-gridDefMaskSerial(grid_t *gridptr, const int *mask)
-{
- long size = gridptr->size;
+ if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+ {
+ grid->number = (int)lpar;
+ if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
+ grid->position = (int)lpar;
+ /*
+ if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+ {
+ if ( strncmp(reference_link, "file://", 7) == 0 )
+ grid->reference = strdupx(reference_link);
+ }
+ */
+ size_t len = (size_t)CDI_UUID_SIZE;
+ if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
+ {
+ memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
+ }
+ }
+ }
+ else if ( gridtype == GRID_GENERIC )
+ {
+ size_t nlon = 0, nlat = 0;
+ if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (size_t)lpar;
+ if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (size_t)lpar;
- if ( size == 0 )
- Error("Size undefined for gridID = %d", gridptr->self);
+ grid->size = numberOfPoints;
- if ( mask == NULL )
- {
- if ( gridptr->mask )
- {
- Free(gridptr->mask);
- gridptr->mask = NULL;
- }
+ if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
+ {
+ grid->x.size = nlon;
+ grid->y.size = nlat;
+ }
+ else
+ {
+ grid->x.size = 0;
+ grid->y.size = 0;
+ }
}
else
{
- if ( gridptr->mask == NULL )
- gridptr->mask = (mask_t *) Malloc((size_t)size*sizeof(mask_t));
- else if ( CDI_Debug )
- Warning("grid mask already defined!");
-
- for (long i = 0; i < size; ++i )
- gridptr->mask[i] = (mask_t)(mask[i] != 0);
+ Error("Unsupported grid type: %s", gridNamePtr(gridtype));
}
-}
-void gridDefMask(int gridID, const int *mask)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defMask(gridptr, mask);
- gridMark4Update(gridID);
-}
+ if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION )
+ {
+ long temp;
+ GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &temp), 0);
+ assert(temp == 0 || temp == 1);
+ grid->uvRelativeToGrid = (bool)temp;
+ }
-static int
-gridInqMaskGMESerial(grid_t *gridptr, int *mask_gme)
-{
- return gridInqMaskSerialGeneric(gridptr, &gridptr->mask_gme, mask_gme);
-}
+ if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION )
+ {
+ long temp;
+ GRIB_CHECK(grib_get_long(gh, "iScansNegatively", &temp), 0);
+ grid->iScansNegatively = (bool)temp;
+ GRIB_CHECK(grib_get_long(gh, "jScansPositively", &temp), 0);
+ grid->jScansPositively = (bool)temp;
+ GRIB_CHECK(grib_get_long(gh, "jPointsAreConsecutive", &temp), 0);
+ grid->jPointsAreConsecutive = (bool)temp;
+ grid->scanningMode = 128*grid->iScansNegatively + 64*grid->jScansPositively + 32*grid->jPointsAreConsecutive;
+ /* scanningMode = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
+ 64 = 128 * 0 + 64 * 1 + 32 * 0
+ 00 = 128 * 0 + 64 * 0 + 32 * 0
+ 96 = 128 * 0 + 64 * 1 + 32 * 1
+ Default / implicit scanning mode is 64:
+ i and j scan positively, i points are consecutive (row-major) */
+#ifdef HIRLAM_EXTENSIONS
+ if (cdiDebugExt>=30)
+ {
+ // indicatorOfParameter=33,indicatorOfTypeOfLevel=105,level
+ long paramId, levelTypeId, levelId;
+ GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", ¶mId), 0);
+ GRIB_CHECK(grib_get_long(gh, "indicatorOfTypeOfLevel", &levelTypeId), 0);
+ GRIB_CHECK(grib_get_long(gh, "level", &levelId), 0);
+ Message("(param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d -> bits:(%1d.%1d.%1d)*32; uvRelativeToGrid = %02d",\
+ (int)paramId, (int)levelTypeId, (int)levelId,
+ grid->scanningMode,grid->jPointsAreConsecutive,
+ grid->jScansPositively,grid->iScansNegatively,
+ grid->uvRelativeToGrid);
+ }
+#endif //HIRLAM_EXTENSIONS
+ }
-int gridInqMaskGME(int gridID, int *mask)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqMaskGME(gridptr, mask);
+ grid->type = gridtype;
+ grid->projtype = projtype;
}
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef CDI_UUID_H
+#define CDI_UUID_H
-static void
-gridDefMaskGMESerial(grid_t *gridptr, const int *mask)
-{
- long size = gridptr->size;
-
- if ( size == 0 )
- Error("Size undefined for gridID = %d", gridptr->self);
-
- if ( gridptr->mask_gme == NULL )
- gridptr->mask_gme = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
- else if ( CDI_Debug )
- Warning("mask already defined!");
+#if defined (HAVE_CONFIG_H)
+#endif
- for (long i = 0; i < size; ++i)
- gridptr->mask_gme[i] = (mask_t)(mask[i] != 0);
-}
-void gridDefMaskGME(int gridID, const int *mask)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defMaskGME(gridptr, mask);
- gridMark4Update(gridID);
-}
+#ifdef __cplusplus
+extern "C" {
+#endif
-static int
-gridInqXValsSerial(grid_t *gridptr, double *xvals)
+static inline int cdiUUIDIsNull(const unsigned char uuid[])
{
- long size;
- if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
- size = gridptr->size;
- else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
- size = 2;
- else
- size = gridptr->xsize;
+ int isNull = 1;
+ for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
+ isNull &= (uuid[i] == 0);
+ return isNull;
+}
- if ( CDI_Debug && size == 0 )
- Warning("size undefined for gridID = %d", gridptr->self);
+void cdiCreateUUID(unsigned char uuid[CDI_UUID_SIZE]);
- if ( gridptr->xvals )
- {
- if ( size && xvals )
- {
- const double *gridptr_xvals = gridptr->vtable->inqXValsPtr(gridptr);
- memcpy(xvals, gridptr_xvals, (size_t)size * sizeof (double));
- }
- }
- else
- size = 0;
+void cdiUUID2Str(const unsigned char uuid[], char uuidstr[]);
+int cdiStr2UUID(const char *uuidstr, unsigned char uuid[]);
- return (int)size;
+#if defined (__cplusplus)
}
+#endif
-/*
- at Function gridInqXvals
- at Title Get all values of a X-axis
+#endif
- at Prototype int gridInqXvals(int gridID, double *xvals)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item xvals Pointer to the location into which the X-values are read.
- The caller must allocate space for the returned values.
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef RESOURCE_UNPACK_H
+#define RESOURCE_UNPACK_H
- at Description
-The function @func{gridInqXvals} returns all values of the X-axis.
+#ifdef HAVE_CONFIG_H
+#endif
- at Result
-Upon successful completion @func{gridInqXvals} returns the number of values and
-the values are stored in @func{xvals}.
-Otherwise, 0 is returned and @func{xvals} is empty.
+enum
+{ GRID = 1,
+ ZAXIS = 2,
+ TAXIS = 3,
+ INSTITUTE = 4,
+ MODEL = 5,
+ STREAM = 6,
+ VLIST = 7,
+ RESH_DELETE,
+ START = 55555555,
+ END = 99999999
+};
- at EndFunction
-*/
-int gridInqXvals(int gridID, double *xvals)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqXVals(gridptr, xvals);
-}
+int reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
+ void *context);
+#endif
-static void
-gridDefXValsSerial(grid_t *gridptr, const double *xvals)
-{
- int gridtype = gridptr->type;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _VLIST_H
+#define _VLIST_H
- long size;
- if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
- size = gridptr->size;
- else if ( gridtype == GRID_GAUSSIAN_REDUCED )
- size = 2;
- else
- size = gridptr->xsize;
+#ifdef HAVE_CONFIG_H
+#endif
- if ( size == 0 )
- Error("Size undefined for gridID = %d", gridptr->self);
+#ifndef ERROR_H
+#endif
- if (gridptr->xvals && CDI_Debug)
- Warning("values already defined!");
- gridptr->xvals = (double *)Realloc(gridptr->xvals,
- (size_t)size * sizeof(double));
- memcpy(gridptr->xvals, xvals, (size_t)size * sizeof (double));
-}
+#include <stddef.h> /* size_t */
-/*
- at Function gridDefXvals
- at Title Define the values of a X-axis
+#ifndef _CDI_LIMITS_H
+#endif
- at Prototype void gridDefXvals(int gridID, const double *xvals)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item xvals X-values of the grid.
+#define VALIDMISS 1.e+303
- at Description
-The function @func{gridDefXvals} defines all values of the X-axis.
- at EndFunction
-*/
-void gridDefXvals(int gridID, const double *xvals)
+typedef struct
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defXVals(gridptr, xvals);
- gridMark4Update(gridID);
+ bool flag;
+ int index;
+ int mlevelID;
+ int flevelID;
}
+levinfo_t;
-static int
-gridInqYValsSerial(grid_t *gridptr, double *yvals)
+#define DEFAULT_LEVINFO(levID) \
+ (levinfo_t){ 0, -1, levID, levID}
+/*
+#define DEFAULT_LEVINFO(levID) \
+ (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
+*/
+typedef struct
{
- int gridtype = gridptr->type;
- long size
- = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
- ? gridptr->size : gridptr->ysize;
-
- if ( CDI_Debug && size == 0 )
- Warning("size undefined for gridID = %d!", gridptr->self);
+ int ens_index;
+ int ens_count;
+ int forecast_init_type;
+}
+ensinfo_t;
- if ( gridptr->yvals )
- {
- if ( size && yvals )
- {
- const double *gridptr_yvals = gridptr->vtable->inqYValsPtr(gridptr);
- memcpy(yvals, gridptr_yvals, (size_t)size * sizeof (double));
- }
- }
- else
- size = 0;
- return (int)size;
-}
-/*
- at Function gridInqYvals
- at Title Get all values of a Y-axis
+typedef struct
+{
+ bool isUsed;
+ bool flag;
+ int mvarID;
+ int fvarID;
+ int param;
+ int gridID;
+ int zaxisID;
+ int timetype; /* TIME_* */
+ int tsteptype; /* TSTEP_* */
+ int datatype; /* CDI_DATATYPE_PACKX for GRIB data, else CDI_DATATYPE_FLT32 or CDI_DATATYPE_FLT64 */
+ int instID;
+ int modelID;
+ int tableID;
+ int timave;
+ int timaccu;
+ int typeOfGeneratingProcess;
+ int productDefinitionTemplate;
+ int chunktype;
+ int xyz;
+ bool missvalused; /* true if missval is defined */
+ bool lvalidrange;
+ char *name;
+ char *longname;
+ char *stdname;
+ char *units;
+ char *extra;
+ double missval;
+ double scalefactor;
+ double addoffset;
+ double validrange[2];
+ levinfo_t *levinfo;
+ int comptype; // compression type
+ int complevel; // compression level
+ ensinfo_t *ensdata; /* Ensemble information */
+ cdi_atts_t atts;
+ int iorank;
- at Prototype int gridInqYvals(int gridID, double *yvals)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item yvals Pointer to the location into which the Y-values are read.
- The caller must allocate space for the returned values.
+ int subtypeID; /* subtype ID for tile-related meta-data, currently for GRIB-API only. */
- at Description
-The function @func{gridInqYvals} returns all values of the Y-axis.
+ int opt_grib_nentries; /* current no. key-value pairs */
+ int opt_grib_kvpair_size; /* current allocated size */
+ opt_key_val_pair_t *opt_grib_kvpair; /* (optional) list of keyword/value pairs */
+}
+var_t;
- at Result
-Upon successful completion @func{gridInqYvals} returns the number of values and
-the values are stored in @func{yvals}.
-Otherwise, 0 is returned and @func{yvals} is empty.
- at EndFunction
-*/
-int gridInqYvals(int gridID, double *yvals)
+typedef struct
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqYVals(gridptr, yvals);
+ //set when a vlist is passed to streamDefVlist() to safeguard against modifications of the wrong vlist object
+ bool immutable;
+ //set if this vlist has been created by CDI itself, and must not be destroyed by the user, consequently
+ bool internal;
+ int self;
+ int nvars; /* number of variables */
+ int ngrids;
+ int nzaxis;
+ int nsubtypes; /* no. of variable subtypes (e.g. sets of tiles) */
+ long ntsteps;
+ int taxisID;
+ int tableID;
+ int instID;
+ int modelID;
+ int varsAllocated;
+ int gridIDs[MAX_GRIDS_PS];
+ int zaxisIDs[MAX_ZAXES_PS];
+ int subtypeIDs[MAX_SUBTYPES_PS];
+ var_t *vars;
+ cdi_atts_t atts;
}
+vlist_t;
-static void
-gridDefYValsSerial(grid_t *gridptr, const double *yvals)
-{
- int gridtype = gridptr->type;
- long size
- = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
- ? gridptr->size : gridptr->ysize;
- if ( size == 0 )
- Error("Size undefined for gridID = %d!", gridptr->self);
+vlist_t *vlist_to_pointer(int vlistID);
+void cdiVlistMakeInternal(int vlistID);
+void cdiVlistMakeImmutable(int vlistID);
+void vlistCheckVarID(const char *caller, int vlistID, int varID);
+void vlistDestroyVarName(int vlistID, int varID);
+void vlistDestroyVarLongname(int vlistID, int varID);
+void vlistDestroyVarStdname(int vlistID, int varID);
+void vlistDestroyVarUnits(int vlistID, int varID);
+void cdiVlistDestroy_(int vlistID);
+int vlistInqVarMissvalUsed(int vlistID, int varID);
+int vlistHasTime(int vlistID);
- if (gridptr->yvals && CDI_Debug)
- Warning("Values already defined!");
+int cdiDelAtts(int vlistID, int varID);
- gridptr->yvals = (double *)Realloc(gridptr->yvals, (size_t)size * sizeof (double));
- memcpy(gridptr->yvals, yvals, (size_t)size * sizeof (double));
-}
+void vlistUnpack(char * buffer, int bufferSize, int * pos,
+ int originNamespace, void *context, int force_id);
+/* vlistDefVarValidrange: Define the valid range of a Variable */
+void vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
-/*
- at Function gridDefYvals
- at Title Define the values of a Y-axis
+/* vlistInqVarValidrange: Get the valid range of a Variable */
+int vlistInqVarValidrange(int vlistID, int varID, double *validrange);
- at Prototype void gridDefYvals(int gridID, const double *yvals)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item yvals Y-values of the grid.
+void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3]);
- at Description
-The function @func{gridDefYvals} defines all values of the Y-axis.
+int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
- at EndFunction
-*/
-void gridDefYvals(int gridID, const double *yvals)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defYVals(gridptr, yvals);
- gridMark4Update(gridID);
-}
+void resize_opt_grib_entries(var_t *var, int nentries);
-static double
-gridInqXValSerial(grid_t *gridptr, int index)
-{
- double xval = gridptr->xvals ? gridptr->xvals[index] : 0;
- return xval;
-}
-double gridInqXval(int gridID, int index)
+static inline
+void vlistAdd2GridIDs(vlist_t *vlistptr, int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqXVal(gridptr, index);
-}
+ int index, ngrids = vlistptr->ngrids;
+ for ( index = 0; index < ngrids; index++ )
+ {
+ if ( vlistptr->gridIDs[index] == gridID ) break;
+ // if ( gridIsEqual(vlistptr->gridIDs[index], gridID) ) break;
+ }
-static double
-gridInqYValSerial(grid_t *gridptr, int index)
-{
- double yval = gridptr->yvals ? gridptr->yvals[index] : 0;
- return yval;
+ if ( index == ngrids )
+ {
+ if ( ngrids >= MAX_GRIDS_PS )
+ Error("Internal limit exceeded: more than %d grids.", MAX_GRIDS_PS);
+ vlistptr->gridIDs[ngrids] = gridID;
+ ++(vlistptr->ngrids);
+ }
}
-/*
- at Function
- at Title
+static inline
+void vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
+{
+ int index, nzaxis = vlistptr->nzaxis;
+ for ( index = 0; index < nzaxis; index++ )
+ if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
- at Prototype
- at Parameter
- @Item Grid identifier
+ if ( index == nzaxis )
+ {
+ if ( nzaxis >= MAX_ZAXES_PS )
+ Error("Internal limit exceeded: more than %d zaxis.", MAX_ZAXES_PS);
+ vlistptr->zaxisIDs[nzaxis] = zaxisID;
+ ++(vlistptr->nzaxis);
+ }
+}
- at EndFunction
-*/
-double gridInqYval(int gridID, int index)
+static inline
+void vlistAdd2SubtypeIDs(vlist_t *vlistptr, int subtypeID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqYVal(gridptr, index);
-}
+ if ( subtypeID == CDI_UNDEFID ) return;
-/*
- at Function
- at Title
+ int index, nsubs = vlistptr->nsubtypes;
+ for ( index = 0; index < nsubs; index++ )
+ if ( vlistptr->subtypeIDs[index] == subtypeID ) break;
- at Prototype
- at Parameter
- @Item Grid identifier
+ if ( index == nsubs )
+ {
+ if ( nsubs >= MAX_SUBTYPES_PS )
+ Error("Internal limit exceeded: more than %d subs.", MAX_SUBTYPES_PS);
+ vlistptr->subtypeIDs[nsubs] = subtypeID;
+ ++(vlistptr->nsubtypes);
+ }
+}
- at EndFunction
-*/
-double gridInqXinc(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- double xinc = gridptr->xinc;
- const double *restrict xvals = gridptr->vtable->inqXValsPtr(gridptr);
- if ( (! (fabs(xinc) > 0)) && xvals )
- {
- int xsize = gridptr->xsize;
- if ( xsize > 1 )
- {
- xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
- for (size_t i = 2; i < (size_t)xsize; i++ )
- if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc )
- {
- xinc = 0;
- break;
- }
- gridptr->xinc = xinc;
- }
- }
+#if defined (HAVE_LIBGRIB_API)
+extern int cdiNAdditionalGRIBKeys;
+extern char* cdiAdditionalGRIBKeys[];
+#endif
- return xinc;
-}
+extern
+#ifndef __cplusplus
+const
+#endif
+resOps vlistOps;
+#endif /* _VLIST_H */
/*
- at Function
- at Title
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- at Prototype
- at Parameter
- @Item Grid identifier
+#include <assert.h>
+#include <string.h>
- at EndFunction
-*/
-double gridInqYinc(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- double yinc = gridptr->yinc;
- const double *yvals = gridptr->vtable->inqYValsPtr(gridptr);
- if ( (! (fabs(yinc) > 0)) && yvals )
- {
- int ysize = gridptr->ysize;
- if ( ysize > 1 )
- {
- yinc = yvals[1] - yvals[0];
- double abs_yinc = fabs(yinc);
- for ( size_t i = 2; i < (size_t)ysize; i++ )
- if ( fabs(fabs(yvals[i] - yvals[i-1]) - abs_yinc) > (0.01*abs_yinc) )
- {
- yinc = 0;
- break;
- }
+double grid_missval = -9999.;
+int (*proj_lonlat_to_lcc_func)() = NULL;
+int (*proj_lcc_to_lonlat_func)() = NULL;
- gridptr->yinc = yinc;
- }
- }
+/* the value in the second pair of brackets must match the length of
+ * the longest string (including terminating NUL) */
+static const char Grids[][17] = {
+ /* 0 */ "undefined",
+ /* 1 */ "generic",
+ /* 2 */ "gaussian",
+ /* 3 */ "gaussian reduced",
+ /* 4 */ "lonlat",
+ /* 5 */ "spectral",
+ /* 6 */ "fourier",
+ /* 7 */ "gme",
+ /* 8 */ "trajectory",
+ /* 9 */ "unstructured",
+ /* 10 */ "curvilinear",
+ /* 11 */ "lcc",
+ /* 12 */ "projection",
+ /* 13 */ "characterXY",
+};
- return yinc;
-}
+/* must match table below */
+enum xystdname_idx {
+ grid_xystdname_grid_latlon,
+ grid_xystdname_latlon,
+ grid_xystdname_projection,
+ grid_xystdname_char,
+};
+static const char xystdname_tab[][2][24] = {
+ [grid_xystdname_grid_latlon] = { "grid_longitude",
+ "grid_latitude" },
+ [grid_xystdname_latlon] = { "longitude",
+ "latitude" },
+ [grid_xystdname_projection] = { "projection_x_coordinate",
+ "projection_y_coordinate" },
+ [grid_xystdname_char] = { "region",
+ "region" },
+};
-/*
- at Function
- at Title
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-double gridInqXpole(int gridID)
-{
- // Xpole -> grid_north_pole_longitude
- grid_t *gridptr = gridID2Ptr(gridID);
+static int gridCompareP ( void * gridptr1, void * gridptr2 );
+static void gridDestroyP ( void * gridptr );
+static void gridPrintP ( void * gridptr, FILE * fp );
+static int gridGetPackSize ( void * gridptr, void *context);
+static void gridPack ( void * gridptr, void * buff, int size, int *position, void *context);
+static int gridTxCode ( void );
- return gridptr->xpole;
-}
+static const resOps gridOps = {
+ gridCompareP,
+ gridDestroyP,
+ gridPrintP,
+ gridGetPackSize,
+ gridPack,
+ gridTxCode
+};
-/*
- at Function
- at Title
+static int GRID_Debug = 0; /* If set to 1, debugging */
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-void gridDefXpole(int gridID, double xpole)
+grid_t *grid_to_pointer(int gridID)
{
- // Xpole -> grid_north_pole_longitude
- grid_t *gridptr = gridID2Ptr(gridID);
+ return (grid_t *)reshGetVal(gridID, &gridOps);
+}
+
+#define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
- if ( gridptr->xstdname && memcmp(gridptr->xstdname, "grid", 4) != 0 )
- gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+static
+bool cdiInqAttConvertedToFloat(int gridID, int atttype, const char *attname, int attlen, double *attflt)
+{
+ bool status = true;
- if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->xpole, xpole) )
+ if ( atttype == CDI_DATATYPE_INT32 )
{
- gridptr->isRotated = TRUE;
- gridptr->xpole = xpole;
- gridMark4Update(gridID);
+ int attint[attlen];
+ cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, attint);
+ for ( int i = 0; i < attlen; ++i ) attflt[i] = (double)attint[i];
+ }
+ else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
+ {
+ cdiInqAttFlt(gridID, CDI_GLOBAL, attname, attlen, attflt);
+ }
+ else
+ {
+ status = false;
}
-}
-/*
- at Function
- at Title
+ return status;
+}
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-double gridInqYpole(int gridID)
+void grid_init(grid_t *gridptr)
{
- // Ypole -> grid_north_pole_latitude
- grid_t *gridptr = gridID2Ptr(gridID);
-
- return gridptr->ypole;
-}
-
-/*
- at Function
- at Title
+ gridptr->self = CDI_UNDEFID;
+ gridptr->type = CDI_UNDEFID;
+ gridptr->proj = CDI_UNDEFID;
+ gridptr->projtype = CDI_UNDEFID;
+ gridptr->mask = NULL;
+ gridptr->mask_gme = NULL;
+ gridptr->x.vals = NULL;
+ gridptr->x.cvals = NULL;
+ gridptr->x.clength = 0;
+ gridptr->y.vals = NULL;
+ gridptr->y.cvals = NULL;
+ gridptr->y.clength = 0;
+ gridptr->x.bounds = NULL;
+ gridptr->y.bounds = NULL;
+ gridptr->area = NULL;
+ gridptr->rowlon = NULL;
+ gridptr->nrowlon = 0;
- at Prototype
- at Parameter
- @Item Grid identifier
+ gridptr->x.first = 0.0;
+ gridptr->x.last = 0.0;
+ gridptr->x.inc = 0.0;
+ gridptr->y.first = 0.0;
+ gridptr->y.last = 0.0;
+ gridptr->y.inc = 0.0;
- at EndFunction
-*/
-void gridDefYpole(int gridID, double ypole)
-{
- // Ypole -> grid_north_pole_latitude
- grid_t *gridptr = gridID2Ptr(gridID);
+ gridptr->gme.nd = 0;
+ gridptr->gme.ni = 0;
+ gridptr->gme.ni2 = 0;
+ gridptr->gme.ni3 = 0;
- if ( gridptr->ystdname && memcmp(gridptr->ystdname, "grid", 4) != 0 )
- gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+ gridptr->trunc = 0;
+ gridptr->nvertex = 0;
+ gridptr->number = 0;
+ gridptr->position = 0;
+ gridptr->reference = NULL;
+ gridptr->datatype = 0;
+ gridptr->size = 0;
+ gridptr->x.size = 0;
+ gridptr->y.size = 0;
+ gridptr->np = 0;
+ gridptr->x.flag = 0;
+ gridptr->y.flag = 0;
+ gridptr->isCyclic = CDI_UNDEFID;
- if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->ypole, ypole) )
- {
- gridptr->isRotated = TRUE;
- gridptr->ypole = ypole;
- gridMark4Update(gridID);
- }
+ gridptr->lcomplex = false;
+ gridptr->hasdims = true;
+ gridptr->x.dimname[0] = 0;
+ gridptr->y.dimname[0] = 0;
+ gridptr->x.name[0] = 0;
+ gridptr->y.name[0] = 0;
+ gridptr->x.longname[0] = 0;
+ gridptr->y.longname[0] = 0;
+ gridptr->x.units[0] = 0;
+ gridptr->y.units[0] = 0;
+ gridptr->x.stdname = NULL;
+ gridptr->y.stdname = NULL;
+ gridptr->vdimname[0] = 0;
+ gridptr->mapname[0] = 0;
+ gridptr->mapping[0] = 0;
+ memset(gridptr->uuid, 0, CDI_UUID_SIZE);
+ gridptr->name = NULL;
+ gridptr->vtable = &cdiGridVtable;
+ gridptr->atts.nalloc = MAX_ATTRIBUTES;
+ gridptr->atts.nelems = 0;
+ gridptr->uvRelativeToGrid = 0; // Some models deliver wind U,V relative to the grid-cell
+ gridptr->iScansNegatively = 0;
+ gridptr->jScansPositively = 1;
+ gridptr->jPointsAreConsecutive = 0;
+ gridptr->scanningMode = 128*gridptr->iScansNegatively + 64*gridptr->jScansPositively + 32*gridptr->jPointsAreConsecutive;
+ /* scanningMode = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
+ 64 = 128 * 0 + 64 * 1 + 32 * 0
+ 00 = 128 * 0 + 64 * 0 + 32 * 0
+ 96 = 128 * 0 + 64 * 1 + 32 * 1
+ Default / implicit scanning mode is 64:
+ i and j scan positively, i points are consecutive (row-major) */
}
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-double gridInqAngle(int gridID)
+static
+void grid_free_components(grid_t *gridptr)
{
- // Angle -> north_pole_grid_longitude
- grid_t *gridptr = gridID2Ptr(gridID);
+ void *p2free[] = { gridptr->mask, gridptr->mask_gme,
+ gridptr->x.vals, gridptr->y.vals,
+ gridptr->x.cvals, gridptr->y.cvals,
+ gridptr->x.bounds, gridptr->y.bounds,
+ gridptr->rowlon, gridptr->area,
+ gridptr->reference, gridptr->name};
- return gridptr->angle;
+ for ( size_t i = 0; i < sizeof(p2free)/sizeof(p2free[0]); ++i )
+ if ( p2free[i] ) Free(p2free[i]);
}
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
- @Item Grid identifier
+void grid_free(grid_t *gridptr)
+{
+ grid_free_components(gridptr);
+ grid_init(gridptr);
+}
- at EndFunction<
-*/
-void gridDefAngle(int gridID, double angle)
+static
+grid_t *gridNewEntry(cdiResH resH)
{
- // Angle -> north_pole_grid_longitude
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
+ grid_init(gridptr);
- if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->angle, angle) )
+ if ( resH == CDI_UNDEFID )
+ gridptr->self = reshPut(gridptr, &gridOps);
+ else
{
- gridptr->isRotated = TRUE;
- gridptr->angle = angle;
- gridMark4Update(gridID);
+ gridptr->self = resH;
+ reshReplace(resH, gridptr, &gridOps);
}
-}
-
-/*
- at Function
- at Title
- at Prototype
- at Parameter
- @Item Grid identifier
+ return gridptr;
+}
- at EndFunction
-*/
-int gridInqGMEnd(int gridID)
+static
+void gridInit(void)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ static bool gridInitialized = false;
+ if ( gridInitialized ) return;
+ gridInitialized = true;
- return gridptr->nd;
+ const char *env = getenv("GRID_DEBUG");
+ if ( env ) GRID_Debug = atoi(env);
}
-/*
- at Function
- at Title
+static
+void grid_copy_base_scalar_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
+{
+ memcpy(gridptrDup, gridptrOrig, sizeof(grid_t));
+ gridptrDup->self = CDI_UNDEFID;
+ if ( gridptrOrig->reference )
+ gridptrDup->reference = strdupx(gridptrOrig->reference);
+}
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-void gridDefGMEnd(int gridID, int nd)
+static
+grid_t *grid_copy_base(grid_t *gridptrOrig)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- if (gridptr->nd != nd)
- {
- gridptr->nd = nd;
- gridMark4Update(gridID);
- }
+ grid_t *gridptrDup = (grid_t *)Malloc(sizeof (*gridptrDup));
+ gridptrOrig->vtable->copyScalarFields(gridptrOrig, gridptrDup);
+ gridptrOrig->vtable->copyArrayFields(gridptrOrig, gridptrDup);
+ return gridptrDup;
}
-/*
- at Function
- at Title
- at Prototype
- at Parameter
- @Item Grid identifier
+unsigned cdiGridCount(void)
+{
+ return reshCountType(&gridOps);
+}
- at EndFunction
-*/
-int gridInqGMEni(int gridID)
+static inline
+void gridSetString(char *gridstrname, const char *name, size_t len)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
+ strncpy(gridstrname, name, len);
+ gridstrname[len - 1] = 0;
+}
- return gridptr->ni;
+static inline
+void gridGetString(char *name, const char *gridstrname, size_t len)
+{
+ if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
+ strncpy(name, gridstrname, len);
+ name[len - 1] = 0;
}
-/*
- at Function
- at Title
+static inline
+void gridSetName(char *gridstrname, const char *name)
+{
+ strncpy(gridstrname, name, CDI_MAX_NAME);
+ gridstrname[CDI_MAX_NAME - 1] = 0;
+}
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-void gridDefGMEni(int gridID, int ni)
+void cdiGridTypeInit(grid_t *gridptr, int gridtype, size_t size)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ gridptr->type = gridtype;
+ gridptr->size = size;
- if ( gridptr->ni != ni )
- {
- gridptr->ni = ni;
- gridMark4Update(gridID);
- }
-}
+ if ( gridtype == GRID_CURVILINEAR ) gridptr->nvertex = 4;
+ else if ( gridtype == GRID_UNSTRUCTURED ) gridptr->x.size = size;
-/*
- at Function
- at Title
+ switch (gridtype)
+ {
+ case GRID_LONLAT:
+ case GRID_GAUSSIAN:
+ case GRID_GAUSSIAN_REDUCED:
+ case GRID_TRAJECTORY:
+ case GRID_CURVILINEAR:
+ case GRID_UNSTRUCTURED:
+ case GRID_GME:
+ {
+ if ( gridtype == GRID_TRAJECTORY )
+ {
+ if ( !gridptr->x.name[0] ) gridSetName(gridptr->x.name, "tlon");
+ if ( !gridptr->y.name[0] ) gridSetName(gridptr->y.name, "tlat");
+ }
+ else
+ {
+ if ( !gridptr->x.name[0] ) gridSetName(gridptr->x.name, "lon");
+ if ( !gridptr->y.name[0] ) gridSetName(gridptr->y.name, "lat");
+ }
- at Prototype
- at Parameter
- @Item Grid identifier
+ if ( !gridptr->x.longname[0] ) gridSetName(gridptr->x.longname, "longitude");
+ if ( !gridptr->y.longname[0] ) gridSetName(gridptr->y.longname, "latitude");
- at EndFunction
-*/
-int gridInqGMEni2(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "degrees_east");
+ if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "degrees_north");
- return gridptr->ni2;
-}
+ gridptr->x.stdname = xystdname_tab[grid_xystdname_latlon][0];
+ gridptr->y.stdname = xystdname_tab[grid_xystdname_latlon][1];
-/*
- at Function
- at Title
+ break;
+ }
+ case GRID_CHARXY:
+ {
+ if ( gridptr->x.cvals ) gridptr->x.stdname = xystdname_tab[grid_xystdname_char][0];
+ if ( gridptr->y.cvals ) gridptr->y.stdname = xystdname_tab[grid_xystdname_char][0];
- at Prototype
- at Parameter
- @Item Grid identifier
+ break;
+ }
+ case GRID_GENERIC:
+ case GRID_PROJECTION:
+ {
+ if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "x");
+ if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "y");
+ if ( gridtype == GRID_PROJECTION )
+ {
+ gridSetName(gridptr->mapname, "Projection");
- at EndFunction
-*/
-void gridDefGMEni2(int gridID, int ni2)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
+ gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
- if ( gridptr->ni2 != ni2 )
- {
- gridptr->ni2 = ni2;
- gridMark4Update(gridID);
+ if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "m");
+ if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "m");
+ }
+ break;
+ }
}
}
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
- @Item Grid identifier
- at EndFunction
-*/
-int gridInqGMEni3(int gridID)
+// used also in CDO
+void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *restrict xvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( (! (fabs(xinc) > 0)) && xsize > 1 )
+ {
+ if ( xfirst >= xlast )
+ {
+ while ( xfirst >= xlast ) xlast += 360;
+ xinc = (xlast-xfirst)/(xsize);
+ }
+ else
+ {
+ xinc = (xlast-xfirst)/(xsize-1);
+ }
+ }
- return gridptr->ni3;
+ for ( int i = 0; i < xsize; ++i )
+ xvals[i] = xfirst + i*xinc;
}
-void gridDefGMEni3(int gridID, int ni3)
+static
+void calc_gaussgrid(double *restrict yvals, size_t ysize, double yfirst, double ylast)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ double *restrict yw = (double *) Malloc(ysize * sizeof(double));
+ gaussaw(yvals, yw, ysize);
+ Free(yw);
+ for (size_t i = 0; i < ysize; i++ )
+ yvals[i] = asin(yvals[i])/M_PI*180.0;
- if ( gridptr->ni3 != ni3 )
+ if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
{
- gridptr->ni3 = ni3;
- gridMark4Update(gridID);
+ size_t yhsize = ysize/2;
+ for (size_t i = 0; i < yhsize; i++ )
+ {
+ double ytmp = yvals[i];
+ yvals[i] = yvals[ysize-i-1];
+ yvals[ysize-i-1] = ytmp;
+ }
}
}
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
- @Item Grid identifier
-
- at EndFunction
-*/
-void gridChangeType(int gridID, int gridtype)
+// used also in CDO
+void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- if ( CDI_Debug )
- Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
+ const double deleps = 0.002;
- if (gridptr->type != gridtype)
+ if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
{
- gridptr->type = gridtype;
- gridMark4Update(gridID);
- }
-}
+ if ( ysize > 2 )
+ {
+ calc_gaussgrid(yvals, ysize, yfirst, ylast);
-static
-void grid_check_cyclic(grid_t *gridptr)
-{
- gridptr->isCyclic = FALSE;
- enum { numVertices = 4 };
- size_t xsize = gridptr->xsize >= 0 ? (size_t)gridptr->xsize : 0,
- ysize = gridptr->ysize >= 0 ? (size_t)gridptr->ysize : 0;
- const double *xvals = gridptr->vtable->inqXValsPtr(gridptr),
- (*xbounds)[numVertices]
- = (const double (*)[numVertices])gridptr->vtable->inqXBoundsPtr(gridptr);
+ if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
+ if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
+ {
+ double *restrict ytmp = NULL;
+ int nstart;
+ bool lfound = false;
+ int ny = (int) (180./(fabs(ylast-yfirst)/(ysize-1)) + 0.5);
+ ny -= ny%2;
+ if ( ny > ysize && ny < 4096 )
+ {
+ ytmp = (double *) Malloc((size_t)ny * sizeof (double));
+ calc_gaussgrid(ytmp, ny, yfirst, ylast);
+ {
+ int i;
+ for ( i = 0; i < (ny-ysize); i++ )
+ if ( fabs(ytmp[i] - yfirst) < deleps ) break;
+ nstart = i;
+ }
- if ( gridptr->type == GRID_GAUSSIAN || gridptr->type == GRID_LONLAT )
- {
- if ( xvals && xsize > 1 )
- {
- double xinc = xvals[1] - xvals[0];
- if ( IS_EQUAL(xinc, 0) )
- xinc = (xvals[xsize-1] - xvals[0])/(double)(xsize-1);
+ lfound = (nstart+ysize-1) < ny
+ && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
+ if ( lfound )
+ {
+ for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
+ }
+ }
- double x0 = 2*xvals[xsize-1]-xvals[xsize-2]-360;
+ if ( !lfound )
+ {
+ Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
+ for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
+ yvals[0] = yfirst;
+ yvals[ysize-1] = ylast;
+ }
- if ( IS_NOT_EQUAL(xvals[0], xvals[xsize-1]) )
- if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
+ if ( ytmp ) Free(ytmp);
+ }
+ }
+ else
+ {
+ yvals[0] = yfirst;
+ yvals[ysize-1] = ylast;
}
}
- else if ( gridptr->type == GRID_CURVILINEAR )
+ /* else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
+ else
{
- if ( xvals && xsize > 1 )
+ if ( (! (fabs(yinc) > 0)) && ysize > 1 )
{
- size_t nc = 0;
- for ( size_t j = 0; j < ysize; ++j )
- {
- size_t i1 = j*xsize,
- i2 = j*xsize+1,
- in = j*xsize+(xsize-1);
- double val1 = xvals[i1],
- val2 = xvals[i2],
- valn = xvals[in];
-
- double xinc = fabs(val2-val1);
-
- if ( val1 < 1 && valn > 300 ) val1 += 360;
- if ( valn < 1 && val1 > 300 ) valn += 360;
- if ( val1 < -179 && valn > 120 ) val1 += 360;
- if ( valn < -179 && val1 > 120 ) valn += 360;
- if ( fabs(valn-val1) > 180 ) val1 += 360;
-
- double x0 = valn + copysign(xinc, val1 - valn);
+ if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
- nc += fabs(x0-val1) < 0.5*xinc;
+ if ( yfirst > ylast )
+ yinc = (yfirst-ylast)/(ysize-1);
+ else if ( yfirst < ylast )
+ yinc = (ylast-yfirst)/(ysize-1);
+ else
+ {
+ if ( ysize%2 != 0 )
+ {
+ yinc = 180.0/(ysize-1);
+ yfirst = -90;
+ }
+ else
+ {
+ yinc = 180.0/ysize;
+ yfirst = -90 + yinc/2;
+ }
}
- gridptr->isCyclic = nc > ysize/2 ? TRUE : FALSE;
}
- if ( xbounds && xsize > 1 )
- {
- bool isCyclic = true;
- for ( size_t j = 0; j < ysize; ++j )
- {
- size_t i1 = j*xsize,
- i2 = j*xsize+(xsize-1);
- for (size_t k1 = 0; k1 < numVertices; ++k1 )
- {
- double val1 = xbounds[i1][k1];
- for (size_t k2 = 0; k2 < numVertices; ++k2 )
- {
- double val2 = xbounds[i2][k2];
-
- if ( val1 < 1 && val2 > 300 ) val1 += 360;
- if ( val2 < 1 && val1 > 300 ) val2 += 360;
- if ( val1 < -179 && val2 > 120 ) val1 += 360;
- if ( val2 < -179 && val1 > 120 ) val2 += 360;
- if ( fabs(val2-val1) > 180 ) val1 += 360;
+ if ( yfirst > ylast && yinc > 0 ) yinc = -yinc;
- if ( fabs(val1-val2) < 0.001 )
- goto foundCloseVertices;
- }
- }
- /* all vertices more than 0.001 degrees apart */
- isCyclic = false;
- break;
- foundCloseVertices:
- ;
- }
- gridptr->isCyclic = (int) isCyclic;
- }
+ for (int i = 0; i < ysize; i++ )
+ yvals[i] = yfirst + i*yinc;
}
+ /*
+ else
+ Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
+ */
}
+/*
+ at Function gridCreate
+ at Title Create a horizontal Grid
-int gridIsCircular(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ at Prototype int gridCreate(int gridtype, size_t size)
+ at Parameter
+ @Item gridtype The type of the grid, one of the set of predefined CDI grid types.
+ The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
+ @func{GRID_LONLAT}, @func{GRID_PROJECTION}, @func{GRID_SPECTRAL},
+ @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
+ @Item size Number of gridpoints.
- if ( gridptr->isCyclic == CDI_UNDEFID ) grid_check_cyclic(gridptr);
+ at Description
+The function @func{gridCreate} creates a horizontal Grid.
- return gridptr->isCyclic;
-}
+ at Result
+ at func{gridCreate} returns an identifier to the Grid.
+ at Example
+Here is an example using @func{gridCreate} to create a regular lon/lat Grid:
-int gridIsRotated(int gridID)
+ at Source
+ ...
+#define nlon 12
+#define nlat 6
+ ...
+double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
+double lats[nlat] = {-75, -45, -15, 15, 45, 75};
+int gridID;
+ ...
+gridID = gridCreate(GRID_LONLAT, nlon*nlat);
+gridDefXsize(gridID, nlon);
+gridDefYsize(gridID, nlat);
+gridDefXvals(gridID, lons);
+gridDefYvals(gridID, lats);
+ ...
+ at EndSource
+ at EndFunction
+*/
+int gridCreate(int gridtype, size_t size)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( CDI_Debug ) Message("gridtype=%s size=%zu", gridNamePtr(gridtype), size);
- return gridptr->isRotated;
-}
+ gridInit();
-static
-bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
-{
- bool differ = false;
+ grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
+ if ( ! gridptr ) Error("No memory");
- int xsizeTest = gridTest->xsize, ysizeTest = gridTest->ysize;
- if ( !differ && xsizeTest > 0 && xsizeTest == gridRef->vtable->inqXVals(gridRef, NULL) )
- {
- const double *restrict xvalsRef = gridRef->vtable->inqXValsPtr(gridRef),
- *restrict xvalsTest = gridTest->vtable->inqXValsPtr(gridTest);
+ int gridID = gridptr->self;
- for ( size_t i = 0; i < (size_t)xsizeTest; ++i )
- if ( fabs(xvalsTest[i] - xvalsRef[i]) > 1.e-10 )
- {
- differ = true;
- break;
- }
- }
+ if ( CDI_Debug ) Message("gridID: %d", gridID);
- if ( !differ && ysizeTest > 0 && ysizeTest == gridRef->vtable->inqYVals(gridRef, NULL) )
- {
- const double *restrict yvalsRef = gridRef->vtable->inqYValsPtr(gridRef),
- *restrict yvalsTest = gridTest->vtable->inqYValsPtr(gridTest);
- for ( size_t i = 0; i < (size_t)ysizeTest; ++i )
- if ( fabs(yvalsTest[i] - yvalsRef[i]) > 1.e-10 )
- {
- differ = true;
- break;
- }
- }
+ cdiGridTypeInit(gridptr, gridtype, size);
- return differ;
+ return gridID;
}
static
-bool compareXYvals2(grid_t *gridRef, grid_t *gridTest)
+void gridDestroyKernel( grid_t * gridptr )
{
- int gridsize = gridTest->size;
- bool differ
- = ((gridTest->xvals == NULL) ^ (gridRef->xvals == NULL))
- || ((gridTest->yvals == NULL) ^ (gridRef->yvals == NULL));
-
- typedef double (*inqVal)(grid_t *grid, int index);
- inqVal inqXValRef = gridRef->vtable->inqXVal,
- inqYValRef = gridRef->vtable->inqXVal,
- inqXValTest = gridTest->vtable->inqXVal,
- inqYValTest = gridTest->vtable->inqYVal;
+ xassert ( gridptr );
- if ( !differ && gridTest->xvals )
- differ = fabs(inqXValTest(gridTest, 0) - inqXValRef(gridRef, 0)) > 1.e-9
- || fabs(inqXValTest(gridTest, gridsize-1) - inqXValRef(gridRef, gridsize-1)) > 1.e-9;
+ int id = gridptr->self;
- if ( !differ && gridTest->yvals )
- differ = fabs(inqYValTest(gridTest, 0) - inqYValRef(gridRef, 0)) > 1.e-9
- || fabs(inqYValTest(gridTest, gridsize-1) - inqYValRef(gridRef, gridsize-1)) > 1.e-9;
+ grid_free_components(gridptr);
+ Free( gridptr );
- return differ;
+ reshRemove ( id, &gridOps );
}
-static
-bool gridCompare(int gridID, const grid_t *grid)
-{
- bool differ = true;
- grid_t *gridRef = gridID2Ptr(gridID);
-
- if ( grid->type == gridRef->type || grid->type == GRID_GENERIC )
- {
- if ( grid->size == gridRef->size )
- {
- differ = false;
- if ( grid->type == GRID_LONLAT )
- {
- /*
- printf("gridID %d\n", gridID);
- printf("grid.xdef %d\n", grid->xdef);
- printf("grid.ydef %d\n", grid->ydef);
- printf("grid.xsize %d\n", grid->xsize);
- printf("grid.ysize %d\n", grid->ysize);
- printf("grid.xfirst %f\n", grid->xfirst);
- printf("grid.yfirst %f\n", grid->yfirst);
- printf("grid.xfirst %f\n", gridInqXval(gridID, 0));
- printf("grid.yfirst %f\n", gridInqYval(gridID, 0));
- printf("grid.xinc %f\n", grid->xinc);
- printf("grid.yinc %f\n", grid->yinc);
- printf("grid.xinc %f\n", gridInqXinc(gridID));
- printf("grid.yinc %f\n", gridInqYinc(gridID));
- */
- if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
- {
- if ( grid->xdef == 2 && grid->ydef == 2 )
- {
- if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
- ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0) && IS_EQUAL(grid->yinc, 0)) &&
- IS_NOT_EQUAL(grid->xfirst, grid->xlast) && IS_NOT_EQUAL(grid->yfirst, grid->ylast) )
- {
- if ( IS_NOT_EQUAL(grid->xfirst, gridInqXval(gridID, 0)) ||
- IS_NOT_EQUAL(grid->yfirst, gridInqYval(gridID, 0)))
- {
- differ = true;
- }
- if ( !differ && fabs(grid->xinc) > 0 &&
- fabs(fabs(grid->xinc) - fabs(gridRef->xinc)) > fabs(grid->xinc/1000))
- {
- differ = true;
- }
- if ( !differ && fabs(grid->yinc) > 0 &&
- fabs(fabs(grid->yinc) - fabs(gridRef->yinc)) > fabs(grid->yinc/1000))
- {
- differ = true;
- }
- }
- }
- else if ( grid->xvals && grid->yvals )
- differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
- }
- else
- differ = true;
- }
- else if ( grid->type == GRID_GENERIC )
- {
- if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
- {
- if ( grid->xdef == 1 && grid->ydef == 1
- && grid->xvals && grid->yvals )
- differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
- }
- else if ( (grid->ysize == 0 || grid->ysize == 1) &&
- grid->xsize == gridRef->xsize*gridRef->ysize )
- {
- }
- else
- differ = true;
- }
- else if ( grid->type == GRID_GAUSSIAN )
- {
- if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
- {
- if ( grid->xdef == 2 && grid->ydef == 2 )
- {
- if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
- ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0)) )
- if ( fabs(grid->xfirst - gridInqXval(gridID, 0)) > 0.0015 ||
- fabs(grid->yfirst - gridInqYval(gridID, 0)) > 0.0015 ||
- (fabs(grid->xinc)>0 && fabs(fabs(grid->xinc) - fabs(gridRef->xinc)) > fabs(grid->xinc/1000)) )
- {
- differ = true;
- }
- }
- else if ( grid->xvals && grid->yvals )
- differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
- }
- else
- differ = true;
- }
- else if ( grid->type == GRID_CURVILINEAR )
- {
- /*
- printf("gridID %d\n", gridID);
- printf("grid.xsize %d\n", grid->xsize);
- printf("grid.ysize %d\n", grid->ysize);
- printf("grid.xfirst %f\n", grid->xvals[0]);
- printf("grid.yfirst %f\n", grid->yvals[0]);
- printf("grid xfirst %f\n", gridInqXval(gridID, 0));
- printf("grid yfirst %f\n", gridInqYval(gridID, 0));
- printf("grid.xlast %f\n", grid->xvals[grid->size-1]);
- printf("grid.ylast %f\n", grid->yvals[grid->size-1]);
- printf("grid xlast %f\n", gridInqXval(gridID, grid->size-1));
- printf("grid ylast %f\n", gridInqYval(gridID, grid->size-1));
- printf("grid.nv %d\n", grid->nvertex);
- printf("grid nv %d\n", gridInqNvertex(gridID));
- */
- if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
- differ = gridRef->vtable->compareXYAO(gridRef, (grid_t *)grid);
- }
- else if ( grid->type == GRID_UNSTRUCTURED )
- {
- /* FIXME: not octet 0 but octet 7 is guaranteed non-zero
- * for any non-NULL UUID */
- differ = differ || ( gridRef->uuid[0] && grid->uuid[0] && memcmp(gridRef->uuid, grid->uuid, CDI_UUID_SIZE) != 0 );
+/*
+ at Function gridDestroy
+ at Title Destroy a horizontal Grid
- if ( !differ &&
- ((grid->xvals == NULL) ^ (gridRef->xvals == NULL)) &&
- ((grid->yvals == NULL) ^ (gridRef->yvals == NULL)) )
- {
- int nvertexA, nvertexB, numberA, numberB;
- differ = ( (nvertexA = grid->nvertex)
- && (nvertexB = gridRef->nvertex)
- && (nvertexA != nvertexB) )
- || (numberA = grid->number, numberB = gridRef->number,
- ( (numberA)
- && numberB
- && (numberA != numberB) )
- || ( (numberA && numberB)
- && (grid->position) != (gridRef->position) ) );
- }
- else if ( !differ )
- {
- differ = grid->nvertex != gridRef->nvertex
- || grid->number != gridRef->number
- || (grid->number > 0 && grid->position != gridRef->position)
- || gridRef->vtable->compareXYAO(gridRef, (grid_t *)grid);
- }
- }
- }
- }
+ at Prototype void gridDestroy(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- return differ;
+ at EndFunction
+*/
+void gridDestroy(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->destroy(gridptr);
+}
+
+static
+void gridDestroyP(void * gridptr)
+{
+ ((grid_t *)gridptr)->vtable->destroy((grid_t *)gridptr);
}
-int gridCompareP ( void * gridptr1, void * gridptr2 )
+const char *gridNamePtr(int gridtype)
{
- grid_t * g1 = ( grid_t * ) gridptr1;
- grid_t * g2 = ( grid_t * ) gridptr2;
- enum { equal = 0,
- differ = -1 };
- int i, size;
+ int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
- xassert ( g1 );
- xassert ( g2 );
+ const char *name = (gridtype >= 0 && gridtype < size) ? Grids[gridtype] : Grids[GRID_GENERIC];
- if ( g1->type != g2->type ) return differ;
- if ( g1->prec != g2->prec ) return differ;
- if ( g1->lcc_projflag != g2->lcc_projflag ) return differ;
- if ( g1->lcc_scanflag != g2->lcc_scanflag ) return differ;
- if ( g1->lcc_defined != g2->lcc_defined ) return differ;
- if ( g1->lcc2_defined != g2->lcc2_defined ) return differ;
- if ( g1->laea_defined != g2->laea_defined ) return differ;
- if ( g1->isCyclic != g2->isCyclic ) return differ;
- if ( g1->isRotated != g2->isRotated ) return differ;
- if ( g1->xdef != g2->xdef ) return differ;
- if ( g1->ydef != g2->ydef ) return differ;
- if ( g1->nd != g2->nd ) return differ;
- if ( g1->ni != g2->ni ) return differ;
- if ( g1->ni2 != g2->ni2 ) return differ;
- if ( g1->ni3 != g2->ni3 ) return differ;
- if ( g1->number != g2->number ) return differ;
- if ( g1->position != g2->position ) return differ;
- if ( g1->trunc != g2->trunc ) return differ;
- if ( g1->nvertex != g2->nvertex ) return differ;
- if ( g1->nrowlon != g2->nrowlon ) return differ;
- if ( g1->size != g2->size ) return differ;
- if ( g1->xsize != g2->xsize ) return differ;
- if ( g1->ysize != g2->ysize ) return differ;
- if ( g1->lcomplex != g2->lcomplex ) return differ;
+ return name;
+}
- if ( IS_NOT_EQUAL(g1->xfirst , g2->xfirst) ) return differ;
- if ( IS_NOT_EQUAL(g1->yfirst , g2->yfirst) ) return differ;
- if ( IS_NOT_EQUAL(g1->xlast , g2->xlast) ) return differ;
- if ( IS_NOT_EQUAL(g1->ylast , g2->ylast) ) return differ;
- if ( IS_NOT_EQUAL(g1->xinc , g2->xinc) ) return differ;
- if ( IS_NOT_EQUAL(g1->yinc , g2->yinc) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_originLon , g2->lcc_originLon) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_originLat , g2->lcc_originLat) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_lonParY , g2->lcc_lonParY) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_lat1 , g2->lcc_lat1) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_lat2 , g2->lcc_lat2) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_xinc , g2->lcc_xinc) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc_yinc , g2->lcc_yinc) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc2_lon_0 , g2->lcc2_lon_0) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc2_lat_0 , g2->lcc2_lat_0) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc2_lat_1 , g2->lcc2_lat_1) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc2_lat_2 , g2->lcc2_lat_2) ) return differ;
- if ( IS_NOT_EQUAL(g1->lcc2_a , g2->lcc2_a) ) return differ;
- if ( IS_NOT_EQUAL(g1->laea_lon_0 , g2->laea_lon_0) ) return differ;
- if ( IS_NOT_EQUAL(g1->laea_lat_0 , g2->laea_lat_0) ) return differ;
- if ( IS_NOT_EQUAL(g1->laea_a , g2->laea_a) ) return differ;
- if ( IS_NOT_EQUAL(g1->xpole , g2->xpole) ) return differ;
- if ( IS_NOT_EQUAL(g1->ypole , g2->ypole) ) return differ;
- if ( IS_NOT_EQUAL(g1->angle , g2->angle) ) return differ;
- const double *restrict g1_xvals = g1->vtable->inqXValsPtr(g1),
- *restrict g2_xvals = g2->vtable->inqXValsPtr(g2);
- if ( g1_xvals )
- {
- if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
- size = g1->size;
- else
- size = g1->xsize;
- xassert ( size );
+void gridName(int gridtype, char *gridname)
+{
+ strcpy(gridname, gridNamePtr(gridtype));
+}
- if ( !g2_xvals ) return differ;
+static
+void *grid_key_to_ptr(grid_t *gridptr, int key)
+{
+ void *keyptr = NULL;
- for ( i = 0; i < size; i++ )
- if ( IS_NOT_EQUAL(g1_xvals[i], g2_xvals[i]) ) return differ;
+ switch (key)
+ {
+ case CDI_KEY_XNAME: keyptr = (void*)gridptr->x.name; break;
+ case CDI_KEY_XLONGNAME: keyptr = (void*)gridptr->x.longname; break;
+ case CDI_KEY_XUNITS: keyptr = (void*)gridptr->x.units; break;
+ case CDI_KEY_YNAME: keyptr = (void*)gridptr->y.name; break;
+ case CDI_KEY_YLONGNAME: keyptr = (void*)gridptr->y.longname; break;
+ case CDI_KEY_YUNITS: keyptr = (void*)gridptr->y.units; break;
+ case CDI_KEY_XDIMNAME: keyptr = (void*)gridptr->x.dimname; break;
+ case CDI_KEY_YDIMNAME: keyptr = (void*)gridptr->y.dimname; break;
+ case CDI_KEY_VDIMNAME: keyptr = (void*)gridptr->vdimname; break;
+ case CDI_KEY_MAPPING: keyptr = (void*)gridptr->mapname; break;
+ case CDI_KEY_MAPNAME: keyptr = (void*)gridptr->mapping; break;
}
- else if ( g2_xvals )
- return differ;
- const double *restrict g1_yvals = g1->vtable->inqYValsPtr(g1),
- *restrict g2_yvals = g2->vtable->inqYValsPtr(g2);
- if ( g1_yvals )
- {
- if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
- size = g1->size;
- else
- size = g1->ysize;
- xassert ( size );
+ return keyptr;
+}
- if ( !g2_yvals ) return differ;
+/*
+ at Function cdiGridDefKeyStr
+ at Title Define a CDI grid string value from a key
- for ( i = 0; i < size; i++ )
- if ( IS_NOT_EQUAL(g1_yvals[i], g2_yvals[i]) ) return differ;
- }
- else if ( g2_yvals )
- return differ;
+ at Prototype int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item key The key to be searched
+ @Item size The allocated length of the string on input
+ @Item mesg The address of a string where the data will be read
- const double *restrict g1_area = g1->vtable->inqAreaPtr(g1),
- *restrict g2_area = g2->vtable->inqAreaPtr(g2);
- if ( g1_area )
- {
- xassert ( g1->size );
+ at Description
+The function @func{cdiGridDefKeyStr} defines a CDI grid string value from a key.
- if ( !g2_area ) return differ;
+ at Result
+ at func{cdiGridDefKeyStr} returns 0 if OK and integer value on error.
- for ( i = 0; i < g1->size; i++ )
- if ( IS_NOT_EQUAL(g1_area[i], g2_area[i]) ) return differ;
+ at EndFunction
+*/
+int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg)
+{
+ if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
+
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ char *keyptr = (char*)grid_key_to_ptr(gridptr, key);
+ if ( keyptr == NULL )
+ {
+ Warning("CDI grid string key %d not supported!", key);
+ return -1;
}
- else if ( g2_area )
- return differ;
- {
- const double *restrict g1_xbounds, *restrict g2_xbounds;
- if ( (g1_xbounds = g1->vtable->inqXBoundsPtr(g1)) )
- {
- xassert ( g1->nvertex );
- if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
- size = g1->nvertex * g1->size;
- else
- size = g1->nvertex * g1->xsize;
- xassert ( size );
+ gridSetString(keyptr, mesg, (size_t)size);
+ gridMark4Update(gridID);
- if ( !(g2_xbounds = g2->vtable->inqXBoundsPtr(g2)) ) return differ;
+ return 0;
+}
- for ( i = 0; i < size; i++ )
- if ( IS_NOT_EQUAL(g1_xbounds[i], g2_xbounds[i]) ) return differ;
- }
- else if ( g2->vtable->inqXBoundsPtr(g2) )
- return differ;
- }
+/*
+ at Function cdiGridInqKeyStr
+ at Title Get a CDI grid string value from a key
- {
- const double *restrict g1_ybounds, *restrict g2_ybounds;
- if ( (g1_ybounds = g1->vtable->inqYBoundsPtr(g1)) )
- {
- xassert ( g1->nvertex );
- if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
- size = g1->nvertex * g1->size;
- else
- size = g1->nvertex * g1->ysize;
- xassert ( size );
+ at Prototype int cdiGridInqKeyStr(int gridID, int key, int size, char *mesg)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item key The key to be searched.
+ @Item size The allocated length of the string on input.
+ @Item mesg The address of a string where the data will be retrieved.
+ The caller must allocate space for the returned string.
+ The maximum possible length, in characters, of the string
+ is given by the predefined constant @func{CDI_MAX_NAME}.
- if ( ! (g2_ybounds = g2->vtable->inqYBoundsPtr(g2)) ) return differ;
+ at Description
+The function @func{cdiGridInqKeyStr} return a CDI grid string value from a key.
- for ( i = 0; i < size; i++ )
- if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
- }
- else if ( g2->vtable->inqYBoundsPtr(g2) )
- return differ;
- }
+ at Result
+ at func{cdiGridInqKeyStr} returns 0 if OK and integer value on error.
- if (strcmp(g1->xname, g2->xname)) return differ;
- if (strcmp(g1->yname, g2->yname)) return differ;
- if (strcmp(g1->xlongname, g2->xlongname)) return differ;
- if (strcmp(g1->ylongname, g2->ylongname)) return differ;
- if (g1->xstdname != g2->xstdname) return differ;
- if (g1->ystdname != g2->ystdname) return differ;
- if (strcmp(g1->xunits, g2->xunits)) return differ;
- if (strcmp(g1->yunits, g2->yunits)) return differ;
+ at EndFunction
+*/
+int cdiGridInqKeyStr(int gridID, int key, int size, char *mesg)
+{
+ if ( size < 1 || mesg == NULL ) return -1;
- if ( g1->reference )
+ grid_t *gridptr = grid_to_pointer(gridID);
+ const char *keyptr = (const char*)grid_key_to_ptr(gridptr, key);
+ if ( keyptr == NULL)
{
- if ( !g2->reference ) return differ;
- if ( strcmp(g1->reference, g2->reference) ) return differ;
+ Warning("CDI grid string key %d not supported!", key);
+ return -1;
}
- else if ( g2->reference )
- return differ;
- if ( g1->mask )
- {
- xassert ( g1->size );
- if ( !g2->mask ) return differ;
- if ( memcmp ( g1->mask, g2->mask, (size_t)g1->size * sizeof(mask_t)) ) return differ;
- }
- else if ( g2->mask )
- return differ;
+ gridGetString(mesg, keyptr, (size_t)size);
- if ( g1->mask_gme )
- {
- xassert ( g1->size );
- if ( !g2->mask_gme ) return differ;
- if ( memcmp ( g1->mask_gme, g2->mask_gme, (size_t)g1->size * sizeof(mask_t)) ) return differ;
- }
- else if ( g2->mask_gme )
- return differ;
+ return 0;
+}
- if (memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE))
- return differ;
+/*
+ at Function gridDefXname
+ at Title Define the name of a X-axis
- return equal;
+ at Prototype void gridDefXname(int gridID, const char *name)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item name Name of the X-axis.
+
+ at Description
+The function @func{gridDefXname} defines the name of a X-axis.
+
+ at EndFunction
+*/
+void gridDefXname(int gridID, const char *xname)
+{
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xname);
}
-static void gridComplete(grid_t *grid)
+/*
+ at Function gridDefXlongname
+ at Title Define the longname of a X-axis
+
+ at Prototype void gridDefXlongname(int gridID, const char *longname)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item longname Longname of the X-axis.
+
+ at Description
+The function @func{gridDefXlongname} defines the longname of a X-axis.
+
+ at EndFunction
+*/
+void gridDefXlongname(int gridID, const char *xlongname)
{
- int gridID = grid->self;
- gridDefPrec(gridID, grid->prec);
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, xlongname);
+}
- int gridtype = grid->type;
- switch (gridtype)
- {
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- case GRID_UNSTRUCTURED:
- case GRID_CURVILINEAR:
- case GRID_GENERIC:
- case GRID_LCC:
- case GRID_LCC2:
- case GRID_SINUSOIDAL:
- case GRID_LAEA:
- case GRID_PROJECTION:
- {
- if ( grid->xsize > 0 ) gridDefXsize(gridID, grid->xsize);
- if ( grid->ysize > 0 ) gridDefYsize(gridID, grid->ysize);
+/*
+ at Function gridDefXunits
+ at Title Define the units of a X-axis
- if ( gridtype == GRID_GAUSSIAN ) gridDefNP(gridID, grid->np);
+ at Prototype void gridDefXunits(int gridID, const char *units)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item units Units of the X-axis.
- if ( grid->nvertex > 0 )
- gridDefNvertex(gridID, grid->nvertex);
+ at Description
+The function @func{gridDefXunits} defines the units of a X-axis.
- if ( grid->xdef == 2 )
- {
- assert(gridtype != GRID_UNSTRUCTURED
- && gridtype != GRID_CURVILINEAR);
- double *xvals
- = (double *) Malloc((size_t)grid->xsize * sizeof (double));
- gridGenXvals(grid->xsize, grid->xfirst, grid->xlast, grid->xinc, xvals);
- grid->xvals = xvals;
- /*
- gridDefXinc(gridID, grid->xinc);
- */
- }
+ at EndFunction
+*/
+void gridDefXunits(int gridID, const char *xunits)
+{
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, xunits);
+}
- if ( grid->ydef == 2 )
- {
- assert(gridtype != GRID_UNSTRUCTURED
- && gridtype != GRID_CURVILINEAR);
- double *yvals
- = (double *) Malloc((size_t)grid->ysize * sizeof (double));
- gridGenYvals(gridtype, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
- grid->yvals = yvals;
- /*
- gridDefYinc(gridID, grid->yinc);
- */
- }
+/*
+ at Function gridDefYname
+ at Title Define the name of a Y-axis
- if ( grid->isRotated )
- {
- gridDefXname(gridID, "rlon");
- gridDefYname(gridID, "rlat");
- gridDefXlongname(gridID, "longitude in rotated pole grid");
- gridDefYlongname(gridID, "latitude in rotated pole grid");
- grid->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
- grid->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
- gridDefXunits(gridID, "degrees");
- gridDefYunits(gridID, "degrees");
-
- gridDefXpole(gridID, grid->xpole);
- gridDefYpole(gridID, grid->ypole);
- gridDefAngle(gridID, grid->angle);
- }
+ at Prototype void gridDefYname(int gridID, const char *name)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item name Name of the Y-axis.
- switch (gridtype)
- {
- case GRID_LAEA:
- gridDefLaea(gridID, grid->laea_a, grid->laea_lon_0, grid->laea_lat_0);
- break;
- case GRID_LCC2:
- gridDefLcc2(gridID, grid->lcc2_a, grid->lcc2_lon_0, grid->lcc2_lat_0, grid->lcc2_lat_1, grid->lcc2_lat_2);
- break;
- case GRID_LCC:
- gridDefLCC(gridID, grid->lcc_originLon, grid->lcc_originLat, grid->lcc_lonParY,
- grid->lcc_lat1, grid->lcc_lat2, grid->lcc_xinc, grid->lcc_yinc,
- grid->lcc_projflag, grid->lcc_scanflag);
- break;
- case GRID_UNSTRUCTURED:
- {
- int number = grid->number;
- int position = grid->position >= 0 ? grid->position : 0;
- if ( number > 0 )
- {
- gridDefNumber(gridID, number);
- gridDefPosition(gridID, position);
- }
- }
- break;
- }
+ at Description
+The function @func{gridDefYname} defines the name of a Y-axis.
- break;
- }
- case GRID_GAUSSIAN_REDUCED:
- {
- gridDefNP(gridID, grid->np);
- gridDefYsize(gridID, grid->ysize);
- if ( grid->xdef == 2 )
- {
- double xvals[2] = { grid->xfirst, grid->xlast };
- gridDefXvals(gridID, xvals);
- }
+ at EndFunction
+*/
+void gridDefYname(int gridID, const char *yname)
+{
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, yname);
+}
- if ( grid->ydef == 2 )
- {
- double *yvals
- = (double *) Malloc((size_t)grid->ysize * sizeof (double));
- gridGenYvals(gridtype, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
- grid->yvals = yvals;
- /*
- gridDefYinc(gridID, grid->yinc);
- */
- }
- break;
- }
- case GRID_SPECTRAL:
- {
- gridDefTrunc(gridID, grid->trunc);
- if ( grid->lcomplex ) gridDefComplexPacking(gridID, 1);
- break;
- }
- case GRID_FOURIER:
- {
- gridDefTrunc(gridID, grid->trunc);
- break;
- }
- case GRID_GME:
- {
- gridDefGMEnd(gridID, grid->nd);
- gridDefGMEni(gridID, grid->ni);
- gridDefGMEni2(gridID, grid->ni2);
- gridDefGMEni3(gridID, grid->ni3);
- break;
- }
- /*
- case GRID_GENERIC:
- {
- if ( grid->xsize > 0 && grid->ysize > 0 )
- {
- gridDefXsize(gridID, grid->xsize);
- gridDefYsize(gridID, grid->ysize);
- if ( grid->xvals ) gridDefXvals(gridID, grid->xvals);
- if ( grid->yvals ) gridDefYvals(gridID, grid->yvals);
- }
- break;
- }
- */
- case GRID_TRAJECTORY:
- {
- gridDefXsize(gridID, 1);
- gridDefYsize(gridID, 1);
- break;
- }
- default:
- {
- Error("Gridtype %s unsupported!", gridNamePtr(gridtype));
- break;
- }
- }
+/*
+ at Function gridDefYlongname
+ at Title Define the longname of a Y-axis
+
+ at Prototype void gridDefYlongname(int gridID, const char *longname)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item longname Longname of the Y-axis.
- grid->xname[CDI_MAX_NAME - 1] = 0;
- grid->xlongname[CDI_MAX_NAME - 1] = 0;
- grid->xunits[CDI_MAX_NAME - 1] = 0;
- grid->yname[CDI_MAX_NAME - 1] = 0;
- grid->ylongname[CDI_MAX_NAME - 1] = 0;
- grid->yunits[CDI_MAX_NAME - 1] = 0;
+ at Description
+The function @func{gridDefYlongname} defines the longname of a Y-axis.
+
+ at EndFunction
+*/
+void gridDefYlongname(int gridID, const char *ylongname)
+{
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, ylongname);
}
-#define GRID_STR_SERIALIZE(gridP) { gridP->xdimname, gridP->ydimname, \
- gridP->vdimname, gridP->xname, gridP->yname, \
- gridP->xlongname, gridP->ylongname, \
- gridP->xunits, gridP->yunits }
+/*
+ at Function gridDefYunits
+ at Title Define the units of a Y-axis
-int gridGenerate(const grid_t *grid)
+ at Prototype void gridDefYunits(int gridID, const char *units)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item units Units of the Y-axis.
+
+ at Description
+The function @func{gridDefYunits} defines the units of a Y-axis.
+
+ at EndFunction
+*/
+void gridDefYunits(int gridID, const char *yunits)
{
- int gridtype = grid->type;
- int gridID = gridCreate(gridtype, grid->size);
- grid_t *restrict gridptr = gridID2Ptr(gridID);
- gridptr->prec = grid->prec;
- gridptr->xsize = grid->xsize;
- gridptr->ysize = grid->ysize;
- gridptr->np = grid->np;
- gridptr->nvertex = grid->nvertex;
- gridptr->xdef = grid->xdef;
- int valdef_group1 = 0;
- static const int valdef_group1_tab[] = {
- GRID_LONLAT, GRID_GAUSSIAN, GRID_UNSTRUCTURED, GRID_CURVILINEAR,
- GRID_GENERIC, GRID_LCC, GRID_LCC2, GRID_SINUSOIDAL, GRID_LAEA,
- GRID_PROJECTION
- };
- for ( size_t i = 0; i < sizeof (valdef_group1_tab) / sizeof (valdef_group1_tab[0]); ++i)
- valdef_group1 |= (gridtype == valdef_group1_tab[i]);
- if ( valdef_group1 && grid->xdef == 1 )
- {
- gridDefXvals(gridID, grid->xvals);
- if ( grid->xbounds )
- gridDefXbounds(gridID, grid->xbounds);
- }
- gridptr->xfirst = grid->xfirst;
- gridptr->xlast = grid->xlast;
- gridptr->xinc = grid->xinc;
- gridptr->ydef = grid->ydef;
- if ( (valdef_group1 || gridtype == GRID_GAUSSIAN_REDUCED) && grid->ydef == 1)
- {
- gridDefYvals(gridID, grid->yvals);
- if ( grid->ybounds )
- gridDefYbounds(gridID, grid->ybounds);
- }
- gridptr->yfirst = grid->yfirst;
- gridptr->ylast = grid->ylast;
- gridptr->yinc = grid->yinc;
- gridptr->isRotated = grid->isRotated;
- gridptr->xpole = grid->xpole;
- gridptr->ypole = grid->ypole;
- gridptr->angle = grid->angle;
- if ( valdef_group1 && grid->area)
- gridDefArea(gridID, grid->area);
- gridptr->laea_a = grid->laea_a;
- gridptr->laea_lon_0 = grid->laea_lon_0;
- gridptr->laea_lat_0 = grid->laea_lat_0;
- gridptr->lcc2_a = grid->lcc2_a;
- gridptr->lcc2_lon_0 = grid->lcc2_lon_0;
- gridptr->lcc2_lat_0 = grid->lcc2_lat_0;
- gridptr->lcc2_lat_1 = grid->lcc2_lat_1;
- gridptr->lcc2_lat_2 = grid->lcc2_lat_2;
- gridptr->lcc_originLon = grid->lcc_originLon;
- gridptr->lcc_originLat = grid->lcc_originLat;
- gridptr->lcc_lonParY = grid->lcc_lonParY;
- gridptr->lcc_lat1 = grid->lcc_lat1;
- gridptr->lcc_lat2 = grid->lcc_lat2;
- gridptr->lcc_xinc = grid->lcc_xinc;
- gridptr->lcc_yinc = grid->lcc_yinc;
- gridptr->lcc_projflag = grid->lcc_projflag;
- gridptr->lcc_scanflag = grid->lcc_scanflag;
- gridptr->number = grid->number;
- gridptr->position = grid->position;
- memcpy(gridptr->uuid, grid->uuid, CDI_UUID_SIZE);
- if ( gridtype == GRID_UNSTRUCTURED && grid->reference )
- gridDefReference(gridID, grid->reference);
- if ( gridtype == GRID_PROJECTION )
- gridptr->name = strdup(grid->name);
- if ( gridtype == GRID_GAUSSIAN_REDUCED )
- gridDefRowlon(gridID, grid->ysize, grid->rowlon);
- gridptr->trunc = grid->trunc;
- gridptr->lcomplex = grid->lcomplex;
- gridptr->nd = grid->nd;
- gridptr->ni = grid->ni;
- gridptr->ni2 = grid->ni2;
- gridptr->ni3 = grid->ni3;
- const char *grid_str_tab[] = GRID_STR_SERIALIZE(grid);
- char *gridptr_str_tab[] = GRID_STR_SERIALIZE(gridptr);
- for (size_t i = 0; i < sizeof (grid_str_tab) / sizeof (grid_str_tab[0]); ++i)
- if ( grid_str_tab[i][0] )
- memcpy(gridptr_str_tab[i], grid_str_tab[i], CDI_MAX_NAME);
- gridComplete(gridptr);
- return gridID;
+ (void)cdiGridDefKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, yunits);
}
-static void
-grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
+/*
+ at Function gridInqXname
+ at Title Get the name of a X-axis
+
+ at Prototype void gridInqXname(int gridID, char *name)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item name Name of the X-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{gridInqXname} returns the name of a X-axis.
+
+ at Result
+ at func{gridInqXname} returns the name of the X-axis to the parameter name.
+
+ at EndFunction
+*/
+void gridInqXname(int gridID, char *xname)
{
- size_t nrowlon = (size_t)gridptrOrig->nrowlon;
- size_t gridsize = (size_t)gridptrOrig->size;
- int gridtype = gridptrOrig->type;
- int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
- if ( nrowlon )
- {
- gridptrDup->rowlon = (int*) Malloc(nrowlon * sizeof(int));
- memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
- }
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xname);
+}
- if ( gridptrOrig->xvals != NULL )
- {
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->xsize;
+/*
+ at Function gridInqXlongname
+ at Title Get the longname of a X-axis
- gridptrDup->xvals = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->xvals, gridptrOrig->xvals, size * sizeof (double));
- }
+ at Prototype void gridInqXlongname(int gridID, char *longname)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item longname Longname of the X-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
- if ( gridptrOrig->yvals != NULL )
- {
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->ysize;
+ at Description
+The function @func{gridInqXlongname} returns the longname of a X-axis.
- gridptrDup->yvals = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->yvals, gridptrOrig->yvals, size * sizeof (double));
- }
+ at Result
+ at func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
- if ( gridptrOrig->xbounds != NULL )
- {
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->xsize)
- * (size_t)gridptrOrig->nvertex;
+ at EndFunction
+*/
+void gridInqXlongname(int gridID, char *xlongname)
+{
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, xlongname);
+}
- gridptrDup->xbounds = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->xbounds, gridptrOrig->xbounds, size * sizeof (double));
- }
+/*
+ at Function gridInqXunits
+ at Title Get the units of a X-axis
- if ( gridptrOrig->ybounds != NULL )
- {
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->ysize)
- * (size_t)gridptrOrig->nvertex;
+ at Prototype void gridInqXunits(int gridID, char *units)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item units Units of the X-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
- gridptrDup->ybounds = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->ybounds, gridptrOrig->ybounds, size * sizeof (double));
- }
+ at Description
+The function @func{gridInqXunits} returns the units of a X-axis.
- {
- const double *gridptrOrig_area
- = gridptrOrig->vtable->inqAreaPtr(gridptrOrig);
- if ( gridptrOrig_area != NULL )
- {
- size_t size = gridsize;
+ at Result
+ at func{gridInqXunits} returns the units of the X-axis to the parameter units.
- gridptrDup->area = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->area, gridptrOrig_area, size * sizeof (double));
- }
- }
+ at EndFunction
+*/
+void gridInqXunits(int gridID, char *xunits)
+{
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, xunits);
+}
- if ( gridptrOrig->mask != NULL )
- {
- size_t size = gridsize;
- gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
- memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
+void gridInqXstdname(int gridID, char *xstdname)
+{
+ if ( xstdname )
+ {
+ xstdname[0] = 0;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ if ( gridptr->x.stdname ) strcpy(xstdname, gridptr->x.stdname);
}
+}
- if ( gridptrOrig->mask_gme != NULL )
- {
- size_t size = gridsize;
+/*
+ at Function gridInqYname
+ at Title Get the name of a Y-axis
- gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
- memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
- }
+ at Prototype void gridInqYname(int gridID, char *name)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item name Name of the Y-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{gridInqYname} returns the name of a Y-axis.
+
+ at Result
+ at func{gridInqYname} returns the name of the Y-axis to the parameter name.
+
+ at EndFunction
+*/
+void gridInqYname(int gridID, char *yname)
+{
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, yname);
+}
+
+/*
+ at Function gridInqYlongname
+ at Title Get the longname of a Y-axis
+
+ at Prototype void gridInqYlongname(int gridID, char *longname)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item longname Longname of the Y-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{gridInqYlongname} returns the longname of a Y-axis.
+
+ at Result
+ at func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
+
+ at EndFunction
+*/
+void gridInqYlongname(int gridID, char *ylongname)
+{
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, ylongname);
}
-
/*
- at Function gridDuplicate
- at Title Duplicate a horizontal Grid
+ at Function gridInqYunits
+ at Title Get the units of a Y-axis
- at Prototype int gridDuplicate(int gridID)
+ at Prototype void gridInqYunits(int gridID, char *units)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item units Units of the Y-axis. The caller must allocate space for the
+ returned string. The maximum possible length, in characters, of
+ the string is given by the predefined constant @func{CDI_MAX_NAME}.
@Description
-The function @func{gridDuplicate} duplicates a horizontal Grid.
+The function @func{gridInqYunits} returns the units of a Y-axis.
@Result
- at func{gridDuplicate} returns an identifier to the duplicated Grid.
+ at func{gridInqYunits} returns the units of the Y-axis to the parameter units.
@EndFunction
*/
-int gridDuplicate(int gridID)
+void gridInqYunits(int gridID, char *yunits)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- grid_t *gridptrnew = gridptr->vtable->copy(gridptr);
- int gridIDnew = reshPut(gridptrnew, &gridOps);
- gridptrnew->self = gridIDnew;
- return gridIDnew;
+ (void)cdiGridInqKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, yunits);
}
-void gridCompress(int gridID)
+void gridInqYstdname(int gridID, char *ystdname)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- int gridtype = gridInqType(gridID);
- if ( gridtype == GRID_UNSTRUCTURED )
+ if ( ystdname )
{
- if ( gridptr->mask_gme != NULL )
- {
- size_t gridsize = (size_t)gridInqSize(gridID);
- size_t nv = (size_t)gridptr->nvertex;
- double *restrict area
- = (double *)gridptr->vtable->inqAreaPtr(gridptr),
- *restrict xvals = (double *)gridptr->vtable->inqXValsPtr((grid_t *)gridptr),
- *restrict yvals = (double *)gridptr->vtable->inqYValsPtr((grid_t *)gridptr),
- *restrict xbounds = (double *)gridptr->vtable->inqXBoundsPtr(gridptr),
- *restrict ybounds = (double *)gridptr->vtable->inqYBoundsPtr(gridptr);
- mask_t *restrict mask_gme = gridptr->mask_gme;
- size_t *restrict selection = (size_t *)Malloc(gridsize * sizeof (selection[0]));
- size_t nselect;
- {
- size_t j = 0;
- for (size_t i = 0; i < gridsize; i++ )
- selection[j] = i, j += (mask_gme[i] != 0);
- nselect = j;
- }
- selection = (size_t *)Realloc(selection, nselect * sizeof (selection[0]));
- if (xvals)
- for (size_t i = 0; i < nselect; i++ )
- xvals[i] = xvals[selection[i]];
- if (yvals)
- for (size_t i = 0; i < nselect; i++ )
- yvals[i] = yvals[selection[i]];
- if (area)
- for (size_t i = 0; i < nselect; i++ )
- area[i] = area[selection[i]];
- if (xbounds)
- for (size_t i = 0; i < nselect; i++ )
- for (size_t iv = 0; iv < nv; iv++)
- xbounds[i * nv + iv] = xbounds[selection[i] * nv + iv];
- if (ybounds)
- for (size_t i = 0; i < nselect; i++ )
- for (size_t iv = 0; iv < nv; iv++)
- ybounds[i * nv + iv] = ybounds[selection[i] * nv + iv];
- Free(selection);
+ ystdname[0] = 0;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ if ( gridptr->y.stdname ) strcpy(ystdname, gridptr->y.stdname);
+ }
+}
- /* fprintf(stderr, "grid compress %d %d %d\n", i, j, gridsize); */
- gridsize = nselect;
- gridptr->size = (int)gridsize;
- gridptr->xsize = (int)gridsize;
- gridptr->ysize = (int)gridsize;
- double **resizeP[] = { &gridptr->xvals, &gridptr->yvals,
- &gridptr->area,
- &gridptr->xbounds, &gridptr->ybounds };
- size_t newSize[] = { gridsize, gridsize, gridsize, nv*gridsize,
- nv*gridsize };
- for ( size_t i = 0; i < sizeof (resizeP) / sizeof (resizeP[0]); ++i)
- if ( *(resizeP[i]) )
- *(resizeP[i]) = (double *)Realloc(*(resizeP[i]), newSize[i]*sizeof(double));
+void gridDefProj(int gridID, int projID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->proj = projID;
- Free(gridptr->mask_gme);
- gridptr->mask_gme = NULL;
- gridMark4Update(gridID);
- }
+ if ( gridptr->type == GRID_CURVILINEAR )
+ {
+ grid_t *projptr = grid_to_pointer(projID);
+ if ( projptr->x.name[0] ) strcpy(gridptr->x.dimname, projptr->x.name);
+ if ( projptr->y.name[0] ) strcpy(gridptr->y.dimname, projptr->y.name);
}
- else
- Warning("Unsupported grid type: %s", gridNamePtr(gridtype));
}
-static void
-gridDefAreaSerial(grid_t *gridptr, const double *area)
+
+int gridInqProj(int gridID)
{
- size_t size = (size_t)gridptr->size;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->proj;
+}
- if ( size == 0 )
- Error("size undefined for gridID = %d", gridptr->self);
- if ( gridptr->area == NULL )
- gridptr->area = (double *) Malloc(size*sizeof(double));
- else if ( CDI_Debug )
- Warning("values already defined!");
+int gridInqProjType(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
- memcpy(gridptr->area, area, size * sizeof(double));
-}
+ int projtype = gridptr->projtype;
+ if ( projtype == -1 )
+ {
+ char mapping[CDI_MAX_NAME]; mapping[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+ if ( mapping[0] )
+ {
+ if ( strcmp(mapping, "rotated_latitude_longitude") == 0 ) projtype = CDI_PROJ_RLL;
+ else if ( strcmp(mapping, "lambert_azimuthal_equal_area") == 0 ) projtype = CDI_PROJ_LAEA;
+ else if ( strcmp(mapping, "lambert_conformal_conic") == 0 ) projtype = CDI_PROJ_LCC;
+ else if ( strcmp(mapping, "sinusoidal") == 0 ) projtype = CDI_PROJ_SINU;
-void gridDefArea(int gridID, const double *area)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defArea(gridptr, area);
- gridMark4Update(gridID);
-}
+ gridptr->projtype = projtype;
+ }
+ }
-static void
-gridInqAreaSerial(grid_t *gridptr, double *area)
-{
- if (gridptr->area)
- memcpy(area, gridptr->area, (size_t)gridptr->size * sizeof (double));
+ return projtype;
}
-void gridInqArea(int gridID, double *area)
+void gridVerifyProj(int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->inqArea(gridptr, area);
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
-static int
-gridHasAreaBase(grid_t *gridptr)
-{
- return gridptr->area != NULL;
-}
+ int projtype = gridInqProjType(gridID);
-int gridHasArea(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->hasArea(gridptr);
+ if ( projtype == CDI_PROJ_RLL )
+ {
+ gridptr->x.stdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+ gridptr->y.stdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+ gridSetName(gridptr->x.units, "degrees");
+ gridSetName(gridptr->y.units, "degrees");
+ }
+ else if ( projtype == CDI_PROJ_LCC )
+ {
+ gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
+ gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
+ if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "m");
+ if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "m");
+ }
}
+/*
+ at Function gridInqType
+ at Title Get the type of a Grid
-static const double *gridInqAreaPtrBase(grid_t *gridptr)
-{
- return gridptr->area;
-}
+ at Prototype int gridInqType(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-const double *gridInqAreaPtr(int gridID)
+ at Description
+The function @func{gridInqType} returns the type of a Grid.
+
+ at Result
+ at func{gridInqType} returns the type of the grid,
+one of the set of predefined CDI grid types.
+The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
+ at func{GRID_LONLAT}, @func{GRID_PROJECTION}, @func{GRID_SPECTRAL}, @func{GRID_GME},
+ at func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
+
+ at EndFunction
+*/
+int gridInqType(int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqAreaPtr(gridptr);
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ return gridptr->type;
}
-void gridDefNvertex(int gridID, int nvertex)
+/*
+ at Function gridInqSize
+ at Title Get the size of a Grid
+
+ at Prototype size_t gridInqSize(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+
+ at Description
+The function @func{gridInqSize} returns the size of a Grid.
+
+ at Result
+ at func{gridInqSize} returns the number of grid points of a Grid.
+
+ at EndFunction
+*/
+size_t gridInqSize(int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
- if (gridptr->nvertex != nvertex)
+ size_t size = gridptr->size;
+
+ if ( size == 0 )
{
- gridptr->nvertex = nvertex;
- gridMark4Update(gridID);
+ size_t xsize = gridptr->x.size;
+ size_t ysize = gridptr->y.size;
+
+ size = ysize ? xsize * ysize : xsize;
+
+ gridptr->size = size;
}
-}
+ return size;
+}
-int gridInqNvertex(int gridID)
+static
+int nsp2trunc(int nsp)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- return gridptr->nvertex;
+ /* nsp = (trunc+1)*(trunc+1) */
+ /* => trunc^2 + 3*trunc - (x-2) = 0 */
+ /* */
+ /* with: y^2 + p*y + q = 0 */
+ /* y = -p/2 +- sqrt((p/2)^2 - q) */
+ /* p = 3 and q = - (x-2) */
+ int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
+ return trunc;
}
-static void
-gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, int regularSize,
- double **field)
+
+int gridInqTrunc(int gridID)
{
- int irregular = gridptr->type == GRID_CURVILINEAR
- || gridptr->type == GRID_UNSTRUCTURED;
- size_t nvertex = (size_t)gridptr->nvertex;
- if ( nvertex == 0 )
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->trunc == 0 )
{
- Warning("nvertex undefined for gridID = %d. Cannot define bounds!",
- gridptr->self);
- return;
+ if ( gridptr->type == GRID_SPECTRAL )
+ gridptr->trunc = nsp2trunc(gridptr->size);
+ /*
+ else if ( gridptr->type == GRID_GAUSSIAN )
+ gridptr->trunc = nlat2trunc(gridptr->y.size);
+ */
}
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : regularSize);
- if ( size == 0 )
- Error("size undefined for gridID = %d", gridptr->self);
- if (*field == NULL)
- *field = (double *)Malloc(size * sizeof (double));
- else if ( CDI_Debug )
- Warning("values already defined!");
-
- memcpy(*field, bounds, size * sizeof (double));
+ return gridptr->trunc;
}
-static void
-gridDefXBoundsSerial(grid_t *gridptr, const double *xbounds)
+void gridDefTrunc(int gridID, int trunc)
{
- gridDefBoundsGeneric(gridptr, xbounds, gridptr->xsize, &gridptr->xbounds);
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->trunc != trunc )
+ {
+ gridMark4Update(gridID);
+ gridptr->trunc = trunc;
+ }
}
/*
- at Function gridDefXbounds
- at Title Define the bounds of a X-axis
+ at Function gridDefXsize
+ at Title Define the number of values of a X-axis
- at Prototype void gridDefXbounds(int gridID, const double *xbounds)
+ at Prototype void gridDefXsize(int gridID, size_t xsize)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item xbounds X-bounds of the grid.
+ @Item xsize Number of values of a X-axis.
@Description
-The function @func{gridDefXbounds} defines all bounds of the X-axis.
+The function @func{gridDefXsize} defines the number of values of a X-axis.
@EndFunction
*/
-void gridDefXbounds(int gridID, const double *xbounds)
+void gridDefXsize(int gridID, size_t xsize)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defXBounds(gridptr, xbounds);
- gridMark4Update(gridID);
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
-static int
-gridInqXBoundsSerial(grid_t *gridptr, double *xbounds)
-{
- size_t nvertex = (size_t)gridptr->nvertex;
+ size_t gridSize = gridInqSize(gridID);
+ if ( xsize > gridSize )
+ Error("xsize %zu is greater then gridsize %zu", xsize, gridSize);
- int irregular = gridptr->type == GRID_CURVILINEAR
- || gridptr->type == GRID_UNSTRUCTURED;
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->xsize);
+ int gridType = gridInqType(gridID);
+ if ( gridType == GRID_UNSTRUCTURED && xsize != gridSize )
+ Error("xsize %zu must be equal to gridsize %zu for gridtype: UNSTRUCTURED", xsize, gridSize);
- const double *gridptr_xbounds = gridptr->vtable->inqXBoundsPtr(gridptr);
- if ( gridptr_xbounds )
+ if ( gridptr->x.size != xsize )
{
- if ( size && xbounds )
- memcpy(xbounds, gridptr_xbounds, size * sizeof (double));
+ gridMark4Update(gridID);
+ gridptr->x.size = xsize;
}
- else
- size = 0;
- return (int)size;
+ if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
+ {
+ size_t axisproduct = gridptr->x.size*gridptr->y.size;
+ if ( axisproduct > 0 && axisproduct != gridSize )
+ Error("Inconsistent grid declaration! (xsize=%zu ysize=%zu gridsize=%zu)",
+ gridptr->x.size, gridptr->y.size, gridSize);
+ }
}
/*
- at Function gridInqXbounds
- at Title Get the bounds of a X-axis
+ at Function
+ at Title
- at Prototype int gridInqXbounds(int gridID, double *xbounds)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item xbounds Pointer to the location into which the X-bounds are read.
- The caller must allocate space for the returned values.
-
- at Description
-The function @func{gridInqXbounds} returns the bounds of the X-axis.
-
- at Result
-Upon successful completion @func{gridInqXbounds} returns the number of bounds and
-the bounds are stored in @func{xbounds}.
-Otherwise, 0 is returned and @func{xbounds} is empty.
+ @Item Grid identifier
@EndFunction
*/
-int gridInqXbounds(int gridID, double *xbounds)
+void gridDefDatatype(int gridID, int datatype)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqXBounds(gridptr, xbounds);
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
-static const double *
-gridInqXBoundsPtrSerial(grid_t *gridptr)
-{
- return gridptr->xbounds;
+ if ( gridptr->datatype != datatype )
+ {
+ gridMark4Update(gridID);
+ gridptr->datatype = datatype;
+ }
}
+/*
+ at Function
+ at Title
-const double *gridInqXboundsPtr(int gridID)
+ at Prototype
+ at Parameter
+ @Item Grid identifier
+
+ at EndFunction
+*/
+int gridInqDatatype(int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqXBoundsPtr(gridptr);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->datatype;
}
-static void
-gridDefYBoundsSerial(grid_t *gridptr, const double *ybounds)
+/*
+ at Function gridInqXsize
+ at Title Get the number of values of a X-axis
+
+ at Prototype size_t gridInqXsize(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+
+ at Description
+The function @func{gridInqXsize} returns the number of values of a X-axis.
+
+ at Result
+ at func{gridInqXsize} returns the number of values of a X-axis.
+
+ at EndFunction
+*/
+size_t gridInqXsize(int gridID)
{
- gridDefBoundsGeneric(gridptr, ybounds, gridptr->ysize, &gridptr->ybounds);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->x.size;
}
/*
- at Function gridDefYbounds
- at Title Define the bounds of a Y-axis
+ at Function gridDefYsize
+ at Title Define the number of values of a Y-axis
- at Prototype void gridDefYbounds(int gridID, const double *ybounds)
+ at Prototype void gridDefYsize(int gridID, size_t ysize)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item ybounds Y-bounds of the grid.
+ @Item ysize Number of values of a Y-axis.
@Description
-The function @func{gridDefYbounds} defines all bounds of the Y-axis.
+The function @func{gridDefYsize} defines the number of values of a Y-axis.
@EndFunction
*/
-void gridDefYbounds(int gridID, const double *ybounds)
+void gridDefYsize(int gridID, size_t ysize)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- gridptr->vtable->defYBounds(gridptr, ybounds);
- gridMark4Update(gridID);
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
-static int
-gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
-{
- size_t nvertex = (size_t)gridptr->nvertex;
+ size_t gridSize = gridInqSize(gridID);
- int irregular = gridptr->type == GRID_CURVILINEAR
- || gridptr->type == GRID_UNSTRUCTURED;
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
+ if ( ysize > gridSize )
+ Error("ysize %zu is greater then gridsize %zu", ysize, gridSize);
- const double *gridptr_ybounds = gridptr->vtable->inqYBoundsPtr(gridptr);
- if ( gridptr_ybounds )
+ int gridType = gridInqType(gridID);
+ if ( gridType == GRID_UNSTRUCTURED && ysize != gridSize )
+ Error("ysize %zu must be equal gridsize %zu for gridtype: UNSTRUCTURED", ysize, gridSize);
+
+ if ( gridptr->y.size != ysize )
{
- if ( size && ybounds )
- memcpy(ybounds, gridptr_ybounds, size * sizeof (double));
+ gridMark4Update(gridID);
+ gridptr->y.size = ysize;
}
- else
- size = 0;
- return (int)size;
+ if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
+ {
+ size_t axisproduct = gridptr->x.size*gridptr->y.size;
+ if ( axisproduct > 0 && axisproduct != gridSize )
+ Error("Inconsistent grid declaration! (xsize=%zu ysize=%zu gridsize=%zu)",
+ gridptr->x.size, gridptr->y.size, gridSize);
+ }
}
-
/*
- at Function gridInqYbounds
- at Title Get the bounds of a Y-axis
+ at Function gridInqYsize
+ at Title Get the number of values of a Y-axis
- at Prototype int gridInqYbounds(int gridID, double *ybounds)
+ at Prototype size_t gridInqYsize(int gridID)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item ybounds Pointer to the location into which the Y-bounds are read.
- The caller must allocate space for the returned values.
@Description
-The function @func{gridInqYbounds} returns the bounds of the Y-axis.
+The function @func{gridInqYsize} returns the number of values of a Y-axis.
@Result
-Upon successful completion @func{gridInqYbounds} returns the number of bounds and
-the bounds are stored in @func{ybounds}.
-Otherwise, 0 is returned and @func{ybounds} is empty.
+ at func{gridInqYsize} returns the number of values of a Y-axis.
@EndFunction
*/
-int gridInqYbounds(int gridID, double *ybounds)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqYBounds(gridptr, ybounds);
-}
-
-static const double *
-gridInqYBoundsPtrSerial(grid_t *gridptr)
+size_t gridInqYsize(int gridID)
{
- return gridptr->ybounds;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->y.size;
}
+/*
+ at Function gridDefNP
+ at Title Define the number of parallels between a pole and the equator
-const double *gridInqYboundsPtr(int gridID)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqYBoundsPtr(gridptr);
-}
-
-static void
-printDblsPrefixAutoBrk(FILE *fp, int dig, const char prefix[], size_t nbyte0,
- size_t n, const double vals[])
-{
- fputs(prefix, fp);
- size_t nbyte = nbyte0;
- for ( size_t i = 0; i < n; i++ )
- {
- if ( nbyte > 80 )
- {
- fprintf(fp, "\n%*s", (int)nbyte0, "");
- nbyte = nbyte0;
- }
- nbyte += (size_t)fprintf(fp, "%.*g ", dig, vals[i]);
- }
- fputs("\n", fp);
-}
+ at Prototype void gridDefNP(int gridID, int np)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item np Number of parallels between a pole and the equator.
-static void
-printIntsPrefixAutoBrk(FILE *fp, const char prefix[], size_t nbyte0,
- size_t n, const int vals[])
-{
- fputs(prefix, fp);
- size_t nbyte = nbyte0;
- for ( size_t i = 0; i < n; i++ )
- {
- if ( nbyte > 80 )
- {
- fprintf(fp, "\n%*s", (int)nbyte0, "");
- nbyte = nbyte0;
- }
- nbyte += (size_t)fprintf(fp, "%d ", vals[i]);
- }
- fputs("\n", fp);
-}
+ at Description
+The function @func{gridDefNP} defines the number of parallels between a pole and the equator
+of a Gaussian grid.
-static void
-printBounds(FILE *fp, int dig, const char prefix[], size_t nbyte0,
- size_t n, size_t nvertex, const double bounds[])
+ at EndFunction
+*/
+void gridDefNP(int gridID, int np)
{
- fputs(prefix, fp);
- if ( n > 0 )
- {
- for ( size_t iv = 0; iv < nvertex; iv++ )
- fprintf(fp, "%.*g ", dig, bounds[iv]);
- for ( size_t i = 1; i < (size_t)n; i++ )
- {
- fprintf(fp, "\n%*s", (int)nbyte0, "");
- for ( size_t iv = 0; iv < nvertex; iv++ )
- fprintf(fp, "%.*g ", dig, bounds[i*nvertex+iv]);
- }
- fputs("\n", fp);
- }
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
-static void
-printMask(FILE *fp, const char prefix[], size_t nbyte0,
- size_t n, const mask_t mask[])
-{
- fputs(prefix, fp);
- size_t nbyte = nbyte0;
- for ( size_t i = 0; i < n; i++ )
+ if ( gridptr->np != np )
{
- if ( nbyte > 80 )
- {
- fprintf(fp, "\n%*s", (int)nbyte0, "");
- nbyte = nbyte0;
- }
- nbyte += (size_t)fprintf(fp, "%d ", (int)mask[i]);
+ gridMark4Update(gridID);
+ gridptr->np = np;
}
- fputs("\n", fp);
}
-static void gridPrintKernel(grid_t * gridptr, int index, int opt, FILE *fp)
-{
- int xdim, ydim;
- unsigned char uuidOfHGrid[CDI_UUID_SIZE];
- int gridID = gridptr->self;
- const double *area = gridInqAreaPtr(gridID);
- const double *xvals = gridInqXvalsPtr(gridID);
- const double *yvals = gridInqYvalsPtr(gridID);
- const double *xbounds = gridInqXboundsPtr(gridID);
- const double *ybounds = gridInqYboundsPtr(gridID);
-
- int type = gridInqType(gridID);
- int trunc = gridInqTrunc(gridID);
- int gridsize = gridInqSize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
- int nvertex = gridInqNvertex(gridID);
- int prec = gridInqPrec(gridID);
-
- int dig = (prec == DATATYPE_FLT64) ? 15 : 7;
-
- fprintf(fp, "#\n"
- "# gridID %d\n"
- "#\n"
- "gridtype = %s\n"
- "gridsize = %d\n", index, gridNamePtr(type), gridsize);
-
- if ( type != GRID_GME )
- {
- if ( xvals )
- {
- if ( gridptr->xname[0] ) fprintf(fp, "xname = %s\n", gridptr->xname);
- if ( gridptr->xlongname[0] ) fprintf(fp, "xlongname = %s\n", gridptr->xlongname);
- if ( gridptr->xunits[0] ) fprintf(fp, "xunits = %s\n", gridptr->xunits);
- }
- if ( yvals )
- {
- if ( gridptr->yname[0] ) fprintf(fp, "yname = %s\n", gridptr->yname);
- if ( gridptr->ylongname[0] ) fprintf(fp, "ylongname = %s\n", gridptr->ylongname);
- if ( gridptr->yunits[0] ) fprintf(fp, "yunits = %s\n", gridptr->yunits);
- }
- if ( type == GRID_UNSTRUCTURED && nvertex > 0 ) fprintf(fp, "nvertex = %d\n", nvertex);
- }
-
- switch (type)
- {
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- case GRID_GAUSSIAN_REDUCED:
- case GRID_GENERIC:
- case GRID_LCC2:
- case GRID_SINUSOIDAL:
- case GRID_LAEA:
- case GRID_CURVILINEAR:
- case GRID_UNSTRUCTURED:
- {
- if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np = %d\n", gridptr->np);
-
- if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
- {
- xdim = gridsize;
- ydim = gridsize;
- }
- else if ( type == GRID_GAUSSIAN_REDUCED )
- {
- xdim = 2;
- ydim = ysize;
- }
- else
- {
- xdim = xsize;
- ydim = ysize;
- }
-
- if ( type != GRID_UNSTRUCTURED )
- {
- if ( xsize > 0 ) fprintf(fp, "xsize = %d\n", xsize);
- if ( ysize > 0 ) fprintf(fp, "ysize = %d\n", ysize);
- }
-
- if ( type == GRID_UNSTRUCTURED )
- {
- int number = gridInqNumber(gridID);
- int position = gridInqPosition(gridID);
- // const unsigned char *d;
- if ( number > 0 )
- {
- fprintf(fp, "number = %d\n", number);
- if ( position >= 0 ) fprintf(fp, "position = %d\n", position);
- }
- /*
- gridInqUUID(gridID, uuidOfHGrid);
- d = (unsigned char *) &uuidOfHGrid;
- fprintf(fp, "uuid = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
- d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
- */
- if ( gridInqReference(gridID, NULL) )
- {
- char reference_link[8192];
- gridInqReference(gridID, reference_link);
- fprintf(fp, "uri = %s\n", reference_link);
- }
- }
+/*
+ at Function gridInqNP
+ at Title Get the number of parallels between a pole and the equator
- if ( type == GRID_LAEA )
- {
- double a = 0, lon_0 = 0, lat_0 = 0;
- gridInqLaea(gridID, &a, &lon_0, &lat_0);
- fprintf(fp, "a = %.*g\n"
- "lon_0 = %.*g\n"
- "lat_0 = %.*g\n", dig, a, dig, lon_0, dig, lat_0);
- }
+ at Prototype int gridInqNP(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- if ( type == GRID_LCC2 )
- {
- double a = 0, lon_0 = 0, lat_0 = 0, lat_1 = 0, lat_2 = 0;
- gridInqLcc2(gridID, &a, &lon_0, &lat_0, &lat_1, &lat_2);
- fprintf(fp, "a = %.*g\n"
- "lon_0 = %.*g\n"
- "lat_0 = %.*g\n"
- "lat_1 = %.*g\n"
- "lat_2 = %.*g\n",
- dig, a, dig, lon_0, dig, lat_0, dig, lat_1, dig, lat_2);
- }
+ at Description
+The function @func{gridInqNP} returns the number of parallels between a pole and the equator
+of a Gaussian grid.
- if ( gridptr->isRotated )
- {
- if ( xsize > 0 ) fprintf(fp, "xnpole = %.*g\n", dig, gridptr->xpole);
- if ( ysize > 0 ) fprintf(fp, "ynpole = %.*g\n", dig, gridptr->ypole);
- if ( IS_NOT_EQUAL(gridptr->angle, 0) ) fprintf(fp, "angle = %.*g\n", dig, gridptr->angle);
- }
+ at Result
+ at func{gridInqNP} returns the number of parallels between a pole and the equator.
- if ( xvals )
- {
- double xfirst = 0.0, xinc = 0.0;
+ at EndFunction
+*/
+int gridInqNP(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->np;
+}
- if ( type == GRID_LONLAT || type == GRID_GAUSSIAN ||
- type == GRID_GENERIC || type == GRID_LCC2 ||
- type == GRID_SINUSOIDAL || type == GRID_LAEA )
- {
- xfirst = gridInqXval(gridID, 0);
- xinc = gridInqXinc(gridID);
- }
+/*
+ at Function
+ at Title
- if ( IS_NOT_EQUAL(xinc, 0) && opt )
- {
- fprintf(fp, "xfirst = %.*g\n"
- "xinc = %.*g\n", dig, xfirst, dig, xinc);
- }
- else
- {
- static const char prefix[] = "xvals = ";
- printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
- (size_t)(xdim > 0 ? xdim : 0), xvals);
- }
- }
+ at Prototype
+ at Parameter
+ @Item Grid identifier
- if ( xbounds )
- {
- static const char prefix[] = "xbounds = ";
- printBounds(fp, dig, prefix, sizeof(prefix)-1,
- (size_t)(xdim > 0 ? xdim : 0),
- (size_t)(nvertex > 0 ? nvertex : 0), xbounds);
- }
+ at EndFunction
+*/
+void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
- if ( yvals )
- {
- double yfirst = 0.0, yinc = 0.0;
+ gridptr->rowlon = (int *) Malloc((size_t)nrowlon * sizeof(int));
+ gridptr->nrowlon = nrowlon;
+ memcpy(gridptr->rowlon, rowlon, (size_t)nrowlon * sizeof(int));
+ gridMark4Update(gridID);
+}
- if ( type == GRID_LONLAT || type == GRID_GENERIC || type == GRID_LCC2 ||
- type == GRID_SINUSOIDAL || type == GRID_LAEA )
- {
- yfirst = gridInqYval(gridID, 0);
- yinc = gridInqYinc(gridID);
- }
+/*
+ at Function
+ at Title
- if ( IS_NOT_EQUAL(yinc, 0) && opt )
- {
- fprintf(fp, "yfirst = %.*g\n"
- "yinc = %.*g\n", dig, yfirst, dig, yinc);
- }
- else
- {
- static const char prefix[] = "yvals = ";
- printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
- (size_t)(ydim > 0 ? ydim : 0), yvals);
- }
- }
+ at Prototype
+ at Parameter
+ @Item Grid identifier
- if ( ybounds )
- {
- static const char prefix[] = "ybounds = ";
- printBounds(fp, dig, prefix, sizeof(prefix)-1,
- (size_t)(ydim > 0 ? ydim : 0),
- (size_t)(nvertex > 0 ? nvertex : 0), ybounds);
- }
+ at EndFunction
+*/
+void gridInqRowlon(int gridID, int *rowlon)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
- if ( area )
- {
- static const char prefix[] = "area = ";
- printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
- (size_t)(gridsize > 0 ? gridsize : 0), area);
- }
+ if ( gridptr->rowlon == 0 ) Error("undefined pointer!");
- if ( type == GRID_GAUSSIAN_REDUCED )
- {
- static const char prefix[] = "rowlon = ";
- int *rowlon = (int *)Malloc((size_t)ysize*sizeof(int));
- gridInqRowlon(gridID, rowlon);
- printIntsPrefixAutoBrk(fp, prefix, sizeof(prefix)-1,
- (size_t)(ysize > 0 ? ysize : 0), rowlon);
- Free(rowlon);
- }
+ memcpy(rowlon, gridptr->rowlon, (size_t)gridptr->nrowlon * sizeof(int));
+}
- break;
- }
- case GRID_LCC:
- {
- double originLon = 0, originLat = 0, lonParY = 0, lat1 = 0, lat2 = 0, xincm = 0, yincm = 0;
- int projflag = 0, scanflag = 0;
- gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
- &projflag, &scanflag);
-
- fprintf(fp,
- "xsize = %d\n"
- "ysize = %d\n"
- "originLon = %.*g\n"
- "originLat = %.*g\n"
- "lonParY = %.*g\n"
- "lat1 = %.*g\n"
- "lat2 = %.*g\n"
- "xinc = %.*g\n"
- "yinc = %.*g\n"
- "projection = %s\n",
- xsize, ysize, dig, originLon, dig, originLat, dig, lonParY,
- dig, lat1, dig, lat2, dig, xincm, dig, yincm,
- (projflag & 128) == 0 ? "northpole" : "southpole");
- break;
- }
- case GRID_SPECTRAL:
- {
- fprintf(fp, "truncation = %d\n"
- "complexpacking = %d\n", trunc, gridptr->lcomplex );
- break;
- }
- case GRID_FOURIER:
- {
- fprintf(fp, "truncation = %d\n", trunc);
- break;
- }
- case GRID_GME:
- {
- fprintf(fp, "ni = %d\n", gridptr->ni );
- break;
- }
- default:
- {
- fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
- break;
- }
- }
+static size_t
+gridInqMaskSerialGeneric(grid_t *gridptr, mask_t **internalMask,
+ int *restrict mask)
+{
+ size_t size = gridptr->size;
- gridInqUUID(gridID, uuidOfHGrid);
- if ( !cdiUUIDIsNull(uuidOfHGrid) )
- {
- char uuidOfHGridStr[37];
- cdiUUID2Str(uuidOfHGrid, uuidOfHGridStr);
- if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
- fprintf(fp, "uuid = %s\n", uuidOfHGridStr);
- }
+ if ( CDI_Debug && size == 0 )
+ Warning("Size undefined for gridID = %d", gridptr->self);
- if ( gridptr->mask )
+ const mask_t *restrict mask_src = *internalMask;
+ if ( mask_src )
{
- static const char prefix[] = "mask = ";
- printMask(fp, prefix, sizeof(prefix)-1,
- (size_t)(gridsize > 0 ? gridsize : 0), gridptr->mask);
+ if (mask && size > 0)
+ for (size_t i = 0; i < size; ++i)
+ mask[i] = (int)mask_src[i];
}
+ else
+ size = 0;
+
+ return size;
}
-void gridPrint ( int gridID, int index, int opt )
+static size_t
+gridInqMaskSerial(grid_t *gridptr, int *mask)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- gridPrintKernel ( gridptr, index, opt, stdout );
+ return gridInqMaskSerialGeneric(gridptr, &gridptr->mask, mask);
}
-
-void gridPrintP ( void * voidptr, FILE * fp )
+int gridInqMask(int gridID, int *mask)
{
- grid_t * gridptr = ( grid_t * ) voidptr;
-
- xassert ( gridptr );
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqMask(gridptr, mask);
+}
- gridPrintKernel ( gridptr , gridptr->self, 0, fp );
+static void
+gridDefMaskSerial(grid_t *gridptr, const int *mask)
+{
+ size_t size = gridptr->size;
- fprintf(fp,
- "precision = %d\n"
- "nd = %d\n"
- "ni = %d\n"
- "ni2 = %d\n"
- "ni3 = %d\n"
- "number = %d\n"
- "position = %d\n"
- "trunc = %d\n"
- "lcomplex = %d\n"
- "nrowlon = %d\n",
- gridptr->prec, gridptr->nd, gridptr->ni, gridptr->ni2,
- gridptr->ni3, gridptr->number, gridptr->position, gridptr->trunc,
- gridptr->lcomplex, gridptr->nrowlon );
+ if ( size == 0 )
+ Error("Size undefined for gridID = %d", gridptr->self);
- if ( gridptr->rowlon )
+ if ( mask == NULL )
{
- static const char prefix[] = "rowlon = ";
- printIntsPrefixAutoBrk(fp, prefix, sizeof(prefix)-1,
- (size_t)(gridptr->nrowlon > 0
- ? gridptr->nrowlon : 0), gridptr->rowlon);
+ if ( gridptr->mask )
+ {
+ Free(gridptr->mask);
+ gridptr->mask = NULL;
+ }
}
-
- if ( gridptr->mask_gme )
+ else
{
- static const char prefix[] = "mask_gme = ";
- printMask(fp, prefix, sizeof(prefix)-1,
- (size_t)(gridptr->size > 0 ? gridptr->size : 0),
- gridptr->mask_gme);
+ if ( gridptr->mask == NULL )
+ gridptr->mask = (mask_t *) Malloc(size*sizeof(mask_t));
+ else if ( CDI_Debug )
+ Warning("grid mask already defined!");
+
+ for (size_t i = 0; i < size; ++i )
+ gridptr->mask[i] = (mask_t)(mask[i] != 0);
}
}
-static const double *gridInqXValsPtrSerial(grid_t *gridptr)
+void gridDefMask(int gridID, const int *mask)
{
- return gridptr->xvals;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defMask(gridptr, mask);
+ gridMark4Update(gridID);
}
-const double *gridInqXvalsPtr(int gridID)
+static int
+gridInqMaskGMESerial(grid_t *gridptr, int *mask_gme)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqXValsPtr(gridptr);
+ return gridInqMaskSerialGeneric(gridptr, &gridptr->mask_gme, mask_gme);
}
+int gridInqMaskGME(int gridID, int *mask)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqMaskGME(gridptr, mask);
+}
-static const double *gridInqYValsPtrSerial(grid_t *gridptr)
+static void
+gridDefMaskGMESerial(grid_t *gridptr, const int *mask)
{
- return gridptr->yvals;
+ size_t size = gridptr->size;
+
+ if ( size == 0 )
+ Error("Size undefined for gridID = %d", gridptr->self);
+
+ if ( gridptr->mask_gme == NULL )
+ gridptr->mask_gme = (mask_t *) Malloc(size * sizeof (mask_t));
+ else if ( CDI_Debug )
+ Warning("mask already defined!");
+
+ for (size_t i = 0; i < size; ++i)
+ gridptr->mask_gme[i] = (mask_t)(mask[i] != 0);
}
-const double *gridInqYvalsPtr(int gridID)
+void gridDefMaskGME(int gridID, const int *mask)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->vtable->inqYValsPtr(gridptr);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defMaskGME(gridptr, mask);
+ gridMark4Update(gridID);
}
-/*
- at Function gridDefLCC
- at Title Define the parameter of a Lambert Conformal Conic grid
+static
+size_t gridInqXValsSerial(grid_t *gridptr, double *xvals)
+{
+ size_t size;
+ if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
+ size = gridptr->size;
+ else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
+ size = 2;
+ else
+ size = gridptr->x.size;
- at Prototype void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item originLon Longitude of the first grid point.
- @Item originLat Latitude of the first grid point.
- @Item lonParY The East longitude of the meridian which is parallel to the Y-axis.
- @Item lat1 First latitude from the pole at which the secant cone cuts the sphere.
- @Item lat2 Second latitude at which the secant cone cuts the sphere.
- @Item xinc X-direction grid lenght in meter.
- @Item yinc Y-direction grid lenght in meter.
- @Item projflag Projection centre flag.
- @Item scanflag Scanning mode flag.
+ if ( CDI_Debug && size == 0 )
+ Warning("size undefined for gridID = %d", gridptr->self);
- at Description
-The function @func{gridDefLCC} defines the parameter of a Lambert Conformal Conic grid.
+ if ( gridptr->x.vals )
+ {
+ if ( size && xvals )
+ {
+ const double *gridptr_xvals = gridptr->vtable->inqXValsPtr(gridptr);
+ memcpy(xvals, gridptr_xvals, size * sizeof (double));
+ }
+ }
+ else
+ size = 0;
- at EndFunction
-*/
-void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
- double lat1, double lat2, double xinc, double yinc,
- int projflag, int scanflag)
+ return size;
+}
+
+static
+size_t gridInqXCvalsSerial(grid_t *gridptr, char **xcvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( gridptr->type != GRID_CHARXY )
+ Error("Function only valid for grid type 'GRID_CHARXY'.");
- if ( gridptr->type != GRID_LCC )
- Warning("Definition of LCC grid for %s grid not allowed!",
- gridNamePtr(gridptr->type));
- else
+ size_t size = gridptr->x.size;
+ size_t maxclength = 0;
+
+ const char **gridptr_xcvals = gridptr->vtable->inqXCvalsPtr(gridptr);
+ if ( gridptr_xcvals && size && xcvals )
{
- gridptr->lcc_originLon = originLon;
- gridptr->lcc_originLat = originLat;
- gridptr->lcc_lonParY = lonParY;
- gridptr->lcc_lat1 = lat1;
- gridptr->lcc_lat2 = lat2;
- gridptr->lcc_xinc = xinc;
- gridptr->lcc_yinc = yinc;
- gridptr->lcc_projflag = projflag;
- gridptr->lcc_scanflag = scanflag;
- gridptr->lcc_defined = TRUE;
- gridMark4Update(gridID);
+ maxclength = gridptr->x.clength;
+ for ( size_t i = 0; i < size; i++ )
+ memcpy(xcvals[i], gridptr_xcvals[i], maxclength*sizeof(char));
}
+
+ return maxclength;
+}
+
+static
+int gridInqXIscSerial(grid_t *gridptr)
+{
+ int clen = gridptr->x.clength;
+ /*
+ if ( gridptr->type != GRID_CHARXY )
+ Error("Axis type is 'char' but grid is not type 'GRID_CHARXY'.");
+ */
+ return clen;
}
/*
- at Function gridInqLCC
- at Title Get the parameter of a Lambert Conformal Conic grid
+ at Function gridInqXvals
+ at Title Get all values of a X-axis
- at Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
+ at Prototype size_t gridInqXvals(int gridID, double *xvals)
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- @Item originLon Longitude of the first grid point.
- @Item originLat Latitude of the first grid point.
- @Item lonParY The East longitude of the meridian which is parallel to the Y-axis.
- @Item lat1 First latitude from the pole at which the secant cone cuts the sphere.
- @Item lat2 Second latitude at which the secant cone cuts the sphere.
- @Item xinc X-direction grid lenght in meter.
- @Item yinc Y-direction grid lenght in meter.
- @Item projflag Projection centre flag.
- @Item scanflag Scanning mode flag.
-
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item xvals Pointer to the location into which the X-values are read.
+ The caller must allocate space for the returned values.
+
@Description
-The function @func{gridInqLCC} returns the parameter of a Lambert Conformal Conic grid.
+The function @func{gridInqXvals} returns all values of the X-axis.
+
+ at Result
+Upon successful completion @func{gridInqXvals} returns the number of values and
+the values are stored in @func{xvals}.
+Otherwise, 0 is returned and @func{xvals} is empty.
@EndFunction
*/
-void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY,
- double *lat1, double *lat2, double *xinc, double *yinc,
- int *projflag, int *scanflag)
+size_t gridInqXvals(int gridID, double *xvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
-
- if ( gridptr->type != GRID_LCC )
- Warning("Inquire of LCC grid definition for %s grid not allowed!",
- gridNamePtr(gridptr->type));
- else
- {
- if ( gridptr->lcc_defined )
- {
- *originLon = gridptr->lcc_originLon;
- *originLat = gridptr->lcc_originLat;
- *lonParY = gridptr->lcc_lonParY;
- *lat1 = gridptr->lcc_lat1;
- *lat2 = gridptr->lcc_lat2;
- *xinc = gridptr->lcc_xinc;
- *yinc = gridptr->lcc_yinc;
- *projflag = gridptr->lcc_projflag;
- *scanflag = gridptr->lcc_scanflag;
- }
- else
- Warning("Lambert Conformal grid undefined (gridID = %d)", gridID);
- }
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXVals(gridptr, xvals);
}
-void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2)
-{
- grid_t *gridptr = gridID2Ptr(gridID);
- if ( gridptr->type != GRID_LCC2 )
- Warning("Definition of LCC2 grid for %s grid not allowed!",
- gridNamePtr(gridptr->type));
- else
- {
- gridptr->lcc2_a = earth_radius;
- gridptr->lcc2_lon_0 = lon_0;
- gridptr->lcc2_lat_0 = lat_0;
- gridptr->lcc2_lat_1 = lat_1;
- gridptr->lcc2_lat_2 = lat_2;
- gridptr->lcc2_defined = TRUE;
- gridMark4Update(gridID);
- }
+size_t gridInqXCvals(int gridID, char **xcvals)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXCvals(gridptr, xcvals);
}
-void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0, double *lat_1, double *lat_2)
+int gridInqXIsc(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXIsc(gridptr);
+}
+
+static
+void gridDefXValsSerial(grid_t *gridptr, const double *xvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ int gridtype = gridptr->type;
- if ( gridptr->type != GRID_LCC2 )
- Warning("Inquire of LCC2 grid definition for %s grid not allowed!",
- gridNamePtr(gridptr->type));
+ size_t size;
+ if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
+ size = gridptr->size;
+ else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+ size = 2;
else
- {
- if ( gridptr->lcc2_defined )
- {
- *earth_radius = gridptr->lcc2_a;
- *lon_0 = gridptr->lcc2_lon_0;
- *lat_0 = gridptr->lcc2_lat_0;
- *lat_1 = gridptr->lcc2_lat_1;
- *lat_2 = gridptr->lcc2_lat_2;
- }
- else
- Warning("LCC2 grid undefined (gridID = %d)", gridID);
- }
+ size = gridptr->x.size;
+
+ if ( size == 0 )
+ Error("Size undefined for gridID = %d", gridptr->self);
+
+ if (gridptr->x.vals && CDI_Debug)
+ Warning("values already defined!");
+ gridptr->x.vals = (double *)Realloc(gridptr->x.vals,
+ size * sizeof(double));
+ memcpy(gridptr->x.vals, xvals, size * sizeof (double));
}
-void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
+static
+size_t gridInqYCvalsSerial(grid_t *gridptr, char **ycvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( gridptr->type != GRID_CHARXY )
+ Error("Function only valid for grid type 'GRID_CHARXY'.");
- if ( gridptr->type != GRID_LAEA )
- Warning("Definition of LAEA grid for %s grid not allowed!",
- gridNamePtr(gridptr->type));
- else
+ size_t size = gridptr->y.size;
+ size_t maxclength = 0;
+
+ const char **gridptr_ycvals = gridptr->vtable->inqYCvalsPtr(gridptr);
+ if ( gridptr_ycvals && size && ycvals )
{
- gridptr->laea_a = earth_radius;
- gridptr->laea_lon_0 = lon_0;
- gridptr->laea_lat_0 = lat_0;
- gridptr->laea_defined = TRUE;
- gridMark4Update(gridID);
+ maxclength = gridptr->y.clength;
+ for ( size_t i = 0; i < size; i++ )
+ memcpy(ycvals[i], gridptr_ycvals[i], maxclength*sizeof(char));
}
+
+ return maxclength;
+}
+
+static
+int gridInqYIscSerial(grid_t *gridptr)
+{
+ int clen = gridptr->y.clength;
+ /*
+ if ( gridptr->type != GRID_CHARXY )
+ Error("Axis type is 'char' but grid is not type 'GRID_CHARXY'.");
+ */
+ return clen;
}
+/*
+ at Function gridDefXvals
+ at Title Define the values of a X-axis
+
+ at Prototype void gridDefXvals(int gridID, const double *xvals)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item xvals X-values of the grid.
+
+ at Description
+The function @func{gridDefXvals} defines all values of the X-axis.
+
+ at EndFunction
+*/
+void gridDefXvals(int gridID, const double *xvals)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defXVals(gridptr, xvals);
+ gridMark4Update(gridID);
+}
-void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
+static
+size_t gridInqYValsSerial(grid_t *gridptr, double *yvals)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ int gridtype = gridptr->type;
+ size_t size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+ ? gridptr->size : gridptr->y.size;
- if ( gridptr->type != GRID_LAEA )
- Warning("Inquire of LAEA grid definition for %s grid not allowed!",
- gridNamePtr(gridptr->type));
- else
+ if ( CDI_Debug && size == 0 )
+ Warning("size undefined for gridID = %d!", gridptr->self);
+
+ if ( gridptr->y.vals )
{
- if ( gridptr->laea_defined )
+ if ( size && yvals )
{
- *earth_radius = gridptr->laea_a;
- *lon_0 = gridptr->laea_lon_0;
- *lat_0 = gridptr->laea_lat_0;
+ const double *gridptr_yvals = gridptr->vtable->inqYValsPtr(gridptr);
+ memcpy(yvals, gridptr_yvals, size * sizeof (double));
}
- else
- Warning("LAEA grid undefined (gridID = %d)", gridID);
}
+ else
+ size = 0;
+
+ return size;
}
+/*
+ at Function gridInqYvals
+ at Title Get all values of a Y-axis
-void gridDefComplexPacking(int gridID, int lcomplex)
+ at Prototype size_t gridInqYvals(int gridID, double *yvals)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item yvals Pointer to the location into which the Y-values are read.
+ The caller must allocate space for the returned values.
+
+ at Description
+The function @func{gridInqYvals} returns all values of the Y-axis.
+
+ at Result
+Upon successful completion @func{gridInqYvals} returns the number of values and
+the values are stored in @func{yvals}.
+Otherwise, 0 is returned and @func{yvals} is empty.
+
+ at EndFunction
+*/
+size_t gridInqYvals(int gridID, double *yvals)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYVals(gridptr, yvals);
+}
- if (gridptr->lcomplex != lcomplex)
- {
- gridptr->lcomplex = (short)(lcomplex != 0);
- gridMark4Update(gridID);
- }
+
+size_t gridInqYCvals(int gridID, char **ycvals)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYCvals(gridptr, ycvals);
}
-int gridInqComplexPacking(int gridID)
+int gridInqYIsc(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYIsc(gridptr);
+}
+
+static
+void gridDefYValsSerial(grid_t *gridptr, const double *yvals)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ int gridtype = gridptr->type;
+ size_t size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+ ? gridptr->size : gridptr->y.size;
+
+ if ( size == 0 )
+ Error("Size undefined for gridID = %d!", gridptr->self);
+
+ if ( gridptr->y.vals && CDI_Debug )
+ Warning("Values already defined!");
- return gridptr->lcomplex;
+ gridptr->y.vals = (double *)Realloc(gridptr->y.vals, size * sizeof (double));
+ memcpy(gridptr->y.vals, yvals, size * sizeof (double));
}
-void gridDefHasDims(int gridID, int hasdims)
+/*
+ at Function gridDefYvals
+ at Title Define the values of a Y-axis
+
+ at Prototype void gridDefYvals(int gridID, const double *yvals)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item yvals Y-values of the grid.
+
+ at Description
+The function @func{gridDefYvals} defines all values of the Y-axis.
+
+ at EndFunction
+*/
+void gridDefYvals(int gridID, const double *yvals)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defYVals(gridptr, yvals);
+ gridMark4Update(gridID);
+}
- if ( gridptr->hasdims != (hasdims != 0) )
- {
- gridptr->hasdims = hasdims != 0;
- gridMark4Update(gridID);
- }
+static double
+gridInqXValSerial(grid_t *gridptr, size_t index)
+{
+ double xval = gridptr->x.vals ? gridptr->x.vals[index] : 0;
+ return xval;
}
-int gridInqHasDims(int gridID)
+double gridInqXval(int gridID, size_t index)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXVal(gridptr, index);
+}
- return gridptr->hasdims;
+static double
+gridInqYValSerial(grid_t *gridptr, size_t index)
+{
+ double yval = gridptr->y.vals ? gridptr->y.vals[index] : 0;
+ return yval;
}
/*
- at Function gridDefNumber
- at Title Define the reference number for an unstructured grid
+ at Function
+ at Title
- at Prototype void gridDefNumber(int gridID, const int number)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item number Reference number for an unstructured grid.
+ @Item Grid identifier
- at Description
-The function @func{gridDefNumber} defines the reference number for an unstructured grid.
+ at EndFunction
+*/
+double gridInqYval(int gridID, size_t index)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYVal(gridptr, index);
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+ @Item Grid identifier
@EndFunction
*/
-void gridDefNumber(int gridID, const int number)
+double gridInqXinc(int gridID)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ double xinc = gridptr->x.inc;
+ const double *restrict xvals = gridptr->vtable->inqXValsPtr(gridptr);
- if ( gridptr->number != number )
+ if ( (! (fabs(xinc) > 0)) && xvals )
{
- gridptr->number = number;
- gridMark4Update(gridID);
+ size_t xsize = gridptr->x.size;
+ if ( xsize > 1 )
+ {
+ xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
+ for ( size_t i = 2; i < xsize; i++ )
+ if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc )
+ {
+ xinc = 0;
+ break;
+ }
+
+ gridptr->x.inc = xinc;
+ }
}
+
+ return xinc;
}
/*
- at Function gridInqNumber
- at Title Get the reference number to an unstructured grid
+ at Function
+ at Title
- at Prototype int gridInqNumber(int gridID)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item Grid identifier
- at Description
-The function @func{gridInqNumber} returns the reference number to an unstructured grid.
+ at EndFunction
+*/
+double gridInqYinc(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ double yinc = gridptr->y.inc;
+ const double *yvals = gridptr->vtable->inqYValsPtr(gridptr);
+
+ if ( (! (fabs(yinc) > 0)) && yvals )
+ {
+ size_t ysize = gridptr->y.size;
+ if ( ysize > 1 )
+ {
+ yinc = yvals[1] - yvals[0];
+ double abs_yinc = fabs(yinc);
+ for ( size_t i = 2; i < ysize; i++ )
+ if ( fabs(fabs(yvals[i] - yvals[i-1]) - abs_yinc) > (0.01*abs_yinc) )
+ {
+ yinc = 0;
+ break;
+ }
+
+ gridptr->y.inc = yinc;
+ }
+ }
+
+ return yinc;
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+ @Item Grid identifier
- at Result
- at func{gridInqNumber} returns the reference number to an unstructured grid.
@EndFunction
*/
-int gridInqNumber(int gridID)
+void gridInqParamRLL(int gridID, double *xpole, double *ypole, double *angle)
{
- grid_t* gridptr = gridID2Ptr(gridID);
- return gridptr->number;
+ *xpole = 0; *ypole = 0; *angle = 0;
+
+ const char *projection = "rotated_latitude_longitude";
+ char mapping[CDI_MAX_NAME]; mapping[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+ if ( mapping[0] && strcmp(mapping, projection) == 0 )
+ {
+ int atttype, attlen;
+ char attname[CDI_MAX_NAME+1];
+
+ int natts;
+ cdiInqNatts(gridID, CDI_GLOBAL, &natts);
+
+ for ( int iatt = 0; iatt < natts; ++iatt )
+ {
+ cdiInqAtt(gridID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
+ if ( attlen != 1 ) continue;
+
+ double attflt;
+ if ( cdiInqAttConvertedToFloat(gridID, atttype, attname, attlen, &attflt) )
+ {
+ if ( strcmp(attname, "grid_north_pole_longitude") == 0 ) *xpole = attflt;
+ else if ( strcmp(attname, "grid_north_pole_latitude") == 0 ) *ypole = attflt;
+ else if ( strcmp(attname, "north_pole_grid_longitude") == 0 ) *angle = attflt;
+ }
+ }
+ }
+ else
+ Warning("%s mapping parameter missing!", projection);
}
/*
- at Function gridDefPosition
- at Title Define the position of grid in the reference file
+ at Function
+ at Title
- at Prototype void gridDefPosition(int gridID, const int position)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item position Position of grid in the reference file.
-
- at Description
-The function @func{gridDefPosition} defines the position of grid in the reference file.
+ @Item Grid identifier
@EndFunction
*/
-void gridDefPosition(int gridID, int position)
+void gridDefParamRLL(int gridID, double xpole, double ypole, double angle)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ cdiGridDefKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, "rotated_pole");
- if ( gridptr->position != position )
- {
- gridptr->position = position;
- gridMark4Update(gridID);
- }
+ const char *mapping = "rotated_latitude_longitude";
+ cdiGridDefKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+ cdiDefAttTxt(gridID, CDI_GLOBAL, "grid_mapping_name", (int)(strlen(mapping)), mapping);
+ cdiDefAttFlt(gridID, CDI_GLOBAL, "grid_north_pole_longitude", CDI_DATATYPE_FLT64, 1, &xpole);
+ cdiDefAttFlt(gridID, CDI_GLOBAL, "grid_north_pole_latitude", CDI_DATATYPE_FLT64, 1, &ypole);
+ if ( IS_NOT_EQUAL(angle, 0) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "north_pole_grid_longitude", CDI_DATATYPE_FLT64, 1, &angle);
+
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->projtype = CDI_PROJ_RLL;
+
+ gridVerifyProj(gridID);
}
/*
- at Function gridInqPosition
- at Title Get the position of grid in the reference file
+ at Function
+ at Title
- at Prototype int gridInqPosition(int gridID)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqPosition} returns the position of grid in the reference file.
+ @Item Grid identifier
- at Result
- at func{gridInqPosition} returns the position of grid in the reference file.
@EndFunction
*/
-int gridInqPosition(int gridID)
+void gridInqParamGME(int gridID, int *nd, int *ni, int *ni2, int *ni3)
{
- grid_t *gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
- return gridptr->position;
+ *nd = gridptr->gme.nd;
+ *ni = gridptr->gme.ni;
+ *ni2 = gridptr->gme.ni2;
+ *ni3 = gridptr->gme.ni3;
}
/*
- at Function gridDefReference
- at Title Define the reference URI for an unstructured grid
+ at Function
+ at Title
- at Prototype void gridDefReference(int gridID, const char *reference)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item reference Reference URI for an unstructured grid.
-
- at Description
-The function @func{gridDefReference} defines the reference URI for an unstructured grid.
+ @Item Grid identifier
@EndFunction
*/
-void gridDefReference(int gridID, const char *reference)
+void gridDefParamGME(int gridID, int nd, int ni, int ni2, int ni3)
{
- grid_t* gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
- if ( reference )
+ if ( gridptr->gme.nd != nd )
{
- if ( gridptr->reference )
- {
- Free(gridptr->reference);
- gridptr->reference = NULL;
- }
-
- gridptr->reference = strdupx(reference);
+ gridptr->gme.nd = nd;
+ gridptr->gme.ni = ni;
+ gridptr->gme.ni2 = ni2;
+ gridptr->gme.ni3 = ni3;
gridMark4Update(gridID);
}
}
/*
- at Function gridInqReference
- at Title Get the reference URI to an unstructured grid
+ at Function
+ at Title
- at Prototype char *gridInqReference(int gridID, char *reference)
+ at Prototype
@Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqReference} returns the reference URI to an unstructured grid.
+ @Item Grid identifier
- at Result
- at func{gridInqReference} returns the reference URI to an unstructured grid.
@EndFunction
*/
-int gridInqReference(int gridID, char *reference)
+void gridChangeType(int gridID, int gridtype)
{
- size_t len = 0;
- grid_t* gridptr = gridID2Ptr(gridID);
+ grid_t *gridptr = grid_to_pointer(gridID);
- if ( gridptr->reference )
+ if ( CDI_Debug )
+ Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
+
+ if (gridptr->type != gridtype)
{
- len = strlen(gridptr->reference);
- if ( reference )
- strcpy(reference, gridptr->reference);
+ gridptr->type = gridtype;
+ gridMark4Update(gridID);
}
-
- return (int)len;
}
-const char *gridInqReferencePtr(int gridID)
+static
+void grid_check_cyclic(grid_t *gridptr)
{
- grid_t *gridptr = gridID2Ptr(gridID);
- return gridptr->reference;
-}
+ gridptr->isCyclic = 0;
+ enum { numVertices = 4 };
+ size_t xsize = gridptr->x.size,
+ ysize = gridptr->y.size;
+ const double *xvals = gridptr->vtable->inqXValsPtr(gridptr),
+ *yvals = gridptr->vtable->inqYValsPtr(gridptr),
+ (*xbounds)[numVertices]
+ = (const double (*)[numVertices])gridptr->vtable->inqXBoundsPtr(gridptr);
-/*
- at Function gridDefUUID
- at Title Define the UUID for an unstructured grid
+ if ( gridptr->type == GRID_GAUSSIAN || gridptr->type == GRID_LONLAT )
+ {
+ if ( xvals && xsize > 1 )
+ {
+ double xval1 = xvals[0];
+ double xval2 = xvals[1];
+ double xvaln = xvals[xsize-1];
+ if ( xval2 < xval1 ) xval2 += 360;
+ if ( xvaln < xval1 ) xvaln += 360;
- at Prototype void gridDefUUID(int gridID, const char *uuid)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
- @Item uuid UUID for an unstructured grid.
+ if ( IS_NOT_EQUAL(xval1, xvaln) )
+ {
+ double xinc = xval2 - xval1;
+ if ( IS_EQUAL(xinc, 0) ) xinc = (xvaln - xval1)/(xsize-1);
- at Description
-The function @func{gridDefUUID} defines the UUID for an unstructured grid.
+ double x0 = xvaln + xinc - 360;
- at EndFunction
-*/
-void gridDefUUID(int gridID, const unsigned char uuid[CDI_UUID_SIZE])
-{
- grid_t* gridptr = gridID2Ptr(gridID);
+ if ( fabs(x0 - xval1) < 0.01*xinc ) gridptr->isCyclic = 1;
+ }
+ }
+ }
+ else if ( gridptr->type == GRID_CURVILINEAR )
+ {
+ bool lcheck = true;
+ if ( yvals && xvals )
+ {
+ if ( (fabs(yvals[0] - yvals[xsize-1]) > fabs(yvals[0] - yvals[xsize*ysize-xsize])) &&
+ (fabs(yvals[xsize*ysize-xsize] - yvals[xsize*ysize-1]) > fabs(yvals[xsize-1] - yvals[xsize*ysize-1])) )
+ lcheck = false;
+ }
+ else lcheck = false;
- memcpy(gridptr->uuid, uuid, CDI_UUID_SIZE);
- gridMark4Update(gridID);
-}
+ if ( lcheck && xvals && xsize > 1 )
+ {
+ size_t nc = 0;
+ for ( size_t j = 0; j < ysize; ++j )
+ {
+ size_t i1 = j*xsize,
+ i2 = j*xsize+1,
+ in = j*xsize+(xsize-1);
+ double val1 = xvals[i1],
+ val2 = xvals[i2],
+ valn = xvals[in];
+ double xinc = fabs(val2-val1);
-/*
- at Function gridInqUUID
- at Title Get the UUID to an unstructured grid
+ if ( val1 < 1 && valn > 300 ) val1 += 360;
+ if ( valn < 1 && val1 > 300 ) valn += 360;
+ if ( val1 < -179 && valn > 120 ) val1 += 360;
+ if ( valn < -179 && val1 > 120 ) valn += 360;
+ if ( fabs(valn-val1) > 180 ) val1 += 360;
- at Prototype void gridInqUUID(int gridID, char *uuid)
- at Parameter
- @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ double x0 = valn + copysign(xinc, val1 - valn);
- at Description
-The function @func{gridInqUUID} returns the UUID to an unstructured grid.
+ nc += fabs(x0-val1) < 0.5*xinc;
+ }
+ gridptr->isCyclic = nc > ysize/2;
+ }
- at Result
- at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
- at EndFunction
-*/
-void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
-{
- grid_t *gridptr = gridID2Ptr(gridID);
+ if ( lcheck && xbounds && xsize > 1 )
+ {
+ bool isCyclic = true;
+ for ( size_t j = 0; j < ysize; ++j )
+ {
+ size_t i1 = j*xsize,
+ i2 = j*xsize+(xsize-1);
+ for (size_t k1 = 0; k1 < numVertices; ++k1 )
+ {
+ double val1 = xbounds[i1][k1];
+ for (size_t k2 = 0; k2 < numVertices; ++k2 )
+ {
+ double val2 = xbounds[i2][k2];
- memcpy(uuid, gridptr->uuid, CDI_UUID_SIZE);
+ if ( val1 < 1 && val2 > 300 ) val1 += 360;
+ if ( val2 < 1 && val1 > 300 ) val2 += 360;
+ if ( val1 < -179 && val2 > 120 ) val1 += 360;
+ if ( val2 < -179 && val1 > 120 ) val2 += 360;
+ if ( fabs(val2-val1) > 180 ) val1 += 360;
+
+ if ( fabs(val1-val2) < 0.001 )
+ goto foundCloseVertices;
+ }
+ }
+ /* all vertices more than 0.001 degrees apart */
+ isCyclic = false;
+ break;
+ foundCloseVertices:
+ ;
+ }
+ gridptr->isCyclic = isCyclic;
+ }
+ }
}
-void cdiGridGetIndexList(unsigned ngrids, int * gridIndexList)
+int gridIsCircular(int gridID)
{
- reshGetResHListOfType(ngrids, gridIndexList, &gridOps);
-}
+ grid_t *gridptr = grid_to_pointer(gridID);
+ if ( gridptr->isCyclic == CDI_UNDEFID ) grid_check_cyclic(gridptr);
-static int
-gridTxCode ()
-{
- return GRID;
+ return gridptr->isCyclic;
}
-enum { gridNint = 28,
- gridNdouble = 24,
- gridHasMaskFlag = 1 << 0,
- gridHasGMEMaskFlag = 1 << 1,
- gridHasXValsFlag = 1 << 2,
- gridHasYValsFlag = 1 << 3,
- gridHasAreaFlag = 1 << 4,
- gridHasXBoundsFlag = 1 << 5,
- gridHasYBoundsFlag = 1 << 6,
- gridHasReferenceFlag = 1 << 7,
- gridHasRowLonFlag = 1 << 8,
- gridHasUUIDFlag = 1 << 9,
-};
+static
+bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
+{
+ bool differ = false;
+ size_t xsizeTest = gridTest->x.size, ysizeTest = gridTest->y.size;
+ if ( !differ && xsizeTest > 0 && xsizeTest == gridRef->vtable->inqXVals(gridRef, NULL) )
+ {
+ const double *restrict xvalsRef = gridRef->vtable->inqXValsPtr(gridRef),
+ *restrict xvalsTest = gridTest->vtable->inqXValsPtr(gridTest);
-static int gridGetComponentFlags(const grid_t * gridP)
-{
- int flags = (gridHasMaskFlag & (int)((unsigned)(gridP->mask == NULL) - 1U))
- | (gridHasGMEMaskFlag & (int)((unsigned)(gridP->mask_gme == NULL) - 1U))
- | (gridHasXValsFlag
- & (int)((unsigned)(gridP->vtable->inqXValsPtr((grid_t *)gridP) == NULL) - 1U))
- | (gridHasYValsFlag
- & (int)((unsigned)(gridP->vtable->inqYValsPtr((grid_t *)gridP) == NULL) - 1U))
- | (gridHasAreaFlag
- & (int)((unsigned)(gridP->vtable->inqAreaPtr((grid_t *)gridP) == NULL)
- - 1U))
- | (gridHasXBoundsFlag & (int)((unsigned)(gridP->xbounds == NULL) - 1U))
- | (gridHasYBoundsFlag & (int)((unsigned)(gridP->ybounds == NULL) - 1U))
- | (gridHasReferenceFlag & (int)((unsigned)(gridP->reference == NULL) - 1U))
- | (gridHasRowLonFlag & (int)((unsigned)(gridP->rowlon == NULL) - 1U))
- | (gridHasUUIDFlag & (int)((unsigned)cdiUUIDIsNull(gridP->uuid) - 1U));
- return flags;
+ for ( size_t i = 0; i < xsizeTest; ++i )
+ if ( fabs(xvalsTest[i] - xvalsRef[i]) > 1.e-10 )
+ {
+ differ = true;
+ break;
+ }
+ }
+
+ if ( !differ && ysizeTest > 0 && ysizeTest == gridRef->vtable->inqYVals(gridRef, NULL) )
+ {
+ const double *restrict yvalsRef = gridRef->vtable->inqYValsPtr(gridRef),
+ *restrict yvalsTest = gridTest->vtable->inqYValsPtr(gridTest);
+ for ( size_t i = 0; i < ysizeTest; ++i )
+ if ( fabs(yvalsTest[i] - yvalsRef[i]) > 1.e-10 )
+ {
+ differ = true;
+ break;
+ }
+ }
+
+ return differ;
}
-static int
-gridGetPackSize(void * voidP, void *context)
+static
+bool compareXYvals2(grid_t *gridRef, grid_t *gridTest)
{
- grid_t * gridP = ( grid_t * ) voidP;
- int packBuffSize = 0, count;
+ size_t gridsize = gridTest->size;
+ bool differ = ((gridTest->x.vals == NULL) ^ (gridRef->x.vals == NULL))
+ || ((gridTest->y.vals == NULL) ^ (gridRef->y.vals == NULL));
- packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ typedef double (*inqVal)(grid_t *grid, size_t index);
+ inqVal inqXValRef = gridRef->vtable->inqXVal,
+ inqYValRef = gridRef->vtable->inqYVal,
+ inqXValTest = gridTest->vtable->inqXVal,
+ inqYValTest = gridTest->vtable->inqYVal;
- if (gridP->rowlon)
- {
- xassert(gridP->nrowlon);
- packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
- + serializeGetSize( 1, DATATYPE_UINT32, context);
- }
+ if ( !differ && gridTest->x.vals )
+ differ = fabs(inqXValTest(gridTest, 0) - inqXValRef(gridRef, 0)) > 1.e-9
+ || fabs(inqXValTest(gridTest, gridsize-1) - inqXValRef(gridRef, gridsize-1)) > 1.e-9;
- packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
+ if ( !differ && gridTest->y.vals )
+ differ = fabs(inqYValTest(gridTest, 0) - inqYValRef(gridRef, 0)) > 1.e-9
+ || fabs(inqYValTest(gridTest, gridsize-1) - inqYValRef(gridRef, gridsize-1)) > 1.e-9;
- if (gridP->vtable->inqXValsPtr(gridP))
- {
- if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
- count = gridP->size;
- else
- count = gridP->xsize;
- xassert(count);
- packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
- }
+ return differ;
+}
- if (gridP->vtable->inqYValsPtr(gridP))
- {
- if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
- count = gridP->size;
- else
- count = gridP->ysize;
- xassert(count);
- packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
- }
+static
+bool gridCompare(int gridID, const grid_t *grid, bool coord_compare)
+{
+ bool differ = true;
+ const grid_t *gridRef = grid_to_pointer(gridID);
- if (gridP->vtable->inqAreaPtr(gridP))
+ if ( grid->type == gridRef->type || grid->type == GRID_GENERIC )
{
- xassert(gridP->size);
- packBuffSize +=
- serializeGetSize(gridP->size, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ if ( grid->size == gridRef->size )
+ {
+ differ = false;
+ if ( grid->type == GRID_LONLAT || grid->type == GRID_PROJECTION )
+ {
+ /*
+ printf("gridID %d\n", gridID);
+ printf("grid.xdef %d\n", grid->x.flag);
+ printf("grid.ydef %d\n", grid->y.flag);
+ printf("grid.xsize %zu\n", grid->x.size);
+ printf("grid.ysize %zu\n", grid->y.size);
+ printf("grid.xfirst %f\n", grid->x.first);
+ printf("grid.yfirst %f\n", grid->y.first);
+ printf("grid.xfirst %f\n", gridInqXval(gridID, 0));
+ printf("grid.yfirst %f\n", gridInqYval(gridID, 0));
+ printf("grid.xinc %f\n", grid->x.inc);
+ printf("grid.yinc %f\n", grid->y.inc);
+ printf("grid.xinc %f\n", gridInqXinc(gridID));
+ printf("grid.yinc %f\n", gridInqYinc(gridID));
+ */
+ if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+ {
+ if ( grid->x.flag == 2 && grid->y.flag == 2 )
+ {
+ if ( ! (IS_EQUAL(grid->x.first, 0) && IS_EQUAL(grid->x.last, 0) && IS_EQUAL(grid->x.inc, 0)) &&
+ ! (IS_EQUAL(grid->y.first, 0) && IS_EQUAL(grid->y.last, 0) && IS_EQUAL(grid->y.inc, 0)) &&
+ IS_NOT_EQUAL(grid->x.first, grid->x.last) && IS_NOT_EQUAL(grid->y.first, grid->y.last) )
+ {
+ if ( IS_NOT_EQUAL(grid->x.first, gridInqXval(gridID, 0)) ||
+ IS_NOT_EQUAL(grid->y.first, gridInqYval(gridID, 0)))
+ {
+ differ = true;
+ }
+ if ( !differ && fabs(grid->x.inc) > 0 &&
+ fabs(fabs(grid->x.inc) - fabs(gridRef->x.inc)) > fabs(grid->x.inc/1000))
+ {
+ differ = true;
+ }
+ if ( !differ && fabs(grid->y.inc) > 0 &&
+ fabs(fabs(grid->y.inc) - fabs(gridRef->y.inc)) > fabs(grid->y.inc/1000))
+ {
+ differ = true;
+ }
+ }
+ }
+ else if ( grid->x.vals && grid->y.vals )
+ differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+ }
+ else
+ differ = true;
+ }
+ else if ( grid->type == GRID_GENERIC )
+ {
+ if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+ {
+ if ( grid->x.flag == 1 && grid->y.flag == 1
+ && grid->x.vals && grid->y.vals )
+ differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+ }
+ else if ( (grid->y.size == 0 || grid->y.size == 1) &&
+ grid->x.size == gridRef->x.size*gridRef->y.size )
+ {
+ }
+ else
+ differ = true;
+ }
+ else if ( grid->type == GRID_GAUSSIAN )
+ {
+ if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+ {
+ if ( grid->x.flag == 2 && grid->y.flag == 2 )
+ {
+ if ( ! (IS_EQUAL(grid->x.first, 0) && IS_EQUAL(grid->x.last, 0) && IS_EQUAL(grid->x.inc, 0)) &&
+ ! (IS_EQUAL(grid->y.first, 0) && IS_EQUAL(grid->y.last, 0)) )
+ if ( fabs(grid->x.first - gridInqXval(gridID, 0)) > 0.0015 ||
+ fabs(grid->y.first - gridInqYval(gridID, 0)) > 0.0015 ||
+ (fabs(grid->x.inc)>0 && fabs(fabs(grid->x.inc) - fabs(gridRef->x.inc)) > fabs(grid->x.inc/1000)) )
+ {
+ differ = true;
+ }
+ }
+ else if ( grid->x.vals && grid->y.vals )
+ differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+ }
+ else
+ differ = true;
+ }
+ else if ( grid->type == GRID_CURVILINEAR )
+ {
+ /*
+ printf("gridID %d\n", gridID);
+ printf("grid.xsize %d\n", grid->x.size);
+ printf("grid.ysize %d\n", grid->y.size);
+ printf("grid.xfirst %f\n", grid->x.vals[0]);
+ printf("grid.yfirst %f\n", grid->y.vals[0]);
+ printf("grid xfirst %f\n", gridInqXval(gridID, 0));
+ printf("grid yfirst %f\n", gridInqYval(gridID, 0));
+ printf("grid.xlast %f\n", grid->x.vals[grid->size-1]);
+ printf("grid.ylast %f\n", grid->y.vals[grid->size-1]);
+ printf("grid xlast %f\n", gridInqXval(gridID, grid->size-1));
+ printf("grid ylast %f\n", gridInqYval(gridID, grid->size-1));
+ printf("grid.nv %d\n", grid->nvertex);
+ printf("grid nv %d\n", gridInqNvertex(gridID));
+ */
+ if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+ differ = gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
+ }
+ else if ( grid->type == GRID_UNSTRUCTURED )
+ {
+ if ( coord_compare )
+ {
+ differ = grid->nvertex != gridRef->nvertex
+ || gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
+ }
+ else
+ {
+ /* FIXME: not octet 0 but octet 7 is guaranteed non-zero for any non-NULL UUID */
+ differ = differ || (gridRef->uuid[0] && grid->uuid[0] && memcmp(gridRef->uuid, grid->uuid, CDI_UUID_SIZE) != 0);
+
+ if ( !differ &&
+ ((grid->x.vals == NULL) ^ (gridRef->x.vals == NULL)) &&
+ ((grid->y.vals == NULL) ^ (gridRef->y.vals == NULL)) )
+ {
+ int nvertexA, nvertexB, numberA, numberB;
+ differ = ( (nvertexA = grid->nvertex)
+ && (nvertexB = gridRef->nvertex)
+ && (nvertexA != nvertexB) )
+ || (numberA = grid->number, numberB = gridRef->number,
+ ( (numberA)
+ && numberB
+ && (numberA != numberB) )
+ || ( (numberA && numberB)
+ && (grid->position) != (gridRef->position) ) );
+ }
+ else if ( !differ )
+ {
+ differ = grid->nvertex != gridRef->nvertex
+ || grid->number != gridRef->number
+ || (grid->number > 0 && grid->position != gridRef->position)
+ || gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
+ }
+ }
+ }
+ }
}
- if (gridP->xbounds)
+ if ( (grid->scanningMode != gridInqScanningMode(gridID)) || (grid->uvRelativeToGrid != gridInqUvRelativeToGrid(gridID)) )
{
- xassert(gridP->nvertex);
- if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
- count = gridP->size;
- else
- count = gridP->xsize;
- xassert(count);
- packBuffSize
- += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context));
+ // often grid definition may differ in UV-relativeToGrid
+ differ = 1;
+#ifdef HIRLAM_EXTENSIONS
+ if ( cdiDebugExt>=200 )
+ printf("gridCompare(gridID=%d): Differs: grid.scanningMode [%d] != gridInqScanningMode(gridID) [%d] or grid.uvRelativeToGrid [%ld] != gridInqUvRelativeToGrid(gridID) [%d]\n",
+ gridID, grid->scanningMode, gridInqScanningMode(gridID), grid->uvRelativeToGrid, gridInqUvRelativeToGrid(gridID) );
+#endif // HIRLAM_EXTENSIONS
}
+ return differ;
+}
+
+/*
+int gridIsEqual(int gridID1, int gridID2)
+{
+ const grid_t *grid2 = grid_to_pointer(gridID2);
+
+ int grid_is_equal = gridCompare(gridID1, grid2, true) == false;
+
+ return grid_is_equal;
+}
+*/
+
+int gridCompareP(void *gridptr1, void *gridptr2)
+{
+ grid_t *g1 = ( grid_t * ) gridptr1;
+ grid_t *g2 = ( grid_t * ) gridptr2;
+ enum { equal = 0,
+ differ = -1 };
+ size_t i, size;
+
+ xassert ( g1 );
+ xassert ( g2 );
+
+ if ( g1->type != g2->type ) return differ;
+ if ( g1->datatype != g2->datatype ) return differ;
+ if ( g1->isCyclic != g2->isCyclic ) return differ;
+ if ( g1->x.flag != g2->x.flag ) return differ;
+ if ( g1->y.flag != g2->y.flag ) return differ;
+ if ( g1->gme.nd != g2->gme.nd ) return differ;
+ if ( g1->gme.ni != g2->gme.ni ) return differ;
+ if ( g1->gme.ni2 != g2->gme.ni2 ) return differ;
+ if ( g1->gme.ni3 != g2->gme.ni3 ) return differ;
+ if ( g1->number != g2->number ) return differ;
+ if ( g1->position != g2->position ) return differ;
+ if ( g1->trunc != g2->trunc ) return differ;
+ if ( g1->nvertex != g2->nvertex ) return differ;
+ if ( g1->nrowlon != g2->nrowlon ) return differ;
+ if ( g1->size != g2->size ) return differ;
+ if ( g1->x.size != g2->x.size ) return differ;
+ if ( g1->y.size != g2->y.size ) return differ;
+ if ( g1->lcomplex != g2->lcomplex ) return differ;
- if (gridP->ybounds)
+ if ( IS_NOT_EQUAL(g1->x.first , g2->x.first) ) return differ;
+ if ( IS_NOT_EQUAL(g1->y.first , g2->y.first) ) return differ;
+ if ( IS_NOT_EQUAL(g1->x.last , g2->x.last) ) return differ;
+ if ( IS_NOT_EQUAL(g1->y.last , g2->y.last) ) return differ;
+ if ( IS_NOT_EQUAL(g1->x.inc , g2->x.inc) ) return differ;
+ if ( IS_NOT_EQUAL(g1->y.inc , g2->y.inc) ) return differ;
+ if ( IS_NOT_EQUAL(g1->uvRelativeToGrid , g2->uvRelativeToGrid) ) return differ;
+ if ( IS_NOT_EQUAL(g1->scanningMode , g2->scanningMode) ) return differ;
+
+ const double *restrict g1_xvals = g1->vtable->inqXValsPtr(g1),
+ *restrict g2_xvals = g2->vtable->inqXValsPtr(g2);
+ if ( g1_xvals )
{
- xassert(gridP->nvertex);
- if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
- count = gridP->size;
+ if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
+ size = g1->size;
else
- count = gridP->ysize;
- xassert(count);
- packBuffSize
- += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context));
- }
+ size = g1->x.size;
+ xassert ( size );
- {
- const char *strTab[] = GRID_STR_SERIALIZE(gridP);
- int numStr = (int)(sizeof (strTab) / sizeof (strTab[0]));
- packBuffSize
- += serializeStrTabGetPackSize(strTab, numStr, context);
- }
+ if ( !g2_xvals ) return differ;
- if (gridP->reference)
- {
- size_t len = strlen(gridP->reference);
- packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
- + serializeGetSize((int)len + 1, DATATYPE_TXT, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ for ( i = 0; i < size; i++ )
+ if ( IS_NOT_EQUAL(g1_xvals[i], g2_xvals[i]) ) return differ;
}
+ else if ( g2_xvals )
+ return differ;
- if (gridP->mask)
+ const double *restrict g1_yvals = g1->vtable->inqYValsPtr(g1),
+ *restrict g2_yvals = g2->vtable->inqYValsPtr(g2);
+ if ( g1_yvals )
{
- xassert(gridP->size);
- packBuffSize
- += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
- }
+ if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
+ size = g1->size;
+ else
+ size = g1->y.size;
+ xassert ( size );
- if (gridP->mask_gme)
- {
- xassert(gridP->size);
- packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
- }
+ if ( !g2_yvals ) return differ;
- if (!cdiUUIDIsNull(gridP->uuid))
- packBuffSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+ for ( i = 0; i < size; i++ )
+ if ( IS_NOT_EQUAL(g1_yvals[i], g2_yvals[i]) ) return differ;
+ }
+ else if ( g2_yvals )
+ return differ;
- return packBuffSize;
-}
+ const double *restrict g1_area = g1->vtable->inqAreaPtr(g1),
+ *restrict g2_area = g2->vtable->inqAreaPtr(g2);
+ if ( g1_area )
+ {
+ xassert ( g1->size );
-void
-gridUnpack(char * unpackBuffer, int unpackBufferSize,
- int * unpackBufferPos, int originNamespace, void *context,
- int force_id)
-{
- grid_t * gridP;
- uint32_t d;
- int memberMask, size;
+ if ( !g2_area ) return differ;
- gridInit();
+ for ( i = 0; i < g1->size; i++ )
+ if ( IS_NOT_EQUAL(g1_area[i], g2_area[i]) ) return differ;
+ }
+ else if ( g2_area )
+ return differ;
{
- int intBuffer[gridNint];
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- intBuffer, gridNint, DATATYPE_INT, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
-
- xassert(cdiCheckSum(DATATYPE_INT, gridNint, intBuffer) == d);
- int targetID = namespaceAdaptKey(intBuffer[0], originNamespace);
- gridP = gridNewEntry(force_id?targetID:CDI_UNDEFID);
+ const double *restrict g1_xbounds, *restrict g2_xbounds;
+ if ( (g1_xbounds = g1->vtable->inqXBoundsPtr(g1)) )
+ {
+ xassert ( g1->nvertex );
+ if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
+ size = g1->nvertex * g1->size;
+ else
+ size = g1->nvertex * g1->x.size;
+ xassert ( size );
- xassert(!force_id || targetID == gridP->self);
+ if ( !(g2_xbounds = g2->vtable->inqXBoundsPtr(g2)) ) return differ;
- gridP->type = intBuffer[1];
- gridP->prec = intBuffer[2];
- gridP->lcc_projflag = intBuffer[3];
- gridP->lcc_scanflag = intBuffer[4];
- gridP->lcc_defined = (short)intBuffer[5];
- gridP->lcc2_defined = (short)intBuffer[6];
- gridP->laea_defined = intBuffer[7];
- gridP->isCyclic = (short)intBuffer[8];
- gridP->isRotated = (short)intBuffer[9];
- gridP->xdef = (short)intBuffer[10];
- gridP->ydef = (short)intBuffer[11];
- gridP->nd = intBuffer[12];
- gridP->ni = intBuffer[13];
- gridP->ni2 = intBuffer[14];
- gridP->ni3 = intBuffer[15];
- gridP->number = intBuffer[16];
- gridP->position = intBuffer[17];
- gridP->trunc = intBuffer[18];
- gridP->nvertex = intBuffer[19];
- gridP->nrowlon = intBuffer[20];
- gridP->size = intBuffer[21];
- gridP->xsize = intBuffer[22];
- gridP->ysize = intBuffer[23];
- gridP->lcomplex = (short)intBuffer[24];
- memberMask = intBuffer[25];
- gridP->xstdname = xystdname_tab[intBuffer[26]][0];
- gridP->ystdname = xystdname_tab[intBuffer[27]][1];
+ for ( i = 0; i < size; i++ )
+ if ( IS_NOT_EQUAL(g1_xbounds[i], g2_xbounds[i]) ) return differ;
+ }
+ else if ( g2->vtable->inqXBoundsPtr(g2) )
+ return differ;
}
- if (memberMask & gridHasRowLonFlag)
- {
- xassert(gridP->nrowlon);
- gridP->rowlon = (int *) Malloc((size_t)gridP->nrowlon * sizeof (int));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
- }
-
{
- double doubleBuffer[gridNdouble];
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(d == cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer));
-
- gridP->xfirst = doubleBuffer[0];
- gridP->yfirst = doubleBuffer[1];
- gridP->xlast = doubleBuffer[2];
- gridP->ylast = doubleBuffer[3];
- gridP->xinc = doubleBuffer[4];
- gridP->yinc = doubleBuffer[5];
- gridP->lcc_originLon = doubleBuffer[6];
- gridP->lcc_originLat = doubleBuffer[7];
- gridP->lcc_lonParY = doubleBuffer[8];
- gridP->lcc_lat1 = doubleBuffer[9];
- gridP->lcc_lat2 = doubleBuffer[10];
- gridP->lcc_xinc = doubleBuffer[11];
- gridP->lcc_yinc = doubleBuffer[12];
- gridP->lcc2_lon_0 = doubleBuffer[13];
- gridP->lcc2_lat_0 = doubleBuffer[14];
- gridP->lcc2_lat_1 = doubleBuffer[15];
- gridP->lcc2_lat_2 = doubleBuffer[16];
- gridP->lcc2_a = doubleBuffer[17];
- gridP->laea_lon_0 = doubleBuffer[18];
- gridP->laea_lat_0 = doubleBuffer[19];
- gridP->laea_a = doubleBuffer[20];
- gridP->xpole = doubleBuffer[21];
- gridP->ypole = doubleBuffer[22];
- gridP->angle = doubleBuffer[23];
+ const double *restrict g1_ybounds, *restrict g2_ybounds;
+ if ( (g1_ybounds = g1->vtable->inqYBoundsPtr(g1)) )
+ {
+ xassert ( g1->nvertex );
+ if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
+ size = g1->nvertex * g1->size;
+ else
+ size = g1->nvertex * g1->y.size;
+ xassert ( size );
+
+ if ( ! (g2_ybounds = g2->vtable->inqYBoundsPtr(g2)) ) return differ;
+
+ for ( i = 0; i < size; i++ )
+ if ( IS_NOT_EQUAL(g1->y.bounds[i], g2->y.bounds[i]) ) return differ;
+ }
+ else if ( g2->vtable->inqYBoundsPtr(g2) )
+ return differ;
}
- int irregular = gridP->type == GRID_UNSTRUCTURED
- || gridP->type == GRID_CURVILINEAR;
- if (memberMask & gridHasXValsFlag)
- {
- size = irregular ? gridP->size : gridP->xsize;
+ if (strcmp(g1->x.name, g2->x.name)) return differ;
+ if (strcmp(g1->y.name, g2->y.name)) return differ;
+ if (strcmp(g1->x.longname, g2->x.longname)) return differ;
+ if (strcmp(g1->y.longname, g2->y.longname)) return differ;
+ if (g1->x.stdname != g2->x.stdname) return differ;
+ if (g1->y.stdname != g2->y.stdname) return differ;
+ if (strcmp(g1->x.units, g2->x.units)) return differ;
+ if (strcmp(g1->y.units, g2->y.units)) return differ;
- gridP->xvals = (double *) Malloc((size_t)size * sizeof (double));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->xvals, size, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
- }
+ if (strcmp(g1->mapping, g2->mapping)) return differ;
- if (memberMask & gridHasYValsFlag)
+ if ( g1->reference )
{
- size = irregular ? gridP->size : gridP->ysize;
-
- gridP->yvals = (double *) Malloc((size_t)size * sizeof (double));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->yvals, size, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
+ if ( !g2->reference ) return differ;
+ if ( strcmp(g1->reference, g2->reference) ) return differ;
}
+ else if ( g2->reference )
+ return differ;
- if (memberMask & gridHasAreaFlag)
+ if ( g1->mask )
{
- size = gridP->size;
- xassert(size);
- gridP->area = (double *) Malloc((size_t)size * sizeof (double));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->area, size, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
+ xassert ( g1->size );
+ if ( !g2->mask ) return differ;
+ if ( memcmp ( g1->mask, g2->mask, g1->size * sizeof(mask_t)) ) return differ;
}
+ else if ( g2->mask )
+ return differ;
- if (memberMask & gridHasXBoundsFlag)
+ if ( g1->mask_gme )
{
- size = gridP->nvertex * (irregular ? gridP->size : gridP->xsize);
- xassert(size);
-
- gridP->xbounds = (double *) Malloc((size_t)size * sizeof (double));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->xbounds, size, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
+ xassert ( g1->size );
+ if ( !g2->mask_gme ) return differ;
+ if ( memcmp ( g1->mask_gme, g2->mask_gme, g1->size * sizeof(mask_t)) ) return differ;
}
+ else if ( g2->mask_gme )
+ return differ;
- if (memberMask & gridHasYBoundsFlag)
- {
- size = gridP->nvertex * (irregular ? gridP->size : gridP->ysize);
- xassert(size);
+ if ( memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE) )
+ return differ;
- gridP->ybounds = (double *) Malloc((size_t)size * sizeof (double));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->ybounds, size, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
- }
+ return equal;
+}
- {
- char *strTab[] = GRID_STR_SERIALIZE(gridP);
- int numStr = sizeof (strTab) / sizeof (strTab[0]);
- serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- strTab, numStr, context);
- }
+static
+void gridComplete(grid_t *grid)
+{
+ int gridID = grid->self;
+ gridDefDatatype(gridID, grid->datatype);
- if (memberMask & gridHasReferenceFlag)
+ int gridtype = grid->type;
+ switch (gridtype)
{
- int referenceSize;
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &referenceSize, 1, DATATYPE_INT, context);
- gridP->reference = (char *) Malloc((size_t)referenceSize);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->reference, referenceSize, DATATYPE_TXT, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
- }
+ case GRID_LONLAT:
+ case GRID_GAUSSIAN:
+ case GRID_UNSTRUCTURED:
+ case GRID_CURVILINEAR:
+ case GRID_GENERIC:
+ case GRID_PROJECTION:
+ case GRID_CHARXY:
+ {
+ if ( grid->x.size > 0 ) gridDefXsize(gridID, grid->x.size);
+ if ( grid->y.size > 0 ) gridDefYsize(gridID, grid->y.size);
- if (memberMask & gridHasMaskFlag)
- {
- xassert((size = gridP->size));
- gridP->mask = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->mask, gridP->size, DATATYPE_UCHAR, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
- }
+ if ( gridtype == GRID_GAUSSIAN ) gridDefNP(gridID, grid->np);
- if (memberMask & gridHasGMEMaskFlag)
- {
- xassert((size = gridP->size));
- gridP->mask_gme = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
- }
- if (memberMask & gridHasUUIDFlag)
- {
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
- }
+ if ( grid->nvertex > 0 )
+ gridDefNvertex(gridID, grid->nvertex);
- reshSetStatus(gridP->self, &gridOps,
- reshGetStatus(gridP->self, &gridOps) & ~RESH_SYNC_BIT);
-}
+ if ( grid->x.flag == 2 )
+ {
+ assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
+ double *xvals = (double *) Malloc(grid->x.size * sizeof (double));
+ gridGenXvals(grid->x.size, grid->x.first, grid->x.last, grid->x.inc, xvals);
+ grid->x.vals = xvals;
+ // gridDefXinc(gridID, grid->x.inc);
+ }
+ if ( grid->y.flag == 2 )
+ {
+ assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
+ double *yvals = (double *) Malloc(grid->y.size * sizeof (double));
+ gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
+ grid->y.vals = yvals;
+ // gridDefYinc(gridID, grid->y.inc);
+ }
-static void
-gridPack(void * voidP, void * packBuffer, int packBufferSize,
- int * packBufferPos, void *context)
-{
- grid_t * gridP = ( grid_t * ) voidP;
- int size;
- uint32_t d;
- int memberMask;
+ if ( grid->projtype == CDI_PROJ_RLL )
+ {
+ if ( grid->x.name[0] == 0 || grid->x.name[0] == 'x' ) strcpy(grid->x.name, "rlon");
+ if ( grid->y.name[0] == 0 || grid->y.name[0] == 'y' ) strcpy(grid->y.name, "rlat");
+ if ( grid->x.longname[0] == 0 ) strcpy(grid->x.longname, "longitude in rotated pole grid");
+ if ( grid->y.longname[0] == 0 ) strcpy(grid->y.longname, "latitude in rotated pole grid");
+ grid->x.stdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+ grid->y.stdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+ if ( grid->x.units[0] == 0 ) strcpy(grid->x.units, "degrees");
+ if ( grid->y.units[0] == 0 ) strcpy(grid->y.units, "degrees");
+ }
- {
- int intBuffer[gridNint];
+ if ( gridtype == GRID_UNSTRUCTURED )
+ {
+ int number = grid->number;
+ int position = grid->position >= 0 ? grid->position : 0;
+ if ( number > 0 ) gridDefNumber(gridID, number);
+ gridDefPosition(gridID, position);
+ }
- intBuffer[0] = gridP->self;
- intBuffer[1] = gridP->type;
- intBuffer[2] = gridP->prec;
- intBuffer[3] = gridP->lcc_projflag;
- intBuffer[4] = gridP->lcc_scanflag;
- intBuffer[5] = gridP->lcc_defined;
- intBuffer[6] = gridP->lcc2_defined;
- intBuffer[7] = gridP->laea_defined;
- intBuffer[8] = gridP->isCyclic;
- intBuffer[9] = gridP->isRotated;
- intBuffer[10] = gridP->xdef;
- intBuffer[11] = gridP->ydef;
- intBuffer[12] = gridP->nd;
- intBuffer[13] = gridP->ni;
- intBuffer[14] = gridP->ni2;
- intBuffer[15] = gridP->ni3;
- intBuffer[16] = gridP->number;
- intBuffer[17] = gridP->position;
- intBuffer[18] = gridP->trunc;
- intBuffer[19] = gridP->nvertex;
- intBuffer[20] = gridP->nrowlon;
- intBuffer[21] = gridP->size;
- intBuffer[22] = gridP->xsize;
- intBuffer[23] = gridP->ysize;
- intBuffer[24] = gridP->lcomplex;
- intBuffer[25] = memberMask = gridGetComponentFlags(gridP);
- intBuffer[26] = (int)((const char (*)[2][24])gridP->xstdname
- - xystdname_tab);
- intBuffer[27] = (int)((const char (*)[2][24])gridP->ystdname
- - (const char (*)[2][24])xystdname_tab[0][1]);
-
- serializePack(intBuffer, gridNint, DATATYPE_INT,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
- }
+ break;
+ }
+ case GRID_GAUSSIAN_REDUCED:
+ {
+ gridDefNP(gridID, grid->np);
+ gridDefYsize(gridID, grid->y.size);
+ if ( grid->x.flag == 2 )
+ {
+ double xvals[2] = { grid->x.first, grid->x.last };
+ gridDefXvals(gridID, xvals);
+ }
- if (memberMask & gridHasRowLonFlag)
- {
- size = gridP->nrowlon;
- xassert(size > 0);
- serializePack(gridP->rowlon, size, DATATYPE_INT,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ if ( grid->y.flag == 2 )
+ {
+ double *yvals = (double *) Malloc(grid->y.size * sizeof (double));
+ gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
+ grid->y.vals = yvals;
+ /*
+ gridDefYinc(gridID, grid->y.inc);
+ */
+ }
+ break;
+ }
+ case GRID_SPECTRAL:
+ {
+ gridDefTrunc(gridID, grid->trunc);
+ if ( grid->lcomplex ) gridDefComplexPacking(gridID, 1);
+ break;
+ }
+ case GRID_FOURIER:
+ {
+ gridDefTrunc(gridID, grid->trunc);
+ break;
+ }
+ case GRID_GME:
+ {
+ gridDefParamGME(gridID, grid->gme.nd, grid->gme.ni, grid->gme.ni2, grid->gme.ni3);
+ break;
+ }
+ /*
+ case GRID_GENERIC:
+ {
+ if ( grid->x.size > 0 && grid->y.size > 0 )
+ {
+ gridDefXsize(gridID, grid->x.size);
+ gridDefYsize(gridID, grid->y.size);
+ if ( grid->x.vals ) gridDefXvals(gridID, grid->x.vals);
+ if ( grid->y.vals ) gridDefYvals(gridID, grid->y.vals);
+ }
+ break;
+ }
+ */
+ case GRID_TRAJECTORY:
+ {
+ gridDefXsize(gridID, 1);
+ gridDefYsize(gridID, 1);
+ break;
+ }
+ default:
+ {
+ Error("Gridtype %s unsupported!", gridNamePtr(gridtype));
+ break;
+ }
}
- {
- double doubleBuffer[gridNdouble];
+ grid->x.name[CDI_MAX_NAME - 1] = 0;
+ grid->x.longname[CDI_MAX_NAME - 1] = 0;
+ grid->x.units[CDI_MAX_NAME - 1] = 0;
+ grid->y.name[CDI_MAX_NAME - 1] = 0;
+ grid->y.longname[CDI_MAX_NAME - 1] = 0;
+ grid->y.units[CDI_MAX_NAME - 1] = 0;
+}
- doubleBuffer[0] = gridP->xfirst;
- doubleBuffer[1] = gridP->yfirst;
- doubleBuffer[2] = gridP->xlast;
- doubleBuffer[3] = gridP->ylast;
- doubleBuffer[4] = gridP->xinc;
- doubleBuffer[5] = gridP->yinc;
- doubleBuffer[6] = gridP->lcc_originLon;
- doubleBuffer[7] = gridP->lcc_originLat;
- doubleBuffer[8] = gridP->lcc_lonParY;
- doubleBuffer[9] = gridP->lcc_lat1;
- doubleBuffer[10] = gridP->lcc_lat2;
- doubleBuffer[11] = gridP->lcc_xinc;
- doubleBuffer[12] = gridP->lcc_yinc;
- doubleBuffer[13] = gridP->lcc2_lon_0;
- doubleBuffer[14] = gridP->lcc2_lat_0;
- doubleBuffer[15] = gridP->lcc2_lat_1;
- doubleBuffer[16] = gridP->lcc2_lat_2;
- doubleBuffer[17] = gridP->lcc2_a;
- doubleBuffer[18] = gridP->laea_lon_0;
- doubleBuffer[19] = gridP->laea_lat_0;
- doubleBuffer[20] = gridP->laea_a;
- doubleBuffer[21] = gridP->xpole;
- doubleBuffer[22] = gridP->ypole;
- doubleBuffer[23] = gridP->angle;
-
- serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
- }
+#define GRID_STR_SERIALIZE(gridP) { gridP->x.dimname, gridP->y.dimname, \
+ gridP->vdimname, gridP->x.name, gridP->y.name, \
+ gridP->x.longname, gridP->y.longname, \
+ gridP->x.units, gridP->y.units }
- if (memberMask & gridHasXValsFlag)
+int gridGenerate(const grid_t *grid)
+{
+ int gridtype = grid->type;
+ int gridID = gridCreate(gridtype, grid->size);
+ grid_t *restrict gridptr = grid_to_pointer(gridID);
+ gridptr->datatype = grid->datatype;
+ gridptr->x.size = grid->x.size;
+ gridptr->y.size = grid->y.size;
+ gridptr->np = grid->np;
+ gridptr->nvertex = grid->nvertex;
+ gridptr->x.flag = grid->x.flag;
+ int valdef_group1 = 0;
+ static const int valdef_group1_tab[] = {
+ GRID_LONLAT, GRID_GAUSSIAN, GRID_UNSTRUCTURED, GRID_CURVILINEAR,
+ GRID_GENERIC, GRID_PROJECTION
+ };
+ for ( size_t i = 0; i < sizeof (valdef_group1_tab) / sizeof (valdef_group1_tab[0]); ++i)
+ valdef_group1 |= (gridtype == valdef_group1_tab[i]);
+ if ( valdef_group1 && grid->x.flag == 1 )
{
- if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
- size = gridP->size;
- else
- size = gridP->xsize;
- xassert(size);
+ gridDefXvals(gridID, grid->x.vals);
+ if ( grid->x.bounds )
+ gridDefXbounds(gridID, grid->x.bounds);
+ }
+ gridptr->x.first = grid->x.first;
+ gridptr->x.last = grid->x.last;
+ gridptr->x.inc = grid->x.inc;
+ gridptr->y.flag = grid->y.flag;
+ if ( (valdef_group1 || gridtype == GRID_GAUSSIAN_REDUCED) && grid->y.flag == 1)
+ {
+ gridDefYvals(gridID, grid->y.vals);
+ if ( grid->y.bounds )
+ gridDefYbounds(gridID, grid->y.bounds);
+ }
+ gridptr->y.first = grid->y.first;
+ gridptr->y.last = grid->y.last;
+ gridptr->y.inc = grid->y.inc;
+ if ( valdef_group1 && grid->area)
+ gridDefArea(gridID, grid->area);
+ gridptr->number = grid->number;
+ gridptr->position = grid->position;
+ gridptr->uvRelativeToGrid = grid->uvRelativeToGrid;
+ gridptr->scanningMode = grid->scanningMode;
+ gridptr->iScansNegatively = grid->iScansNegatively;
+ gridptr->jScansPositively = grid->jScansPositively;
+ gridptr->jPointsAreConsecutive = grid->jPointsAreConsecutive;
+ memcpy(gridptr->uuid, grid->uuid, CDI_UUID_SIZE);
+ if ( gridtype == GRID_UNSTRUCTURED && grid->reference )
+ gridDefReference(gridID, grid->reference);
+ if ( gridtype == GRID_PROJECTION )
+ gridptr->name = strdup(grid->name);
+ if ( gridtype == GRID_GAUSSIAN_REDUCED )
+ gridDefRowlon(gridID, grid->y.size, grid->rowlon);
+ gridptr->trunc = grid->trunc;
+ gridptr->lcomplex = grid->lcomplex;
+ gridptr->gme.nd = grid->gme.nd;
+ gridptr->gme.ni = grid->gme.ni;
+ gridptr->gme.ni2 = grid->gme.ni2;
+ gridptr->gme.ni3 = grid->gme.ni3;
+ const char *grid_str_tab[] = GRID_STR_SERIALIZE(grid);
+ char *gridptr_str_tab[] = GRID_STR_SERIALIZE(gridptr);
+ for (size_t i = 0; i < sizeof (grid_str_tab) / sizeof (grid_str_tab[0]); ++i)
+ if ( grid_str_tab[i][0] )
+ memcpy(gridptr_str_tab[i], grid_str_tab[i], CDI_MAX_NAME);
+ gridComplete(gridptr);
- const double *gridP_xvals = gridP->vtable->inqXValsPtr(gridP);
- serializePack(gridP_xvals, size, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, size, gridP_xvals);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ return gridID;
+}
+
+static void
+grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
+{
+ size_t nrowlon = (size_t)gridptrOrig->nrowlon;
+ size_t gridsize = gridptrOrig->size;
+ int gridtype = gridptrOrig->type;
+ int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
+ if ( nrowlon )
+ {
+ gridptrDup->rowlon = (int*) Malloc(nrowlon * sizeof(int));
+ memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
}
- if (memberMask & gridHasYValsFlag)
+ if ( gridptrOrig->x.vals != NULL )
{
- if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR )
- size = gridP->size;
- else
- size = gridP->ysize;
- xassert(size);
- const double *gridP_yvals = gridP->vtable->inqYValsPtr(gridP);
- serializePack(gridP_yvals, size, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, size, gridP_yvals);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ size_t size = irregular ? gridsize : gridptrOrig->x.size;
+
+ gridptrDup->x.vals = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->x.vals, gridptrOrig->x.vals, size * sizeof (double));
}
- if (memberMask & gridHasAreaFlag)
+ if ( gridptrOrig->y.vals != NULL )
{
- xassert(gridP->size);
+ size_t size = irregular ? gridsize : gridptrOrig->y.size;
- serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ gridptrDup->y.vals = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->y.vals, gridptrOrig->y.vals, size * sizeof (double));
}
- if (memberMask & gridHasXBoundsFlag)
+ if ( gridptrOrig->x.bounds != NULL )
{
- xassert ( gridP->nvertex );
- if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
- size = gridP->nvertex * gridP->size;
- else
- size = gridP->nvertex * gridP->xsize;
- xassert ( size );
+ size_t size = (irregular ? gridsize : gridptrOrig->x.size)
+ * gridptrOrig->nvertex;
- serializePack(gridP->xbounds, size, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ gridptrDup->x.bounds = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->x.bounds, gridptrOrig->x.bounds, size * sizeof (double));
}
- if (memberMask & gridHasYBoundsFlag)
+ if ( gridptrOrig->y.bounds != NULL )
{
- xassert(gridP->nvertex);
- if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
- size = gridP->nvertex * gridP->size;
- else
- size = gridP->nvertex * gridP->ysize;
- xassert ( size );
+ size_t size = (irregular ? gridsize : gridptrOrig->y.size)
+ * gridptrOrig->nvertex;
- serializePack(gridP->ybounds, size, DATATYPE_FLT64,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ gridptrDup->y.bounds = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->y.bounds, gridptrOrig->y.bounds, size * sizeof (double));
}
{
- const char *strTab[] = GRID_STR_SERIALIZE(gridP);
- int numStr = sizeof (strTab) / sizeof (strTab[0]);
- serializeStrTabPack(strTab, numStr,
- packBuffer, packBufferSize, packBufferPos, context);
+ const double *gridptrOrig_area
+ = gridptrOrig->vtable->inqAreaPtr(gridptrOrig);
+ if ( gridptrOrig_area != NULL )
+ {
+ size_t size = gridsize;
+
+ gridptrDup->area = (double *)Malloc(size * sizeof (double));
+ memcpy(gridptrDup->area, gridptrOrig_area, size * sizeof (double));
+ }
}
- if (memberMask & gridHasReferenceFlag)
+ if ( gridptrOrig->mask != NULL )
{
- size = (int)strlen(gridP->reference) + 1;
- serializePack(&size, 1, DATATYPE_INT,
- packBuffer, packBufferSize, packBufferPos, context);
- serializePack(gridP->reference, size, DATATYPE_TXT,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
- }
+ size_t size = gridsize;
- if (memberMask & gridHasMaskFlag)
- {
- xassert((size = gridP->size));
- serializePack(gridP->mask, size, DATATYPE_UCHAR,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
+ memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
}
- if (memberMask & gridHasGMEMaskFlag)
+ if ( gridptrOrig->mask_gme != NULL )
{
- xassert((size = gridP->size));
+ size_t size = gridsize;
- serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
- packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
- serializePack(&d, 1, DATATYPE_UINT32,
- packBuffer, packBufferSize, packBufferPos, context);
+ gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
+ memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
}
-
- if (memberMask & gridHasUUIDFlag)
- serializePack(gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
- packBuffer, packBufferSize, packBufferPos, context);
}
-#undef GRID_STR_SERIALIZE
+/*
+ at Function gridDuplicate
+ at Title Duplicate a horizontal Grid
-struct gridCompareSearchState
+ at Prototype int gridDuplicate(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+
+ at Description
+The function @func{gridDuplicate} duplicates a horizontal Grid.
+
+ at Result
+ at func{gridDuplicate} returns an identifier to the duplicated Grid.
+
+ at EndFunction
+*/
+int gridDuplicate(int gridID)
{
- int resIDValue;
- const grid_t *queryKey;
-};
+ grid_t *gridptr = grid_to_pointer(gridID);
+ grid_t *gridptrnew = gridptr->vtable->copy(gridptr);
+ int gridIDnew = reshPut(gridptrnew, &gridOps);
+ gridptrnew->self = gridIDnew;
+ return gridIDnew;
+}
-static enum cdiApplyRet
-gridCompareSearch(int id, void *res, void *data)
+
+void gridCompress(int gridID)
{
- struct gridCompareSearchState *state = (struct gridCompareSearchState*)data;
- (void)res;
- if ( gridCompare(id, state->queryKey) == false )
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ int gridtype = gridInqType(gridID);
+ if ( gridtype == GRID_UNSTRUCTURED )
{
- state->resIDValue = id;
- return CDI_APPLY_STOP;
+ if ( gridptr->mask_gme != NULL )
+ {
+ size_t gridsize = gridInqSize(gridID);
+ size_t nv = (size_t)gridptr->nvertex;
+ double *restrict area
+ = (double *)gridptr->vtable->inqAreaPtr(gridptr),
+ *restrict xvals = (double *)gridptr->vtable->inqXValsPtr((grid_t *)gridptr),
+ *restrict yvals = (double *)gridptr->vtable->inqYValsPtr((grid_t *)gridptr),
+ *restrict xbounds = (double *)gridptr->vtable->inqXBoundsPtr(gridptr),
+ *restrict ybounds = (double *)gridptr->vtable->inqYBoundsPtr(gridptr);
+ mask_t *restrict mask_gme = gridptr->mask_gme;
+ size_t *restrict selection = (size_t *)Malloc(gridsize * sizeof (selection[0]));
+ size_t nselect;
+ {
+ size_t j = 0;
+ for (size_t i = 0; i < gridsize; i++ )
+ selection[j] = i, j += (mask_gme[i] != 0);
+ nselect = j;
+ }
+ selection = (size_t *)Realloc(selection, nselect * sizeof (selection[0]));
+ if (xvals)
+ for (size_t i = 0; i < nselect; i++ )
+ xvals[i] = xvals[selection[i]];
+ if (yvals)
+ for (size_t i = 0; i < nselect; i++ )
+ yvals[i] = yvals[selection[i]];
+ if (area)
+ for (size_t i = 0; i < nselect; i++ )
+ area[i] = area[selection[i]];
+ if (xbounds)
+ for (size_t i = 0; i < nselect; i++ )
+ for (size_t iv = 0; iv < nv; iv++)
+ xbounds[i * nv + iv] = xbounds[selection[i] * nv + iv];
+ if (ybounds)
+ for (size_t i = 0; i < nselect; i++ )
+ for (size_t iv = 0; iv < nv; iv++)
+ ybounds[i * nv + iv] = ybounds[selection[i] * nv + iv];
+ Free(selection);
+
+ /* fprintf(stderr, "grid compress %d %d %d\n", i, j, gridsize); */
+ gridsize = nselect;
+ gridptr->size = (int)gridsize;
+ gridptr->x.size = (int)gridsize;
+ gridptr->y.size = (int)gridsize;
+
+ double **resizeP[] = { &gridptr->x.vals, &gridptr->y.vals,
+ &gridptr->area,
+ &gridptr->x.bounds, &gridptr->y.bounds };
+ size_t newSize[] = { gridsize, gridsize, gridsize, nv*gridsize,
+ nv*gridsize };
+ for ( size_t i = 0; i < sizeof (resizeP) / sizeof (resizeP[0]); ++i)
+ if ( *(resizeP[i]) )
+ *(resizeP[i]) = (double *)Realloc(*(resizeP[i]), newSize[i]*sizeof(double));
+
+ Free(gridptr->mask_gme);
+ gridptr->mask_gme = NULL;
+ gridMark4Update(gridID);
+ }
}
else
- return CDI_APPLY_GO_ON;
+ Warning("Unsupported grid type: %s", gridNamePtr(gridtype));
}
-/* Add grid (which must be Malloc'ed to vlist if not already found */
-struct addIffNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
+static void
+gridDefAreaSerial(grid_t *gridptr, const double *area)
{
- /*
- mode: 0 search in vlist and grid table
- 1 search in grid table only
- */
- bool gridglobdefined = false;
- bool griddefined = false;
- int gridID = CDI_UNDEFID;
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
+ size_t size = gridptr->size;
- unsigned ngrids = (unsigned)vlistptr->ngrids;
+ if ( size == 0 )
+ Error("size undefined for gridID = %d", gridptr->self);
- if ( mode == 0 )
- for ( unsigned index = 0; index < ngrids; index++ )
- {
- if ( (gridID = vlistptr->gridIDs[index]) != UNDEFID )
- {
- if ( gridCompare(gridID, grid) == false )
- {
- griddefined = true;
- break;
- }
- }
- else
- Error("Internal problem: undefined gridID in vlist "
- "%d, position %u!", vlistID, index);
+ if ( gridptr->area == NULL )
+ gridptr->area = (double *) Malloc(size*sizeof(double));
+ else if ( CDI_Debug )
+ Warning("values already defined!");
- }
+ memcpy(gridptr->area, area, size * sizeof(double));
+}
- if ( ! griddefined )
- {
- struct gridCompareSearchState query;
- query.queryKey = grid;// = { .queryKey = grid };
- if ((gridglobdefined
- = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query)
- == CDI_APPLY_STOP)))
- gridID = query.resIDValue;
- if ( mode == 1 && gridglobdefined )
- for (unsigned index = 0; index < ngrids; index++ )
- if ( vlistptr->gridIDs[index] == gridID )
- {
- gridglobdefined = false;
- break;
- }
- }
+void gridDefArea(int gridID, const double *area)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defArea(gridptr, area);
+ gridMark4Update(gridID);
+}
- if ( ! griddefined )
- {
- if ( ! gridglobdefined )
- {
- grid->self = gridID = reshPut(grid, &gridOps);
- gridComplete(grid);
- }
- vlistptr->gridIDs[ngrids] = gridID;
- vlistptr->ngrids++;
- }
+static void
+gridInqAreaSerial(grid_t *gridptr, double *area)
+{
+ if (gridptr->area)
+ memcpy(area, gridptr->area, gridptr->size * sizeof (double));
+}
- return (struct addIffNewRes){ .Id = gridID,
- .isNew = !griddefined && !gridglobdefined };
+
+void gridInqArea(int gridID, double *area)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->inqArea(gridptr, area);
}
-const struct gridVirtTable cdiGridVtable
- = {
- .destroy = gridDestroyKernel,
- .copy = grid_copy_base,
- .copyScalarFields = grid_copy_base_scalar_fields,
- .copyArrayFields = grid_copy_base_array_fields,
- .defXVals = gridDefXValsSerial,
- .defYVals = gridDefYValsSerial,
- .defMask = gridDefMaskSerial,
- .defMaskGME = gridDefMaskGMESerial,
- .defXBounds = gridDefXBoundsSerial,
- .defYBounds = gridDefYBoundsSerial,
- .defArea = gridDefAreaSerial,
- .inqXVal = gridInqXValSerial,
- .inqYVal = gridInqYValSerial,
- .inqXVals = gridInqXValsSerial,
- .inqYVals = gridInqYValsSerial,
- .inqXValsPtr = gridInqXValsPtrSerial,
- .inqYValsPtr = gridInqYValsPtrSerial,
- .compareXYFull = compareXYvals,
- .compareXYAO = compareXYvals2,
- .inqArea = gridInqAreaSerial,
- .inqAreaPtr = gridInqAreaPtrBase,
- .hasArea = gridHasAreaBase,
- .inqMask = gridInqMaskSerial,
- .inqMaskGME = gridInqMaskGMESerial,
- .inqXBounds = gridInqXBoundsSerial,
- .inqYBounds = gridInqYBoundsSerial,
- .inqXBoundsPtr = gridInqXBoundsPtrSerial,
- .inqYBoundsPtr = gridInqYBoundsPtrSerial,
-};
+static int
+gridHasAreaBase(grid_t *gridptr)
+{
+ return gridptr->area != NULL;
+}
+
+int gridHasArea(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->hasArea(gridptr);
+}
+
+
+static const double *gridInqAreaPtrBase(grid_t *gridptr)
+{
+ return gridptr->area;
+}
+
+const double *gridInqAreaPtr(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqAreaPtr(gridptr);
+}
+
+
+void gridDefNvertex(int gridID, int nvertex)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ if (gridptr->nvertex != nvertex)
+ {
+ gridptr->nvertex = nvertex;
+ gridMark4Update(gridID);
+ }
+}
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
+int gridInqNvertex(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->nvertex;
+}
+static void
+gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, size_t regularSize,
+ double **field)
+{
+ int irregular = gridptr->type == GRID_CURVILINEAR
+ || gridptr->type == GRID_UNSTRUCTURED;
+ size_t nvertex = (size_t)gridptr->nvertex;
+ if ( nvertex == 0 )
+ {
+ Warning("nvertex undefined for gridID = %d. Cannot define bounds!",
+ gridptr->self);
+ return;
+ }
+ size_t size = nvertex * (irregular ? gridptr->size : regularSize);
+ if ( size == 0 )
+ Error("size undefined for gridID = %d", gridptr->self);
-static int initIegLib = 0;
-static int iegDefaultDprec = 0;
+ if (*field == NULL)
+ *field = (double *)Malloc(size * sizeof (double));
+ else if ( CDI_Debug )
+ Warning("values already defined!");
+ memcpy(*field, bounds, size * sizeof (double));
+}
-/*
- * A version string.
- */
-#undef LIBVERSION
-#define LIBVERSION 1.4.0
-#define XSTRING(x) #x
-#define STRING(x) XSTRING(x)
-static const char ieg_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__;
-const char *iegLibraryVersion(void)
+static void
+gridDefXBoundsSerial(grid_t *gridptr, const double *xbounds)
{
- return ieg_libvers;
+ gridDefBoundsGeneric(gridptr, xbounds, gridptr->x.size, &gridptr->x.bounds);
}
+/*
+ at Function gridDefXbounds
+ at Title Define the bounds of a X-axis
-static int IEG_Debug = 0; /* If set to 1, debugging */
+ at Prototype void gridDefXbounds(int gridID, const double *xbounds)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item xbounds X-bounds of the grid.
-static
-void iegLibInit(void)
+ at Description
+The function @func{gridDefXbounds} defines all bounds of the X-axis.
+
+ at EndFunction
+*/
+void gridDefXbounds(int gridID, const double *xbounds)
{
- const char *envName = "IEG_PRECISION";
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defXBounds(gridptr, xbounds);
+ gridMark4Update(gridID);
+}
- char *envString = getenv(envName);
- if ( envString )
- {
- int pos;
- int nrun;
- if ( strlen(envString) == 2 ) nrun = 1;
- else nrun = 2;
+static size_t
+gridInqXBoundsSerial(grid_t *gridptr, double *xbounds)
+{
+ size_t nvertex = (size_t)gridptr->nvertex;
- pos = 0;
- while ( nrun-- )
- {
- switch ( tolower((int) envString[pos]) )
- {
- case 'r':
- {
- switch ( (int) envString[pos+1] )
- {
- case '4': iegDefaultDprec = EXSE_SINGLE_PRECISION; break;
- case '8': iegDefaultDprec = EXSE_DOUBLE_PRECISION; break;
- default:
- Message("Invalid digit in %s: %s", envName, envString);
- }
- break;
- }
- default:
- {
- Message("Invalid character in %s: %s", envName, envString);
- break;
- }
- }
- pos += 2;
- }
+ int irregular = gridptr->type == GRID_CURVILINEAR
+ || gridptr->type == GRID_UNSTRUCTURED;
+ size_t size = nvertex * (irregular ? gridptr->size : gridptr->x.size);
+
+ const double *gridptr_xbounds = gridptr->vtable->inqXBoundsPtr(gridptr);
+ if ( gridptr_xbounds )
+ {
+ if ( size && xbounds )
+ memcpy(xbounds, gridptr_xbounds, size * sizeof (double));
}
+ else
+ size = 0;
- initIegLib = 1;
+ return size;
}
+/*
+ at Function gridInqXbounds
+ at Title Get the bounds of a X-axis
+
+ at Prototype size_t gridInqXbounds(int gridID, double *xbounds)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item xbounds Pointer to the location into which the X-bounds are read.
+ The caller must allocate space for the returned values.
-void iegDebug(int debug)
-{
- IEG_Debug = debug;
+ at Description
+The function @func{gridInqXbounds} returns the bounds of the X-axis.
- if ( IEG_Debug )
- Message("debug level %d", debug);
+ at Result
+Upon successful completion @func{gridInqXbounds} returns the number of bounds and
+the bounds are stored in @func{xbounds}.
+Otherwise, 0 is returned and @func{xbounds} is empty.
+
+ at EndFunction
+*/
+size_t gridInqXbounds(int gridID, double *xbounds)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXBounds(gridptr, xbounds);
}
-static
-void iegInit(iegrec_t *iegp)
+static const double *
+gridInqXBoundsPtrSerial(grid_t *gridptr)
{
- iegp->checked = 0;
- iegp->byteswap = 0;
- iegp->dprec = 0;
- iegp->refval = 0;
- iegp->datasize = 0;
- iegp->buffersize = 0;
- iegp->buffer = NULL;
+ return gridptr->x.bounds;
}
-void iegInitMem(void *ieg)
+const double *gridInqXboundsPtr(int gridID)
{
- iegrec_t *iegp = (iegrec_t *) ieg;
-
- memset(iegp->ipdb, 0, sizeof(iegp->ipdb));
- memset(iegp->igdb, 0, sizeof(iegp->igdb));
- memset(iegp->vct, 0, sizeof(iegp->vct));
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXBoundsPtr(gridptr);
}
-
-void *iegNew(void)
+static void
+gridDefYBoundsSerial(grid_t *gridptr, const double *ybounds)
{
- if ( ! initIegLib ) iegLibInit();
+ gridDefBoundsGeneric(gridptr, ybounds, gridptr->y.size, &gridptr->y.bounds);
+}
- iegrec_t *iegp = (iegrec_t *) Malloc(sizeof(iegrec_t));
+/*
+ at Function gridDefYbounds
+ at Title Define the bounds of a Y-axis
- iegInit(iegp);
- iegInitMem(iegp);
+ at Prototype void gridDefYbounds(int gridID, const double *ybounds)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item ybounds Y-bounds of the grid.
- return (void*)iegp;
-}
+ at Description
+The function @func{gridDefYbounds} defines all bounds of the Y-axis.
+ at EndFunction
+*/
+void gridDefYbounds(int gridID, const double *ybounds)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->vtable->defYBounds(gridptr, ybounds);
+ gridMark4Update(gridID);
+}
-void iegDelete(void *ieg)
+static size_t
+gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
{
- iegrec_t *iegp = (iegrec_t *) ieg;
+ size_t nvertex = (size_t)gridptr->nvertex;
- if ( iegp )
+ int irregular = gridptr->type == GRID_CURVILINEAR
+ || gridptr->type == GRID_UNSTRUCTURED;
+ size_t size = nvertex * (irregular ? gridptr->size : gridptr->y.size);
+
+ const double *gridptr_ybounds = gridptr->vtable->inqYBoundsPtr(gridptr);
+ if ( gridptr_ybounds )
{
- if ( iegp->buffer ) Free(iegp->buffer);
- Free(iegp);
+ if ( size && ybounds )
+ memcpy(ybounds, gridptr_ybounds, size * sizeof (double));
}
+ else
+ size = 0;
+
+ return size;
}
-int iegCheckFiletype(int fileID, int *swap)
+/*
+ at Function gridInqYbounds
+ at Title Get the bounds of a Y-axis
+
+ at Prototype size_t gridInqYbounds(int gridID, double *ybounds)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item ybounds Pointer to the location into which the Y-bounds are read.
+ The caller must allocate space for the returned values.
+
+ at Description
+The function @func{gridInqYbounds} returns the bounds of the Y-axis.
+
+ at Result
+Upon successful completion @func{gridInqYbounds} returns the number of bounds and
+the bounds are stored in @func{ybounds}.
+Otherwise, 0 is returned and @func{ybounds} is empty.
+
+ at EndFunction
+*/
+size_t gridInqYbounds(int gridID, double *ybounds)
{
- size_t data = 0;
- size_t dimx = 0, dimy = 0;
- size_t fact = 0;
- unsigned char buffer[1048], *pbuf;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYBounds(gridptr, ybounds);
+}
- if ( fileRead(fileID, buffer, 4) != 4 ) return 0;
+static const double *
+gridInqYBoundsPtrSerial(grid_t *gridptr)
+{
+ return gridptr->y.bounds;
+}
- size_t blocklen = get_UINT32(buffer);
- size_t sblocklen = get_SUINT32(buffer);
- if ( IEG_Debug )
- Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+const double *gridInqYboundsPtr(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYBoundsPtr(gridptr);
+}
- if ( blocklen == 636 || blocklen == 640 )
+static void
+printDblsPrefixAutoBrk(FILE *fp, int dig, const char prefix[], size_t nbyte0,
+ size_t n, const double vals[])
+{
+ fputs(prefix, fp);
+ size_t nbyte = nbyte0;
+ for ( size_t i = 0; i < n; i++ )
{
- *swap = 0;
- fact = 4;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
- pbuf = buffer+(37+4)*4; dimx = (size_t) get_UINT32(pbuf);
- pbuf = buffer+(37+5)*4; dimy = (size_t) get_UINT32(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ if ( nbyte > 80 )
+ {
+ fprintf(fp, "\n%*s", (int)nbyte0, "");
+ nbyte = nbyte0;
+ }
+ nbyte += (size_t)fprintf(fp, "%.*g ", dig, vals[i]);
}
- else if ( blocklen == 1040 || blocklen == 1036 )
+ fputs("\n", fp);
+}
+
+static void
+printIntsPrefixAutoBrk(FILE *fp, const char prefix[], size_t nbyte0,
+ size_t n, const int vals[])
+{
+ fputs(prefix, fp);
+ size_t nbyte = nbyte0;
+ for ( size_t i = 0; i < n; i++ )
{
- *swap = 0;
- fact = 8;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
- pbuf = buffer+(37+4)*4; dimx = (size_t) get_UINT32(pbuf);
- pbuf = buffer+(37+5)*4; dimy = (size_t) get_UINT32(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ if ( nbyte > 80 )
+ {
+ fprintf(fp, "\n%*s", (int)nbyte0, "");
+ nbyte = nbyte0;
+ }
+ nbyte += (size_t)fprintf(fp, "%d ", vals[i]);
}
- else if ( sblocklen == 636 || sblocklen == 640 )
+ fputs("\n", fp);
+}
+
+static void
+printBounds(FILE *fp, int dig, const char prefix[], size_t nbyte0,
+ size_t n, size_t nvertex, const double bounds[])
+{
+ fputs(prefix, fp);
+ if ( n > 0 )
{
- *swap = 1;
- fact = 4;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
- pbuf = buffer+(37+4)*4; dimx = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+(37+5)*4; dimy = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ for ( size_t iv = 0; iv < nvertex; iv++ )
+ fprintf(fp, "%.*g ", dig, bounds[iv]);
+ for ( size_t i = 1; i < n; i++ )
+ {
+ fprintf(fp, "\n%*s", (int)nbyte0, "");
+ for ( size_t iv = 0; iv < nvertex; iv++ )
+ fprintf(fp, "%.*g ", dig, bounds[i*nvertex+iv]);
+ }
+ fputs("\n", fp);
}
- else if ( sblocklen == 1040 || sblocklen == 1036 )
+}
+
+static void
+printMask(FILE *fp, const char prefix[], size_t nbyte0,
+ size_t n, const int mask[])
+{
+ fputs(prefix, fp);
+ size_t nbyte = nbyte0;
+ for ( size_t i = 0; i < n; i++ )
{
- *swap = 1;
- fact = 8;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
- pbuf = buffer+(37+4)*4; dimx = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+(37+5)*4; dimy = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ if ( nbyte > 80 )
+ {
+ fprintf(fp, "\n%*s", (int)nbyte0, "");
+ nbyte = nbyte0;
+ }
+ nbyte += (size_t)fprintf(fp, "%d ", mask[i]);
}
+ fputs("\n", fp);
+}
- fileRewind(fileID);
-
- int found = data && (dimx*dimy*fact == data || dimx*dimy*8 == data);
-
- if ( IEG_Debug )
+static inline
+void *resizeBuffer(void **buf, size_t *bufSize, size_t reqSize)
+{
+ if (reqSize > *bufSize)
{
- Message("swap = %d fact = %d", *swap, fact);
- Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
+ *buf = Realloc(*buf, reqSize);
+ *bufSize = reqSize;
}
-
- return found;
+ return *buf;
}
-
-void iegCopyMeta(void *dieg, void *sieg)
+static
+void gridPrintAttributes(FILE *fp, int gridID)
{
- iegrec_t *diegp = (iegrec_t *) dieg;
- iegrec_t *siegp = (iegrec_t *) sieg;
+ int cdiID = gridID;
+ int varID = CDI_GLOBAL;
+ int atttype, attlen;
+ char attname[CDI_MAX_NAME+1];
+ void *attBuf = NULL;
+ size_t attBufSize = 0;
- /* diegp->byteswap = siegp->byteswap; */
- diegp->dprec = siegp->dprec;
- diegp->refval = siegp->refval;
+ int natts;
+ cdiInqNatts(cdiID, varID, &natts);
- memcpy(diegp->ipdb, siegp->ipdb, sizeof(siegp->ipdb));
- memcpy(diegp->igdb, siegp->igdb, sizeof(siegp->igdb));
- memcpy(diegp->vct, siegp->vct, sizeof(siegp->vct));
+ for ( int iatt = 0; iatt < natts; ++iatt )
+ {
+ cdiInqAtt(cdiID, varID, iatt, attname, &atttype, &attlen);
+
+ if ( attlen == 0 ) continue;
+
+ if ( atttype == CDI_DATATYPE_TXT )
+ {
+ size_t attSize = (size_t)(attlen+1)*sizeof(char);
+ char *atttxt = (char *)resizeBuffer(&attBuf, &attBufSize, attSize);
+ cdiInqAttTxt(cdiID, varID, attname, attlen, atttxt);
+ atttxt[attlen] = 0;
+ fprintf(fp, "ATTR_TXT: %s = \"%s\"\n", attname, atttxt);
+ }
+ else if ( atttype == CDI_DATATYPE_INT8 || atttype == CDI_DATATYPE_UINT8 ||
+ atttype == CDI_DATATYPE_INT16 || atttype == CDI_DATATYPE_UINT16 ||
+ atttype == CDI_DATATYPE_INT32 || atttype == CDI_DATATYPE_UINT32 )
+ {
+ size_t attSize = (size_t)attlen*sizeof(int);
+ int *attint = (int *)resizeBuffer(&attBuf, &attBufSize, attSize);
+ cdiInqAttInt(cdiID, varID, attname, attlen, &attint[0]);
+ if ( attlen == 1 )
+ fprintf(fp, "ATTR_INT: %s =", attname);
+ else
+ fprintf(fp, "ATTR_INT_%d: %s =", attlen, attname);
+ for ( int i = 0; i < attlen; ++i ) fprintf(fp, " %d", attint[i]);
+ fprintf(fp, "\n");
+ }
+ else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
+ {
+ size_t attSize = (size_t)attlen * sizeof(double);
+ double *attflt = (double *)resizeBuffer(&attBuf, &attBufSize, attSize);
+ int dig = (atttype == CDI_DATATYPE_FLT64) ? 15 : 7;
+ cdiInqAttFlt(cdiID, varID, attname, attlen, attflt);
+ if ( attlen == 1 )
+ fprintf(fp, "ATTR_FLT: %s =", attname);
+ else
+ fprintf(fp, "ATTR_FLT_%d: %s =", attlen, attname);
+ for ( int i = 0; i < attlen; ++i ) fprintf(fp, " %.*g", dig, attflt[i]);
+ fprintf(fp, "\n");
+ }
+ }
+
+ Free(attBuf);
}
static
-int iegInqData(void *ieg, int prec, void *data)
+void gridPrintKernel(int gridID, int opt, FILE *fp)
{
- iegrec_t *iegp = (iegrec_t *) ieg;
- int ierr = 0;
- int byteswap = iegp->byteswap;
- size_t datasize = iegp->datasize;
- void *buffer = iegp->buffer;
- int dprec = iegp->dprec;
+ size_t xdimLen, ydimLen;
+ char attstr[CDI_MAX_NAME];
+ char attstr2[CDI_MAX_NAME];
+ unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+ const char **xcvals = gridInqXCvalsPtr(gridID);
+ const char **ycvals = gridInqYCvalsPtr(gridID);
+ size_t nxvals = gridInqXvals(gridID, NULL);
+ size_t nyvals = gridInqYvals(gridID, NULL);
+ size_t nxbounds = gridInqXbounds(gridID, NULL);
+ size_t nybounds = gridInqYbounds(gridID, NULL);
- switch ( dprec )
+ int type = gridInqType(gridID);
+ size_t gridsize = gridInqSize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
+ int xstrlen = gridInqXIsc(gridID);
+ int ystrlen = gridInqYIsc(gridID);
+ int nvertex = gridInqNvertex(gridID);
+ int datatype = gridInqDatatype(gridID);
+
+ int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
+
+ fprintf(fp, "gridtype = %s\n" "gridsize = %zu\n", gridNamePtr(type), gridsize);
+
+ if ( type != GRID_GME )
{
- case EXSE_SINGLE_PRECISION:
+ if ( type != GRID_UNSTRUCTURED && type != GRID_SPECTRAL && type != GRID_FOURIER )
+ {
+ if ( xsize > 0 ) fprintf(fp, "xsize = %zu\n", xsize);
+ if ( ysize > 0 ) fprintf(fp, "ysize = %zu\n", ysize);
+ }
+
+ if ( nxvals > 0 || xcvals )
+ {
+ if ( xstrlen ) fprintf(fp, "xstringlen= %d\n", xstrlen);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "xname = %s\n", attstr);
+ attstr2[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, attstr2);
+ if ( attstr2[0] && strcmp(attstr, attstr2) ) fprintf(fp, "xdimname = %s\n", attstr2);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "xlongname = %s\n", attstr);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "xunits = %s\n", attstr);
+ }
+
+ if ( nyvals > 0 || ycvals )
+ {
+ if ( ystrlen ) fprintf(fp, "ystringlen= %d\n", ystrlen);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "yname = %s\n", attstr);
+ attstr2[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, attstr2);
+ if ( attstr2[0] && strcmp(attstr, attstr2) ) fprintf(fp, "ydimname = %s\n", attstr2);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "ylongname = %s\n", attstr);
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "yunits = %s\n", attstr);
+ }
+
+ if ( type == GRID_UNSTRUCTURED || type == GRID_CURVILINEAR )
+ {
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_VDIMNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] ) fprintf(fp, "vdimname = %s\n", attstr);
+ }
+ if ( type == GRID_UNSTRUCTURED && nvertex > 0 ) fprintf(fp, "nvertex = %d\n", nvertex);
+ }
+
+ switch (type)
+ {
+ case GRID_LONLAT:
+ case GRID_GAUSSIAN:
+ case GRID_GAUSSIAN_REDUCED:
+ case GRID_GENERIC:
+ case GRID_PROJECTION:
+ case GRID_CURVILINEAR:
+ case GRID_UNSTRUCTURED:
+ case GRID_CHARXY:
{
- if ( sizeof(FLT32) == 4 )
+ if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np = %d\n", gridInqNP(gridID));
+
+ if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
{
- if ( byteswap ) swap4byte(buffer, datasize);
+ xdimLen = gridsize;
+ ydimLen = gridsize;
+ }
+ else if ( type == GRID_GAUSSIAN_REDUCED )
+ {
+ xdimLen = 2;
+ ydimLen = ysize;
+ }
+ else
+ {
+ xdimLen = xsize;
+ ydimLen = ysize;
+ }
- if ( dprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT32));
- else
+ if ( type == GRID_UNSTRUCTURED )
+ {
+ int number = gridInqNumber(gridID);
+ int position = gridInqPosition(gridID);
+ // const unsigned char *d;
+ if ( number > 0 )
{
- const float *restrict p = (float *)buffer;
- double *restrict q = (double *)data;
- for ( size_t i = 0; i < datasize; i++)
- q[i] = p[i];
+ fprintf(fp, "number = %d\n", number);
+ if ( position >= 0 ) fprintf(fp, "position = %d\n", position);
+ }
+ /*
+ gridInqUUID(gridID, uuidOfHGrid);
+ d = (unsigned char *) &uuidOfHGrid;
+ fprintf(fp, "uuid = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+ d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ */
+ if ( gridInqReference(gridID, NULL) )
+ {
+ char reference_link[8192];
+ gridInqReference(gridID, reference_link);
+ fprintf(fp, "uri = %s\n", reference_link);
}
+ }
+
+ if ( nxvals > 0 )
+ {
+ double xfirst = 0.0, xinc = 0.0;
+
+ if ( type == GRID_LONLAT || type == GRID_GAUSSIAN ||
+ type == GRID_PROJECTION || type == GRID_GENERIC )
+ {
+ xfirst = gridInqXval(gridID, 0);
+ xinc = gridInqXinc(gridID);
+ }
+
+ if ( IS_NOT_EQUAL(xinc, 0) && opt )
+ {
+ fprintf(fp, "xfirst = %.*g\n"
+ "xinc = %.*g\n", dig, xfirst, dig, xinc);
+ }
+ else
+ {
+ double *xvals = (double*) Malloc(nxvals*sizeof(double));
+ gridInqXvals(gridID, xvals);
+ static const char prefix[] = "xvals = ";
+ printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, nxvals, xvals);
+ Free(xvals);
+ }
+ }
+
+ if ( xcvals )
+ {
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] )
+ fprintf(fp, "x%ss = %.*s\n", attstr, xstrlen, xcvals[0]);
+ else
+ fprintf(fp, "xstrings = %.*s\n", xstrlen, xcvals[0]);
+ for ( size_t i = 1; i < xsize; i++ )
+ fprintf(fp, " = %.*s\n", xstrlen, xcvals[i]);
+ }
+
+ if ( nxbounds )
+ {
+ double *xbounds = (double*) Malloc(nxbounds*sizeof(double));
+ gridInqXbounds(gridID, xbounds);
+ static const char prefix[] = "xbounds = ";
+ printBounds(fp, dig, prefix, sizeof(prefix)-1, xdimLen, (size_t)nvertex, xbounds);
+ Free(xbounds);
+ }
+
+ if ( nyvals > 0 )
+ {
+ double yfirst = 0.0, yinc = 0.0;
+
+ if ( type == GRID_LONLAT || type == GRID_GENERIC ||
+ type == GRID_PROJECTION || type == GRID_GENERIC )
+ {
+ yfirst = gridInqYval(gridID, 0);
+ yinc = gridInqYinc(gridID);
+ }
+
+ if ( IS_NOT_EQUAL(yinc, 0) && opt )
+ {
+ fprintf(fp, "yfirst = %.*g\n"
+ "yinc = %.*g\n", dig, yfirst, dig, yinc);
+ }
+ else
+ {
+ double *yvals = (double*) Malloc(nyvals*sizeof(double));
+ gridInqYvals(gridID, yvals);
+ static const char prefix[] = "yvals = ";
+ printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, nyvals, yvals);
+ Free(yvals);
+ }
}
- else
+
+ if ( ycvals )
+ {
+ attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, attstr);
+ if ( attstr[0] )
+ fprintf(fp, "x%ss = %.*s\n", attstr, ystrlen, ycvals[0]);
+ else
+ fprintf(fp, "ystrings = %.*s\n", ystrlen, ycvals[0]);
+ for ( size_t i = 1; i < ysize; i++ )
+ fprintf(fp, " = %.*s\n", ystrlen, ycvals[i]);
+ }
+
+ if ( nybounds )
{
- Error("not implemented for %d byte float", sizeof(FLT32));
+ double *ybounds = (double*) Malloc(nybounds*sizeof(double));
+ gridInqYbounds(gridID, ybounds);
+ static const char prefix[] = "ybounds = ";
+ printBounds(fp, dig, prefix, sizeof(prefix)-1, ydimLen, (size_t)nvertex, ybounds);
+ Free(ybounds);
}
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- if ( sizeof(FLT64) == 8 )
- {
- if ( byteswap ) swap8byte(buffer, datasize);
- if ( dprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT64));
- else
- {
- const double *restrict p = (double *)buffer;
- float *restrict q = (float *)data;
- for ( size_t i = 0; i < datasize; i++)
- q[i] = (float)p[i];
- }
- }
- else
+ if ( gridHasArea(gridID) )
{
- Error("not implemented for %d byte float", sizeof(FLT64));
+ double *area = (double*) Malloc(gridsize*sizeof(double));
+ gridInqArea(gridID, area);
+ static const char prefix[] = "area = ";
+ printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, gridsize, area);
+ Free(area);
}
+
+ if ( type == GRID_GAUSSIAN_REDUCED )
+ {
+ static const char prefix[] = "rowlon = ";
+ int *rowlon = (int *)Malloc(ysize*sizeof(int));
+ gridInqRowlon(gridID, rowlon);
+ printIntsPrefixAutoBrk(fp, prefix, sizeof(prefix)-1,
+ (ysize > 0 ? ysize : 0), rowlon);
+ Free(rowlon);
+ }
+
+ if ( type == GRID_PROJECTION ) gridPrintAttributes(fp, gridID);
+
break;
- default:
+ }
+ case GRID_SPECTRAL:
{
- Error("unexpected data precision %d", dprec);
+ fprintf(fp, "truncation = %d\n"
+ "complexpacking = %d\n", gridInqTrunc(gridID), gridInqComplexPacking(gridID) );
+ break;
+ }
+ case GRID_FOURIER:
+ {
+ fprintf(fp, "truncation = %d\n", gridInqTrunc(gridID));
+ break;
+ }
+ case GRID_GME:
+ {
+ int nd, ni, ni2, ni3;
+ gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
+ fprintf(fp, "ni = %d\n", ni );
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
break;
}
}
- return ierr;
-}
-
+ gridInqUUID(gridID, uuidOfHGrid);
+ if ( !cdiUUIDIsNull(uuidOfHGrid) )
+ {
+ char uuidOfHGridStr[37];
+ cdiUUID2Str(uuidOfHGrid, uuidOfHGridStr);
+ if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+ fprintf(fp, "uuid = %s\n", uuidOfHGridStr);
+ }
-int iegInqDataSP(void *ieg, float *data)
-{
- return iegInqData(ieg, EXSE_SINGLE_PRECISION, (void *) data);
+ if ( gridInqMask(gridID, NULL) )
+ {
+ int *mask = (gridsize>0) ? (int*) Malloc(gridsize*sizeof(int)) : NULL;
+ gridInqMask(gridID, mask);
+ static const char prefix[] = "mask = ";
+ printMask(fp, prefix, sizeof(prefix)-1,
+ (gridsize > 0 ? gridsize : 0), mask);
+ if ( mask ) Free(mask);
+ }
}
-int iegInqDataDP(void *ieg, double *data)
+void gridPrint(int gridID, int opt)
{
- return iegInqData(ieg, EXSE_DOUBLE_PRECISION, (void *) data);
+ gridPrintKernel(gridID, opt, stdout);
}
-static int
-iegDefData(iegrec_t *iegp, int prec, const void *data)
+void gridPrintP(void *voidptr, FILE *fp)
{
- int dprec = iegDefaultDprec ? iegDefaultDprec : iegp->dprec;
-
- iegp->dprec = dprec = dprec ? dprec : prec;
+ grid_t *gridptr = (grid_t *) voidptr;
+ int gridID = gridptr->self;
- size_t datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
- size_t blocklen = datasize * (size_t)dprec;
+ xassert( gridptr );
- iegp->datasize = datasize;
+ gridPrintKernel(gridID, 0, fp);
- size_t buffersize = iegp->buffersize;
+ fprintf(fp,
+ "datatype = %d\n"
+ "nd = %d\n"
+ "ni = %d\n"
+ "ni2 = %d\n"
+ "ni3 = %d\n"
+ "number = %d\n"
+ "position = %d\n"
+ "trunc = %d\n"
+ "lcomplex = %d\n"
+ "nrowlon = %d\n",
+ gridptr->datatype, gridptr->gme.nd, gridptr->gme.ni, gridptr->gme.ni2,
+ gridptr->gme.ni3, gridptr->number, gridptr->position, gridptr->trunc,
+ gridptr->lcomplex, gridptr->nrowlon );
- void *buffer = iegp->buffer;
- if ( buffersize != blocklen )
+ if ( gridptr->rowlon )
{
- buffersize = blocklen;
- buffer = Realloc(buffer, buffersize);
- iegp->buffer = buffer;
- iegp->buffersize = buffersize;
+ static const char prefix[] = "rowlon = ";
+ printIntsPrefixAutoBrk(fp, prefix, sizeof(prefix)-1,
+ (size_t)(gridptr->nrowlon > 0
+ ? gridptr->nrowlon : 0), gridptr->rowlon);
}
- switch ( dprec )
+ if ( gridInqMaskGME(gridID, NULL) )
{
- case EXSE_SINGLE_PRECISION:
- {
- if ( dprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT32));
- else
- {
- const double *restrict p = (const double *)data;
- float *restrict q = (float *)buffer;
- for (size_t i = 0; i < datasize; i++)
- q[i] = (float)p[i];
- }
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- if ( dprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT64));
- else
- {
- const float *restrict p = (const float *)data;
- double *restrict q = (double *)buffer;
- for ( size_t i = 0; i < datasize; i++)
- q[i] = p[i];
- }
- break;
- }
- default:
- {
- Error("unexpected data precision %d", dprec);
- break;
- }
+ size_t gridsize = gridptr->size;
+ int *mask = (gridsize>0) ? (int*) Malloc(gridsize*sizeof(int)) : NULL;
+ gridInqMaskGME(gridID, mask);
+ static const char prefix[] = "mask_gme = ";
+ printMask(fp, prefix, sizeof(prefix)-1,
+ (gridptr->size > 0 ? gridptr->size : 0), mask);
+ if ( mask ) Free(mask);
}
+}
- return 0;
+static const double *gridInqXValsPtrSerial(grid_t *gridptr)
+{
+ return gridptr->x.vals;
+}
+
+static const char **gridInqXCvalsPtrSerial(grid_t *gridptr)
+{
+ return (const char **) gridptr->x.cvals;
}
-int iegDefDataSP(void *ieg, const float *data)
+const double *gridInqXvalsPtr(int gridID)
{
- return iegDefData((iegrec_t *)ieg, EXSE_SINGLE_PRECISION, (void *) data);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXValsPtr(gridptr);
}
-int iegDefDataDP(void *ieg, const double *data)
+const char **gridInqXCvalsPtr(int gridID)
{
- return iegDefData((iegrec_t *)ieg, EXSE_DOUBLE_PRECISION, (void *) data);
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqXCvalsPtr(gridptr);
}
+static const double *gridInqYValsPtrSerial(grid_t *gridptr)
+{
+ return gridptr->y.vals;
+}
-int iegRead(int fileID, void *ieg)
+static const char **gridInqYCvalsPtrSerial(grid_t *gridptr)
{
- iegrec_t *iegp = (iegrec_t *) ieg;
- union { double d[200]; float f[200]; int32_t i32[200]; } buf;
+ return (const char **) gridptr->y.cvals;
+}
- if ( ! iegp->checked )
- {
- int status = iegCheckFiletype(fileID, &iegp->byteswap);
- if ( status == 0 ) Error("Not a IEG file!");
- iegp->checked = 1;
- }
+const double *gridInqYvalsPtr(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYValsPtr(gridptr);
+}
- int byteswap = iegp->byteswap;
+const char **gridInqYCvalsPtr(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->vtable->inqYCvalsPtr(gridptr);
+}
- /* read header record */
- size_t blocklen = binReadF77Block(fileID, byteswap);
+/*
+ at Function gridDefParamLCC
+ at Title Define the parameter of a Lambert Conformal Conic grid
- if ( fileEOF(fileID) ) return -1;
+ at Prototype void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double xval_0, double yval_0, double x_0, double y_0)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item missval Missing value
+ @Item lon_0 The East longitude of the meridian which is parallel to the Y-axis.
+ @Item lat_0 Latitude of the projection origin
+ @Item lat_1 First latitude from the pole at which the secant cone cuts the sphere.
+ @Item lat_2 Second latitude at which the secant cone cuts the sphere.
+ @Item a Earth radius in metres (optional).
+ @Item rf Inverse flattening (1/f) (optional).
+ @Item xval_0 Longitude of the first grid point in degree (optional).
+ @Item yval_0 Latitude of the first grid point in degree (optional).
+ @Item x_0 False easting (optional).
+ @Item y_0 False northing (optional).
- if ( IEG_Debug )
- Message("blocklen = %lu", blocklen);
+ at Description
+The function @func{gridDefParamLCC} defines the parameter of a Lambert Conformal Conic grid.
- int dprec = 0;
- if ( blocklen == 636 || blocklen == 640 )
- dprec = 4;
- else if ( blocklen == 1040 || blocklen == 1036 )
- dprec = 8;
- else
- {
- Warning("unexpecteted header size %d!", (int) blocklen);
- return -1;
- }
+ at EndFunction
+*/
+void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2,
+ double a, double rf, double xval_0, double yval_0, double x_0, double y_0)
+{
+ (void)lat_0;
+ cdiGridDefKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, "Lambert_Conformal");
+
+ const char *mapname = "lambert_conformal_conic";
+ cdiGridDefKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapname);
+ cdiDefAttTxt(gridID, CDI_GLOBAL, "grid_mapping_name", (int)(strlen(mapname)), mapname);
+ int nlats = 0;
+ double lats[2];
+ lats[nlats++] = lat_1;
+ if ( IS_NOT_EQUAL(lat_1, lat_2) ) lats[nlats++] = lat_2;
+ cdiDefAttFlt(gridID, CDI_GLOBAL, "standard_parallel", CDI_DATATYPE_FLT64, nlats, lats);
+ cdiDefAttFlt(gridID, CDI_GLOBAL, "longitude_of_central_meridian", CDI_DATATYPE_FLT64, 1, &lon_0);
+ cdiDefAttFlt(gridID, CDI_GLOBAL, "latitude_of_projection_origin", CDI_DATATYPE_FLT64, 1, &lat_2);
+ if ( a > 0 ) cdiDefAttFlt(gridID, CDI_GLOBAL, "earth_radius", CDI_DATATYPE_FLT64, 1, &a);
+ if ( rf > 0 ) cdiDefAttFlt(gridID, CDI_GLOBAL, "inverse_flattening", CDI_DATATYPE_FLT64, 1, &rf);
+ if ( IS_NOT_EQUAL(x_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "false_easting", CDI_DATATYPE_FLT64, 1, &x_0);
+ if ( IS_NOT_EQUAL(y_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "false_northing", CDI_DATATYPE_FLT64, 1, &y_0);
+ if ( IS_NOT_EQUAL(xval_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "longitudeOfFirstGridPointInDegrees", CDI_DATATYPE_FLT64, 1, &xval_0);
+ if ( IS_NOT_EQUAL(yval_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "latitudeOfFirstGridPointInDegrees", CDI_DATATYPE_FLT64, 1, &yval_0);
+
+ grid_t *gridptr = grid_to_pointer(gridID);
+ gridptr->projtype = CDI_PROJ_LCC;
+
+ gridVerifyProj(gridID);
+}
- iegp->dprec = dprec;
+/*
+ at Function gridInqParamLCC
+ at Title Get the parameter of a Lambert Conformal Conic grid
- binReadInt32(fileID, byteswap, 37, buf.i32);
- for ( size_t i = 0; i < 37; i++ ) iegp->ipdb[i] = (int)buf.i32[i];
+ at Prototype void gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2, double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ @Item missval Missing value
+ @Item lon_0 The East longitude of the meridian which is parallel to the Y-axis.
+ @Item lat_0 Latitude of the projection origin
+ @Item lat_1 First latitude from the pole at which the secant cone cuts the sphere.
+ @Item lat_2 Second latitude at which the secant cone cuts the sphere.
+ @Item a Earth radius in metres (optional).
+ @Item rf Inverse flattening (1/f) (optional).
+ @Item xval_0 Longitude of the first grid point in degree (optional).
+ @Item yval_0 Latitude of the first grid point in degree (optional).
+ @Item x_0 False easting (optional).
+ @Item y_0 False northing (optional).
- binReadInt32(fileID, byteswap, 18, buf.i32);
- for ( size_t i = 0; i < 18; i++ ) iegp->igdb[i] = (int)buf.i32[i];
+ at Description
+The function @func{gridInqParamLCC} returns the parameter of a Lambert Conformal Conic grid.
- if ( blocklen == 636 || blocklen == 1036 )
- {
- fileRead(fileID, buf.f, 4);
- if ( byteswap ) swap4byte(buf.f, 1);
- iegp->refval = (double)buf.f[0];
- }
- else
- {
- fileRead(fileID, buf.d, 8);
- if ( byteswap ) swap8byte(buf.d, 1);
- iegp->refval = (double)buf.d[0];
- }
+ at EndFunction
+*/
+int gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
+ double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+{
+ *a = 0; *rf = 0;
+ *lon_0 = missval; *lat_0 = missval, *lat_1 = missval, *lat_2 = missval;
+ *xval_0 = missval; *yval_0 = missval; *x_0 = missval, *y_0 = missval;
- binReadInt32(fileID, byteswap, 3, buf.i32);
- for ( size_t i = 0; i < 3; i++ ) iegp->igdb[18+i] = (int)buf.i32[i];
+ int status = -1;
+ if ( gridInqType(gridID) != GRID_PROJECTION ) return status;
- if ( dprec == EXSE_SINGLE_PRECISION )
- {
- fileRead(fileID, buf.f, 400);
- if ( byteswap ) swap4byte(buf.f, 100);
- for ( size_t i = 0; i < 100; i++ )
- iegp->vct[i] = (double)buf.f[i];
- }
- else
+ status = -2;
+ const char *projection = "lambert_conformal_conic";
+ char mapname[CDI_MAX_NAME]; mapname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapname);
+ if ( mapname[0] && strcmp(mapname, projection) == 0 )
{
- fileRead(fileID, buf.d, 800);
- if ( byteswap ) swap8byte(buf.d, 100);
- for ( size_t i = 0; i < 100; i++ )
- iegp->vct[i] = buf.d[i];
- }
+ int atttype, attlen;
+ char attname[CDI_MAX_NAME+1];
- /*
- fprintf(stderr, "refval %g\n", iegp->refval);
+ int natts;
+ cdiInqNatts(gridID, CDI_GLOBAL, &natts);
- for ( size_t i = 0; i < 100; i++ )
- fprintf(stderr, "%3d %g\n", i, iegp->vct[i]);
+ if ( natts ) status = 0;
- {
- int i;
- for ( size_t i = 0; i < 37; i++ )
- fprintf(stderr, "pdb: %d %d\n", i, iegp->ipdb[i]);
- for ( size_t i = 0; i < 22; i++ )
- fprintf(stderr, "gdb: %d %d\n", i, iegp->igdb[i]);
- }
- */
- size_t blocklen2 = binReadF77Block(fileID, byteswap);
+ for ( int iatt = 0; iatt < natts; ++iatt )
+ {
+ cdiInqAtt(gridID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
+ if ( attlen > 2 ) continue;
- if ( blocklen2 != blocklen )
- {
- Warning("header blocklen differ!");
- return -1;
+ double attflt[2];
+ if ( cdiInqAttConvertedToFloat(gridID, atttype, attname, attlen, attflt) )
+ {
+ if ( strcmp(attname, "earth_radius") == 0 ) *a = attflt[0];
+ else if ( strcmp(attname, "inverse_flattening") == 0 ) *rf = attflt[0];
+ else if ( strcmp(attname, "longitude_of_central_meridian") == 0 ) *lon_0 = attflt[0];
+ else if ( strcmp(attname, "latitude_of_projection_origin") == 0 ) *lat_0 = attflt[0];
+ else if ( strcmp(attname, "false_easting") == 0 ) *x_0 = attflt[0];
+ else if ( strcmp(attname, "false_northing") == 0 ) *y_0 = attflt[0];
+ else if ( strcmp(attname, "longitudeOfFirstGridPointInDegrees") == 0 ) *xval_0 = attflt[0];
+ else if ( strcmp(attname, "latitudeOfFirstGridPointInDegrees") == 0 ) *yval_0 = attflt[0];
+ else if ( strcmp(attname, "standard_parallel") == 0 )
+ {
+ *lat_1 = attflt[0];
+ *lat_2 = (attlen == 2) ? attflt[1] : attflt[0];
+ }
+ }
+ }
}
- size_t datasize = iegp->datasize
- = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
-
- if ( IEG_Debug )
- Message("datasize = %lu", iegp->datasize);
+ return status;
+}
- blocklen = binReadF77Block(fileID, byteswap);
+int gridVerifyGribParamLCC(double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
+ double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+{
+ static bool lwarn = true;
- void *buffer = iegp->buffer;
- if ( iegp->buffersize < blocklen )
+ if ( lwarn )
{
- iegp->buffer = buffer = Realloc(buffer, blocklen);
- iegp->buffersize = blocklen;
+ // lwarn = false;
+ const char *projection = "lambert_conformal_conic";
+ if ( IS_EQUAL(*lon_0, missval) ) { Warning("%s mapping parameter %s missing!", projection, "longitude_of_central_meridian"); }
+ if ( IS_EQUAL(*lat_0, missval) ) { Warning("%s mapping parameter %s missing!", projection, "latitude_of_central_meridian"); }
+ if ( IS_EQUAL(*lat_1, missval) ) { Warning("%s mapping parameter %s missing!", projection, "standard_parallel"); }
+ if ( IS_NOT_EQUAL(*x_0, missval) && IS_NOT_EQUAL(*y_0, grid_missval) && (IS_EQUAL(*xval_0, missval) || IS_EQUAL(*yval_0, missval)) )
+ {
+ if ( proj_lcc_to_lonlat_func )
+ {
+ *xval_0 = -(*x_0); *yval_0 = -(*y_0);
+ proj_lcc_to_lonlat_func(missval, *lon_0, *lat_0, *lat_1, *lat_2, *a, *rf, 0.0, 0.0, (size_t)1, xval_0, yval_0);
+ }
+ if ( IS_EQUAL(*xval_0, missval) || IS_EQUAL(*yval_0, missval) )
+ Warning("%s mapping parameter %s missing!", projection, "longitudeOfFirstGridPointInDegrees and latitudeOfFirstGridPointInDegrees");
+ }
}
- if ( dprec != (int) (blocklen/datasize) )
- {
- Warning("data precision differ! (h = %d; d = %d)",
- (int) dprec, (int) (blocklen/datasize));
- return -1;
- }
+ return 0;
+}
- fileRead(fileID, buffer, blocklen);
- blocklen2 = binReadF77Block(fileID, byteswap);
+void gridDefComplexPacking(int gridID, int lcomplex)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
- if ( blocklen2 != blocklen )
+ if (gridptr->lcomplex != lcomplex)
{
- Warning("data blocklen differ!");
- return -1;
+ gridptr->lcomplex = lcomplex != 0;
+ gridMark4Update(gridID);
}
+}
- return 0;
+
+int gridInqComplexPacking(int gridID)
+{
+ grid_t* gridptr = grid_to_pointer(gridID);
+
+ return (int)gridptr->lcomplex;
}
-int iegWrite(int fileID, void *ieg)
+void gridDefHasDims(int gridID, int hasdims)
{
- iegrec_t *iegp = (iegrec_t *) ieg;
- union { INT32 i32[200]; float fvct[100]; } buf;
- int dprec = iegp->dprec;
- int byteswap = iegp->byteswap;
+ grid_t* gridptr = grid_to_pointer(gridID);
- /* write header record */
- size_t blocklen = ( dprec == EXSE_SINGLE_PRECISION ) ? 636 : 1040;
+ if ( gridptr->hasdims != (hasdims != 0) )
+ {
+ gridptr->hasdims = hasdims != 0;
+ gridMark4Update(gridID);
+ }
+}
- binWriteF77Block(fileID, byteswap, blocklen);
- for ( size_t i = 0; i < 37; i++ ) buf.i32[i] = (INT32) iegp->ipdb[i];
- binWriteInt32(fileID, byteswap, 37, buf.i32);
+int gridInqHasDims(int gridID)
+{
+ grid_t* gridptr = grid_to_pointer(gridID);
- for ( size_t i = 0; i < 18; i++ ) buf.i32[i] = (INT32) iegp->igdb[i];
- binWriteInt32(fileID, byteswap, 18, buf.i32);
+ return (int)gridptr->hasdims;
+}
- FLT64 refval = (FLT64)iegp->refval;
- FLT32 refvalf = (FLT32)iegp->refval;
- if ( dprec == EXSE_SINGLE_PRECISION )
- binWriteFlt32(fileID, byteswap, 1, &refvalf);
- else
- binWriteFlt64(fileID, byteswap, 1, &refval);
+/*
+ at Function gridDefNumber
+ at Title Define the reference number for an unstructured grid
- for ( size_t i = 0; i < 3; i++ ) buf.i32[i] = (INT32) iegp->igdb[18+i];
- binWriteInt32(fileID, byteswap, 3, buf.i32);
+ at Prototype void gridDefNumber(int gridID, const int number)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item number Reference number for an unstructured grid.
- if ( dprec == EXSE_SINGLE_PRECISION )
- {
- for ( size_t i = 0; i < 100; i++ ) buf.fvct[i] = (float) iegp->vct[i];
- binWriteFlt32(fileID, byteswap, 100, buf.fvct);
- }
- else
+ at Description
+The function @func{gridDefNumber} defines the reference number for an unstructured grid.
+
+ at EndFunction
+*/
+void gridDefNumber(int gridID, const int number)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->number != number )
{
- binWriteFlt64(fileID, byteswap, 100, iegp->vct);
+ gridptr->number = number;
+ gridMark4Update(gridID);
}
+}
- binWriteF77Block(fileID, byteswap, blocklen);
+/*
+ at Function gridInqNumber
+ at Title Get the reference number to an unstructured grid
- size_t datasize = (size_t)iegp->igdb[4] * (size_t)iegp->igdb[5];
- blocklen = datasize * (size_t)dprec;
+ at Prototype int gridInqNumber(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
- binWriteF77Block(fileID, byteswap, blocklen);
+ at Description
+The function @func{gridInqNumber} returns the reference number to an unstructured grid.
- iegp->datasize = datasize;
+ at Result
+ at func{gridInqNumber} returns the reference number to an unstructured grid.
+ at EndFunction
+*/
+int gridInqNumber(int gridID)
+{
+ grid_t* gridptr = grid_to_pointer(gridID);
+ return gridptr->number;
+}
- void *buffer = iegp->buffer;
+/*
+ at Function gridDefPosition
+ at Title Define the position of grid in the reference file
- switch ( dprec )
- {
- case EXSE_SINGLE_PRECISION:
- {
- binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
- break;
- }
- default:
- {
- Error("unexpected data precision %d", dprec);
- break;
- }
- }
+ at Prototype void gridDefPosition(int gridID, const int position)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item position Position of grid in the reference file.
- binWriteF77Block(fileID, byteswap, blocklen);
+ at Description
+The function @func{gridDefPosition} defines the position of grid in the reference file.
- return 0;
+ at EndFunction
+*/
+void gridDefPosition(int gridID, int position)
+{
+ grid_t* gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->position != position )
+ {
+ gridptr->position = position;
+ gridMark4Update(gridID);
+ }
}
+
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef INCLUDE_GUARD_CDI_REFERENCE_COUNTING
-#define INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+ at Function gridInqPosition
+ at Title Get the position of grid in the reference file
+
+ at Prototype int gridInqPosition(int gridID)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+ at Description
+The function @func{gridInqPosition} returns the position of grid in the reference file.
-#include <sys/types.h>
-#include <stdlib.h>
+ at Result
+ at func{gridInqPosition} returns the position of grid in the reference file.
+ at EndFunction
+*/
+int gridInqPosition(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->position;
+}
/*
-This is a base class for all objects that need reference counting.
-A CdiReferencedObject has a reference count of one when it is constructed, refObjectRetain() increments the reference count, refObject Release() decrements it.
-When the reference count reaches zero, the destructor function is called before the memory of the object is deallocated with Free().
+ at Function gridDefReference
+ at Title Define the reference URI for an unstructured grid
->>> Warning <<<
-This code is currently not thread-safe.
+ at Prototype void gridDefReference(int gridID, const char *reference)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item reference Reference URI for an unstructured grid.
-We are currently using the C99 standard, which does not have atomic types.
-Also, there are still tons of systems out there that have a gcc without wrong C11 atomics support
-(__STDC_NO_ATOMICS__ not defined even though stdatomics.h is not even present).
-Consequently, it is impossible to write preprocessor code to even check for the presence of atomic types.
-So, we have two options: provide multithreading support by means of locks, or wait a year or two before doing this right.
-I, for one, prefer doing things right.
-*/
-typedef struct CdiReferencedObject CdiReferencedObject;
-struct CdiReferencedObject {
- //protected:
- void (*destructor)(CdiReferencedObject* me); //Subclass constructors should set this to their own destructor.
+ at Description
+The function @func{gridDefReference} defines the reference URI for an unstructured grid.
- //private: //Subclasses may read it to determine whether there is only one reference, though.
- size_t refCount;
-};
+ at EndFunction
+*/
+void gridDefReference(int gridID, const char *reference)
+{
+ grid_t* gridptr = grid_to_pointer(gridID);
-void cdiRefObject_construct(CdiReferencedObject* me);
-void cdiRefObject_retain(CdiReferencedObject* me);
-void cdiRefObject_release(CdiReferencedObject* me);
-void cdiRefObject_destruct(CdiReferencedObject* me);
+ if ( reference )
+ {
+ if ( gridptr->reference )
+ {
+ Free(gridptr->reference);
+ gridptr->reference = NULL;
+ }
-#endif
+ gridptr->reference = strdupx(reference);
+ gridMark4Update(gridID);
+ }
+}
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef INCLUDE_GUARD_CDI_GRIB_FILE_H
-#define INCLUDE_GUARD_CDI_GRIB_FILE_H
+ at Function gridInqReference
+ at Title Get the reference URI to an unstructured grid
+ at Prototype char *gridInqReference(int gridID, char *reference)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-/*
-CdiInputFile is a file abstraction that allows accessing an input file through any number of channels:
-It is reference counted, so that it is closed at the right place,
-and it is stateless, so that accesses from different callers cannot interfere with each other.
-Once the reference counting code is threadsafe, CdiInputFile will also be threadsafe.
+ at Description
+The function @func{gridInqReference} returns the reference URI to an unstructured grid.
+
+ at Result
+ at func{gridInqReference} returns the reference URI to an unstructured grid.
+ at EndFunction
*/
-typedef struct CdiInputFile {
- //public:
- CdiReferencedObject super;
+int gridInqReference(int gridID, char *reference)
+{
+ size_t len = 0;
+ grid_t* gridptr = grid_to_pointer(gridID);
- //private:
- char* path;
- int fileDescriptor;
-} CdiInputFile;
+ if ( gridptr->reference )
+ {
+ len = strlen(gridptr->reference);
+ if ( reference )
+ strcpy(reference, gridptr->reference);
+ }
-//Final class, the constructor is private and not defined here.
-CdiInputFile* cdiInputFile_make(const char* path); //The caller is responsible to call cdiRefObject_release() on the returned object.
-int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer); //Returns one of CDI_EINVAL, CDI_ESYSTEM, CDI_EEOF, OR CDI_NOERR.
-/* Returns path string, don't use after destruction of CdiInputFile
- * object */
-const char* cdiInputFile_getPath(const CdiInputFile* me);
-//Destructor is private as well.
+ return (int)len;
+}
-#endif
+const char *gridInqReferencePtr(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->reference;
+}
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#define _XOPEN_SOURCE 600
-
+ at Function gridDefUUID
+ at Title Define the UUID for an unstructured grid
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <string.h>
-#include <unistd.h>
+ at Prototype void gridDefUUID(int gridID, const char *uuid)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate}.
+ @Item uuid UUID for an unstructured grid.
-static void cdiInputFile_destruct(CdiInputFile* me);
+ at Description
+The function @func{gridDefUUID} defines the UUID for an unstructured grid.
-//For an explanation of the condestruct() pattern, see the comment in iterator_grib.c
-//path != NULL -> construction
-//path = NULL -> destruction
-static CdiInputFile* cdiInputFile_condestruct(CdiInputFile* me, const char* path)
+ at EndFunction
+*/
+void gridDefUUID(int gridID, const unsigned char uuid[CDI_UUID_SIZE])
{
- #define super() (&me->super)
- if(!path) goto destruct;
- cdiRefObject_construct(super());
- me->path = strdup(path);
- if(!me->path) goto destructSuper;
- do
- {
- me->fileDescriptor = open(me->path, O_RDONLY);
- }
- while(me->fileDescriptor == -1 && (errno == EINTR || errno == EAGAIN));
- if(me->fileDescriptor == -1) goto freePath;
- //construction successfull, now we can set our own destructor
- super()->destructor = (void(*)(CdiReferencedObject*))cdiInputFile_destruct;
- goto success;
+ grid_t* gridptr = grid_to_pointer(gridID);
-// ^ constructor code ^
-// | |
-// v destructor/error-cleanup code v
+ memcpy(gridptr->uuid, uuid, CDI_UUID_SIZE);
+ gridMark4Update(gridID);
+}
-destruct:
- close(me->fileDescriptor);
-freePath:
- Free(me->path);
-destructSuper:
- cdiRefObject_destruct(super());
- me = NULL;
+/*
+ at Function gridInqUUID
+ at Title Get the UUID to an unstructured grid
-success:
- return me;
- #undef super
-}
+ at Prototype void gridInqUUID(int gridID, char *uuid)
+ at Parameter
+ @Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-static CdiInputFile **openFileList = NULL;
-static size_t openFileCount = 0, openFileListSize = 0;
-static pthread_mutex_t openFileListLock = PTHREAD_MUTEX_INITIALIZER;
+ at Description
+The function @func{gridInqUUID} returns the UUID to an unstructured grid.
-//This either returns a new object, or retains and returns a preexisting open file.
-CdiInputFile* cdiInputFile_make(const char* path)
+ at Result
+ at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
+ at EndFunction
+*/
+void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
{
- CdiInputFile* result = NULL;
- xassert(path);
- int error = pthread_mutex_lock(&openFileListLock);
- xassert(!error);
- {
- //Check the list of open files for the given path.
- for(size_t i = openFileCount; i-- && !result; )
- {
- if(!strcmp(path, openFileList[i]->path)) result = openFileList[i];
- }
- //If no open file was found, we open one, otherwise we just retain the existing one one more time.
- if(result)
- {
- cdiRefObject_retain(&result->super);
- }
- else
- {
- result = (CdiInputFile *) Malloc(sizeof(*result));
- if(!cdiInputFile_condestruct(result, path))
- {
- //An error occured during construction, avoid a memory leak.
- Free(result);
- result = NULL;
- }
- else
- {
- //Add the new file to the list of open files.
- if(openFileCount == openFileListSize)
- {
- openFileListSize *= 2;
- if(openFileListSize < 16) openFileListSize = 16;
- openFileList = (CdiInputFile **) Realloc(openFileList, openFileListSize);
- }
- xassert(openFileCount < openFileListSize);
- openFileList[openFileCount++] = result;
- }
- }
- }
- error = pthread_mutex_unlock(&openFileListLock);
- xassert(!error);
- return result;
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ memcpy(uuid, gridptr->uuid, CDI_UUID_SIZE);
}
-int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer)
+
+void gridDefUvRelativeToGrid(int gridID, int uvRelativeToGrid)
{
- char* byteBuffer = (char *)buffer;
- size_t trash;
- if(!outActualReadSize) outActualReadSize = &trash;
- *outActualReadSize = 0;
- while(readSize)
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->uvRelativeToGrid != uvRelativeToGrid )
{
- ssize_t bytesRead = pread(me->fileDescriptor, byteBuffer, readSize, readPosition);
- if(bytesRead == -1) return (errno == EINVAL) ? CDI_EINVAL : CDI_ESYSTEM;
- if(bytesRead == 0) return CDI_EEOF;
- byteBuffer += bytesRead;
- readPosition += bytesRead;
- readSize -= (size_t)bytesRead;
- *outActualReadSize += (size_t)bytesRead;
+ gridMark4Update(gridID);
+ gridptr->uvRelativeToGrid = (bool)uvRelativeToGrid;
}
- return CDI_NOERR;
}
-const char* cdiInputFile_getPath(const CdiInputFile* me)
+
+int gridInqUvRelativeToGrid(int gridID)
{
- return me->path;
+ grid_t *gridptr = grid_to_pointer(gridID);
+ return gridptr->uvRelativeToGrid;
}
-void cdiInputFile_destruct(CdiInputFile* me)
+
+void gridDefScanningMode(int gridID, int mode)
{
- int error = pthread_mutex_lock(&openFileListLock);
- xassert(!error);
+ grid_t *gridptr = grid_to_pointer(gridID);
+
+ if ( gridptr->scanningMode != mode )
{
- //Find the position of me in the list of open files.
- ssize_t position = (ssize_t)openFileCount;
- while (position > 0 && openFileList[--position] != me);
- //Remove me from the list
- openFileList[position] = openFileList[--openFileCount];
+ gridMark4Update(gridID);
+ gridptr->scanningMode = mode;
}
- error = pthread_mutex_unlock(&openFileListLock);
- xassert(!error);
- cdiInputFile_condestruct(me, NULL);
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef INSTITUTION_H
-#define INSTITUTION_H
-
-int
-instituteUnpack(void *buf, int size, int *position, int originNamespace,
- void *context, int force_id);
-
-void instituteDefaultEntries(void);
-#endif
+int gridInqScanningMode(int gridID)
+{
+ grid_t *gridptr = grid_to_pointer(gridID);
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ int scanningModeTMP = 128 * gridptr->iScansNegatively + 64 * gridptr->jScansPositively + 32 * gridptr->jPointsAreConsecutive;
+ if ( scanningModeTMP != gridptr->scanningMode )
+ Message("WARNING: scanningMode (%d) ! = (%d) 128 * iScansNegatively(%d) + 64 * jScansPositively(%d) + 32 * jPointsAreConsecutive(%d) ",
+ gridptr->scanningMode, scanningModeTMP, gridptr->iScansNegatively,gridptr->jScansPositively,gridptr->jPointsAreConsecutive );
-#include <assert.h>
-#include <limits.h>
+ return gridptr->scanningMode;
+}
-#undef UNDEFID
-#define UNDEFID -1
+void cdiGridGetIndexList(unsigned ngrids, int * gridIndexList)
+{
+ reshGetResHListOfType(ngrids, gridIndexList, &gridOps);
+}
-static int ECMWF = UNDEFID,
- MPIMET = UNDEFID,
- MCH = UNDEFID;
-typedef struct
+static int
+gridTxCode ()
{
- int self;
- int used;
- int center;
- int subcenter;
- char *name;
- char *longname;
+ return GRID;
}
-institute_t;
+enum {
+ GRID_PACK_INT_IDX_SELF,
+ GRID_PACK_INT_IDX_TYPE,
+ GRID_PACK_INT_IDX_DATATYPE,
+ GRID_PACK_INT_IDX_IS_CYCLIC,
+ GRID_PACK_INT_IDX_X_FLAG,
+ GRID_PACK_INT_IDX_Y_FLAG,
+ GRID_PACK_INT_IDX_GME_ND,
+ GRID_PACK_INT_IDX_GME_NI,
+ GRID_PACK_INT_IDX_GME_NI2,
+ GRID_PACK_INT_IDX_GME_NI3,
+ GRID_PACK_INT_IDX_NUMBER,
+ GRID_PACK_INT_IDX_POSITION,
+ GRID_PACK_INT_IDX_TRUNC,
+ GRID_PACK_INT_IDX_NVERTEX,
+ GRID_PACK_INT_IDX_NROWLON,
+ GRID_PACK_INT_IDX_SIZE,
+ GRID_PACK_INT_IDX_X_SIZE,
+ GRID_PACK_INT_IDX_Y_SIZE,
+ GRID_PACK_INT_IDX_LCOMPLEX,
+ GRID_PACK_INT_IDX_MEMBERMASK,
+ GRID_PACK_INT_IDX_XTSTDNNAME,
+ GRID_PACK_INT_IDX_YTSTDNNAME,
+ GRID_PACK_INT_IDX_UVRELATIVETOGRID,
+ GRID_PACK_INT_IDX_ISCANSNEGATIVELY,
+ GRID_PACK_INT_IDX_JSCANSPOSITIVELY,
+ GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE,
+ GRID_PACK_INT_IDX_SCANNINGMODE,
+ gridNint
+};
-static int instituteCompareKernel(institute_t *ip1, institute_t *ip2);
-static void instituteDestroyP(institute_t *instituteptr);
-static void institutePrintP(institute_t *instituteptr, FILE * fp);
-static int instituteGetPackSize(institute_t *instituteptr, void *context);
-static void institutePackP ( void * instituteptr, void *buf, int size, int *position, void *context );
-static int instituteTxCode ( void );
+enum {
+ GRID_PACK_DBL_IDX_X_FIRST,
+ GRID_PACK_DBL_IDX_Y_FIRST,
+ GRID_PACK_DBL_IDX_X_LAST,
+ GRID_PACK_DBL_IDX_Y_LAST,
+ GRID_PACK_DBL_IDX_X_INC,
+ GRID_PACK_DBL_IDX_Y_INC,
+ gridNdouble
+};
-static const resOps instituteOps = {
- (int (*)(void *, void *))instituteCompareKernel,
- (void (*)(void *))instituteDestroyP,
- (void (*)(void *, FILE *))institutePrintP,
- (int (*)(void *, void *))instituteGetPackSize,
- institutePackP,
- instituteTxCode
+enum {
+ gridHasMaskFlag = 1 << 0,
+ gridHasGMEMaskFlag = 1 << 1,
+ gridHasXValsFlag = 1 << 2,
+ gridHasYValsFlag = 1 << 3,
+ gridHasAreaFlag = 1 << 4,
+ gridHasXBoundsFlag = 1 << 5,
+ gridHasYBoundsFlag = 1 << 6,
+ gridHasReferenceFlag = 1 << 7,
+ gridHasRowLonFlag = 1 << 8,
+ gridHasUUIDFlag = 1 << 9,
};
-static
-void instituteDefaultValue ( institute_t * instituteptr )
+
+static int gridGetComponentFlags(const grid_t * gridP)
{
- instituteptr->self = UNDEFID;
- instituteptr->used = 0;
- instituteptr->center = UNDEFID;
- instituteptr->subcenter = UNDEFID;
- instituteptr->name = NULL;
- instituteptr->longname = NULL;
+ int flags = (gridHasMaskFlag & (int)((unsigned)(gridP->mask == NULL) - 1U))
+ | (gridHasGMEMaskFlag & (int)((unsigned)(gridP->mask_gme == NULL) - 1U))
+ | (gridHasXValsFlag
+ & (int)((unsigned)(gridP->vtable->inqXValsPtr((grid_t *)gridP) == NULL) - 1U))
+ | (gridHasYValsFlag
+ & (int)((unsigned)(gridP->vtable->inqYValsPtr((grid_t *)gridP) == NULL) - 1U))
+ | (gridHasAreaFlag
+ & (int)((unsigned)(gridP->vtable->inqAreaPtr((grid_t *)gridP) == NULL)
+ - 1U))
+ | (gridHasXBoundsFlag & (int)((unsigned)(gridP->x.bounds == NULL) - 1U))
+ | (gridHasYBoundsFlag & (int)((unsigned)(gridP->y.bounds == NULL) - 1U))
+ | (gridHasReferenceFlag & (int)((unsigned)(gridP->reference == NULL) - 1U))
+ | (gridHasRowLonFlag & (int)((unsigned)(gridP->rowlon == NULL) - 1U))
+ | (gridHasUUIDFlag & (int)((unsigned)cdiUUIDIsNull(gridP->uuid) - 1U));
+ return flags;
}
-void instituteDefaultEntries ( void )
+static int
+gridGetPackSize(void * voidP, void *context)
{
- cdiResH resH[]
- = { ECMWF = institutDef( 98, 0, "ECMWF", "European Centre for Medium-Range Weather Forecasts"),
- MPIMET = institutDef( 98, 232, "MPIMET", "Max-Planck-Institute for Meteorology"),
- institutDef( 98, 255, "MPIMET", "Max-Planck-Institute for Meteorology"),
- institutDef( 98, 232, "MPIMET", "Max Planck Institute for Meteorology"),
- institutDef( 78, 0, "DWD", "Deutscher Wetterdienst"),
- institutDef( 78, 255, "DWD", "Deutscher Wetterdienst"),
- MCH = institutDef(215, 255, "MCH", "MeteoSwiss"),
- institutDef( 7, 0, "NCEP", "National Centers for Environmental Prediction"),
- institutDef( 7, 1, "NCEP", "National Centers for Environmental Prediction"),
- institutDef( 60, 0, "NCAR", "National Center for Atmospheric Research"),
- institutDef( 74, 0, "METOFFICE", "U.K. Met Office"),
- institutDef( 97, 0, "ESA", "European Space Agency"),
- institutDef( 99, 0, "KNMI", "Royal Netherlands Meteorological Institute"),
- };
- /* (void) institutDef( 0, 0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
+ grid_t * gridP = ( grid_t * ) voidP;
+ int packBuffSize = 0, count;
- size_t n = sizeof(resH)/sizeof(*resH);
+ packBuffSize += serializeGetSize(gridNint, CDI_DATATYPE_INT, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
- for (size_t i = 0; i < n ; i++ )
- reshSetStatus(resH[i], &instituteOps, RESH_IN_USE);
-}
+ if (gridP->rowlon)
+ {
+ xassert(gridP->nrowlon);
+ packBuffSize += serializeGetSize(gridP->nrowlon, CDI_DATATYPE_INT, context)
+ + serializeGetSize( 1, CDI_DATATYPE_UINT32, context);
+ }
+ packBuffSize += serializeGetSize(gridNdouble, CDI_DATATYPE_FLT64, context);
-static int
-instituteCompareKernel(institute_t * ip1, institute_t * ip2)
-{
- int differ = 0;
- size_t len1, len2;
+ if (gridP->vtable->inqXValsPtr(gridP))
+ {
+ if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+ count = gridP->size;
+ else
+ count = gridP->x.size;
+ xassert(count);
+ packBuffSize += serializeGetSize(count, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+ }
- if ( ip1->name )
+ if (gridP->vtable->inqYValsPtr(gridP))
{
- if ( ip1->center > 0 && ip2->center != ip1->center ) differ = 1;
- if ( ip1->subcenter > 0 && ip2->subcenter != ip1->subcenter ) differ = 1;
+ if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+ count = gridP->size;
+ else
+ count = gridP->y.size;
+ xassert(count);
+ packBuffSize += serializeGetSize(count, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+ }
- if ( !differ )
- {
- if ( ip2->name )
- {
- len1 = strlen(ip1->name);
- len2 = strlen(ip2->name);
- if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
- }
- }
+ if (gridP->vtable->inqAreaPtr(gridP))
+ {
+ xassert(gridP->size);
+ packBuffSize +=
+ serializeGetSize(gridP->size, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
}
- else if ( ip1->longname )
+
+ if (gridP->x.bounds)
{
- if ( ip2->longname )
- {
- len1 = strlen(ip1->longname);
- len2 = strlen(ip2->longname);
- if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
- }
+ xassert(gridP->nvertex);
+ if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+ count = gridP->size;
+ else
+ count = gridP->x.size;
+ xassert(count);
+ packBuffSize
+ += (serializeGetSize(gridP->nvertex * count, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context));
}
- else
+
+ if (gridP->y.bounds)
{
- if ( !( ip2->center == ip1->center &&
- ip2->subcenter == ip1->subcenter )) differ = 1;
+ xassert(gridP->nvertex);
+ if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+ count = gridP->size;
+ else
+ count = gridP->y.size;
+ xassert(count);
+ packBuffSize
+ += (serializeGetSize(gridP->nvertex * count, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context));
}
- return differ;
-}
+ {
+ const char *strTab[] = GRID_STR_SERIALIZE(gridP);
+ int numStr = (int)(sizeof (strTab) / sizeof (strTab[0]));
+ packBuffSize
+ += serializeStrTabGetPackSize(strTab, numStr, context);
+ }
+ if (gridP->reference)
+ {
+ size_t len = strlen(gridP->reference);
+ packBuffSize += serializeGetSize(1, CDI_DATATYPE_INT, context)
+ + serializeGetSize((int)len + 1, CDI_DATATYPE_TXT, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+ }
-struct instLoc
-{
- institute_t *ip;
- int id;
-};
+ if (gridP->mask)
+ {
+ xassert(gridP->size);
+ packBuffSize
+ += serializeGetSize(gridP->size, CDI_DATATYPE_UCHAR, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+ }
-static enum cdiApplyRet
-findInstitute(int id, void *res, void *data)
-{
- institute_t * ip1 = ((struct instLoc *)data)->ip;
- institute_t * ip2 = (institute_t*) res;
- if (ip2->used && !instituteCompareKernel(ip1, ip2))
+ if (gridP->mask_gme)
{
- ((struct instLoc *)data)->id = id;
- return CDI_APPLY_STOP;
+ xassert(gridP->size);
+ packBuffSize += serializeGetSize(gridP->size, CDI_DATATYPE_UCHAR, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
}
- else
- return CDI_APPLY_GO_ON;
-}
+ if (!cdiUUIDIsNull(gridP->uuid))
+ packBuffSize += serializeGetSize(CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
+
+ return packBuffSize;
+}
-int institutInq(int center, int subcenter, const char *name, const char *longname)
+void
+gridUnpack(char * unpackBuffer, int unpackBufferSize,
+ int * unpackBufferPos, int originNamespace, void *context,
+ int force_id)
{
- institute_t * ip_ref = (institute_t *) Malloc(sizeof (*ip_ref));
- ip_ref->self = UNDEFID;
- ip_ref->used = 0;
- ip_ref->center = center;
- ip_ref->subcenter = subcenter;
- ip_ref->name = name && name[0] ? (char *)name : NULL;
- ip_ref->longname = longname && longname[0] ? (char *)longname : NULL;
+ grid_t * gridP;
+ uint32_t d;
+ int memberMask, size;
- struct instLoc state = { .ip = ip_ref, .id = UNDEFID };
- cdiResHFilterApply(&instituteOps, findInstitute, &state);
+ gridInit();
- Free(ip_ref);
+ {
+ int intBuffer[gridNint];
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ intBuffer, gridNint, CDI_DATATYPE_INT, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
- return state.id;
-}
+ xassert(cdiCheckSum(CDI_DATATYPE_INT, gridNint, intBuffer) == d);
+ int targetID = namespaceAdaptKey(intBuffer[0], originNamespace);
+ gridP = gridNewEntry(force_id?targetID:CDI_UNDEFID);
+
+ xassert(!force_id || targetID == gridP->self);
+
+ gridP->type = intBuffer[GRID_PACK_INT_IDX_TYPE];
+ gridP->datatype = intBuffer[GRID_PACK_INT_IDX_DATATYPE];
+ gridP->isCyclic = (signed char)intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC];
+ gridP->x.flag = (short)intBuffer[GRID_PACK_INT_IDX_X_FLAG];
+ gridP->y.flag = (short)intBuffer[GRID_PACK_INT_IDX_Y_FLAG];
+ gridP->gme.nd = intBuffer[GRID_PACK_INT_IDX_GME_ND];
+ gridP->gme.ni = intBuffer[GRID_PACK_INT_IDX_GME_NI];
+ gridP->gme.ni2 = intBuffer[GRID_PACK_INT_IDX_GME_NI2];
+ gridP->gme.ni3 = intBuffer[GRID_PACK_INT_IDX_GME_NI3];
+ gridP->number = intBuffer[GRID_PACK_INT_IDX_NUMBER];
+ gridP->position = intBuffer[GRID_PACK_INT_IDX_POSITION];
+ gridP->trunc = intBuffer[GRID_PACK_INT_IDX_TRUNC];
+ gridP->nvertex = intBuffer[GRID_PACK_INT_IDX_NVERTEX];
+ gridP->nrowlon = intBuffer[GRID_PACK_INT_IDX_NROWLON];
+ gridP->size = intBuffer[GRID_PACK_INT_IDX_SIZE];
+ gridP->x.size = intBuffer[GRID_PACK_INT_IDX_X_SIZE];
+ gridP->y.size = intBuffer[GRID_PACK_INT_IDX_Y_SIZE];
+ gridP->lcomplex = (bool)intBuffer[GRID_PACK_INT_IDX_LCOMPLEX];
+ memberMask = intBuffer[GRID_PACK_INT_IDX_MEMBERMASK];
+ gridP->x.stdname =
+ xystdname_tab[intBuffer[GRID_PACK_INT_IDX_XTSTDNNAME]][0];
+ gridP->y.stdname =
+ xystdname_tab[intBuffer[GRID_PACK_INT_IDX_YTSTDNNAME]][1];
+ gridP->uvRelativeToGrid = intBuffer[GRID_PACK_INT_IDX_UVRELATIVETOGRID];
+ gridP->iScansNegatively = (bool)intBuffer[GRID_PACK_INT_IDX_ISCANSNEGATIVELY];
+ gridP->jScansPositively = (bool)intBuffer[GRID_PACK_INT_IDX_JSCANSPOSITIVELY];
+ gridP->jPointsAreConsecutive = (bool)intBuffer[GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE];
+ gridP->scanningMode = intBuffer[GRID_PACK_INT_IDX_SCANNINGMODE];
+ }
+
+ if (memberMask & gridHasRowLonFlag)
+ {
+ xassert(gridP->nrowlon);
+ gridP->rowlon = (int *) Malloc((size_t)gridP->nrowlon * sizeof (int));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->rowlon, gridP->nrowlon , CDI_DATATYPE_INT, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
+ }
+
+ {
+ double doubleBuffer[gridNdouble];
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ doubleBuffer, gridNdouble, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(d == cdiCheckSum(CDI_DATATYPE_FLT, gridNdouble, doubleBuffer));
+
+ gridP->x.first = doubleBuffer[GRID_PACK_DBL_IDX_X_FIRST];
+ gridP->y.first = doubleBuffer[GRID_PACK_DBL_IDX_Y_FIRST];
+ gridP->x.last = doubleBuffer[GRID_PACK_DBL_IDX_X_LAST];
+ gridP->y.last = doubleBuffer[GRID_PACK_DBL_IDX_Y_LAST];
+ gridP->x.inc = doubleBuffer[GRID_PACK_DBL_IDX_X_INC];
+ gridP->y.inc = doubleBuffer[GRID_PACK_DBL_IDX_Y_INC];
+ }
+
+ bool irregular = gridP->type == GRID_UNSTRUCTURED
+ || gridP->type == GRID_CURVILINEAR;
+ if (memberMask & gridHasXValsFlag)
+ {
+ size = irregular ? gridP->size : gridP->x.size;
+
+ gridP->x.vals = (double *) Malloc(size * sizeof (double));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->x.vals, size, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.vals) == d );
+ }
+
+ if (memberMask & gridHasYValsFlag)
+ {
+ size = irregular ? gridP->size : gridP->y.size;
+
+ gridP->y.vals = (double *) Malloc(size * sizeof (double));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->y.vals, size, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.vals) == d);
+ }
+
+ if (memberMask & gridHasAreaFlag)
+ {
+ size = gridP->size;
+ xassert(size);
+ gridP->area = (double *) Malloc(size * sizeof (double));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->area, size, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->area) == d);
+ }
+
+ if (memberMask & gridHasXBoundsFlag)
+ {
+ size = gridP->nvertex * (irregular ? gridP->size : gridP->x.size);
+ xassert(size);
+
+ gridP->x.bounds = (double *) Malloc(size * sizeof (double));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->x.bounds, size, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.bounds) == d);
+ }
+
+ if (memberMask & gridHasYBoundsFlag)
+ {
+ size = gridP->nvertex * (irregular ? gridP->size : gridP->y.size);
+ xassert(size);
+
+ gridP->y.bounds = (double *) Malloc(size * sizeof (double));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->y.bounds, size, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.bounds) == d);
+ }
+
+ {
+ char *strTab[] = GRID_STR_SERIALIZE(gridP);
+ int numStr = sizeof (strTab) / sizeof (strTab[0]);
+ serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ strTab, numStr, context);
+ }
-static
-institute_t *instituteNewEntry(cdiResH resH, int center, int subcenter,
- const char *name, const char *longname)
-{
- institute_t *instituteptr = (institute_t*) Malloc(sizeof(institute_t));
- instituteDefaultValue(instituteptr);
- if (resH == CDI_UNDEFID)
- instituteptr->self = reshPut(instituteptr, &instituteOps);
- else
+ if (memberMask & gridHasReferenceFlag)
{
- instituteptr->self = resH;
- reshReplace(resH, instituteptr, &instituteOps);
+ int referenceSize;
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &referenceSize, 1, CDI_DATATYPE_INT, context);
+ gridP->reference = (char *) Malloc(referenceSize);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->reference, referenceSize, CDI_DATATYPE_TXT, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_TXT, referenceSize, gridP->reference) == d);
}
- instituteptr->used = 1;
- instituteptr->center = center;
- instituteptr->subcenter = subcenter;
- if ( name && *name )
- instituteptr->name = strdupx(name);
- if (longname && *longname)
- instituteptr->longname = strdupx(longname);
- return instituteptr;
-}
+ if (memberMask & gridHasMaskFlag)
+ {
+ xassert((size = gridP->size));
+ gridP->mask = (mask_t *) Malloc(size * sizeof (mask_t));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->mask, gridP->size, CDI_DATATYPE_UCHAR, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
+ }
-int institutDef(int center, int subcenter, const char *name, const char *longname)
-{
- institute_t * instituteptr
- = instituteNewEntry(CDI_UNDEFID, center, subcenter, name, longname);
- return instituteptr->self;
+ if (memberMask & gridHasGMEMaskFlag)
+ {
+ xassert((size = gridP->size));
+ gridP->mask_gme = (mask_t *) Malloc(size * sizeof (mask_t));
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->mask_gme, gridP->size, CDI_DATATYPE_UCHAR, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
+ }
+ if (memberMask & gridHasUUIDFlag)
+ {
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ gridP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
+ }
+
+ reshSetStatus(gridP->self, &gridOps,
+ reshGetStatus(gridP->self, &gridOps) & ~RESH_SYNC_BIT);
}
-int institutInqCenter(int instID)
+static void
+gridPack(void * voidP, void * packBuffer, int packBufferSize,
+ int * packBufferPos, void *context)
{
- institute_t * instituteptr = NULL;
-
- if ( instID != UNDEFID )
- instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+ grid_t * gridP = ( grid_t * ) voidP;
+ int size;
+ uint32_t d;
+ int memberMask;
- return instituteptr ? instituteptr->center : UNDEFID;
-}
+ {
+ int intBuffer[gridNint];
+ intBuffer[GRID_PACK_INT_IDX_SELF] = gridP->self;
+ intBuffer[GRID_PACK_INT_IDX_TYPE] = gridP->type;
+ intBuffer[GRID_PACK_INT_IDX_DATATYPE] = gridP->datatype;
+ intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC] = gridP->isCyclic;
+ intBuffer[GRID_PACK_INT_IDX_X_FLAG] = gridP->x.flag;
+ intBuffer[GRID_PACK_INT_IDX_Y_FLAG] = gridP->y.flag;
+ intBuffer[GRID_PACK_INT_IDX_GME_ND] = gridP->gme.nd;
+ intBuffer[GRID_PACK_INT_IDX_GME_NI] = gridP->gme.ni;
+ intBuffer[GRID_PACK_INT_IDX_GME_NI2] = gridP->gme.ni2;
+ intBuffer[GRID_PACK_INT_IDX_GME_NI3] = gridP->gme.ni3;
+ intBuffer[GRID_PACK_INT_IDX_NUMBER] = gridP->number;
+ intBuffer[GRID_PACK_INT_IDX_POSITION] = gridP->position;
+ intBuffer[GRID_PACK_INT_IDX_TRUNC] = gridP->trunc;
+ intBuffer[GRID_PACK_INT_IDX_NVERTEX] = gridP->nvertex;
+ intBuffer[GRID_PACK_INT_IDX_NROWLON] = gridP->nrowlon;
+ intBuffer[GRID_PACK_INT_IDX_SIZE] = gridP->size;
+ intBuffer[GRID_PACK_INT_IDX_X_SIZE] = gridP->x.size;
+ intBuffer[GRID_PACK_INT_IDX_Y_SIZE] = gridP->y.size;
+ intBuffer[GRID_PACK_INT_IDX_LCOMPLEX] = gridP->lcomplex;
+ intBuffer[GRID_PACK_INT_IDX_MEMBERMASK] = memberMask
+ = gridGetComponentFlags(gridP);
+ intBuffer[GRID_PACK_INT_IDX_XTSTDNNAME] =
+ (int)((const char (*)[2][24])gridP->x.stdname - xystdname_tab);
+ intBuffer[GRID_PACK_INT_IDX_YTSTDNNAME] =
+ (int)((const char (*)[2][24])gridP->y.stdname
+ - (const char (*)[2][24])xystdname_tab[0][1]);
+
+ intBuffer[GRID_PACK_INT_IDX_UVRELATIVETOGRID] = gridP->uvRelativeToGrid;
+ intBuffer[GRID_PACK_INT_IDX_ISCANSNEGATIVELY] = gridP->iScansNegatively;
+ intBuffer[GRID_PACK_INT_IDX_JSCANSPOSITIVELY] = gridP->jScansPositively;
+ intBuffer[GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE] = gridP->jPointsAreConsecutive;
+ intBuffer[GRID_PACK_INT_IDX_SCANNINGMODE] = gridP->scanningMode;
+
+ serializePack(intBuffer, gridNint, CDI_DATATYPE_INT,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_INT, gridNint, intBuffer);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
-int institutInqSubcenter(int instID)
-{
- institute_t * instituteptr = NULL;
+ if (memberMask & gridHasRowLonFlag)
+ {
+ size = gridP->nrowlon;
+ xassert(size > 0);
+ serializePack(gridP->rowlon, size, CDI_DATATYPE_INT,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_INT , size, gridP->rowlon);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
- if ( instID != UNDEFID )
- instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+ {
+ double doubleBuffer[gridNdouble];
- return instituteptr ? instituteptr->subcenter: UNDEFID;
-}
+ doubleBuffer[GRID_PACK_DBL_IDX_X_FIRST] = gridP->x.first;
+ doubleBuffer[GRID_PACK_DBL_IDX_Y_FIRST] = gridP->y.first;
+ doubleBuffer[GRID_PACK_DBL_IDX_X_LAST] = gridP->x.last;
+ doubleBuffer[GRID_PACK_DBL_IDX_Y_LAST] = gridP->y.last;
+ doubleBuffer[GRID_PACK_DBL_IDX_X_INC] = gridP->x.inc;
+ doubleBuffer[GRID_PACK_DBL_IDX_Y_INC] = gridP->y.inc;
+ serializePack(doubleBuffer, gridNdouble, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, gridNdouble, doubleBuffer);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
-const char *institutInqNamePtr(int instID)
-{
- institute_t * instituteptr = NULL;
+ if (memberMask & gridHasXValsFlag)
+ {
+ if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+ size = gridP->size;
+ else
+ size = gridP->x.size;
+ xassert(size);
- if ( instID != UNDEFID )
- instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+ const double *gridP_xvals = gridP->vtable->inqXValsPtr(gridP);
+ serializePack(gridP_xvals, size, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP_xvals);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
- return instituteptr ? instituteptr->name : NULL;
-}
+ if (memberMask & gridHasYValsFlag)
+ {
+ if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR )
+ size = gridP->size;
+ else
+ size = gridP->y.size;
+ xassert(size);
+ const double *gridP_yvals = gridP->vtable->inqYValsPtr(gridP);
+ serializePack(gridP_yvals, size, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP_yvals);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
+ if (memberMask & gridHasAreaFlag)
+ {
+ xassert(gridP->size);
-const char *institutInqLongnamePtr(int instID)
-{
- institute_t * instituteptr = NULL;
+ serializePack(gridP->area, gridP->size, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, gridP->size, gridP->area);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
- if ( instID != UNDEFID )
- instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+ if (memberMask & gridHasXBoundsFlag)
+ {
+ xassert ( gridP->nvertex );
+ if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+ size = gridP->nvertex * gridP->size;
+ else
+ size = gridP->nvertex * gridP->x.size;
+ xassert ( size );
- return instituteptr ? instituteptr->longname : NULL;
-}
+ serializePack(gridP->x.bounds, size, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.bounds);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
-static enum cdiApplyRet
-activeInstitutes(int id, void *res, void *data)
-{
- (void)id;
- if (res && ((institute_t *)res)->used)
- ++(*(int *)data);
- return CDI_APPLY_GO_ON;
-}
+ if (memberMask & gridHasYBoundsFlag)
+ {
+ xassert(gridP->nvertex);
+ if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+ size = gridP->nvertex * gridP->size;
+ else
+ size = gridP->nvertex * gridP->y.size;
+ xassert ( size );
-int institutInqNumber(void)
-{
- int instNum = 0;
+ serializePack(gridP->y.bounds, size, CDI_DATATYPE_FLT64,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.bounds);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
- cdiResHFilterApply(&instituteOps, activeInstitutes, &instNum);
- return instNum;
-}
+ {
+ const char *strTab[] = GRID_STR_SERIALIZE(gridP);
+ int numStr = sizeof (strTab) / sizeof (strTab[0]);
+ serializeStrTabPack(strTab, numStr,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
+ if (memberMask & gridHasReferenceFlag)
+ {
+ size = (int)strlen(gridP->reference) + 1;
+ serializePack(&size, 1, CDI_DATATYPE_INT,
+ packBuffer, packBufferSize, packBufferPos, context);
+ serializePack(gridP->reference, size, CDI_DATATYPE_TXT,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_TXT, size, gridP->reference);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
-static void
-instituteDestroyP(institute_t *instituteptr)
-{
- xassert(instituteptr);
+ if (memberMask & gridHasMaskFlag)
+ {
+ xassert((size = gridP->size));
+ serializePack(gridP->mask, size, CDI_DATATYPE_UCHAR,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_UCHAR, size, gridP->mask);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
- int instituteID = instituteptr->self;
- Free(instituteptr->name);
- Free(instituteptr->longname);
- reshRemove(instituteID, &instituteOps);
- Free(instituteptr);
-}
+ if (memberMask & gridHasGMEMaskFlag)
+ {
+ xassert((size = gridP->size));
+ serializePack(gridP->mask_gme, size, CDI_DATATYPE_UCHAR,
+ packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_UCHAR, size, gridP->mask_gme);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
+ packBuffer, packBufferSize, packBufferPos, context);
+ }
-static void institutePrintP(institute_t *ip, FILE * fp )
-{
- if (ip)
- fprintf(fp, "#\n"
- "# instituteID %d\n"
- "#\n"
- "self = %d\n"
- "used = %d\n"
- "center = %d\n"
- "subcenter = %d\n"
- "name = %s\n"
- "longname = %s\n",
- ip->self, ip->self, ip->used, ip->center, ip->subcenter,
- ip->name ? ip->name : "NN",
- ip->longname ? ip->longname : "NN");
+ if (memberMask & gridHasUUIDFlag)
+ serializePack(gridP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR,
+ packBuffer, packBufferSize, packBufferPos, context);
}
+#undef GRID_STR_SERIALIZE
-static int
-instituteTxCode ( void )
-{
- return INSTITUTE;
-}
-
-enum {
- institute_nints = 5,
-};
-static int instituteGetPackSize(institute_t *ip, void *context)
+struct gridCompareSearchState
{
- size_t namelen = strlen(ip->name), longnamelen = strlen(ip->longname);
- xassert(namelen < INT_MAX && longnamelen < INT_MAX);
- size_t txsize = (size_t)serializeGetSize(institute_nints, DATATYPE_INT, context)
- + (size_t)serializeGetSize((int)namelen + 1, DATATYPE_TXT, context)
- + (size_t)serializeGetSize((int)longnamelen + 1, DATATYPE_TXT, context);
- xassert(txsize <= INT_MAX);
- return (int)txsize;
-}
+ int resIDValue;
+ const grid_t *queryKey;
+};
-static void institutePackP(void * instituteptr, void *buf, int size, int *position, void *context)
+static enum cdiApplyRet
+gridCompareSearch(int id, void *res, void *data)
{
- institute_t *p = (institute_t*) instituteptr;
- int tempbuf[institute_nints];
- tempbuf[0] = p->self;
- tempbuf[1] = p->center;
- tempbuf[2] = p->subcenter;
- tempbuf[3] = (int)strlen(p->name) + 1;
- tempbuf[4] = (int)strlen(p->longname) + 1;
- serializePack(tempbuf, institute_nints, DATATYPE_INT, buf, size, position, context);
- serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
- serializePack(p->longname, tempbuf[4], DATATYPE_TXT, buf, size, position, context);
+ struct gridCompareSearchState *state = (struct gridCompareSearchState*)data;
+ (void)res;
+ if ( gridCompare(id, state->queryKey, true) == false )
+ {
+ state->resIDValue = id;
+ return CDI_APPLY_STOP;
+ }
+ else
+ return CDI_APPLY_GO_ON;
}
-int instituteUnpack(void *buf, int size, int *position, int originNamespace,
- void *context, int force_id)
+/* Add grid (which must be Malloc'ed to vlist if not already found) */
+struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
{
- int tempbuf[institute_nints];
- int instituteID;
- char *name, *longname;
- serializeUnpack(buf, size, position, tempbuf, institute_nints, DATATYPE_INT, context);
- name = (char *) Malloc((size_t)tempbuf[3] + (size_t)tempbuf[4]);
- longname = name + tempbuf[3];
- serializeUnpack(buf, size, position, name, tempbuf[3], DATATYPE_TXT, context);
- serializeUnpack(buf, size, position, longname, tempbuf[4], DATATYPE_TXT, context);
- int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
- institute_t *ip = instituteNewEntry(force_id?targetID:CDI_UNDEFID,
- tempbuf[1], tempbuf[2], name, longname);
- instituteID = ip->self;
- xassert(!force_id || instituteID == targetID);
- Free(name);
- reshSetStatus(instituteID, &instituteOps,
- reshGetStatus(instituteID, &instituteOps) & ~RESH_SYNC_BIT);
- return instituteID;
-}
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-/*
- * This file is for the use of iterator.c and the CdiIterator subclasses only.
- */
-
-#ifndef INCLUDE_GUARD_CDI_ITERATOR_INT_H
-#define INCLUDE_GUARD_CDI_ITERATOR_INT_H
-
-
-#include <stdbool.h>
+ /*
+ mode: 0 search in vlist and grid table
+ 1 search in grid table only
+ 2 search in grid table only and don't store the grid in vlist
+ */
+ bool gridglobdefined = false;
+ bool griddefined = false;
+ int gridID = CDI_UNDEFID;
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
-/*
-class CdiIterator
+ unsigned ngrids = (unsigned)vlistptr->ngrids;
-An iterator is an object that identifies the position of one record in a file, where a record is defined as the data belonging to one level, timestep, and variable.
-Using iterators to read a file can be significantly faster than using streams, because they can avoid building an index of the file.
-For file formats like grib that do not provide an index within the file, this makes the difference between reading the file once or reading the file twice.
+ if ( mode == 0 )
+ for ( unsigned index = 0; index < ngrids; index++ )
+ {
+ if ( (gridID = vlistptr->gridIDs[index]) != CDI_UNDEFID )
+ {
+ if ( gridCompare(gridID, grid, false) == false )
+ {
+ griddefined = true;
+ break;
+ }
+ }
+ else
+ Error("Internal problem: undefined gridID in vlist "
+ "%d, position %u!", vlistID, index);
+ }
-CdiIterator is an abstract base class. Which derived class is used depends on the type of the file. The class hierarchy currently looks like this:
+ if ( ! griddefined )
+ {
+ struct gridCompareSearchState query;
+ query.queryKey = grid;// = { .queryKey = grid };
+ if ( (gridglobdefined = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query)
+ == CDI_APPLY_STOP)) )
+ gridID = query.resIDValue;
- CdiIterator <|--+-- CdiFallbackIterator
- |
- +-- CdiGribIterator
+ if ( mode == 1 && gridglobdefined )
+ for ( unsigned index = 0; index < ngrids; index++ )
+ if ( vlistptr->gridIDs[index] == gridID )
+ {
+ gridglobdefined = false;
+ break;
+ }
+ }
-The fallback implementation currently uses the stream interface of CDI under the hood to provide full functionality for all filetypes for which no iterator implementation exists yet.
-*/
-//TODO[NH]: Debug messages, print function.
+ if ( ! griddefined )
+ {
+ if ( ! gridglobdefined )
+ {
+ grid->self = gridID = reshPut(grid, &gridOps);
+ gridComplete(grid);
+ }
+ if ( mode < 2 )
+ {
+ vlistptr->gridIDs[ngrids] = gridID;
+ vlistptr->ngrids++;
+ }
+ }
-struct CdiIterator {
- int filetype; //This is used to dispatch calls to the correct subclass.
- bool isAdvanced; //Used to catch inquiries before the first call to CdiIteratorNextField(). //XXX: Advanced is probably not a good word (initialized?)
+ return (struct addIfNewRes){ .Id = gridID, .isNew = !griddefined && !gridglobdefined };
+}
- //The metadata that can be accessed by the inquiry calls.
- //While theoretically redundant, these fields allow the handling of most inquiry calls within the base class.
- //Only the name is excempted because it needs an allocation.
- //These fields are set by the subclasses in the xxxIterNextField() method.
- int datatype, timesteptype;
- int gridId;
- CdiParam param;
- //The status information for reading/advancing is added in the subclasses.
+const struct gridVirtTable cdiGridVtable
+ = {
+ .destroy = gridDestroyKernel,
+ .copy = grid_copy_base,
+ .copyScalarFields = grid_copy_base_scalar_fields,
+ .copyArrayFields = grid_copy_base_array_fields,
+ .defXVals = gridDefXValsSerial,
+ .defYVals = gridDefYValsSerial,
+ .defMask = gridDefMaskSerial,
+ .defMaskGME = gridDefMaskGMESerial,
+ .defXBounds = gridDefXBoundsSerial,
+ .defYBounds = gridDefYBoundsSerial,
+ .defArea = gridDefAreaSerial,
+ .inqXVal = gridInqXValSerial,
+ .inqYVal = gridInqYValSerial,
+ .inqXVals = gridInqXValsSerial,
+ .inqXCvals = gridInqXCvalsSerial,
+ .inqXIsc = gridInqXIscSerial,
+ .inqYVals = gridInqYValsSerial,
+ .inqYCvals = gridInqYCvalsSerial,
+ .inqYIsc = gridInqYIscSerial,
+ .inqXValsPtr = gridInqXValsPtrSerial,
+ .inqYValsPtr = gridInqYValsPtrSerial,
+ .inqXCvalsPtr = gridInqXCvalsPtrSerial,
+ .inqYCvalsPtr = gridInqYCvalsPtrSerial,
+ .compareXYFull = compareXYvals,
+ .compareXYAO = compareXYvals2,
+ .inqArea = gridInqAreaSerial,
+ .inqAreaPtr = gridInqAreaPtrBase,
+ .hasArea = gridHasAreaBase,
+ .inqMask = gridInqMaskSerial,
+ .inqMaskGME = gridInqMaskGMESerial,
+ .inqXBounds = gridInqXBoundsSerial,
+ .inqYBounds = gridInqYBoundsSerial,
+ .inqXBoundsPtr = gridInqXBoundsPtrSerial,
+ .inqYBoundsPtr = gridInqYBoundsPtrSerial,
};
-void baseIterConstruct(CdiIterator *me, int filetype);
-const char* baseIter_constructFromString(CdiIterator *me, const char *description); //Returns a pointer past the end of the parsed portion of the description string.
-void baseIterDestruct(CdiIterator *me);
-
-#endif
-
/*
* Local Variables:
* c-file-style: "Java"
@@ -30300,1218 +29585,822 @@ void baseIterDestruct(CdiIterator *me);
* require-trailing-newline: t
* End:
*/
-/*
- * A fallback implementation of the iterator interface that opens a stream under the hood.
- *
- * This implementation is mainly available to provide iterator access to file formats that don't support iterator access natively,
- * nevertheless, it allows the file to dictate the order in which data is read, possibly providing performance benefits.
- */
-
-#ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
-#define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
-
-
-typedef struct CdiFallbackIterator CdiFallbackIterator;
-
-CdiIterator *cdiFallbackIterator_new(const char *path, int filetype);
-CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *me);
-CdiIterator *cdiFallbackIterator_getSuper(CdiFallbackIterator *me);
-char *cdiFallbackIterator_serialize(CdiIterator *me);
-CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *me);
+#if defined (HAVE_CONFIG_H)
+#endif
-int cdiFallbackIterator_nextField(CdiIterator *me);
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
-char *cdiFallbackIterator_inqTime(CdiIterator *me, CdiTimeType timeType);
-int cdiFallbackIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit);
-int cdiFallbackIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
-int cdiFallbackIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
-char *cdiFallbackIterator_copyVariableName(CdiIterator *me);
-int cdiFallbackIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute);
-int cdiFallbackIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount);
-void cdiFallbackIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
-void cdiFallbackIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss);
-void cdiFallbackIterator_delete(CdiIterator *super);
+static int initIegLib = 0;
+static int iegDefaultDprec = 0;
-#endif
/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-/*
- * An implementation of the iterator interface for GRIB files.
- * Since GRIB files do not contain an index, this avoids scanning the entire file to generate an in-memory index as streamOpenRead() does.
- * Consequently, using this interface is much more efficient for GRIB files.
+ * A version string.
*/
+#undef LIBVERSION
+#define LIBVERSION 1.4.0
+#define XSTRING(x) #x
+#define STRING(x) XSTRING(x)
+static const char ieg_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__;
-#ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
-#define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
-
-
-#ifdef HAVE_LIBGRIB_API
-#include <grib_api.h>
-#endif
-
-typedef struct recordList recordList;
-
-CdiIterator *cdiGribIterator_new(const char *path, int filetype);
-CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *me);
-CdiIterator *cdiGribIterator_getSuper(CdiGribIterator *me);
-char *cdiGribIterator_serialize(CdiIterator *me);
-CdiGribIterator *cdiGribIterator_deserialize(const char *me);
+const char *iegLibraryVersion(void)
+{
+ return ieg_libvers;
+}
-int cdiGribIterator_nextField(CdiIterator *me);
-char *cdiGribIterator_inqTime(CdiIterator *me, CdiTimeType timeType);
-int cdiGribIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit);
-int cdiGribIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
-int cdiGribIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
-int cdiGribIterator_inqTile(CdiIterator *me, int *outTileIndex, int *outTileAttribute);
-int cdiGribIterator_inqTileCount(CdiIterator *me, int *outTileCount, int *outTileAttributeCount);
-char *cdiGribIterator_copyVariableName(CdiIterator *me);
+static int IEG_Debug = 0; /* If set to 1, debugging */
-void cdiGribIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
-void cdiGribIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss);
+static
+void iegLibInit(void)
+{
+ const char *envName = "IEG_PRECISION";
-#endif
+ char *envString = getenv(envName);
+ if ( envString )
+ {
+ int pos;
+ int nrun;
+ if ( strlen(envString) == 2 ) nrun = 1;
+ else nrun = 2;
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
+ pos = 0;
+ while ( nrun-- )
+ {
+ switch ( tolower((int) envString[pos]) )
+ {
+ case 'r':
+ {
+ switch ( (int) envString[pos+1] )
+ {
+ case '4': iegDefaultDprec = EXSE_SINGLE_PRECISION; break;
+ case '8': iegDefaultDprec = EXSE_DOUBLE_PRECISION; break;
+ default:
+ Message("Invalid digit in %s: %s", envName, envString);
+ }
+ break;
+ }
+ default:
+ {
+ Message("Invalid character in %s: %s", envName, envString);
+ break;
+ }
+ }
+ pos += 2;
+ }
+ }
-#include <assert.h>
-#include <ctype.h>
+ initIegLib = 1;
+}
-static const char kUnexpectedFileTypeMessage[]
- = "Internal error: Unexpected file type encountered in iterator.\n"
- "This is either due to an illegal memory access by the application\n"
- " or an internal logical error in CDI (unlikely, but possible).";
-static const char kAdvancedString[] = "advanced";
-static const char kUnadvancedString[] = "unadvanced";
-//Returns a static string.
-static const char* fileType2String(int fileType)
+void iegDebug(int debug)
{
- switch(fileType)
- {
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB: return "CDI::Iterator::GRIB1";
- case FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
-#endif
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC: return "CDI::Iterator::NetCDF";
- case FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
- case FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
- case FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV: return "CDI::Iterator::SRV";
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT: return "CDI::Iterator::EXT";
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG: return "CDI::Iterator::IEG";
-#endif
+ IEG_Debug = debug;
- default: return NULL;
- }
+ if ( IEG_Debug )
+ Message("debug level %d", debug);
}
-static int string2FileType(const char* fileType, const char **outRestString)
+static
+void iegInit(iegrec_t *iegp)
{
- //This first part unconditionally checks all known type strings, and only if the given string matches one of these strings, we use fileType2string() to check whether support for this type has been compiled in. This is to avoid throwing "invalid type string" errors when we just have a library version mismatch.
-#define check(givenString, typeString, typeConstant) do \
- { \
- if(givenString == strstr(givenString, typeString)) \
- { \
- if(outRestString) *outRestString = givenString + strlen(typeString); \
- if(fileType2String(typeConstant)) return typeConstant; \
- Error("Support for " typeString " not compiled in. Please check that the result of `cdiIterator_serialize()` is only passed to a `cdiIterator_deserialize()` implementation of the same CDI library version."); \
- return FILETYPE_UNDEF; \
- } \
- } while(0)
- check(fileType, "CDI::Iterator::GRIB1", FILETYPE_GRB);
- check(fileType, "CDI::Iterator::GRIB2", FILETYPE_GRB2);
- check(fileType, "CDI::Iterator::NetCDF", FILETYPE_NC);
- check(fileType, "CDI::Iterator::NetCDF2", FILETYPE_NC2);
- check(fileType, "CDI::Iterator::NetCDF4", FILETYPE_NC4);
- check(fileType, "CDI::Iterator::NetCDF4C", FILETYPE_NC4C);
- check(fileType, "CDI::Iterator::SRV", FILETYPE_SRV);
- check(fileType, "CDI::Iterator::EXT", FILETYPE_EXT);
- check(fileType, "CDI::Iterator::IEG", FILETYPE_IEG);
-#undef check
-
- //If this point is reached, the given string does not seem to be produced by a cdiIterator_serialize() call.
- Error("The string \"%s\" does not start with a valid iterator type. Please check the source of this string.", fileType);
- *outRestString = fileType;
- return FILETYPE_UNDEF;
+ iegp->checked = 0;
+ iegp->byteswap = 0;
+ iegp->dprec = 0;
+ iegp->refval = 0;
+ iegp->datasize = 0;
+ iegp->buffersize = 0;
+ iegp->buffer = NULL;
}
-/*
- at Function cdiIterator_new
- at Title Create an iterator for an input file
- at Prototype CdiIterator* cdiIterator_new(const char* path)
- at Parameter
- @item path Path to the file that is to be read.
+void iegInitMem(void *ieg)
+{
+ iegrec_t *iegp = (iegrec_t *) ieg;
- at Result An iterator for the given file.
+ memset(iegp->ipdb, 0, sizeof(iegp->ipdb));
+ memset(iegp->igdb, 0, sizeof(iegp->igdb));
+ memset(iegp->vct, 0, sizeof(iegp->vct));
+}
- at Description
- Combined allocator and constructor for CdiIterator.
- The returned iterator does not point to the first field yet,
- it must first be advanced once before the first field can be introspected.
- This design decision has two benefits: 1. Empty files require no special
- cases, 2. Users can start a while(!cdiIterator_nextField(iterator)) loop
- right after the call to cdiIterator_new().
-*/
-CdiIterator* cdiIterator_new(const char* path)
+void *iegNew(void)
{
- int trash;
- int filetype = cdiGetFiletype(path, &trash);
- switch(filetype)
- {
- case FILETYPE_UNDEF:
- Warning("Can't open file \"%s\": unknown format\n", path);
- return NULL;
+ if ( ! initIegLib ) iegLibInit();
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_new(path, filetype);
-#endif
+ iegrec_t *iegp = (iegrec_t *) Malloc(sizeof(iegrec_t));
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_new(path, filetype);
+ iegInit(iegp);
+ iegInitMem(iegp);
- default:
- Warning("the file \"%s\" is of type %s, but support for this format is not compiled in!", path, strfiletype(filetype));
- return NULL;
- }
+ return (void*)iegp;
}
-void baseIterConstruct(CdiIterator* me, int filetype)
-{
- me->filetype = filetype;
- me->isAdvanced = false;
-}
-const char* baseIter_constructFromString(CdiIterator* me, const char* description)
+void iegDelete(void *ieg)
{
- const char* result = description;
- me->filetype = string2FileType(result, &result);
- assert(me->filetype != FILETYPE_UNDEF && "Please report this error."); //This condition should have been checked for in a calling function.
- for(; *result && isspace(*result); result++);
- if(result == strstr(result, kAdvancedString))
- {
- me->isAdvanced = true;
- result += sizeof (kAdvancedString) - 1;
- }
- else if(result == strstr(result, kUnadvancedString))
- {
- me->isAdvanced = false;
- result += sizeof (kUnadvancedString) - 1;
- }
- else
+ iegrec_t *iegp = (iegrec_t *) ieg;
+
+ if ( iegp )
{
- Error("Invalid iterator description string \"%s\". Please check the origin of this string.", description);
- return NULL;
+ if ( iegp->buffer ) Free(iegp->buffer);
+ Free(iegp);
}
- return result;
}
-#define sanityCheck(me) do { \
- if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
- if(!me->isAdvanced) xabort("Calling %s is not allowed without calling cdiIterator_nextField() first.", __func__); \
-} while(0)
-/*
- at Function cdiIterator_clone
- at Title Make a copy of an iterator
+int iegCheckFiletype(int fileID, int *swap)
+{
+ size_t data = 0;
+ size_t dimx = 0, dimy = 0;
+ size_t fact = 0;
+ unsigned char buffer[1048], *pbuf;
- at Prototype CdiIterator* cdiIterator_clone(CdiIterator* me)
- at Parameter
- @item iterator The iterator to copy.
+ if ( fileRead(fileID, buffer, 4) != 4 ) return 0;
- at Result The clone.
+ size_t blocklen = get_UINT32(buffer);
+ size_t sblocklen = get_SUINT32(buffer);
- at Description
- Clones the given iterator. Make sure to call cdiIterator_delete() on both
- the copy and the original.
+ if ( IEG_Debug )
+ Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
- This is not a cheap operation: Depending on the type of the file, it will
- either make a copy of the current field in memory (GRIB files), or reopen
- the file (all other file types). Use it sparingly. And if you do, try to
- avoid keeping too many clones around: their memory footprint is
- significant.
-*/
-CdiIterator* cdiIterator_clone(CdiIterator* me)
-{
- sanityCheck(me);
- switch(me->filetype)
+ if ( blocklen == 636 || blocklen == 640 )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_getSuper(cdiGribIterator_clone(me));
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_getSuper(cdiFallbackIterator_clone(me));
-
- default:
- Error(kUnexpectedFileTypeMessage);
- return NULL;
+ *swap = 0;
+ fact = 4;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
+ pbuf = buffer+(37+4)*4; dimx = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+(37+5)*4; dimy = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
}
-}
-
-/*
- at Function cdiGribIterator_clone
- at Title Gain access to GRIB specific functionality
-
- at Prototype CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
-
- at Result A clone that allows access to GRIB specific functionality, or NULL if the underlying file is not a GRIB file.
-
- at Description
- Clones the given iterator iff the underlying file is a GRIB file, the returned iterator allows access to GRIB specific functionality.
- Make sure to check that the return value is not NULL, and to call cdiGribIterator_delete() on the copy.
-
- This is not a cheap operation: It will make a copy of the current field in memory. Use it sparingly. And if you do, try to avoid keeping too many clones around, their memory footprint is significant.
-*/
-CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
-{
- sanityCheck(me);
- switch(me->filetype)
+ else if ( blocklen == 1040 || blocklen == 1036 )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_makeClone(me);
-#endif
-
- default:
- return NULL;
+ *swap = 0;
+ fact = 8;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
+ pbuf = buffer+(37+4)*4; dimx = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+(37+5)*4; dimy = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
+ }
+ else if ( sblocklen == 636 || sblocklen == 640 )
+ {
+ *swap = 1;
+ fact = 4;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
+ pbuf = buffer+(37+4)*4; dimx = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+(37+5)*4; dimy = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ }
+ else if ( sblocklen == 1040 || sblocklen == 1036 )
+ {
+ *swap = 1;
+ fact = 8;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
+ pbuf = buffer+(37+4)*4; dimx = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+(37+5)*4; dimy = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
}
-}
-
-/*
- at Function cdiIterator_serialize
- at Title Serialize an iterator for sending it to another process
- at Prototype char* cdiIterator_serialize(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
+ fileRewind(fileID);
- at Result A malloc'ed string that contains the full description of the iterator.
+ int found = data && (dimx*dimy*fact == data || dimx*dimy*8 == data);
- at Description
- Make sure to call Free() on the resulting string.
-*/
-char* cdiIterator_serialize(CdiIterator* me)
-{
- if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
- char* subclassDescription = NULL;
- switch(me->filetype)
+ if ( IEG_Debug )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- subclassDescription = cdiGribIterator_serialize(me);
- break;
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- subclassDescription = cdiFallbackIterator_serialize(me);
- break;
-
- default:
- Error(kUnexpectedFileTypeMessage);
- return NULL;
+ Message("swap = %d fact = %d", *swap, fact);
+ Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
}
- const char *ftypeStr = fileType2String(me->filetype),
- *advStr = me->isAdvanced ? kAdvancedString : kUnadvancedString;
- char* result = (char *) Malloc(strlen(ftypeStr) + 1 + strlen(advStr) + 1
- + strlen(subclassDescription) + 1);
- sprintf(result, "%s %s %s", ftypeStr, advStr, subclassDescription);
- Free(subclassDescription);
- return result;
+ return found;
}
-/*
- at Function cdiIterator_deserialize
- at Title Recreate an iterator from its textual description
- at Prototype CdiIterator* cdiIterator_deserialize(const char* description)
- at Parameter
- @item description The result of a call to cdiIterator_serialize().
+void iegCopyMeta(void *dieg, void *sieg)
+{
+ iegrec_t *diegp = (iegrec_t *) dieg;
+ iegrec_t *siegp = (iegrec_t *) sieg;
- at Result A clone of the original iterator.
+ /* diegp->byteswap = siegp->byteswap; */
+ diegp->dprec = siegp->dprec;
+ diegp->refval = siegp->refval;
- at Description
- A pair of cdiIterator_serialize() and cdiIterator_deserialize() is functionally equivalent to a call to cdiIterator_clone()
+ memcpy(diegp->ipdb, siegp->ipdb, sizeof(siegp->ipdb));
+ memcpy(diegp->igdb, siegp->igdb, sizeof(siegp->igdb));
+ memcpy(diegp->vct, siegp->vct, sizeof(siegp->vct));
+}
- This function will reread the current field from disk, so don't expect immediate return.
-*/
-//This only checks the type of the iterator and calls the corresponding subclass function,
-//the real deserialization is done in baseIter_constructFromString().
-CdiIterator* cdiIterator_deserialize(const char* description)
+static
+int iegInqData(void *ieg, int prec, void *data)
{
- switch(string2FileType(description, NULL))
+ iegrec_t *iegp = (iegrec_t *) ieg;
+ int ierr = 0;
+ int byteswap = iegp->byteswap;
+ size_t datasize = iegp->datasize;
+ void *buffer = iegp->buffer;
+ int dprec = iegp->dprec;
+
+ switch ( dprec )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_getSuper(cdiGribIterator_deserialize(description));
-#endif
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( sizeof(FLT32) == 4 )
+ {
+ if ( byteswap ) swap4byte(buffer, datasize);
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_getSuper(cdiFallbackIterator_deserialize(description));
+ if ( dprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT32));
+ else
+ {
+ const float *restrict p = (float *)buffer;
+ double *restrict q = (double *)data;
+ for ( size_t i = 0; i < datasize; i++)
+ q[i] = p[i];
+ }
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT32));
+ }
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ if ( sizeof(FLT64) == 8 )
+ {
+ if ( byteswap ) swap8byte(buffer, datasize);
- default:
- Error(kUnexpectedFileTypeMessage);
- return NULL;
+ if ( dprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT64));
+ else
+ {
+ const double *restrict p = (double *)buffer;
+ float *restrict q = (float *)data;
+ for ( size_t i = 0; i < datasize; i++)
+ q[i] = (float)p[i];
+ }
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT64));
+ }
+ break;
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
}
+
+ return ierr;
}
-/*
- at Function cdiIterator_print
- at Title Print a textual description of the iterator to a stream
+int iegInqDataSP(void *ieg, float *data)
+{
+ return iegInqData(ieg, EXSE_SINGLE_PRECISION, (void *) data);
+}
- at Prototype void cdiIterator_print(CdiIterator* iterator, FILE* stream);
- at Parameter
- @item iterator The iterator to print.
- @item stream The stream to print to.
- at Description
- Use for debugging output.
-*/
-void cdiIterator_print(CdiIterator* me, FILE* stream)
+int iegInqDataDP(void *ieg, double *data)
{
- char* description = cdiIterator_serialize(me);
- fprintf(stream, "%s\n", description);
- Free(description);
+ return iegInqData(ieg, EXSE_DOUBLE_PRECISION, (void *) data);
}
-/*
- at Function cdiIterator_nextField
- at Title Advance an iterator to the next field in the file
+static int
+iegDefData(iegrec_t *iegp, int prec, const void *data)
+{
+ int dprec = iegDefaultDprec ? iegDefaultDprec : iegp->dprec;
- at Prototype int cdiIterator_nextField(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+ iegp->dprec = dprec = dprec ? dprec : prec;
- at Result An error code. May be one of:
- * CDI_NOERR: The iterator has successfully been advanced to the next field.
- * CDI_EEOF: No more fields to read in this file.
+ size_t datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
+ size_t blocklen = datasize * (size_t)dprec;
- at Description
- One call to cdiIterator_nextField() is required before the metadata of the first field can be examined.
- Usually, it will be used directly as the condition for a while() loop.
-*/
-int cdiIterator_nextField(CdiIterator* me)
-{
- if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
- me->isAdvanced = true;
- switch(me->filetype)
- {
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_nextField(me);
-#endif
+ iegp->datasize = datasize;
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_nextField(me);
+ size_t buffersize = iegp->buffersize;
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_EINVAL;
+ void *buffer = iegp->buffer;
+ if ( buffersize != blocklen )
+ {
+ buffersize = blocklen;
+ buffer = Realloc(buffer, buffersize);
+ iegp->buffer = buffer;
+ iegp->buffersize = buffersize;
}
-}
-static char* cdiIterator_inqTime(CdiIterator* me, CdiTimeType timeType)
-{
- sanityCheck(me);
- switch(me->filetype)
+ switch ( dprec )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_inqTime(me, timeType);
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_inqTime(me, timeType);
-
- default:
- Error(kUnexpectedFileTypeMessage);
- return NULL;
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( dprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT32));
+ else
+ {
+ const double *restrict p = (const double *)data;
+ float *restrict q = (float *)buffer;
+ for (size_t i = 0; i < datasize; i++)
+ q[i] = (float)p[i];
+ }
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ if ( dprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT64));
+ else
+ {
+ const float *restrict p = (const float *)data;
+ double *restrict q = (double *)buffer;
+ for ( size_t i = 0; i < datasize; i++)
+ q[i] = p[i];
+ }
+ break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
}
-}
-
-/*
- at Function cdiIterator_inqStartTime
- at Title Get the start time of a measurement
-
- at Prototype char* cdiIterator_inqStartTime(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
-
- at Result A malloc'ed string containing the (start) time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
- at Description
-The returned time is either the time of the data (fields defined at a time point),
-or the start time of an integration time range (statistical fields).
+ return 0;
+}
-Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
-The caller is responsible to Free() the resulting string.
-If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
-as it is implemented by the standard C mktime() function.
-This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
-*/
-char* cdiIterator_inqStartTime(CdiIterator* me)
+int iegDefDataSP(void *ieg, const float *data)
{
- return cdiIterator_inqTime(me, kCdiTimeType_startTime);
+ return iegDefData((iegrec_t *)ieg, EXSE_SINGLE_PRECISION, (void *) data);
}
-/*
- at Function cdiIterator_inqEndTime
- at Title Get the end time of a measurement
-
- at Prototype char* cdiIterator_inqEndTime(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
-
- at Result A malloc'ed string containing the end time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm", or NULL if no such time is defined.
- at Description
-The returned time is the end time of an integration period if such a time exists (statistical fields).
-Otherwise, NULL is returned.
+int iegDefDataDP(void *ieg, const double *data)
+{
+ return iegDefData((iegrec_t *)ieg, EXSE_DOUBLE_PRECISION, (void *) data);
+}
-Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
-The caller is responsible to Free() the resulting string.
-If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
-as it is implemented by the standard C mktime() function.
-This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
-*/
-char* cdiIterator_inqEndTime(CdiIterator* me)
+int iegRead(int fileID, void *ieg)
{
- return cdiIterator_inqTime(me, kCdiTimeType_endTime);
-}
+ iegrec_t *iegp = (iegrec_t *) ieg;
+ union { double d[200]; float f[200]; int32_t i32[200]; } buf;
-/*
- at Function cdiIterator_inqRTime
- at Title Get the validity time of the current field
+ if ( ! iegp->checked )
+ {
+ int status = iegCheckFiletype(fileID, &iegp->byteswap);
+ if ( status == 0 ) Error("Not a IEG file!");
+ iegp->checked = 1;
+ }
- at Prototype char* cdiIterator_inqRTime(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
+ int byteswap = iegp->byteswap;
- at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+ /* read header record */
+ size_t blocklen = binReadF77Block(fileID, byteswap);
- at Description
-The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
-That is, if the field is a time point, its time is returned,
-if it is a statistical field with an integration period, the end time of the integration period is returned.
+ if ( fileEOF(fileID) ) return -1;
-Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
-The caller is responsible to Free() the resulting string.
+ if ( IEG_Debug )
+ Message("blocklen = %lu", blocklen);
-If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
-as it is implemented by the standard C mktime() function.
-This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
-*/
-char* cdiIterator_inqRTime(CdiIterator* me)
-{
- return cdiIterator_inqTime(me, kCdiTimeType_referenceTime);
-}
+ int dprec = 0;
+ if ( blocklen == 636 || blocklen == 640 )
+ dprec = 4;
+ else if ( blocklen == 1040 || blocklen == 1036 )
+ dprec = 8;
+ else
+ {
+ Warning("unexpecteted header size %d!", (int) blocklen);
+ return -1;
+ }
-/*
- at Function cdiIterator_inqVTime
- at Title Get the validity time of the current field
+ iegp->dprec = dprec;
- at Prototype char* cdiIterator_inqVTime(CdiIterator* me)
- at Parameter
- @item iterator The iterator to operate on.
+ binReadInt32(fileID, byteswap, 37, buf.i32);
+ for ( size_t i = 0; i < 37; i++ ) iegp->ipdb[i] = (int)buf.i32[i];
- at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+ binReadInt32(fileID, byteswap, 18, buf.i32);
+ for ( size_t i = 0; i < 18; i++ ) iegp->igdb[i] = (int)buf.i32[i];
- at Description
-The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
-That is, if the field is a time point, its time is returned,
-if it is a statistical field with an integration period, the end time of the integration period is returned.
+ if ( blocklen == 636 || blocklen == 1036 )
+ {
+ fileRead(fileID, buf.f, 4);
+ if ( byteswap ) swap4byte(buf.f, 1);
+ iegp->refval = (double)buf.f[0];
+ }
+ else
+ {
+ fileRead(fileID, buf.d, 8);
+ if ( byteswap ) swap8byte(buf.d, 1);
+ iegp->refval = (double)buf.d[0];
+ }
-Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
-The caller is responsible to Free() the resulting string.
+ binReadInt32(fileID, byteswap, 3, buf.i32);
+ for ( size_t i = 0; i < 3; i++ ) iegp->igdb[18+i] = (int)buf.i32[i];
-If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
-as it is implemented by the standard C mktime() function.
-This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
-*/
-char* cdiIterator_inqVTime(CdiIterator* me)
-{
- char* result = cdiIterator_inqEndTime(me);
- return (result) ? result : cdiIterator_inqStartTime(me);
-}
+ if ( dprec == EXSE_SINGLE_PRECISION )
+ {
+ fileRead(fileID, buf.f, 400);
+ if ( byteswap ) swap4byte(buf.f, 100);
+ for ( size_t i = 0; i < 100; i++ )
+ iegp->vct[i] = (double)buf.f[i];
+ }
+ else
+ {
+ fileRead(fileID, buf.d, 800);
+ if ( byteswap ) swap8byte(buf.d, 100);
+ for ( size_t i = 0; i < 100; i++ )
+ iegp->vct[i] = buf.d[i];
+ }
-/*
- at Function cdiIterator_inqLevelType
- at Title Get the type of a level
+ /*
+ fprintf(stderr, "refval %g\n", iegp->refval);
- at Prototype int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName = NULL, char **outLongName = NULL, char **outStdName = NULL, char **outUnit = NULL)
- at Parameter
- @item iterator The iterator to operate on.
- @item levelSelector Zero for the top level, one for the bottom level
- @item outName Will be set to a Malloc()'ed string with the name of the level if not NULL.
- @item outLongName Will be set to a Malloc()'ed string with the long name of the level if not NULL.
- @item outStdName Will be set to a Malloc()'ed string with the standard name of the level if not NULL.
- @item outUnit Will be set to a Malloc()'ed string with the unit of the level if not NULL.
+ for ( size_t i = 0; i < 100; i++ )
+ fprintf(stderr, "%3d %g\n", i, iegp->vct[i]);
- at Result An integer indicating the type of the level.
+ {
+ int i;
+ for ( size_t i = 0; i < 37; i++ )
+ fprintf(stderr, "pdb: %d %d\n", i, iegp->ipdb[i]);
+ for ( size_t i = 0; i < 22; i++ )
+ fprintf(stderr, "gdb: %d %d\n", i, iegp->igdb[i]);
+ }
+ */
+ size_t blocklen2 = binReadF77Block(fileID, byteswap);
- at Description
-Find out some basic information about the given level, the levelSelector selects the function of the requested level.
-If the requested level does not exist, this returns CDI_UNDEFID.
-*/
-int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
-{
- sanityCheck(me);
- switch(me->filetype)
+ if ( blocklen2 != blocklen )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
-#endif
+ Warning("header blocklen differ!");
+ return -1;
+ }
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+ size_t datasize = iegp->datasize
+ = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_UNDEFID;
- }
-}
+ if ( IEG_Debug )
+ Message("datasize = %lu", iegp->datasize);
-/*
- at Function cdiIterator_inqLevel
- at Title Get the value of the z-coordinate
+ blocklen = binReadF77Block(fileID, byteswap);
- at Prototype void cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2 = NULL)
- at Parameter
- @item iterator The iterator to operate on.
- @item levelSelector Zero for the top level, one for the bottom level
- @item outValue1 For "normal" levels this returns the value, for hybrid levels the first coordinate, for generalized levels the level number.
- @item outValue2 Zero for "normal" levels, for hybrid levels, this returns the second coordinate, for generalized levels the level count.
- at Result An error code.
+ void *buffer = iegp->buffer;
+ if ( iegp->buffersize < blocklen )
+ {
+ iegp->buffer = buffer = Realloc(buffer, blocklen);
+ iegp->buffersize = blocklen;
+ }
- at Description
-Returns the value of the z-coordinate, whatever that may be.
-*/
-int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2)
-{
- sanityCheck(me);
- switch(me->filetype)
+ if ( dprec != (int) (blocklen/datasize) )
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
-#endif
+ Warning("data precision differ! (h = %d; d = %d)",
+ (int) dprec, (int) (blocklen/datasize));
+ return -1;
+ }
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
+ fileRead(fileID, buffer, blocklen);
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_EINVAL;
- }
-}
+ blocklen2 = binReadF77Block(fileID, byteswap);
-/*
- at Function cdiIterator_inqLevelUuid
- at Title Get the UUID of the z-axis used by this field
+ if ( blocklen2 != blocklen )
+ {
+ Warning("data blocklen differ!");
+ return -1;
+ }
- at Prototype int cdiIterator_inqLevelUuid(CdiIterator* me, int levelSelector, unsigned char (*outUuid)[16])
- at Parameter
- @item iterator The iterator to operate on.
- @item outVgridNumber The number of the associated vertical grid description.
- @item outLevelCount The number of levels in the associated vertical grid description.
- @item outUuid A pointer to a user supplied buffer of 16 bytes to store the UUID in.
+ return 0;
+}
- at Result An error code.
- at Description
-Returns identifying information for the external z-axis description. May only be called for generalized levels.
-*/
-int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
+int iegWrite(int fileID, void *ieg)
{
- sanityCheck(me);
- switch(me->filetype)
- {
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
-#endif
+ iegrec_t *iegp = (iegrec_t *) ieg;
+ union { INT32 i32[200]; float fvct[100]; } buf;
+ int dprec = iegp->dprec;
+ int byteswap = iegp->byteswap;
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+ /* write header record */
+ size_t blocklen = ( dprec == EXSE_SINGLE_PRECISION ) ? 636 : 1040;
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_ELIBNAVAIL;
- }
-}
+ binWriteF77Block(fileID, byteswap, blocklen);
-/*
- at Function cdiIterator_inqTile
- at Title Inquire the tile information for the current field
+ for ( size_t i = 0; i < 37; i++ ) buf.i32[i] = (INT32) iegp->ipdb[i];
+ binWriteInt32(fileID, byteswap, 37, buf.i32);
- at Prototype int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
- at Parameter
- @item iterator The iterator to operate on.
- @item outTileIndex The index of the current tile, -1 if no tile information is available.
- @item outTileAttribute The attribute of the current tile, -1 if no tile information is available.
+ for ( size_t i = 0; i < 18; i++ ) buf.i32[i] = (INT32) iegp->igdb[i];
+ binWriteInt32(fileID, byteswap, 18, buf.i32);
- at Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
+ FLT64 refval = (FLT64)iegp->refval;
+ FLT32 refvalf = (FLT32)iegp->refval;
+ if ( dprec == EXSE_SINGLE_PRECISION )
+ binWriteFlt32(fileID, byteswap, 1, &refvalf);
+ else
+ binWriteFlt64(fileID, byteswap, 1, &refval);
- at Description
-Inquire the tile index and attribute for the current field.
-*/
-int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
-{
- sanityCheck(me);
- switch(me->filetype)
+ for ( size_t i = 0; i < 3; i++ ) buf.i32[i] = (INT32) iegp->igdb[18+i];
+ binWriteInt32(fileID, byteswap, 3, buf.i32);
+
+ if ( dprec == EXSE_SINGLE_PRECISION )
{
- #ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute);
- #endif
+ for ( size_t i = 0; i < 100; i++ ) buf.fvct[i] = (float) iegp->vct[i];
+ binWriteFlt32(fileID, byteswap, 100, buf.fvct);
+ }
+ else
+ {
+ binWriteFlt64(fileID, byteswap, 100, iegp->vct);
+ }
- #ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- #endif
- #ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
- #endif
- #ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
- #endif
- #ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
- #endif
- return cdiFallbackIterator_inqTile(me, outTileIndex, outTileAttribute);
+ binWriteF77Block(fileID, byteswap, blocklen);
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_ELIBNAVAIL;
- }
-}
+ size_t datasize = (size_t)iegp->igdb[4] * (size_t)iegp->igdb[5];
+ blocklen = datasize * (size_t)dprec;
-/**
- at Function cdiIterator_inqTileCount
- at Title Inquire the tile count and tile attribute counts for the current field
+ binWriteF77Block(fileID, byteswap, blocklen);
- at Prototype int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
- at Parameter
- @item iterator The iterator to operate on.
- @item outTileCount The number of tiles used for this variable, zero if no tile information is available.
- @item outTileAttributeCount The number of attributes available for the tile of this field, zero if no tile information is available.
- Note: This is not the global attribute count, which would be impossible to infer without reading the entire file if it's a GRIB file.
+ iegp->datasize = datasize;
- at Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
+ void *buffer = iegp->buffer;
- at Description
-Inquire the tile count and tile attribute counts for the current field.
-*/
-int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
-{
- sanityCheck(me);
- switch(me->filetype)
+ switch ( dprec )
{
- #ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
- #endif
+ case EXSE_SINGLE_PRECISION:
+ {
+ binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
+ break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
+ }
- #ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- #endif
- #ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
- #endif
- #ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
- #endif
- #ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
- #endif
- return cdiFallbackIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
+ binWriteF77Block(fileID, byteswap, blocklen);
- default:
- Error(kUnexpectedFileTypeMessage);
- return CDI_ELIBNAVAIL;
- }
+ return 0;
}
-
/*
- at Function cdiIterator_inqParam
- at Title Get discipline, category, and number
-
- at Prototype CdiParam cdiIterator_inqParam(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+#define INCLUDE_GUARD_CDI_REFERENCE_COUNTING
- at Result A struct containing the requested information.
- at Description
- Simple metadata inspection function.
-*/
-CdiParam cdiIterator_inqParam(CdiIterator* me)
-{
- sanityCheck(me);
- return me->param;
-}
+#include <sys/types.h>
+#include <stdlib.h>
/*
- at Function cdiIterator_inqParamParts
- at Title Get discipline, category, and number
-
- at Prototype void cdiIterator_inqParamParts(CdiIterator *me, int *outDiscipline, int *outCategory, int *outNumber)
- at Parameter
- @item iterator The iterator to operate on.
- @item outDiscipline This is used to return the discipline.
- @item outCategory This is used to return the category.
- @item outNumber This is used to return the number.
+This is a base class for all objects that need reference counting.
+A CdiReferencedObject has a reference count of one when it is constructed, refObjectRetain() increments the reference count, refObject Release() decrements it.
+When the reference count reaches zero, the destructor function is called before the memory of the object is deallocated with Free().
- at Description
- Simple metadata inspection function.
+>>> Warning <<<
+This code is currently not thread-safe.
- Some FORTRAN compilers produce wrong code for the cdiIterator_inqParam()-wrapper,
- rendering it unusable from FORTRAN. This function is the workaround.
+We are currently using the C99 standard, which does not have atomic types.
+Also, there are still tons of systems out there that have a gcc without wrong C11 atomics support
+(__STDC_NO_ATOMICS__ not defined even though stdatomics.h is not even present).
+Consequently, it is impossible to write preprocessor code to even check for the presence of atomic types.
+So, we have two options: provide multithreading support by means of locks, or wait a year or two before doing this right.
+I, for one, prefer doing things right.
*/
-void cdiIterator_inqParamParts(CdiIterator *me, int *outDiscipline, int *outCategory, int *outNumber)
-{
- CdiParam result = cdiIterator_inqParam(me);
- if(outDiscipline) *outDiscipline = result.discipline;
- if(outCategory) *outCategory = result.category;
- if(outNumber) *outNumber = result.number;
-}
+typedef struct CdiReferencedObject CdiReferencedObject;
+struct CdiReferencedObject {
+ //protected:
+ void (*destructor)(CdiReferencedObject* me); //Subclass constructors should set this to their own destructor.
-/*
- at Function cdiIterator_inqDatatype
- at Title Get the datatype of the current field
+ //private: //Subclasses may read it to determine whether there is only one reference, though.
+ size_t refCount;
+};
- at Prototype int cdiIterator_inqDatatype(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+void cdiRefObject_construct(CdiReferencedObject* me);
+void cdiRefObject_retain(CdiReferencedObject* me);
+void cdiRefObject_release(CdiReferencedObject* me);
+void cdiRefObject_destruct(CdiReferencedObject* me);
- at Result The datatype that is used to store this field on disk.
+#endif
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INCLUDE_GUARD_CDI_GRIB_FILE_H
+#define INCLUDE_GUARD_CDI_GRIB_FILE_H
- at Description
- Simple metadata inspection function.
-*/
-int cdiIterator_inqDatatype(CdiIterator* me)
-{
- sanityCheck(me);
- return me->datatype;
-}
/*
- at Function cdiIterator_inqTsteptype
- at Title Get the timestep type
+CdiInputFile is a file abstraction that allows accessing an input file through any number of channels:
+It is reference counted, so that it is closed at the right place,
+and it is stateless, so that accesses from different callers cannot interfere with each other.
+Once the reference counting code is threadsafe, CdiInputFile will also be threadsafe.
+*/
+typedef struct CdiInputFile {
+ //public:
+ CdiReferencedObject super;
- at Prototype int cdiIterator_inqTsteptype(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+ //private:
+ char* path;
+ int fileDescriptor;
+} CdiInputFile;
- at Result The timestep type.
+//Final class, the constructor is private and not defined here.
+CdiInputFile* cdiInputFile_make(const char* path); //The caller is responsible to call cdiRefObject_release() on the returned object.
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer); //Returns one of CDI_EINVAL, CDI_ESYSTEM, CDI_EEOF, OR CDI_NOERR.
+/* Returns path string, don't use after destruction of CdiInputFile
+ * object */
+const char* cdiInputFile_getPath(const CdiInputFile* me);
+//Destructor is private as well.
- at Description
- Simple metadata inspection function.
-*/
-int cdiIterator_inqTsteptype(CdiIterator* me)
-{
- sanityCheck(me);
- return me->timesteptype;
-}
+#endif
/*
- at Function cdiIterator_inqVariableName
- at Title Get the variable name of the current field
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#define _XOPEN_SOURCE 600
- at Prototype char* cdiIterator_inqVariableName(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
- at Result A pointer to a C-string containing the name. The storage for this string is allocated with Malloc(), and it is the responsibility of the caller to Free() it.
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
- at Description
- Allocates a buffer to hold the string, copies the current variable name into this buffer, and returns the buffer.
- The caller is responsible to make the corresponding Free() call.
-*/
-char* cdiIterator_inqVariableName(CdiIterator* me)
+static void cdiInputFile_destruct(CdiInputFile* me);
+
+//For an explanation of the condestruct() pattern, see the comment in iterator_grib.c
+//path != NULL -> construction
+//path = NULL -> destruction
+static CdiInputFile* cdiInputFile_condestruct(CdiInputFile* me, const char* path)
{
- sanityCheck(me);
- switch(me->filetype)
+ #define super() (&me->super)
+ if(!path) goto destruct;
+ cdiRefObject_construct(super());
+ me->path = strdup(path);
+ if(!me->path) goto destructSuper;
+ do
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- return cdiGribIterator_copyVariableName(me);
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- return cdiFallbackIterator_copyVariableName(me);
-
- default:
- Error(kUnexpectedFileTypeMessage);
- return NULL;
+ me->fileDescriptor = open(me->path, O_RDONLY);
}
-}
-
-/*
- at Function cdiIterator_inqGridId
- at Title Get the ID of the current grid
+ while(me->fileDescriptor == -1 && (errno == EINTR || errno == EAGAIN));
+ if(me->fileDescriptor == -1) goto freePath;
+ //construction successfull, now we can set our own destructor
+ super()->destructor = (void(*)(CdiReferencedObject*))cdiInputFile_destruct;
+ goto success;
- at Prototype int cdiIterator_inqGridId(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+// ^ constructor code ^
+// | |
+// v destructor/error-cleanup code v
- at Result A gridId that can be used for further introspection.
+destruct:
+ close(me->fileDescriptor);
+freePath:
+ Free(me->path);
+destructSuper:
+ cdiRefObject_destruct(super());
+ me = NULL;
- at Description
- This provides access to the grid related metadata.
- The resulting ID is only valid until the next time cdiIterator_nextField() is called.
-*/
-int cdiIterator_inqGridId(CdiIterator* me)
-{
- sanityCheck(me);
- return me->gridId;
+success:
+ return me;
+ #undef super
}
-/*
- at Function cdiIterator_readField
- at Title Read the whole field into a double buffer
-
- at Prototype void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
- at Parameter
- @item iterator The iterator to operate on.
- @item buffer A pointer to the double array that the data should be written to.
- @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+static CdiInputFile **openFileList = NULL;
+static size_t openFileCount = 0, openFileListSize = 0;
+static pthread_mutex_t openFileListLock = PTHREAD_MUTEX_INITIALIZER;
- at Description
- It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
- Failing to do so results in undefined behavior. You have been warned.
-*/
-void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+//This either returns a new object, or retains and returns a preexisting open file.
+CdiInputFile* cdiInputFile_make(const char* path)
{
- sanityCheck(me);
- if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
- switch(me->filetype)
+ CdiInputFile* result = NULL;
+ xassert(path);
+ int error = pthread_mutex_lock(&openFileListLock);
+ xassert(!error);
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- cdiGribIterator_readField(me, buffer, nmiss);
- return;
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- cdiFallbackIterator_readField(me, buffer, nmiss);
- return;
- default:
- Error(kUnexpectedFileTypeMessage);
+ //Check the list of open files for the given path.
+ for(size_t i = openFileCount; i-- && !result; )
+ {
+ if(!strcmp(path, openFileList[i]->path)) result = openFileList[i];
+ }
+ //If no open file was found, we open one, otherwise we just retain the existing one one more time.
+ if(result)
+ {
+ cdiRefObject_retain(&result->super);
+ }
+ else
+ {
+ result = (CdiInputFile *) Malloc(sizeof(*result));
+ if(!cdiInputFile_condestruct(result, path))
+ {
+ //An error occured during construction, avoid a memory leak.
+ Free(result);
+ result = NULL;
+ }
+ else
+ {
+ //Add the new file to the list of open files.
+ if(openFileCount == openFileListSize)
+ {
+ openFileListSize *= 2;
+ if(openFileListSize < 16) openFileListSize = 16;
+ openFileList = (CdiInputFile **) Realloc(openFileList, openFileListSize);
+ }
+ xassert(openFileCount < openFileListSize);
+ openFileList[openFileCount++] = result;
+ }
+ }
}
+ error = pthread_mutex_unlock(&openFileListLock);
+ xassert(!error);
+ return result;
}
-/*
- at Function cdiIterator_readFieldF
- at Title Read the whole field into a double buffer
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer)
+{
+ char* byteBuffer = (char *)buffer;
+ size_t trash;
+ if(!outActualReadSize) outActualReadSize = &trash;
+ *outActualReadSize = 0;
+ while(readSize)
+ {
+ ssize_t bytesRead = pread(me->fileDescriptor, byteBuffer, readSize, readPosition);
+ if(bytesRead == -1) return (errno == EINVAL) ? CDI_EINVAL : CDI_ESYSTEM;
+ if(bytesRead == 0) return CDI_EEOF;
+ byteBuffer += bytesRead;
+ readPosition += bytesRead;
+ readSize -= (size_t)bytesRead;
+ *outActualReadSize += (size_t)bytesRead;
+ }
+ return CDI_NOERR;
+}
- at Prototype void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
- at Parameter
- @item iterator The iterator to operate on.
- @item buffer A pointer to the double array that the data should be written to.
- @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+const char* cdiInputFile_getPath(const CdiInputFile* me)
+{
+ return me->path;
+}
- at Description
- It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
- Failing to do so results in undefined behavior. You have been warned.
-*/
-void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+void cdiInputFile_destruct(CdiInputFile* me)
{
- sanityCheck(me);
- if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
- switch(me->filetype)
+ int error = pthread_mutex_lock(&openFileListLock);
+ xassert(!error);
{
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- cdiGribIterator_readFieldF(me, buffer, nmiss);
- return;
-#endif
-
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
-#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- cdiFallbackIterator_readFieldF(me, buffer, nmiss);
- return;
- default:
- Error(kUnexpectedFileTypeMessage);
+ //Find the position of me in the list of open files.
+ ssize_t position = (ssize_t)openFileCount;
+ while (position > 0 && openFileList[--position] != me);
+ //Remove me from the list
+ openFileList[position] = openFileList[--openFileCount];
}
+ error = pthread_mutex_unlock(&openFileListLock);
+ xassert(!error);
+ cdiInputFile_condestruct(me, NULL);
}
/*
- at Function cdiIterator_delete
- at Title Destroy an iterator
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INSTITUTION_H
+#define INSTITUTION_H
- at Prototype void cdiIterator_delete(CdiIterator* iterator)
- at Parameter
- @item iterator The iterator to operate on.
+int
+instituteUnpack(void *buf, int size, int *position, int originNamespace,
+ void *context, int force_id);
- at Description
- Combined destructor & deallocator.
-*/
-void cdiIterator_delete(CdiIterator* me)
-{
- if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
- switch(me->filetype)
- {
-#ifdef HAVE_LIBGRIB_API
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- cdiGribIterator_delete((CdiGribIterator*)me);
- break;
-#endif
+void instituteDefaultEntries(void);
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
-#endif
-#ifdef HAVE_LIBSERVICE
- case FILETYPE_SRV:
#endif
-#ifdef HAVE_LIBEXTRA
- case FILETYPE_EXT:
-#endif
-#ifdef HAVE_LIBIEG
- case FILETYPE_IEG:
-#endif
- cdiFallbackIterator_delete(me);
- break;
-
- default:
- Error(kUnexpectedFileTypeMessage);
- }
-}
-
-void baseIterDestruct(CdiIterator* me)
-{
- /*currently empty, but that's no reason not to call it*/
- (void)me;
-}
/*
* Local Variables:
@@ -31522,394 +30411,341 @@ void baseIterDestruct(CdiIterator* me)
* require-trailing-newline: t
* End:
*/
-
+#if defined (HAVE_CONFIG_H)
+#endif
#include <assert.h>
#include <limits.h>
-#include <stdlib.h>
-
-struct CdiFallbackIterator {
- CdiIterator super;
- int streamId, vlistId, subtypeId;
- char *path; //needed for clone() & serialize()
- int variableCount, curVariable;
- int curLevelCount, curLevel;
- int curSubtypeCount, curSubtype;
- int curTimestep;
-};
-CdiIterator *cdiFallbackIterator_getSuper(CdiFallbackIterator *me)
-{
- return &me->super;
-}
+static int ECMWF = CDI_UNDEFID,
+ MPIMET = CDI_UNDEFID,
+ MCH = CDI_UNDEFID;
-//For more information on the condestruct() pattern, see comment in src/iterator_grib.c
-static CdiFallbackIterator *cdiFallbackIterator_condestruct(CdiFallbackIterator *me, const char *path, int filetype)
+typedef struct
{
- if(me) goto destruct;
-
- me = (CdiFallbackIterator *) Malloc(sizeof(*me));
- baseIterConstruct(&me->super, filetype);
-
- me->streamId = streamOpenRead(path);
- if(me->streamId == CDI_UNDEFID) goto destructSuper;
- me->vlistId = streamInqVlist(me->streamId);
- if(me->vlistId == CDI_UNDEFID) goto closeStream;
- me->variableCount = vlistNvars(me->vlistId);
- if(me->variableCount <= 0) goto closeStream;
- me->subtypeId = CDI_UNDEFID; //Will be set in cdiFallbackIterator_nextField()
- me->curSubtypeCount = -1; //Will be set in cdiFallbackIterator_nextField()
- me->curLevelCount = -1; //Will be set in cdiFallbackIterator_nextField()
-
- //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
- me->curTimestep = 0;
- if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
- me->curVariable = -1;
- me->curSubtype = -1;
- me->curLevel = -1;
- me->path = strdup(path);
- if(!me->path) goto closeStream;
+ int self;
+ int used;
+ int center;
+ int subcenter;
+ char *name;
+ char *longname;
+}
+institute_t;
- return me;
-// ^ constructor code ^
-// | |
-// v destructor/error-cleanup code v
+static int instituteCompareKernel(institute_t *ip1, institute_t *ip2);
+static void instituteDestroyP(institute_t *instituteptr);
+static void institutePrintP(institute_t *instituteptr, FILE * fp);
+static int instituteGetPackSize(institute_t *instituteptr, void *context);
+static void institutePackP ( void * instituteptr, void *buf, int size, int *position, void *context );
+static int instituteTxCode ( void );
-destruct:
- Free(me->path);
-closeStream:
- streamClose(me->streamId);
-destructSuper:
- baseIterDestruct(&me->super);
- Free(me);
- return NULL;
-}
+static const resOps instituteOps = {
+ (int (*)(void *, void *))instituteCompareKernel,
+ (void (*)(void *))instituteDestroyP,
+ (void (*)(void *, FILE *))institutePrintP,
+ (int (*)(void *, void *))instituteGetPackSize,
+ institutePackP,
+ instituteTxCode
+};
-CdiIterator *cdiFallbackIterator_new(const char *path, int filetype)
+static
+void instituteDefaultValue ( institute_t * instituteptr )
{
- return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
+ instituteptr->self = CDI_UNDEFID;
+ instituteptr->used = 0;
+ instituteptr->center = CDI_UNDEFID;
+ instituteptr->subcenter = CDI_UNDEFID;
+ instituteptr->name = NULL;
+ instituteptr->longname = NULL;
}
-//Fetches the info that is derived from the current variable. Most of this is published by the data members in the base class.
-static void fetchVariableInfo(CdiFallbackIterator *me)
+void instituteDefaultEntries ( void )
{
- //Fetch data that's published via base class data members.
- me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
- me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
- me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
- int param = vlistInqVarParam(me->vlistId, me->curVariable);
- cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
-
- //Fetch the current level and subtype counts.
- me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
- me->subtypeId = vlistInqVarSubtype(me->vlistId, me->curVariable);
- me->curSubtypeCount = (me->subtypeId == CDI_UNDEFID) ? 1 : subtypeInqSize(me->subtypeId);
-}
+ cdiResH resH[]
+ = { ECMWF = institutDef( 98, 0, "ECMWF", "European Centre for Medium-Range Weather Forecasts"),
+ MPIMET = institutDef( 98, 232, "MPIMET", "Max-Planck-Institute for Meteorology"),
+ institutDef( 98, 255, "MPIMET", "Max-Planck-Institute for Meteorology"),
+ institutDef( 98, 232, "MPIMET", "Max Planck Institute for Meteorology"),
+ institutDef( 78, 0, "DWD", "Deutscher Wetterdienst"),
+ institutDef( 78, 255, "DWD", "Deutscher Wetterdienst"),
+ MCH = institutDef(215, 255, "MCH", "MeteoSwiss"),
+ institutDef( 7, 0, "NCEP", "National Centers for Environmental Prediction"),
+ institutDef( 7, 1, "NCEP", "National Centers for Environmental Prediction"),
+ institutDef( 60, 0, "NCAR", "National Center for Atmospheric Research"),
+ institutDef( 74, 0, "METOFFICE", "U.K. Met Office"),
+ institutDef( 97, 0, "ESA", "European Space Agency"),
+ institutDef( 99, 0, "KNMI", "Royal Netherlands Meteorological Institute"),
+ };
+ /* (void) institutDef( 0, 0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
-CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super)
-{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ size_t n = sizeof(resH)/sizeof(*resH);
- //Make another stream for this file. This yields an unadvanced iterator.
- CdiFallbackIterator *clone = cdiFallbackIterator_condestruct(NULL, me->path, me->super.filetype);
- if(!clone) return NULL;
+ for (size_t i = 0; i < n ; i++ )
+ reshSetStatus(resH[i], &instituteOps, RESH_IN_USE);
+}
- //Point the clone to the same position in the file.
- clone->variableCount = me->variableCount;
- clone->curVariable = me->curVariable;
- clone->curLevelCount = me->curLevelCount;
- clone->curLevel = me->curLevel;
- clone->curSubtypeCount = me->curSubtypeCount;
- clone->curSubtype = me->curSubtype;
- clone->curTimestep = me->curTimestep;
- clone->super.isAdvanced = super->isAdvanced;
- if(super->isAdvanced) fetchVariableInfo(clone);
+static int
+instituteCompareKernel(institute_t * ip1, institute_t * ip2)
+{
+ int differ = 0;
+ size_t len1, len2;
- return clone;
-}
+ if ( ip1->name )
+ {
+ if ( ip1->center > 0 && ip2->center != ip1->center ) differ = 1;
+ if ( ip1->subcenter > 0 && ip2->subcenter != ip1->subcenter ) differ = 1;
-char *cdiFallbackIterator_serialize(CdiIterator *super)
-{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ if ( !differ )
+ {
+ if ( ip2->name )
+ {
+ len1 = strlen(ip1->name);
+ len2 = strlen(ip2->name);
+ if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
+ }
+ }
+ }
+ else if ( ip1->longname )
+ {
+ if ( ip2->longname )
+ {
+ len1 = strlen(ip1->longname);
+ len2 = strlen(ip2->longname);
+ if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
+ }
+ }
+ else
+ {
+ if ( !( ip2->center == ip1->center &&
+ ip2->subcenter == ip1->subcenter )) differ = 1;
+ }
- char *escapedPath = cdiEscapeSpaces(me->path);
- char *result = (char *) Malloc(strlen(escapedPath)
- + 7 * (3 * sizeof (int) * CHAR_BIT / 8 + 1) + 1);
- sprintf(result, "%s %d %d %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curSubtypeCount, me->curSubtype, me->curTimestep);
- Free(escapedPath);
- return result;
+ return differ;
}
-CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *description)
-{
- CdiFallbackIterator *me = (CdiFallbackIterator *) Malloc(sizeof(*me));
- if(!me) goto fail;
- description = baseIter_constructFromString(&me->super, description);
+struct instLoc
+{
+ institute_t *ip;
+ int id;
+};
- while(*description == ' ') description++;
- me->path = cdiUnescapeSpaces(description, &description);
- if(!me->path) goto destructSuper;
+static enum cdiApplyRet
+findInstitute(int id, void *res, void *data)
+{
+ institute_t * ip1 = ((struct instLoc *)data)->ip;
+ institute_t * ip2 = (institute_t*) res;
+ if (ip2->used && !instituteCompareKernel(ip1, ip2))
+ {
+ ((struct instLoc *)data)->id = id;
+ return CDI_APPLY_STOP;
+ }
+ else
+ return CDI_APPLY_GO_ON;
+}
- me->streamId = streamOpenRead(me->path);
- if(me->streamId == CDI_UNDEFID) goto freePath;
- me->vlistId = streamInqVlist(me->streamId);
- if(me->vlistId == CDI_UNDEFID) goto closeStream;
- //This reads one variable from the description string, does error checking, and advances the given string pointer.
-#define decodeValue(variable, description) do \
- { \
- const char *savedStart = description; \
- long long decodedValue = strtoll(description, (char**)&description, 0); /*The cast is a workaround for the wrong signature of strtoll().*/ \
- variable = (int)decodedValue; \
- if(savedStart == description) goto closeStream; \
- if((long long)decodedValue != (long long)variable) goto closeStream; \
- } while(0)
- decodeValue(me->variableCount, description);
- decodeValue(me->curVariable, description);
- decodeValue(me->curLevelCount, description);
- decodeValue(me->curLevel, description);
- decodeValue(me->curSubtypeCount, description);
- decodeValue(me->curSubtype, description);
- decodeValue(me->curTimestep, description);
-#undef decodeValue
+int institutInq(int center, int subcenter, const char *name, const char *longname)
+{
+ institute_t * ip_ref = (institute_t *) Malloc(sizeof (*ip_ref));
+ ip_ref->self = CDI_UNDEFID;
+ ip_ref->used = 0;
+ ip_ref->center = center;
+ ip_ref->subcenter = subcenter;
+ ip_ref->name = name && name[0] ? (char *)name : NULL;
+ ip_ref->longname = longname && longname[0] ? (char *)longname : NULL;
- if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
- if(me->super.isAdvanced) fetchVariableInfo(me);
+ struct instLoc state = { .ip = ip_ref, .id = CDI_UNDEFID };
+ cdiResHFilterApply(&instituteOps, findInstitute, &state);
- return me;
+ Free(ip_ref);
-closeStream:
- streamClose(me->streamId);
-freePath:
- Free(me->path);
-destructSuper:
- baseIterDestruct(&me->super);
- Free(me);
-fail:
- return NULL;
+ return state.id;
}
-static int advance(CdiFallbackIterator *me)
+static
+institute_t *instituteNewEntry(cdiResH resH, int center, int subcenter,
+ const char *name, const char *longname)
{
- me->curLevel++;
- if(me->curLevel >= me->curLevelCount)
+ institute_t *instituteptr = (institute_t*) Malloc(sizeof(institute_t));
+ instituteDefaultValue(instituteptr);
+ if (resH == CDI_UNDEFID)
+ instituteptr->self = reshPut(instituteptr, &instituteOps);
+ else
{
- me->curLevel = 0;
- me->curSubtype++;
- if(me->curSubtype >= me->curSubtypeCount)
- {
- me->curSubtype = 0;
- me->curVariable++;
- if(me->curVariable >= me->variableCount)
- {
- me->curVariable = 0;
- me->curTimestep++;
- if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
- }
- }
+ instituteptr->self = resH;
+ reshReplace(resH, instituteptr, &instituteOps);
}
- return CDI_NOERR;
+ instituteptr->used = 1;
+ instituteptr->center = center;
+ instituteptr->subcenter = subcenter;
+ if ( name && *name )
+ instituteptr->name = strdupx(name);
+ if (longname && *longname)
+ instituteptr->longname = strdupx(longname);
+ return instituteptr;
}
-int cdiFallbackIterator_nextField(CdiIterator *super)
-{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int result = advance(me);
- if(result) return result;
- if(!me->curLevel && !me->curSubtype) fetchVariableInfo(me); //Check whether we are processing a new variable/timestep and fetch the information that may have changed in this case.
- return CDI_NOERR;
+int institutDef(int center, int subcenter, const char *name, const char *longname)
+{
+ institute_t * instituteptr
+ = instituteNewEntry(CDI_UNDEFID, center, subcenter, name, longname);
+ return instituteptr->self;
}
-char *cdiFallbackIterator_inqTime(CdiIterator *super, CdiTimeType timeType)
+
+int institutInqCenter(int instID)
{
- CdiFallbackIterator *me = (CdiFallbackIterator *)(void *)super;
+ institute_t * instituteptr = NULL;
- //retrieve the time information
- int taxisId = vlistInqTaxis(me->vlistId);
- int date = 0, time = 0;
- switch(timeType)
- {
- case kCdiTimeType_referenceTime:
- date = taxisInqRdate(taxisId);
- time = taxisInqRtime(taxisId);
- break;
+ if ( instID != CDI_UNDEFID )
+ instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
- case kCdiTimeType_startTime:
- date = taxisInqVdate(taxisId);
- time = taxisInqVtime(taxisId);
- break;
+ return instituteptr ? instituteptr->center : CDI_UNDEFID;
+}
- case kCdiTimeType_endTime:
- return NULL; //The stream interface does not export the start/end times of statistical fields, so we treat all data as point of time data, returning the validity time as the start time.
- default:
- assert(0 && "internal error, please report this bug");
- }
+int institutInqSubcenter(int instID)
+{
+ institute_t * instituteptr = NULL;
- //decode the time information and reencode it into an ISO-compliant string
- int year, month, day, hour, minute, second;
- cdiDecodeDate(date, &year, &month, &day);
- cdiDecodeTime(time, &hour, &minute, &second);
- char *result
- = (char *) Malloc( 4+1 +2+1 +2+1 +2+1 +2+1 +2+4+1);
- sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.000", year, month, day, hour, minute, second);
- return result;
+ if ( instID != CDI_UNDEFID )
+ instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+
+ return instituteptr ? instituteptr->subcenter: CDI_UNDEFID;
}
-int cdiFallbackIterator_levelType(CdiIterator *super, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
+
+const char *institutInqNamePtr(int instID)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
- (void)levelSelector;
-#define copyString(outPointer, function) do \
- { \
- if(outPointer) \
- { \
- char tempBuffer[CDI_MAX_NAME]; \
- function(zaxisId, tempBuffer); \
- *outPointer = strdup(tempBuffer); \
- } \
- } \
- while(0)
- copyString(outName, zaxisInqName); //FIXME: zaxisInqName is unsafe.
- copyString(outLongName, zaxisInqLongname); //FIXME: zaxisInqLongname is unsafe.
- copyString(outStdName, zaxisInqStdname); //FIXME: zaxisInqStdname is unsafe.
- copyString(outUnit, zaxisInqUnits); //FIXME: zaxisInqUnits is unsafe.
-#undef copyString
- return zaxisInqLtype(zaxisId);
+ institute_t * instituteptr = NULL;
+
+ if ( instID != CDI_UNDEFID )
+ instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+
+ return instituteptr ? instituteptr->name : NULL;
}
-int cdiFallbackIterator_level(CdiIterator *super, int levelSelector, double *outValue1, double *outValue2)
-{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
- //handle NULL pointers once and for all
- double trash;
- if(!outValue1) outValue1 = &trash;
- if(!outValue2) outValue2 = &trash;
+const char *institutInqLongnamePtr(int instID)
+{
+ institute_t * instituteptr = NULL;
- //get the level value
- if(levelSelector)
- {
- *outValue1 = (zaxisInqLbounds(zaxisId, NULL))
- ? zaxisInqLbound(zaxisId, me->curLevel)
- : zaxisInqLevel(zaxisId, me->curLevel);
- }
- else
- {
- *outValue1 = (zaxisInqUbounds(zaxisId, NULL))
- ? zaxisInqUbound(zaxisId, me->curLevel)
- : zaxisInqLevel(zaxisId, me->curLevel);
- }
- *outValue2 = 0.0;
+ if ( instID != CDI_UNDEFID )
+ instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
- //if this is a hybrid zaxis, lookup the coordinates in the vertical coordinate table
- ssize_t intLevel = (ssize_t)(2**outValue1);
- if(0 <= intLevel && intLevel < zaxisInqVctSize(zaxisId) - 1)
- {
- const double *coordinateTable = zaxisInqVctPtr(zaxisId);
- *outValue1 = coordinateTable[intLevel];
- *outValue2 = coordinateTable[intLevel + 1];
- }
- return CDI_NOERR;
+ return instituteptr ? instituteptr->longname : NULL;
}
-int cdiFallbackIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
+static enum cdiApplyRet
+activeInstitutes(int id, void *res, void *data)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
- if(zaxisInqLtype(zaxisId) != ZAXIS_HYBRID) return CDI_EINVAL;
- if(outVgridNumber) *outVgridNumber = zaxisInqNumber(zaxisId);
- if(outLevelCount) *outLevelCount = zaxisInqNlevRef(zaxisId);
- if(outUuid) zaxisInqUUID(zaxisId, outUuid);
- return CDI_NOERR;
+ (void)id;
+ if (res && ((institute_t *)res)->used)
+ ++(*(int *)data);
+ return CDI_APPLY_GO_ON;
}
-int cdiFallbackIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
+int institutInqNumber(void)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
-#ifndef __cplusplus
- if(!outTileIndex) outTileIndex = &(int){0};
- if(!outTileAttribute) outTileAttribute = &(int){0};
-#else
- int dummy = 0;
- if(!outTileIndex) outTileIndex = &dummy;
- if(!outTileAttribute) outTileAttribute = &dummy;
-#endif
+ int instNum = 0;
- int error = CDI_NOERR;
- if(me->subtypeId == CDI_UNDEFID) //must not call subtypeInqAttribute() with an invalid subtype ID, because it would abort the program instead of returning an error
- {
- error = CDI_EINVAL;
- }
- else
- {
- if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileIndex", outTileIndex)) error = CDI_EINVAL;
- if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileAttribute", outTileAttribute)) error = CDI_EINVAL;
- }
- if(error) *outTileIndex = *outTileAttribute = -1; //Guarantee defined values in case of an error.
- return error;
+ cdiResHFilterApply(&instituteOps, activeInstitutes, &instNum);
+ return instNum;
}
-int cdiFallbackIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
+
+static void
+instituteDestroyP(institute_t *instituteptr)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
-#ifndef __cplusplus
- if(!outTileCount) outTileCount = &(int){0};
- if(!outTileAttributeCount) outTileAttributeCount = &(int){0};
-#else
- int temp = 0;
- if(!outTileCount) outTileCount = &temp;
- if(!outTileAttributeCount) outTileAttributeCount = &temp;
-#endif
+ xassert(instituteptr);
- int error = CDI_NOERR;
- if(me->subtypeId == CDI_UNDEFID) //must not call subtypeInqAttribute() with an invalid subtype ID, because it would abort the program instead of returning an error
- {
- error = CDI_EINVAL;
- }
- else
- {
- if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTiles", outTileCount)) error = CDI_EINVAL;
- if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTileAttributes", outTileAttributeCount)) error = CDI_EINVAL;
- }
- if(error) *outTileCount = *outTileAttributeCount = -1; //Guarantee defined values in case of an error.
- return CDI_NOERR;
+ int instituteID = instituteptr->self;
+ Free(instituteptr->name);
+ Free(instituteptr->longname);
+ reshRemove(instituteID, &instituteOps);
+ Free(instituteptr);
}
-char *cdiFallbackIterator_copyVariableName(CdiIterator *super)
+
+static void institutePrintP(institute_t *ip, FILE * fp )
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- return vlistCopyVarName(me->vlistId, me->curVariable);
+ if (ip)
+ fprintf(fp, "#\n"
+ "# instituteID %d\n"
+ "#\n"
+ "self = %d\n"
+ "used = %d\n"
+ "center = %d\n"
+ "subcenter = %d\n"
+ "name = %s\n"
+ "longname = %s\n",
+ ip->self, ip->self, ip->used, ip->center, ip->subcenter,
+ ip->name ? ip->name : "NN",
+ ip->longname ? ip->longname : "NN");
}
-void cdiFallbackIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
+
+static int
+instituteTxCode ( void )
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int missingValues = 0;
- streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
- if(nmiss) *nmiss = (size_t)missingValues;
+ return INSTITUTE;
}
-void cdiFallbackIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
+enum {
+ institute_nints = 5,
+};
+
+static int instituteGetPackSize(institute_t *ip, void *context)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int missingValues = 0;
- streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
- if(nmiss) *nmiss = (size_t)missingValues;
+ size_t namelen = strlen(ip->name), longnamelen = strlen(ip->longname);
+ xassert(namelen < INT_MAX && longnamelen < INT_MAX);
+ size_t txsize = (size_t)serializeGetSize(institute_nints, CDI_DATATYPE_INT, context)
+ + (size_t)serializeGetSize((int)namelen + 1, CDI_DATATYPE_TXT, context)
+ + (size_t)serializeGetSize((int)longnamelen + 1, CDI_DATATYPE_TXT, context);
+ xassert(txsize <= INT_MAX);
+ return (int)txsize;
}
-void cdiFallbackIterator_delete(CdiIterator *super)
+static void institutePackP(void * instituteptr, void *buf, int size, int *position, void *context)
{
- CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- cdiFallbackIterator_condestruct(me, NULL, 0);
+ institute_t *p = (institute_t*) instituteptr;
+ int tempbuf[institute_nints];
+ tempbuf[0] = p->self;
+ tempbuf[1] = p->center;
+ tempbuf[2] = p->subcenter;
+ tempbuf[3] = (int)strlen(p->name) + 1;
+ tempbuf[4] = (int)strlen(p->longname) + 1;
+ serializePack(tempbuf, institute_nints, CDI_DATATYPE_INT, buf, size, position, context);
+ serializePack(p->name, tempbuf[3], CDI_DATATYPE_TXT, buf, size, position, context);
+ serializePack(p->longname, tempbuf[4], CDI_DATATYPE_TXT, buf, size, position, context);
+}
+
+int instituteUnpack(void *buf, int size, int *position, int originNamespace,
+ void *context, int force_id)
+{
+ int tempbuf[institute_nints];
+ int instituteID;
+ char *name, *longname;
+ serializeUnpack(buf, size, position, tempbuf, institute_nints, CDI_DATATYPE_INT, context);
+ name = (char *) Malloc((size_t)tempbuf[3] + (size_t)tempbuf[4]);
+ longname = name + tempbuf[3];
+ serializeUnpack(buf, size, position, name, tempbuf[3], CDI_DATATYPE_TXT, context);
+ serializeUnpack(buf, size, position, longname, tempbuf[4], CDI_DATATYPE_TXT, context);
+ int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
+ institute_t *ip = instituteNewEntry(force_id?targetID:CDI_UNDEFID,
+ tempbuf[1], tempbuf[2], name, longname);
+ instituteID = ip->self;
+ xassert(!force_id || instituteID == targetID);
+ Free(name);
+ reshSetStatus(instituteID, &instituteOps,
+ reshGetStatus(instituteID, &instituteOps) & ~RESH_SYNC_BIT);
+ return instituteID;
}
/*
@@ -31921,33 +30757,54 @@ void cdiFallbackIterator_delete(CdiIterator *super)
* require-trailing-newline: t
* End:
*/
-#ifndef _STREAM_GRB_H
-#define _STREAM_GRB_H
+/*
+ * This file is for the use of iterator.c and the CdiIterator subclasses only.
+ */
-int grbBitsPerValue(int datatype);
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_INT_H
+#define INCLUDE_GUARD_CDI_ITERATOR_INT_H
-int grbInqContents(stream_t *streamptr);
-int grbInqTimestep(stream_t *streamptr, int tsID);
-int grbInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void grbDefRecord(stream_t *streamptr);
-void grb_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss);
-void grb_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
-void grbCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+#include <stdbool.h>
+
+/*
+class CdiIterator
-void grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss);
-void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
+An iterator is an object that identifies the position of one record in a file, where a record is defined as the data belonging to one level, timestep, and variable.
+Using iterators to read a file can be significantly faster than using streams, because they can avoid building an index of the file.
+For file formats like grib that do not provide an index within the file, this makes the difference between reading the file once or reading the file twice.
-void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss);
-void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+CdiIterator is an abstract base class. Which derived class is used depends on the type of the file. The class hierarchy currently looks like this:
-int grib1ltypeToZaxisType(int grib_ltype);
-int grib2ltypeToZaxisType(int grib_ltype);
+ CdiIterator <|--+-- CdiFallbackIterator
+ |
+ +-- CdiGribIterator
-int zaxisTypeToGrib1ltype(int zaxistype);
-int zaxisTypeToGrib2ltype(int zaxistype);
+The fallback implementation currently uses the stream interface of CDI under the hood to provide full functionality for all filetypes for which no iterator implementation exists yet.
+*/
+//TODO[NH]: Debug messages, print function.
+
+struct CdiIterator {
+ int filetype; //This is used to dispatch calls to the correct subclass.
+ bool isAdvanced; //Used to catch inquiries before the first call to CdiIteratorNextField(). //XXX: Advanced is probably not a good word (initialized?)
+
+ //The metadata that can be accessed by the inquiry calls.
+ //While theoretically redundant, these fields allow the handling of most inquiry calls within the base class.
+ //Only the name is excempted because it needs an allocation.
+ //These fields are set by the subclasses in the xxxIterNextField() method.
+ int datatype, timesteptype;
+ int gridId;
+ CdiParam param;
+
+ //The status information for reading/advancing is added in the subclasses.
+};
+
+void baseIterConstruct(CdiIterator *me, int filetype);
+const char* baseIter_constructFromString(CdiIterator *me, const char *description); //Returns a pointer past the end of the parsed portion of the description string.
+void baseIterDestruct(CdiIterator *me);
+
+#endif
-#endif /* _STREAM_GRB_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -31957,25 +30814,93 @@ int zaxisTypeToGrib2ltype(int zaxistype);
* require-trailing-newline: t
* End:
*/
-#ifndef _ZAXIS_H
-#define _ZAXIS_H
+/*
+ * A fallback implementation of the iterator interface that opens a stream under the hood.
+ *
+ * This implementation is mainly available to provide iterator access to file formats that don't support iterator access natively,
+ * nevertheless, it allows the file to dictate the order in which data is read, possibly providing performance benefits.
+ */
-void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit); //The returned const char* point to static storage. Don't free or modify them.
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+#define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
-unsigned cdiZaxisCount(void);
+#if defined (HAVE_CONFIG_H)
+#endif
-void cdiZaxisGetIndexList(unsigned numIDs, int *IDs);
+#include <stdlib.h>
-void
-zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
- int * unpackBufferPos, int originNamespace, void *context,
- int force_id);
-void zaxisDefLtype2(int zaxisID, int ltype2);
+typedef struct CdiFallbackIterator CdiFallbackIterator;
-const resOps *getZaxisOps(void);
+CdiIterator *cdiFallbackIterator_new(const char *path, int filetype);
+CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *me);
+CdiIterator *cdiFallbackIterator_getSuper(CdiFallbackIterator *me);
+char *cdiFallbackIterator_serialize(CdiIterator *me);
+CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *me);
-const char *zaxisInqNamePtr(int zaxisID);
+int cdiFallbackIterator_nextField(CdiIterator *me);
+
+char *cdiFallbackIterator_inqTime(CdiIterator *me, CdiTimeType timeType);
+int cdiFallbackIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit);
+int cdiFallbackIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
+int cdiFallbackIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
+char *cdiFallbackIterator_copyVariableName(CdiIterator *me);
+int cdiFallbackIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute);
+int cdiFallbackIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount);
+
+void cdiFallbackIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
+void cdiFallbackIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss);
+
+void cdiFallbackIterator_delete(CdiIterator *super);
+
+#endif
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+/*
+ * An implementation of the iterator interface for GRIB files.
+ * Since GRIB files do not contain an index, this avoids scanning the entire file to generate an in-memory index as streamOpenRead() does.
+ * Consequently, using this interface is much more efficient for GRIB files.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+#define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+
+#if defined (HAVE_CONFIG_H)
+#endif
+
+
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#endif
+
+typedef struct recordList recordList;
+
+CdiIterator *cdiGribIterator_new(const char *path, int filetype);
+CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *me);
+CdiIterator *cdiGribIterator_getSuper(CdiGribIterator *me);
+char *cdiGribIterator_serialize(CdiIterator *me);
+CdiGribIterator *cdiGribIterator_deserialize(const char *me);
+
+int cdiGribIterator_nextField(CdiIterator *me);
+
+char *cdiGribIterator_inqTime(CdiIterator *me, CdiTimeType timeType);
+int cdiGribIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit);
+int cdiGribIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
+int cdiGribIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
+int cdiGribIterator_inqTile(CdiIterator *me, int *outTileIndex, int *outTileAttribute);
+int cdiGribIterator_inqTileCount(CdiIterator *me, int *outTileCount, int *outTileAttributeCount);
+char *cdiGribIterator_copyVariableName(CdiIterator *me);
+
+void cdiGribIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
+void cdiGribIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss);
#endif
@@ -31989,988 +30914,1144 @@ const char *zaxisInqNamePtr(int zaxisID);
* End:
*/
-
#include <assert.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#ifdef HAVE_LIBGRIB_API
+#include <ctype.h>
-struct CdiGribIterator {
- CdiIterator super;
+static const char kUnexpectedFileTypeMessage[]
+ = "Internal error: Unexpected file type encountered in iterator.\n"
+ "This is either due to an illegal memory access by the application\n"
+ " or an internal logical error in CDI (unlikely, but possible).";
+static const char kAdvancedString[] = "advanced";
+static const char kUnadvancedString[] = "unadvanced";
- CdiInputFile *file;
- off_t fileOffset;
- unsigned char *gribBuffer;
- size_t bufferSize, curRecordSize;
+//Returns a static string.
+static const char* fileType2String(int fileType)
+{
+ switch(fileType)
+ {
#ifdef HAVE_LIBGRIB_API
- grib_handle *gribHandle;
-#else
- void *gribHandle;
+ case CDI_FILETYPE_GRB: return "CDI::Iterator::GRIB1";
+ case CDI_FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
+#endif
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC: return "CDI::Iterator::NetCDF";
+ case CDI_FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
+ case CDI_FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
+ case CDI_FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+ case CDI_FILETYPE_NC5: return "CDI::Iterator::NetCDF5";
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV: return "CDI::Iterator::SRV";
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT: return "CDI::Iterator::EXT";
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG: return "CDI::Iterator::IEG";
#endif
-};
-CdiIterator *cdiGribIterator_getSuper(CdiGribIterator *me)
-{
- return &me->super;
+ default: return NULL;
+ }
}
-//Since the error handling in constructors is usually very closely related to the workings of a destructor,
-//this function combines both functions in one, using a centralized exit.
-//The mode of operation depends on whether me is a NULL pointer on entry:
-//If it is NULL, a new object is allocated and constructed, which is returned if construction is successful.
-//If a non-NULL pointer is passed in, the object is destructed and NULL is returned. In this case, the other arguments are ignored.
-static CdiGribIterator *cdiGribIterator_condestruct(CdiGribIterator *me, const char *path, int filetype)
+static int string2FileType(const char* fileType, const char **outRestString)
{
-#define super() (&me->super)
- if(me) goto destruct;
- me = (CdiGribIterator *) Malloc(sizeof(*me));
- baseIterConstruct(super(), filetype);
+ //This first part unconditionally checks all known type strings, and only if the given string matches one of these strings, we use fileType2string() to check whether support for this type has been compiled in. This is to avoid throwing "invalid type string" errors when we just have a library version mismatch.
+#define check(givenString, typeString, typeConstant) do \
+ { \
+ if(givenString == strstr(givenString, typeString)) \
+ { \
+ if(outRestString) *outRestString = givenString + strlen(typeString); \
+ if(fileType2String(typeConstant)) return typeConstant; \
+ Error("Support for " typeString " not compiled in. Please check that the result of `cdiIterator_serialize()` is only passed to a `cdiIterator_deserialize()` implementation of the same CDI library version."); \
+ return CDI_FILETYPE_UNDEF; \
+ } \
+ } while(0)
+ check(fileType, "CDI::Iterator::GRIB1", CDI_FILETYPE_GRB);
+ check(fileType, "CDI::Iterator::GRIB2", CDI_FILETYPE_GRB2);
+ check(fileType, "CDI::Iterator::NetCDF", CDI_FILETYPE_NC);
+ check(fileType, "CDI::Iterator::NetCDF2", CDI_FILETYPE_NC2);
+ check(fileType, "CDI::Iterator::NetCDF4", CDI_FILETYPE_NC4);
+ check(fileType, "CDI::Iterator::NetCDF4C", CDI_FILETYPE_NC4C);
+ check(fileType, "CDI::Iterator::NetCDF5", CDI_FILETYPE_NC5);
+ check(fileType, "CDI::Iterator::SRV", CDI_FILETYPE_SRV);
+ check(fileType, "CDI::Iterator::EXT", CDI_FILETYPE_EXT);
+ check(fileType, "CDI::Iterator::IEG", CDI_FILETYPE_IEG);
+#undef check
- me->file = cdiInputFile_make(path);
- if(!me->file) goto destructSuper;
- me->fileOffset = 0;
- me->gribHandle = NULL;
- me->gribBuffer = NULL;
- me->bufferSize = me->curRecordSize = 0;
- me->super.gridId = CDI_UNDEFID;
+ //If this point is reached, the given string does not seem to be produced by a cdiIterator_serialize() call.
+ Error("The string \"%s\" does not start with a valid iterator type. Please check the source of this string.", fileType);
+ *outRestString = fileType;
+ return CDI_FILETYPE_UNDEF;
+}
- goto success;
+/*
+ at Function cdiIterator_new
+ at Title Create an iterator for an input file
-// ^ constructor code ^
-// | |
-// v destructor/error-cleanup code v
+ at Prototype CdiIterator* cdiIterator_new(const char* path)
+ at Parameter
+ @item path Path to the file that is to be read.
-destruct:
- if(me->super.gridId != CDI_UNDEFID) gridDestroy(me->super.gridId);
- if(me->gribHandle) grib_handle_delete((struct grib_handle *)me->gribHandle);
- Free(me->gribBuffer);
- cdiRefObject_release(&me->file->super);
-destructSuper:
- baseIterDestruct(super());
- Free(me);
- me = NULL;
+ at Result An iterator for the given file.
-success:
- return me;
-#undef super
-}
+ at Description
+ Combined allocator and constructor for CdiIterator.
-CdiIterator *cdiGribIterator_new(const char *path, int filetype)
+ The returned iterator does not point to the first field yet,
+ it must first be advanced once before the first field can be introspected.
+ This design decision has two benefits: 1. Empty files require no special
+ cases, 2. Users can start a while(!cdiIterator_nextField(iterator)) loop
+ right after the call to cdiIterator_new().
+*/
+CdiIterator* cdiIterator_new(const char* path)
{
- return &cdiGribIterator_condestruct(NULL, path, filetype)->super;
-}
+ int trash;
+ int filetype = cdiGetFiletype(path, &trash);
+ switch(filetype)
+ {
+ case CDI_FILETYPE_UNDEF:
+ Warning("Can't open file \"%s\": unknown format\n", path);
+ return NULL;
-CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *super)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_new(path, filetype);
+#endif
- //Allocate memory and copy data. (operations that may fail)
- CdiGribIterator *result = (struct CdiGribIterator *) Malloc(sizeof(*result));
- if(!result) goto fail;
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_new(path, filetype);
- result->file = me->file;
- result->fileOffset = me->fileOffset;
- result->gribBuffer = NULL;
- result->bufferSize = me->bufferSize;
- result->curRecordSize = me->curRecordSize;
- result->gribHandle = NULL;
+ default:
+ Warning("the file \"%s\" is of type %s, but support for this format is not compiled in!", path, strfiletype(filetype));
+ return NULL;
+ }
+}
- if(me->gribBuffer)
+void baseIterConstruct(CdiIterator* me, int filetype)
+{
+ me->filetype = filetype;
+ me->isAdvanced = false;
+}
+
+const char* baseIter_constructFromString(CdiIterator* me, const char* description)
+{
+ const char* result = description;
+ me->filetype = string2FileType(result, &result);
+ assert(me->filetype != CDI_FILETYPE_UNDEF && "Please report this error."); //This condition should have been checked for in a calling function.
+ for(; *result && isspace(*result); result++);
+ if(result == strstr(result, kAdvancedString))
{
- result->gribBuffer = (unsigned char *) Malloc(me->bufferSize);
- if(!result->gribBuffer) goto freeResult;
- memcpy(result->gribBuffer, me->gribBuffer, me->curRecordSize);
+ me->isAdvanced = true;
+ result += sizeof (kAdvancedString) - 1;
}
- if(me->gribHandle)
+ else if(result == strstr(result, kUnadvancedString))
{
- result->gribHandle = grib_handle_new_from_message(NULL, result->gribBuffer, result->curRecordSize);
- if(!result->gribHandle) goto freeBuffer;
+ me->isAdvanced = false;
+ result += sizeof (kUnadvancedString) - 1;
}
- if(super->gridId != CDI_UNDEFID)
+ else
{
- result->super.gridId = gridDuplicate(super->gridId);
- if(result->super.gridId == CDI_UNDEFID) goto deleteGribHandle;
+ Error("Invalid iterator description string \"%s\". Please check the origin of this string.", description);
+ return NULL;
}
-
- //Finish construction. (operations that cannot fail)
- baseIterConstruct(&result->super, super->filetype);
- result->super.datatype = super->datatype;
- result->super.timesteptype = super->timesteptype;
- result->super.param = super->param;
- cdiRefObject_retain(&result->file->super);
-
return result;
-
- //Error handling.
-deleteGribHandle:
- if(result->gribHandle) grib_handle_delete(result->gribHandle);
-freeBuffer:
- Free(result->gribBuffer);
-freeResult:
- Free(result);
-fail:
- return NULL;
}
-char *cdiGribIterator_serialize(CdiIterator *super)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
+#define sanityCheck(me) do { \
+ if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+ if(!me->isAdvanced) xabort("Calling %s is not allowed without calling cdiIterator_nextField() first.", __func__); \
+} while(0)
- const char *path = cdiInputFile_getPath(me->file);
- char *escapedPath = cdiEscapeSpaces(path);
- char *result = (char *) Malloc(strlen(escapedPath) + 3 * sizeof(int) * CHAR_BIT/8);
- sprintf(result, "%s %zu", escapedPath, me->fileOffset);
- Free(escapedPath);
- return result;
-}
+/*
+ at Function cdiIterator_clone
+ at Title Make a copy of an iterator
+ at Prototype CdiIterator* cdiIterator_clone(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to copy.
-CdiGribIterator *cdiGribIterator_deserialize(const char *description)
-{
- char *path;
- CdiGribIterator *me = (CdiGribIterator *) Malloc(sizeof(*me));
- if(!me) goto fail;
+ at Result The clone.
- description = baseIter_constructFromString(&me->super, description);
+ at Description
+ Clones the given iterator. Make sure to call cdiIterator_delete() on both
+ the copy and the original.
- while(*description == ' ') description++;
- path = cdiUnescapeSpaces(description, &description);
- if(!path) goto destructSuper;
+ This is not a cheap operation: Depending on the type of the file, it will
+ either make a copy of the current field in memory (GRIB files), or reopen
+ the file (all other file types). Use it sparingly. And if you do, try to
+ avoid keeping too many clones around: their memory footprint is
+ significant.
+*/
+CdiIterator* cdiIterator_clone(CdiIterator* me)
+{
+ sanityCheck(me);
+ switch(me->filetype)
+ {
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_getSuper(cdiGribIterator_clone(me));
+#endif
- me->file = cdiInputFile_make(path);
- Free(path);
- if(!me->file) goto destructSuper;
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_getSuper(cdiFallbackIterator_clone(me));
- {
- const char *savedStart = description;
- long long decodedOffset = strtoll(description, (char**)&description, 0); //The cast is a workaround for the wrong signature of strtoll() (it should have been `long long strtoll(const char*, const char**, int)`, not `long long strtoll(const char*, char**, int)`.
- me->fileOffset = (off_t)decodedOffset;
- if(savedStart == description) goto closeFile;
- if((unsigned long long)decodedOffset > (unsigned long long)me->fileOffset) goto closeFile;
- }
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return NULL;
+ }
+}
- me->gribBuffer = NULL;
- me->bufferSize = me->curRecordSize = 0;
- me->gribHandle = NULL;
- me->super.gridId = CDI_UNDEFID;
- if(me->super.isAdvanced && cdiGribIterator_nextField(&me->super)) goto closeFile;
+/*
+ at Function cdiGribIterator_clone
+ at Title Gain access to GRIB specific functionality
- return me;
+ at Prototype CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to operate on.
+ at Result A clone that allows access to GRIB specific functionality, or NULL if the underlying file is not a GRIB file.
-closeFile:
- cdiRefObject_release(&me->file->super);
-destructSuper:
- baseIterDestruct(&me->super);
- Free(me);
-fail:
- return NULL;
-}
+ at Description
+ Clones the given iterator iff the underlying file is a GRIB file, the returned iterator allows access to GRIB specific functionality.
+ Make sure to check that the return value is not NULL, and to call cdiGribIterator_delete() on the copy.
-static void cdiGribIterator_ensureBuffer(CdiGribIterator *me, size_t requiredSize)
+ This is not a cheap operation: It will make a copy of the current field in memory. Use it sparingly. And if you do, try to avoid keeping too many clones around, their memory footprint is significant.
+*/
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
{
- if(me->bufferSize < requiredSize)
+ sanityCheck(me);
+ switch(me->filetype)
{
- me->bufferSize *= 2;
- if(me->bufferSize < requiredSize) me->bufferSize = requiredSize;
- me->gribBuffer = (unsigned char *) Realloc(me->gribBuffer, me->bufferSize);
- }
-}
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_makeClone(me);
+#endif
-static bool isGrib1DualLevel(int levelType)
-{
- switch(levelType)
- {
- case 101: case 104: case 106: case 108: case 110: case 112:
- case 114: case 116: case 120: case 121: case 128: case 141: //This is the complete list after grib_api-1.12.3/definitions/grib1/sections.1.def:106-117:, the code in cdi/src/stream_gribapi.c:grib1GetLevel() seems to be incomplete.
- return true;
default:
- return false;
+ return NULL;
}
}
-static const unsigned char *positionOfGribMarker(const unsigned char *data, size_t size)
-{
- for(const unsigned char *currentPosition = data, *end = data + size; currentPosition < end; currentPosition++)
- {
- currentPosition = (unsigned char *)memchr(currentPosition, 'G', size - (size_t)(currentPosition - data) - 3); //-3 to ensure that we don't overrun the buffer during the strncmp() call.
- if(!currentPosition) return NULL;
- if(!strncmp((const char*)currentPosition, "GRIB", 4)) return currentPosition;
- }
- return NULL;
-}
+/*
+ at Function cdiIterator_serialize
+ at Title Serialize an iterator for sending it to another process
-//This clobbers the contents of the gribBuffer!
-//Returns the file offset of the next 'GRIB' marker.
-static ssize_t scanToGribMarker(CdiGribIterator *me)
+ at Prototype char* cdiIterator_serialize(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string that contains the full description of the iterator.
+
+ at Description
+ Make sure to call Free() on the resulting string.
+*/
+char* cdiIterator_serialize(CdiIterator* me)
{
- cdiGribIterator_ensureBuffer(me, 8*1024);
- const size_t kMaxScanSize = 16*1024*1024;
- for(size_t scannedBytes = 0, scanSize; scannedBytes < kMaxScanSize; scannedBytes += scanSize)
+ if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+ char* subclassDescription = NULL;
+ switch(me->filetype)
{
- //Load a chunk of data into our buffer.
- scanSize = me->bufferSize;
- if(scannedBytes + scanSize > kMaxScanSize) scanSize = kMaxScanSize - scannedBytes;
- assert(scanSize <= me->bufferSize);
- int status = cdiInputFile_read(me->file, me->fileOffset + (off_t)scannedBytes, scanSize, &scanSize, me->gribBuffer);
- if(status != CDI_NOERR && status != CDI_EEOF) return -1;
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ subclassDescription = cdiGribIterator_serialize(me);
+ break;
+#endif
- const unsigned char *startPosition = positionOfGribMarker(me->gribBuffer, scanSize);
- if(startPosition)
- {
- return (ssize_t)(me->fileOffset + (off_t)scannedBytes + (off_t)(startPosition - me->gribBuffer));
- }
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ subclassDescription = cdiFallbackIterator_serialize(me);
+ break;
- //Get the offset for the next iteration if there is a next iteration.
- scanSize -= 3; //so that we won't miss a 'GRIB' sequence that happens to be cut off
- scanSize &= ~(size_t)0xf; //make 16 bytes aligned
- if((ssize_t)scanSize <= 0) return -1; //ensure that we make progress
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return NULL;
}
- return -1;
-}
-
-static unsigned decode24(void *beData)
-{
- unsigned char *bytes = (unsigned char *)beData;
- return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
-}
-static uint64_t decode64(void *beData)
-{
- unsigned char *bytes = (unsigned char *)beData;
- uint64_t result = 0;
- for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
+ const char *ftypeStr = fileType2String(me->filetype),
+ *advStr = me->isAdvanced ? kAdvancedString : kUnadvancedString;
+ char* result = (char *) Malloc(strlen(ftypeStr) + 1 + strlen(advStr) + 1
+ + strlen(subclassDescription) + 1);
+ sprintf(result, "%s %s %s", ftypeStr, advStr, subclassDescription);
+ Free(subclassDescription);
return result;
}
-//Determine the size of the GRIB record that begins at the given file offset.
-static int getRecordSize(CdiGribIterator *me, off_t gribFileOffset, size_t *outRecordSize)
-{
- char buffer[16];
- size_t readSize;
- int status = cdiInputFile_read(me->file, gribFileOffset, sizeof(buffer), &readSize, buffer);
- if(status != CDI_NOERR && status != CDI_EEOF) return status;
- if(readSize < sizeof(buffer)) return CDI_EEOF;
- *outRecordSize = 0;
- switch(buffer[7])
- {
- case 1:
- *outRecordSize = decode24(&buffer[4]);
- if(*outRecordSize & (1 << 23))
- {
- *outRecordSize = 120*(*outRecordSize & ((1 << 23) - 1)); //Rescaling for long records.
- //The corresponding code in cgribexlib.c:4532-4570: is much more complicated
- //due to the fact that it subtracts the padding bytes that are inserted after section 4.
- //However, we are only interested in the total size of data we need to read here,
- //so we can ignore the presence of some padding bytes.
- }
- return CDI_NOERR;
+/*
+ at Function cdiIterator_deserialize
+ at Title Recreate an iterator from its textual description
- case 2:
- *outRecordSize = decode64(&buffer[8]);
- return CDI_NOERR;
+ at Prototype CdiIterator* cdiIterator_deserialize(const char* description)
+ at Parameter
+ @item description The result of a call to cdiIterator_serialize().
- default:
- return CDI_EUFTYPE;
- }
-}
+ at Result A clone of the original iterator.
-#if 0
-static void hexdump(void *data, size_t size)
+ at Description
+ A pair of cdiIterator_serialize() and cdiIterator_deserialize() is functionally equivalent to a call to cdiIterator_clone()
+
+ This function will reread the current field from disk, so don't expect immediate return.
+*/
+//This only checks the type of the iterator and calls the corresponding subclass function,
+//the real deserialization is done in baseIter_constructFromString().
+CdiIterator* cdiIterator_deserialize(const char* description)
{
- unsigned char *charData = data;
- for(size_t offset = 0; offset < size; )
+ switch(string2FileType(description, NULL))
{
- printf("%016zx:", offset);
- for(size_t i = 0; i < 64 && offset < size; i++, offset++)
- {
- if((i & 63) && !(i & 15)) printf(" |");
- if((i & 15) && !(i & 3)) printf(" ");
- printf(" %02x", charData[offset]);
- }
- printf("\n");
- }
-}
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_getSuper(cdiGribIterator_deserialize(description));
#endif
-//Read a record into memory and wrap it in a grib_handle.
-//XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this [...]
-static int readMessage(CdiGribIterator *me)
-{
- //Destroy the old grib_handle.
- if(me->gribHandle) grib_handle_delete(me->gribHandle), me->gribHandle = NULL;
- me->fileOffset += (off_t)me->curRecordSize;
-
- //Find the next record and determine its size.
- ssize_t gribFileOffset = scanToGribMarker(me);
- int result = CDI_EEOF;
- if(gribFileOffset < 0) goto fail;
- result = getRecordSize(me, gribFileOffset, &me->curRecordSize);
- if(result) goto fail;
-
- //Load the whole record into our buffer and create a grib_handle for it.
- cdiGribIterator_ensureBuffer(me, me->curRecordSize);
- result = cdiInputFile_read(me->file, gribFileOffset, me->curRecordSize, NULL, me->gribBuffer);
- if(result) goto fail;
- me->gribHandle = grib_handle_new_from_message(NULL, me->gribBuffer, me->curRecordSize);
- result = CDI_EUFSTRUCT;
- if(!me->gribHandle) goto fail;
-
- return CDI_NOERR;
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_getSuper(cdiFallbackIterator_deserialize(description));
-fail:
- me->curRecordSize = 0; //This ensures that we won't jump to an uncontrolled file position if cdiGribIterator_nextField() is called another time after it has returned an error.
- return result;
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return NULL;
+ }
}
-int cdiGribIterator_nextField(CdiIterator *super)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
-
- if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
-
- //Get the next GRIB message into our buffer.
- int result = readMessage(me);
- if(result) return result;
- //Get the metadata that's published as variables in the base class.
- super->datatype = gribGetDatatype(me->gribHandle);
- super->timesteptype = gribapiGetTsteptype(me->gribHandle);
- cdiDecodeParam(gribapiGetParam(me->gribHandle), &super->param.number, &super->param.category, &super->param.discipline);
- grid_t grid;
- gribapiGetGrid(me->gribHandle, &grid);
- super->gridId = gridGenerate(&grid);
+/*
+ at Function cdiIterator_print
+ at Title Print a textual description of the iterator to a stream
- return CDI_NOERR;
-}
+ at Prototype void cdiIterator_print(CdiIterator* iterator, FILE* stream);
+ at Parameter
+ @item iterator The iterator to print.
+ @item stream The stream to print to.
-char *cdiGribIterator_inqTime(CdiIterator *super, CdiTimeType timeType)
+ at Description
+ Use for debugging output.
+*/
+void cdiIterator_print(CdiIterator* me, FILE* stream)
{
- CdiGribIterator *me = (CdiGribIterator*)super;
- return gribMakeTimeString(me->gribHandle, timeType);
+ char* description = cdiIterator_serialize(me);
+ fprintf(stream, "%s\n", description);
+ Free(description);
}
-int cdiGribIterator_levelType(CdiIterator *super, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
- //First determine the zaxis type corresponding to the given level.
- int zaxisType = ZAXIS_GENERIC;
- if(gribEditionNumber(me->gribHandle) <= 1)
- {
- int levelType = (int)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", 255);
- if(levelSelector && !isGrib1DualLevel(levelType)) levelType = 255;
- zaxisType = grib1ltypeToZaxisType(levelType);
- }
- else
- {
- int levelType = (int)gribGetLongDefault(me->gribHandle, levelSelector ? "typeOfSecondFixedSurface" : "typeOfFirstFixedSurface", 255);
- zaxisType = grib2ltypeToZaxisType(levelType);
- }
+/*
+ at Function cdiIterator_nextField
+ at Title Advance an iterator to the next field in the file
- //Then lookup the requested names.
- const char *name, *longName, *stdName, *unit;
- zaxisGetTypeDescription(zaxisType, NULL, &name, &longName, &stdName, &unit);
- if(outName) *outName = strdup(name);
- if(outLongName) *outLongName = strdup(longName);
- if(outStdName) *outStdName = strdup(stdName);
- if(outUnit) *outUnit = strdup(unit);
+ at Prototype int cdiIterator_nextField(CdiIterator* iterator)
+ at Parameter
+ @item iterator The iterator to operate on.
- return zaxisType;
-}
+ at Result An error code. May be one of:
+ * CDI_NOERR: The iterator has successfully been advanced to the next field.
+ * CDI_EEOF: No more fields to read in this file.
-static double logicalLevelValue2(long gribType, long storedValue, long power)
+ at Description
+ One call to cdiIterator_nextField() is required before the metadata of the first field can be examined.
+ Usually, it will be used directly as the condition for a while() loop.
+*/
+int cdiIterator_nextField(CdiIterator* me)
{
- double factor = 1;
- assert(power >= 0);
- while(power--) factor *= 10; //this is precise up to factor == 22.
- switch(gribType)
+ if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+ me->isAdvanced = true;
+ switch(me->filetype)
{
- case GRIB2_LTYPE_LANDDEPTH:
- case GRIB2_LTYPE_ISOBARIC:
- case GRIB2_LTYPE_SIGMA:
- return (double)storedValue * (1000.0/factor); //The evaluation order allows the factors of ten to cancel out before rounding.
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_nextField(me);
+#endif
- case 255:
- return 0;
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_nextField(me);
default:
- return (double)storedValue/factor;
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_EINVAL;
}
}
-//The output values must be preinitialized, this function does not always write them.
-static int readLevel2(grib_handle *gribHandle, const char *levelTypeKey, const char *powerKey, const char *valueKey, double *outValue1, double *outValue2)
+static char* cdiIterator_inqTime(CdiIterator* me, CdiTimeType timeType)
{
- assert(levelTypeKey && powerKey && valueKey && outValue1 && outValue2);
-
- long levelType = gribGetLongDefault(gribHandle, levelTypeKey, 255); //1 byte
- switch(levelType)
+ sanityCheck(me);
+ switch(me->filetype)
{
- case 255: break;
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_inqTime(me, timeType);
+#endif
- case 105: case 113:
- {
- unsigned long value = (unsigned long)gribGetLongDefault(gribHandle, valueKey, 0);
- unsigned long coordinateCount = (unsigned long)gribGetLongDefault(gribHandle, "numberOfCoordinatesValues", 0);
- if(value >= coordinateCount/2)
- {
- Error("Invalid level coordinate: Level has the hybrid coordinate index %lu, but only %lu coordinate pairs are present.", value, coordinateCount/2);
- return CDI_EUFSTRUCT;
- }
- int status;
- //XXX: I'm not 100% sure about how the coordinate pairs are stored in the file.
- // I'm assuming an array of pairs due to the example code in grib_api-1.12.3/examples/F90/set_pv.f90, but that may be wrong.
- if((status = grib_get_double_element(gribHandle, "pv", (int)value*2 , outValue1))) return status;
- if((status = grib_get_double_element(gribHandle, "pv", (int)value*2 + 1, outValue2))) return status;
- break;
- }
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_inqTime(me, timeType);
default:
- {
- long power = 255 & gribGetLongDefault(gribHandle, powerKey, 0); //1 byte
- if(power == 255) power = 0;
- long value = gribGetLongDefault(gribHandle, valueKey, 0); //4 bytes
- *outValue1 = logicalLevelValue2(levelType, value, power);
- }
+ Error(kUnexpectedFileTypeMessage);
+ return NULL;
}
- return CDI_NOERR;
}
-int cdiGribIterator_level(CdiIterator *super, int levelSelector, double *outValue1, double *outValue2)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
- double trash;
- if(!outValue1) outValue1 = &trash;
- if(!outValue2) outValue2 = &trash;
- *outValue1 = *outValue2 = 0;
+/*
+ at Function cdiIterator_inqStartTime
+ at Title Get the start time of a measurement
- if(gribEditionNumber(me->gribHandle) > 1)
- {
- if(levelSelector)
- {
- return readLevel2(me->gribHandle, "typeOfFirstFixedSurface", "scaleFactorOfFirstFixedSurface", "scaledValueOfFirstFixedSurface", outValue1, outValue2);
- }
- else
- {
- return readLevel2(me->gribHandle, "typeOfSecondFixedSurface", "scaleFactorOfSecondFixedSurface", "scaledValueOfSecondFixedSurface", outValue1, outValue2);
- }
- }
- else
- {
- long levelType = (uint8_t)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", -1); //1 byte
- if(levelType == 255)
- {}
- else if(isGrib1DualLevel((int)levelType))
- {
- *outValue1 = (double)gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0);
- }
- else if(levelType == 100)
- {
- *outValue1 = 100 * (double)gribGetLongDefault(me->gribHandle, "level", 0); //2 bytes
- }
- else
- {
- *outValue1 = (double)gribGetLongDefault(me->gribHandle, "level", 0); //2 bytes
- }
- }
- return CDI_NOERR;
-}
+ at Prototype char* cdiIterator_inqStartTime(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to operate on.
-int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
+ at Result A malloc'ed string containing the (start) time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
- if(outVgridNumber)
- {
- long temp;
- if(grib_get_long(me->gribHandle, "numberOfVGridUsed", &temp)) return CDI_EINVAL;
- *outVgridNumber = (int)temp;
- }
- if(outLevelCount)
- {
- long temp;
- if(grib_get_long(me->gribHandle, "nlev", &temp)) return CDI_EINVAL;
- *outLevelCount = (int)temp;
- }
- if(outUuid)
- {
- size_t size = CDI_UUID_SIZE;
- if(grib_get_bytes(me->gribHandle, "uuidOfVGrid", outUuid, &size)) return CDI_EINVAL;
- if(size != CDI_UUID_SIZE) return CDI_EUFSTRUCT;
- }
+ at Description
+The returned time is either the time of the data (fields defined at a time point),
+or the start time of an integration time range (statistical fields).
- return CDI_NOERR;
-}
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to Free() the resulting string.
-int cdiGribIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqStartTime(CdiIterator* me)
{
- CdiGribIterator *me = (CdiGribIterator*)super;
- int trash;
- if(!outTileIndex) outTileIndex = &trash;
- if(!outTileAttribute) outTileAttribute = &trash;
+ return cdiIterator_inqTime(me, kCdiTimeType_startTime);
+}
- //Get the values if possible.
- int error = CDI_NOERR;
- long value;
- if(grib_get_long(me->gribHandle, "tileIndex", &value)) error = CDI_EINVAL;
- *outTileIndex = (int)value;
- if(grib_get_long(me->gribHandle, "tileAttribute", &value)) error = CDI_EINVAL;
- *outTileAttribute = (int)value;
+/*
+ at Function cdiIterator_inqEndTime
+ at Title Get the end time of a measurement
- //Ensure defined return values in case of failure.
- if(error) *outTileIndex = *outTileAttribute = -1;
- return error;
-}
+ at Prototype char* cdiIterator_inqEndTime(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to operate on.
-int cdiGribIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
- int trash;
- if(!outTileCount) outTileCount = &trash;
- if(!outTileAttributeCount) outTileAttributeCount = &trash;
+ at Result A malloc'ed string containing the end time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm", or NULL if no such time is defined.
- //Get the values if possible.
- int error = CDI_NOERR;
- long value;
- if(grib_get_long(me->gribHandle, "numberOfTiles", &value)) error = CDI_EINVAL;
- *outTileCount = (int)value;
- if(grib_get_long(me->gribHandle, "numberOfTileAttributes", &value)) error = CDI_EINVAL;
- *outTileAttributeCount = (int)value;
+ at Description
+The returned time is the end time of an integration period if such a time exists (statistical fields).
+Otherwise, NULL is returned.
- //Ensure defined return values in case of failure.
- if(error) *outTileCount = *outTileAttributeCount = 0;
- return error;
-}
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to Free() the resulting string.
-char *cdiGribIterator_copyVariableName(CdiIterator *super)
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqEndTime(CdiIterator* me)
{
- CdiGribIterator *me = (CdiGribIterator*)super;
- return gribCopyString(me->gribHandle, "shortName");
+ return cdiIterator_inqTime(me, kCdiTimeType_endTime);
}
-void cdiGribIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
+/*
+ at Function cdiIterator_inqRTime
+ at Title Get the validity time of the current field
- GRIB_CHECK(my_grib_set_double(me->gribHandle, "missingValue", cdiDefaultMissval), 0);
- gribGetDoubleArray(me->gribHandle, "values", buffer);
- long gridType = gribGetLong(me->gribHandle, "gridDefinitionTemplateNumber");
- if(nmiss)
- {
- *nmiss = (gridType >= 50 && gridType <= 53) ? (size_t)0 : (size_t)gribGetLong(me->gribHandle, "numberOfMissing"); //The condition excludes harmonic data.
- }
-}
+ at Prototype char* cdiIterator_inqRTime(CdiIterator* me)
+ at Parameter
+ @item iterator The iterator to operate on.
-void cdiGribIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
-{
- CdiGribIterator *me = (CdiGribIterator*)super;
+ at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
- size_t valueCount = gribGetArraySize(me->gribHandle, "values");
- double *temp = (double *) Malloc(valueCount*sizeof(*temp));
- cdiGribIterator_readField(super, temp, nmiss);
- for(size_t i = valueCount; i--; ) buffer[i] = (float)temp[i];
- Free(temp);
+ at Description
+The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
+That is, if the field is a time point, its time is returned,
+if it is a statistical field with an integration period, the end time of the integration period is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to Free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqRTime(CdiIterator* me)
+{
+ return cdiIterator_inqTime(me, kCdiTimeType_referenceTime);
}
-#endif
/*
- at Function cdiGribIterator_delete
- at Title Dispose off a CdiGribIterator instance.
+ at Function cdiIterator_inqVTime
+ at Title Get the validity time of the current field
- at Prototype void cdiGribIterator_delete(CdiGribIterator *me)
+ at Prototype char* cdiIterator_inqVTime(CdiIterator* me)
@Parameter
- @item me The iterator to delete.
+ @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
@Description
- Combined destructor and deallocator. Make sure to match every call to cdiGribIterator_clone() with a call to this function.
+The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
+That is, if the field is a time point, its time is returned,
+if it is a statistical field with an integration period, the end time of the integration period is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to Free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
*/
-void cdiGribIterator_delete(CdiGribIterator *me)
+char* cdiIterator_inqVTime(CdiIterator* me)
{
-#ifdef HAVE_LIBGRIB_API
- if(me) cdiGribIterator_condestruct(me, NULL, 0);
-#else
- if (me)
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ char* result = cdiIterator_inqEndTime(me);
+ return (result) ? result : cdiIterator_inqStartTime(me);
}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// callthroughs to provide direct access to the grib keys //////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
/*
- at Function cdiGribIterator_inqEdition
- at Title Get the version of the GRIB standard that is used
+ at Function cdiIterator_inqLevelType
+ at Title Get the type of a level
- at Prototype int cdiGribIterator_inqEdition(CdiGribIterator *me)
+ at Prototype int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName = NULL, char **outLongName = NULL, char **outStdName = NULL, char **outUnit = NULL)
@Parameter
- @item me The iterator to operate on.
+ @item iterator The iterator to operate on.
+ @item levelSelector Zero for the top level, one for the bottom level
+ @item outName Will be set to a Malloc()'ed string with the name of the level if not NULL.
+ @item outLongName Will be set to a Malloc()'ed string with the long name of the level if not NULL.
+ @item outStdName Will be set to a Malloc()'ed string with the standard name of the level if not NULL.
+ @item outUnit Will be set to a Malloc()'ed string with the unit of the level if not NULL.
- at Result The GRIB version.
+ at Result An integer indicating the type of the level.
@Description
- Returns the version of the file format.
+Find out some basic information about the given level, the levelSelector selects the function of the requested level.
+If the requested level does not exist, this returns CDI_UNDEFID.
*/
-int cdiGribIterator_inqEdition(CdiGribIterator *me)
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
{
+ sanityCheck(me);
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return (int)gribEditionNumber(me->gribHandle);
-#else
- (void)me;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
#endif
+ return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_UNDEFID;
+ }
}
/*
- at Function cdiGribIterator_getLong
- at Title Access to grib_get_long()
+ at Function cdiIterator_inqLevel
+ at Title Get the value of the z-coordinate
- at Prototype int cdiGribIterator_getLong(CdiGribIterator *me, const char *key, long *result)
+ at Prototype void cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2 = NULL)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
+ @item levelSelector Zero for the top level, one for the bottom level
+ @item outValue1 For "normal" levels this returns the value, for hybrid levels the first coordinate, for generalized levels the level number.
+ @item outValue2 Zero for "normal" levels, for hybrid levels, this returns the second coordinate, for generalized levels the level count.
@Result An error code.
@Description
- Callthrough to grib_get_long().
+Returns the value of the z-coordinate, whatever that may be.
*/
-int cdiGribIterator_getLong(CdiGribIterator *me, const char *key, long *result)
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2)
{
+ sanityCheck(me);
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return grib_get_long(me->gribHandle, key, result);
-#else
- (void)me;
- (void)key;
- (void)result;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_EINVAL;
+ }
}
/*
- at Function cdiGribIterator_getLength
- at Title Access to grib_get_length()
+ at Function cdiIterator_inqLevelUuid
+ at Title Get the UUID of the z-axis used by this field
- at Prototype int cdiGribIterator_getLength(CdiGribIterator *me, const char *key, size_t *result)
+ at Prototype int cdiIterator_inqLevelUuid(CdiIterator* me, int levelSelector, unsigned char (*outUuid)[16])
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
+ @item outVgridNumber The number of the associated vertical grid description.
+ @item outLevelCount The number of levels in the associated vertical grid description.
+ @item outUuid A pointer to a user supplied buffer of 16 bytes to store the UUID in.
@Result An error code.
@Description
- Callthrough to grib_get_length().
+Returns identifying information for the external z-axis description. May only be called for generalized levels.
*/
-int cdiGribIterator_getLength(CdiGribIterator *me, const char *key, size_t *result)
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
{
-#ifdef HAVE_GRIB_GET_LENGTH
- return grib_get_length(me->gribHandle, key, result);
-#elif defined(HAVE_LIBGRIB_API)
- (void)me;
- (void)key;
- (void)result;
- Error("grib_get_length() is not available, so cdiGribIterator_getLength() can't be used");
- return -1;
-#else
- (void)me;
- (void)key;
- (void)result;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ sanityCheck(me);
+ switch(me->filetype)
+ {
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
#endif
+ return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_ELIBNAVAIL;
+ }
}
/*
- at Function cdiGribIterator_getString
- at Title Access to grib_get_string()
+ at Function cdiIterator_inqTile
+ at Title Inquire the tile information for the current field
- at Prototype int cdiGribIterator_getString(CdiGribIterator *me, const char *key, char *result, size_t *length)
+ at Prototype int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
+ @item outTileIndex The index of the current tile, -1 if no tile information is available.
+ @item outTileAttribute The attribute of the current tile, -1 if no tile information is available.
+
+ at Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
+
+ at Description
+Inquire the tile index and attribute for the current field.
+*/
+int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
+{
+ sanityCheck(me);
+ switch(me->filetype)
+ {
+ #ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute);
+ #endif
+
+ #ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ #endif
+ #ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+ #endif
+ #ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+ #endif
+ #ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+ #endif
+ return cdiFallbackIterator_inqTile(me, outTileIndex, outTileAttribute);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_ELIBNAVAIL;
+ }
+}
+
+/**
+ at Function cdiIterator_inqTileCount
+ at Title Inquire the tile count and tile attribute counts for the current field
+
+ at Prototype int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
+ at Parameter
+ @item iterator The iterator to operate on.
+ @item outTileCount The number of tiles used for this variable, zero if no tile information is available.
+ @item outTileAttributeCount The number of attributes available for the tile of this field, zero if no tile information is available.
+ Note: This is not the global attribute count, which would be impossible to infer without reading the entire file if it's a GRIB file.
- at Result An error code.
+ at Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
@Description
- Callthrough to grib_get_string().
+Inquire the tile count and tile attribute counts for the current field.
*/
-int cdiGribIterator_getString(CdiGribIterator *me, const char *key, char *result, size_t *length)
+int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
{
-#ifdef HAVE_LIBGRIB_API
- return grib_get_string(me->gribHandle, key, result, length);
-#else
- (void)me;
- (void)key;
- (void)result;
- (void)length;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ sanityCheck(me);
+ switch(me->filetype)
+ {
+ #ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
+ #endif
+
+ #ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ #endif
+ #ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+ #endif
+ #ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+ #endif
+ #ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+ #endif
+ return cdiFallbackIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return CDI_ELIBNAVAIL;
+ }
}
/*
- at Function cdiGribIterator_inqLongValue
- at Title Get the value of a GRIB-API key as a long
+ at Function cdiIterator_inqParam
+ at Title Get discipline, category, and number
- at Prototype long cdiGribIterator_inqLongValue(CdiGribIterator *me, const char *key)
+ at Prototype CdiParam cdiIterator_inqParam(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item key The GRIB-API key to retrieve.
+ @item iterator The iterator to operate on.
- at Result The value of the key.
+ at Result A struct containing the requested information.
@Description
- Use this to fetch a grib value if you are certain that the given key must be present.
- This will abort the process if the key cannot be retrieved.
+ Simple metadata inspection function.
*/
-long cdiGribIterator_inqLongValue(CdiGribIterator *me, const char *key)
+CdiParam cdiIterator_inqParam(CdiIterator* me)
{
-#ifdef HAVE_LIBGRIB_API
- return gribGetLong(me->gribHandle, key);
-#else
- (void)me;
- (void)key;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ sanityCheck(me);
+ return me->param;
}
/*
- at Function cdiGribIterator_inqLongDefaultValue
- at Title Get the value of a GRIB-API key as a long
+ at Function cdiIterator_inqParamParts
+ at Title Get discipline, category, and number
- at Prototype long cdiGribIterator_inqLongDefaultValue(CdiGribIterator *me, const char *key, long defaultValue)
+ at Prototype void cdiIterator_inqParamParts(CdiIterator *me, int *outDiscipline, int *outCategory, int *outNumber)
@Parameter
- @item me The iterator to operate on.
- @item key The GRIB-API key to retrieve.
- @item defaultValue The value to return if the key is not present.
-
- at Result The value of the key or the given default value.
+ @item iterator The iterator to operate on.
+ @item outDiscipline This is used to return the discipline.
+ @item outCategory This is used to return the category.
+ @item outNumber This is used to return the number.
@Description
- Use this if you can handle failure to fetch the key by supplying a default value.
- This function cannot fail.
+ Simple metadata inspection function.
+
+ Some FORTRAN compilers produce wrong code for the cdiIterator_inqParam()-wrapper,
+ rendering it unusable from FORTRAN. This function is the workaround.
*/
-long cdiGribIterator_inqLongDefaultValue(CdiGribIterator *me, const char *key, long defaultValue)
+void cdiIterator_inqParamParts(CdiIterator *me, int *outDiscipline, int *outCategory, int *outNumber)
{
-#ifdef HAVE_LIBGRIB_API
- return gribGetLongDefault(me->gribHandle, key, defaultValue);
-#else
- (void)me;
- (void)key;
- (void)defaultValue;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ CdiParam result = cdiIterator_inqParam(me);
+ if(outDiscipline) *outDiscipline = result.discipline;
+ if(outCategory) *outCategory = result.category;
+ if(outNumber) *outNumber = result.number;
}
/*
- at Function cdiGribIterator_inqStringValue
- at Title Safely retrieve a GRIB-API key with a string value
+ at Function cdiIterator_inqDatatype
+ at Title Get the datatype of the current field
- at Prototype char *cdiGribIterator_inqStringValue(CdiGribIterator *me, const char *key)
+ at Prototype int cdiIterator_inqDatatype(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item key The GRIB-API key to retrieve.
+ @item iterator The iterator to operate on.
- at Result A malloc'ed string or NULL.
+ at Result The datatype that is used to store this field on disk.
@Description
- This will first call grib_get_length() to inquire the actual size of the string,
- allocate memory accordingly, call grib_get_string(), and return the pointer to the new string.
- Returns NULL on failure.
+ Simple metadata inspection function.
*/
-char *cdiGribIterator_inqStringValue(CdiGribIterator *me, const char *key)
+int cdiIterator_inqDatatype(CdiIterator* me)
{
-#ifdef HAVE_LIBGRIB_API
- return gribCopyString(me->gribHandle, key);
-#else
- (void)me;
- (void)key;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ sanityCheck(me);
+ return me->datatype;
}
/*
- at Function cdiGribIterator_getDouble
- at Title Access to grib_get_double()
+ at Function cdiIterator_inqTsteptype
+ at Title Get the timestep type
- at Prototype int cdiGribIterator_getDouble(CdiGribIterator *me, const char *key, double *result)
+ at Prototype int cdiIterator_inqTsteptype(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
- at Result An error code.
+ at Result The timestep type.
@Description
- Callthrough to grib_get_double().
+ Simple metadata inspection function.
*/
-int cdiGribIterator_getDouble(CdiGribIterator *me, const char *key, double *result)
+int cdiIterator_inqTsteptype(CdiIterator* me)
{
-#ifdef HAVE_LIBGRIB_API
- return grib_get_double(me->gribHandle, key, result);
-#else
- (void)me;
- (void)key;
- (void)result;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ sanityCheck(me);
+ return me->timesteptype;
}
/*
- at Function cdiGribIterator_getSize
- at Title Access to grib_get_size()
+ at Function cdiIterator_inqVariableName
+ at Title Get the variable name of the current field
- at Prototype int cdiGribIterator_getSize(CdiGribIterator *me, const char *key, size_t *result)
+ at Prototype char* cdiIterator_inqVariableName(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
- at Result An error code.
+ at Result A pointer to a C-string containing the name. The storage for this string is allocated with Malloc(), and it is the responsibility of the caller to Free() it.
@Description
- Callthrough to grib_get_size().
+ Allocates a buffer to hold the string, copies the current variable name into this buffer, and returns the buffer.
+ The caller is responsible to make the corresponding Free() call.
*/
-int cdiGribIterator_getSize(CdiGribIterator *me, const char *key, size_t *result)
+char* cdiIterator_inqVariableName(CdiIterator* me)
{
+ sanityCheck(me);
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return grib_get_size(me->gribHandle, key, result);
-#else
- (void)me;
- (void)key;
- (void)result;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ return cdiGribIterator_copyVariableName(me);
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
#endif
+ return cdiFallbackIterator_copyVariableName(me);
+
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ return NULL;
+ }
}
/*
- at Function cdiGribIterator_getLongArray
- at Title Access to grib_get_long_array()
+ at Function cdiIterator_inqGridId
+ at Title Get the ID of the current grid
- at Prototype int cdiGribIterator_getLongArray(CdiGribIterator *me, const char *key, long *result, size_t *size)
+ at Prototype int cdiIterator_inqGridId(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
+ @item iterator The iterator to operate on.
- at Result An error code.
+ at Result A gridId that can be used for further introspection.
@Description
- Callthrough to grib_get_long_array().
+ This provides access to the grid related metadata.
+ The resulting ID is only valid until the next time cdiIterator_nextField() is called.
*/
-int cdiGribIterator_getLongArray(CdiGribIterator *me, const char *key, long *result, size_t *size)
+int cdiIterator_inqGridId(CdiIterator* me)
{
-#ifdef HAVE_LIBGRIB_API
- return grib_get_long_array(me->gribHandle, key, result, size);
-#else
- (void)me;
- (void)key;
- (void)result;
- (void)size;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-#endif
+ sanityCheck(me);
+ return me->gridId;
}
/*
- at Function cdiGribIterator_getDoubleArray
- at Title Access to grib_get_double_array()
+ at Function cdiIterator_readField
+ at Title Read the whole field into a double buffer
- at Prototype int cdiGribIterator_getDoubleArray(CdiGribIterator *me, const char *key, double *result, size_t *size)
+ at Prototype void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
@Parameter
- @item me The iterator to operate on.
- @item ... The arguments to the underlying GRIB-API function.
-
- at Result An error code.
+ @item iterator The iterator to operate on.
+ @item buffer A pointer to the double array that the data should be written to.
+ @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
@Description
- Callthrough to grib_get_double_array().
+ It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+ Failing to do so results in undefined behavior. You have been warned.
*/
-int cdiGribIterator_getDoubleArray(CdiGribIterator *me, const char *key, double *result, size_t *size)
+void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
{
+ sanityCheck(me);
+ if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return grib_get_double_array(me->gribHandle, key, result, size);
-#else
- (void)me;
- (void)key;
- (void)result;
- (void)size;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ cdiGribIterator_readField(me, buffer, nmiss);
+ return;
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ cdiFallbackIterator_readField(me, buffer, nmiss);
+ return;
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ }
}
/*
- at Function cdiGribIterator_inqDoubleValue
- at Title Get the value of a GRIB-API key as a double
+ at Function cdiIterator_readFieldF
+ at Title Read the whole field into a double buffer
- at Prototype double cdiGribIterator_inqDoubleValue(CdiGribIterator *me, const char *key)
+ at Prototype void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
@Parameter
- @item me The iterator to operate on.
- @item key The GRIB-API key to retrieve.
-
- at Result The value of the key.
+ @item iterator The iterator to operate on.
+ @item buffer A pointer to the double array that the data should be written to.
+ @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
@Description
- Use this to fetch a grib value if you are certain that the given key must be present.
- This will abort the process if the key cannot be retrieved.
+ It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+ Failing to do so results in undefined behavior. You have been warned.
*/
-double cdiGribIterator_inqDoubleValue(CdiGribIterator *me, const char *key)
+void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
{
+ sanityCheck(me);
+ if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return gribGetDouble(me->gribHandle, key);
-#else
- (void)me;
- (void)key;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ cdiGribIterator_readFieldF(me, buffer, nmiss);
+ return;
+#endif
+
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
#endif
+ cdiFallbackIterator_readFieldF(me, buffer, nmiss);
+ return;
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ }
}
/*
- at Function cdiGribIterator_inqDoubleDefaultValue
- at Title Get the value of a GRIB-API key as a double
+ at Function cdiIterator_delete
+ at Title Destroy an iterator
- at Prototype double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator *me, const char *key, double defaultValue)
+ at Prototype void cdiIterator_delete(CdiIterator* iterator)
@Parameter
- @item me The iterator to operate on.
- @item key The GRIB-API key to retrieve.
- @item defaultValue The value to return if the key is not present.
-
- at Result The value of the key or the given default value.
+ @item iterator The iterator to operate on.
@Description
- Use this if you can handle failure to fetch the key by supplying a default value.
- This function cannot fail.
+ Combined destructor & deallocator.
*/
-double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator *me, const char *key, double defaultValue)
+void cdiIterator_delete(CdiIterator* me)
{
+ if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+ switch(me->filetype)
+ {
#ifdef HAVE_LIBGRIB_API
- return gribGetDoubleDefault(me->gribHandle, key, defaultValue);
-#else
- (void)me;
- (void)key;
- (void)defaultValue;
- xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ cdiGribIterator_delete((CdiGribIterator*)me);
+ break;
#endif
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef MODEL_H
-#define MODEL_H
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+#endif
+ cdiFallbackIterator_delete(me);
+ break;
-int
-modelUnpack(void *buf, int size, int *position,
- int originNamespace, void *context, int force_id);
+ default:
+ Error(kUnexpectedFileTypeMessage);
+ }
+}
-void modelDefaultEntries(void);
+void baseIterDestruct(CdiIterator* me)
+{
+ /*currently empty, but that's no reason not to call it*/
+ (void)me;
+}
-#endif
/*
* Local Variables:
* c-file-style: "Java"
@@ -32983,342 +32064,394 @@ void modelDefaultEntries(void);
#if defined (HAVE_CONFIG_H)
#endif
-#include <limits.h>
-#undef UNDEFID
-#define UNDEFID -1
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
-static int ECHAM4 = UNDEFID,
- ECHAM5 = UNDEFID,
- COSMO = UNDEFID;
+struct CdiFallbackIterator {
+ CdiIterator super;
+ int streamId, vlistId, subtypeId;
+ char *path; //needed for clone() & serialize()
-typedef struct
+ int variableCount, curVariable;
+ int curLevelCount, curLevel;
+ int curSubtypeCount, curSubtype;
+ int curTimestep;
+};
+
+CdiIterator *cdiFallbackIterator_getSuper(CdiFallbackIterator *me)
{
- int self;
- int used;
- int instID;
- int modelgribID;
- char *name;
+ return &me->super;
}
-model_t;
-static int MODEL_Debug = 0; /* If set to 1, debugging */
+//For more information on the condestruct() pattern, see comment in src/iterator_grib.c
+static CdiFallbackIterator *cdiFallbackIterator_condestruct(CdiFallbackIterator *me, const char *path, int filetype)
+{
+ if(me) goto destruct;
-static void modelInit(void);
+ me = (CdiFallbackIterator *) Malloc(sizeof(*me));
+ baseIterConstruct(&me->super, filetype);
+ me->streamId = streamOpenRead(path);
+ if(me->streamId == CDI_UNDEFID) goto destructSuper;
+ me->vlistId = streamInqVlist(me->streamId);
+ if(me->vlistId == CDI_UNDEFID) goto closeStream;
+ me->variableCount = vlistNvars(me->vlistId);
+ if(me->variableCount <= 0) goto closeStream;
+ me->subtypeId = CDI_UNDEFID; //Will be set in cdiFallbackIterator_nextField()
+ me->curSubtypeCount = -1; //Will be set in cdiFallbackIterator_nextField()
+ me->curLevelCount = -1; //Will be set in cdiFallbackIterator_nextField()
-static int modelCompareP(void *modelptr1, void *modelptr2);
-static void modelDestroyP ( void * modelptr );
-static void modelPrintP ( void * modelptr, FILE * fp );
-static int modelGetSizeP ( void * modelptr, void *context);
-static void modelPackP ( void * modelptr, void * buff, int size,
- int *position, void *context);
-static int modelTxCode ( void );
+ //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
+ me->curTimestep = 0;
+ if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+ me->curVariable = -1;
+ me->curSubtype = -1;
+ me->curLevel = -1;
+ me->path = path ? strdup(path) : NULL;
+ if(!me->path) goto closeStream;
-static const resOps modelOps = {
- modelCompareP,
- modelDestroyP,
- modelPrintP,
- modelGetSizeP,
- modelPackP,
- modelTxCode
-};
+ return me;
-static
-void modelDefaultValue ( model_t *modelptr )
-{
- modelptr->self = UNDEFID;
- modelptr->used = 0;
- modelptr->instID = UNDEFID;
- modelptr->modelgribID = UNDEFID;
- modelptr->name = NULL;
+// ^ constructor code ^
+// | |
+// v destructor/error-cleanup code v
+
+destruct:
+ Free(me->path);
+closeStream:
+ streamClose(me->streamId);
+destructSuper:
+ baseIterDestruct(&me->super);
+ Free(me);
+ return NULL;
}
-static model_t *
-modelNewEntry(cdiResH resH, int instID, int modelgribID, const char *name)
+CdiIterator *cdiFallbackIterator_new(const char *path, int filetype)
{
- model_t *modelptr;
-
- modelptr = (model_t *) Malloc(sizeof(model_t));
- modelDefaultValue ( modelptr );
- if (resH == CDI_UNDEFID)
- modelptr->self = reshPut(modelptr, &modelOps);
- else
- {
- modelptr->self = resH;
- reshReplace(resH, modelptr, &modelOps);
- }
- modelptr->used = 1;
- modelptr->instID = instID;
- modelptr->modelgribID = modelgribID;
- if ( name && *name ) modelptr->name = strdupx(name);
-
- return (modelptr);
+ return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
}
-void modelDefaultEntries ( void )
+//Fetches the info that is derived from the current variable. Most of this is published by the data members in the base class.
+static void fetchVariableInfo(CdiFallbackIterator *me)
{
- int instID, i;
- enum { nDefModels = 10 };
- cdiResH resH[nDefModels];
-
- instID = institutInq( 0, 0, "ECMWF", NULL);
- /* (void) modelDef(instID, 131, "ERA15"); */
- /* (void) modelDef(instID, 199, "ERA40"); */
- instID = institutInq( 0, 0, "MPIMET", NULL);
+ //Fetch data that's published via base class data members.
+ me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
+ me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
+ me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
+ int param = vlistInqVarParam(me->vlistId, me->curVariable);
+ cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
- resH[0] = ECHAM5 = modelDef(instID, 64, "ECHAM5.4");
- resH[1] = modelDef(instID, 63, "ECHAM5.3");
- resH[2] = modelDef(instID, 62, "ECHAM5.2");
- resH[3] = modelDef(instID, 61, "ECHAM5.1");
+ //Fetch the current level and subtype counts.
+ me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
+ me->subtypeId = vlistInqVarSubtype(me->vlistId, me->curVariable);
+ me->curSubtypeCount = (me->subtypeId == CDI_UNDEFID) ? 1 : subtypeInqSize(me->subtypeId);
+}
- instID = institutInq( 98, 255, "MPIMET", NULL);
- resH[4] = modelDef(instID, 60, "ECHAM5.0");
- resH[5] = ECHAM4 = modelDef(instID, 50, "ECHAM4");
- resH[6] = modelDef(instID, 110, "MPIOM1");
+CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super)
+{
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- instID = institutInq( 0, 0, "DWD", NULL);
- resH[7] = modelDef(instID, 149, "GME");
+ //Make another stream for this file. This yields an unadvanced iterator.
+ CdiFallbackIterator *clone = cdiFallbackIterator_condestruct(NULL, me->path, me->super.filetype);
+ if(!clone) return NULL;
- instID = institutInq( 0, 0, "MCH", NULL);
- //(void) = modelDef(instID, 137, "COSMO");
- resH[8] = COSMO = modelDef(instID, 255, "COSMO");
+ //Point the clone to the same position in the file.
+ clone->variableCount = me->variableCount;
+ clone->curVariable = me->curVariable;
+ clone->curLevelCount = me->curLevelCount;
+ clone->curLevel = me->curLevel;
+ clone->curSubtypeCount = me->curSubtypeCount;
+ clone->curSubtype = me->curSubtype;
+ clone->curTimestep = me->curTimestep;
- instID = institutInq( 0, 1, "NCEP", NULL);
- resH[9] = modelDef(instID, 80, "T62L28MRF");
+ clone->super.isAdvanced = super->isAdvanced;
+ if(super->isAdvanced) fetchVariableInfo(clone);
- /* pre-defined models are not synchronized */
- for ( i = 0; i < nDefModels ; i++ )
- reshSetStatus(resH[i], &modelOps, RESH_IN_USE);
+ return clone;
}
-static
-void modelInit(void)
+char *cdiFallbackIterator_serialize(CdiIterator *super)
{
- static int modelInitialized = 0;
-
- if (modelInitialized) return;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- modelInitialized = 1;
- char *env = getenv("MODEL_DEBUG");
- if ( env ) MODEL_Debug = atoi(env);
+ char *escapedPath = cdiEscapeSpaces(me->path);
+ char *result = (char *) Malloc(strlen(escapedPath)
+ + 7 * (3 * sizeof (int) * CHAR_BIT / 8 + 1) + 1);
+ sprintf(result, "%s %d %d %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curSubtypeCount, me->curSubtype, me->curTimestep);
+ Free(escapedPath);
+ return result;
}
-struct modelLoc
+CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *description)
{
- const char *name;
- int instID, modelgribID, resID;
-};
+ CdiFallbackIterator *me = (CdiFallbackIterator *) Malloc(sizeof(*me));
+ if(!me) goto fail;
-static enum cdiApplyRet
-findModelByID(int resID, void *res, void *data)
-{
- model_t *modelptr = (model_t*) res;
- struct modelLoc *ret = (struct modelLoc*) data;
- int instID = ret->instID, modelgribID = ret->modelgribID;
- if (modelptr->used
- && modelptr->instID == instID
- && modelptr->modelgribID == modelgribID)
- {
- ret->resID = resID;
- return CDI_APPLY_STOP;
- }
- else
- return CDI_APPLY_GO_ON;
+ description = baseIter_constructFromString(&me->super, description);
+
+ while(*description == ' ') description++;
+ me->path = cdiUnescapeSpaces(description, &description);
+ if(!me->path) goto destructSuper;
+
+ me->streamId = streamOpenRead(me->path);
+ if(me->streamId == CDI_UNDEFID) goto freePath;
+ me->vlistId = streamInqVlist(me->streamId);
+ if(me->vlistId == CDI_UNDEFID) goto closeStream;
+
+ //This reads one variable from the description string, does error checking, and advances the given string pointer.
+#define decodeValue(variable, description) do \
+ { \
+ const char *savedStart = description; \
+ long long decodedValue = strtoll(description, (char**)&description, 0); /*The cast is a workaround for the wrong signature of strtoll().*/ \
+ variable = (int)decodedValue; \
+ if(savedStart == description) goto closeStream; \
+ if((long long)decodedValue != (long long)variable) goto closeStream; \
+ } while(0)
+ decodeValue(me->variableCount, description);
+ decodeValue(me->curVariable, description);
+ decodeValue(me->curLevelCount, description);
+ decodeValue(me->curLevel, description);
+ decodeValue(me->curSubtypeCount, description);
+ decodeValue(me->curSubtype, description);
+ decodeValue(me->curTimestep, description);
+#undef decodeValue
+
+ if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+ if(me->super.isAdvanced) fetchVariableInfo(me);
+
+ return me;
+
+closeStream:
+ streamClose(me->streamId);
+freePath:
+ Free(me->path);
+destructSuper:
+ baseIterDestruct(&me->super);
+ Free(me);
+fail:
+ return NULL;
}
-static enum cdiApplyRet
-findModelByName(int resID, void *res, void *data)
+static int advance(CdiFallbackIterator *me)
{
- model_t *modelptr = (model_t*) res;
- struct modelLoc *ret = (struct modelLoc*) data;
- int instID = ret->instID, modelgribID = ret->modelgribID;
- const char *name = ret->name;
- if (modelptr->used
- && (instID == -1 || modelptr->instID == instID)
- && (modelgribID == 0 || modelptr->modelgribID == modelgribID)
- && modelptr->name)
+ me->curLevel++;
+ if(me->curLevel >= me->curLevelCount)
{
- const char *p = name, *q = modelptr->name;
- while (*p != '\0' && *p == *q)
- ++p, ++q;
- if (*p == '\0' || *q == '\0')
+ me->curLevel = 0;
+ me->curSubtype++;
+ if(me->curSubtype >= me->curSubtypeCount)
{
- ret->resID = resID;
- return CDI_APPLY_STOP;
+ me->curSubtype = 0;
+ me->curVariable++;
+ if(me->curVariable >= me->variableCount)
+ {
+ me->curVariable = 0;
+ me->curTimestep++;
+ if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
+ }
}
}
- return CDI_APPLY_GO_ON;
+ return CDI_NOERR;
}
-int modelInq(int instID, int modelgribID, const char *name)
+int cdiFallbackIterator_nextField(CdiIterator *super)
{
- modelInit ();
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ int result = advance(me);
+ if(result) return result;
- struct modelLoc searchState = { .name = name, .instID = instID,
- .modelgribID = modelgribID,
- .resID = UNDEFID };
- if (name && *name)
- cdiResHFilterApply(&modelOps, findModelByName, &searchState);
- else
- cdiResHFilterApply(&modelOps, findModelByID, &searchState);
- return searchState.resID;
+ if(!me->curLevel && !me->curSubtype) fetchVariableInfo(me); //Check whether we are processing a new variable/timestep and fetch the information that may have changed in this case.
+ return CDI_NOERR;
}
-
-int modelDef(int instID, int modelgribID, const char *name)
+char *cdiFallbackIterator_inqTime(CdiIterator *super, CdiTimeType timeType)
{
- model_t *modelptr;
-
- modelInit ();
-
- modelptr = modelNewEntry(CDI_UNDEFID, instID, modelgribID, name);
-
- return modelptr->self;
-}
+ CdiFallbackIterator *me = (CdiFallbackIterator *)(void *)super;
+ //retrieve the time information
+ int taxisId = vlistInqTaxis(me->vlistId);
+ int date = 0, time = 0;
+ switch(timeType)
+ {
+ case kCdiTimeType_referenceTime:
+ date = taxisInqRdate(taxisId);
+ time = taxisInqRtime(taxisId);
+ break;
-int modelInqInstitut(int modelID)
-{
- model_t *modelptr = NULL;
+ case kCdiTimeType_startTime:
+ date = taxisInqVdate(taxisId);
+ time = taxisInqVtime(taxisId);
+ break;
- modelInit ();
+ case kCdiTimeType_endTime:
+ return NULL; //The stream interface does not export the start/end times of statistical fields, so we treat all data as point of time data, returning the validity time as the start time.
- if ( modelID != UNDEFID )
- modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+ default:
+ assert(0 && "internal error, please report this bug");
+ }
- return modelptr ? modelptr->instID : UNDEFID;
+ //decode the time information and reencode it into an ISO-compliant string
+ int year, month, day, hour, minute, second;
+ cdiDecodeDate(date, &year, &month, &day);
+ cdiDecodeTime(time, &hour, &minute, &second);
+ char *result
+ = (char *) Malloc( 4+1 +2+1 +2+1 +2+1 +2+1 +2+4+1);
+ sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.000", year, month, day, hour, minute, second);
+ return result;
}
-
-int modelInqGribID(int modelID)
+int cdiFallbackIterator_levelType(CdiIterator *super, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
{
- model_t *modelptr = NULL;
-
- modelInit ();
-
- if ( modelID != UNDEFID )
- modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
-
- return modelptr ? modelptr->modelgribID : UNDEFID;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+ (void)levelSelector;
+#define copyString(outPointer, function) do \
+ { \
+ if(outPointer) \
+ { \
+ char tempBuffer[CDI_MAX_NAME]; \
+ function(zaxisId, tempBuffer); \
+ *outPointer = strdup(tempBuffer); \
+ } \
+ } \
+ while(0)
+ copyString(outName, zaxisInqName); //FIXME: zaxisInqName is unsafe.
+ copyString(outLongName, zaxisInqLongname); //FIXME: zaxisInqLongname is unsafe.
+ copyString(outStdName, zaxisInqStdname); //FIXME: zaxisInqStdname is unsafe.
+ copyString(outUnit, zaxisInqUnits); //FIXME: zaxisInqUnits is unsafe.
+#undef copyString
+ return zaxisInqLtype(zaxisId);
}
-
-const char *modelInqNamePtr(int modelID)
+int cdiFallbackIterator_level(CdiIterator *super, int levelSelector, double *outValue1, double *outValue2)
{
- model_t *modelptr = NULL;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
- modelInit ();
+ //handle NULL pointers once and for all
+ double trash;
+ if(!outValue1) outValue1 = &trash;
+ if(!outValue2) outValue2 = &trash;
- if ( modelID != UNDEFID )
- modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+ //get the level value
+ if(levelSelector)
+ {
+ *outValue1 = (zaxisInqLbounds(zaxisId, NULL))
+ ? zaxisInqLbound(zaxisId, me->curLevel)
+ : zaxisInqLevel(zaxisId, me->curLevel);
+ }
+ else
+ {
+ *outValue1 = (zaxisInqUbounds(zaxisId, NULL))
+ ? zaxisInqUbound(zaxisId, me->curLevel)
+ : zaxisInqLevel(zaxisId, me->curLevel);
+ }
+ *outValue2 = 0.0;
- return modelptr ? modelptr->name : NULL;
+ //if this is a hybrid zaxis, lookup the coordinates in the vertical coordinate table
+ ssize_t intLevel = (ssize_t)(2**outValue1);
+ if(0 <= intLevel && intLevel < zaxisInqVctSize(zaxisId) - 1)
+ {
+ const double *coordinateTable = zaxisInqVctPtr(zaxisId);
+ *outValue1 = coordinateTable[intLevel];
+ *outValue2 = coordinateTable[intLevel + 1];
+ }
+ return CDI_NOERR;
}
-
-static int
-modelCompareP(void *modelptr1, void *modelptr2)
+int cdiFallbackIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
{
- model_t *model1 = (model_t *)modelptr1, *model2 = (model_t *)modelptr2;
- int diff = (namespaceResHDecode(model1->instID).idx
- != namespaceResHDecode(model2->instID).idx)
- | (model1->modelgribID != model2->modelgribID)
- | (strcmp(model1->name, model2->name) != 0);
- return diff;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+ if(zaxisInqLtype(zaxisId) != ZAXIS_HYBRID) return CDI_EINVAL;
+ if(outVgridNumber) *outVgridNumber = zaxisInqNumber(zaxisId);
+ if(outLevelCount) *outLevelCount = zaxisInqNlevRef(zaxisId);
+ if(outUuid) zaxisInqUUID(zaxisId, outUuid);
+ return CDI_NOERR;
}
-
-void modelDestroyP ( void * modelptr )
+int cdiFallbackIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
{
- model_t *mp = (model_t*) modelptr;
- if (mp->name)
- Free(mp->name);
- Free(mp);
-}
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+#ifndef __cplusplus
+ if(!outTileIndex) outTileIndex = &(int){0};
+ if(!outTileAttribute) outTileAttribute = &(int){0};
+#else
+ int dummy = 0;
+ if(!outTileIndex) outTileIndex = &dummy;
+ if(!outTileAttribute) outTileAttribute = &dummy;
+#endif
+ int error = CDI_NOERR;
+ if(me->subtypeId == CDI_UNDEFID) //must not call subtypeInqAttribute() with an invalid subtype ID, because it would abort the program instead of returning an error
+ {
+ error = CDI_EINVAL;
+ }
+ else
+ {
+ if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileIndex", outTileIndex)) error = CDI_EINVAL;
+ if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileAttribute", outTileAttribute)) error = CDI_EINVAL;
+ }
+ if(error) *outTileIndex = *outTileAttribute = -1; //Guarantee defined values in case of an error.
+ return error;
+}
-void modelPrintP ( void * modelptr, FILE * fp )
+int cdiFallbackIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
{
- model_t *mp = (model_t*) modelptr;
-
- if ( !mp ) return;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+#ifndef __cplusplus
+ if(!outTileCount) outTileCount = &(int){0};
+ if(!outTileAttributeCount) outTileAttributeCount = &(int){0};
+#else
+ int temp = 0;
+ if(!outTileCount) outTileCount = &temp;
+ if(!outTileAttributeCount) outTileAttributeCount = &temp;
+#endif
- fprintf ( fp, "#\n");
- fprintf ( fp, "# modelID %d\n", mp->self);
- fprintf ( fp, "#\n");
- fprintf ( fp, "self = %d\n", mp->self );
- fprintf ( fp, "used = %d\n", mp->used );
- fprintf ( fp, "instID = %d\n", mp->instID );
- fprintf ( fp, "modelgribID = %d\n", mp->modelgribID );
- fprintf ( fp, "name = %s\n", mp->name ? mp->name : "NN" );
+ int error = CDI_NOERR;
+ if(me->subtypeId == CDI_UNDEFID) //must not call subtypeInqAttribute() with an invalid subtype ID, because it would abort the program instead of returning an error
+ {
+ error = CDI_EINVAL;
+ }
+ else
+ {
+ if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTiles", outTileCount)) error = CDI_EINVAL;
+ if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTileAttributes", outTileAttributeCount)) error = CDI_EINVAL;
+ }
+ if(error) *outTileCount = *outTileAttributeCount = -1; //Guarantee defined values in case of an error.
+ return CDI_NOERR;
}
-
-static int
-modelTxCode ( void )
+char *cdiFallbackIterator_copyVariableName(CdiIterator *super)
{
- return MODEL;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ return vlistCopyVarName(me->vlistId, me->curVariable);
}
-enum {
- model_nints = 4,
-};
-
-
-static int modelGetSizeP(void * modelptr, void *context)
+void cdiFallbackIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
{
- model_t *p = (model_t*)modelptr;
- size_t txsize = (size_t)serializeGetSize(model_nints, DATATYPE_INT, context)
- + (size_t)serializeGetSize(p->name?(int)strlen(p->name) + 1:0, DATATYPE_TXT, context);
- xassert(txsize <= INT_MAX);
- return (int)txsize;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ size_t missingValues = 0;
+ streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+ if(nmiss) *nmiss = (size_t)missingValues;
}
-
-static void modelPackP(void * modelptr, void * buf, int size, int *position, void *context)
+void cdiFallbackIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
{
- model_t *p = (model_t*) modelptr;
- int tempbuf[model_nints];
- tempbuf[0] = p->self;
- tempbuf[1] = p->instID;
- tempbuf[2] = p->modelgribID;
- tempbuf[3] = p->name ? (int)strlen(p->name) + 1 : 0;
- serializePack(tempbuf, model_nints, DATATYPE_INT, buf, size, position, context);
- if (p->name)
- serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ size_t missingValues = 0;
+ streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+ if(nmiss) *nmiss = (size_t)missingValues;
}
-int
-modelUnpack(void *buf, int size, int *position, int originNamespace, void *context,
- int force_id)
+void cdiFallbackIterator_delete(CdiIterator *super)
{
- int tempbuf[model_nints];
- char *name;
- serializeUnpack(buf, size, position, tempbuf, model_nints, DATATYPE_INT, context);
- if (tempbuf[3] != 0)
- {
- name = (char *) Malloc((size_t)tempbuf[3]);
- serializeUnpack(buf, size, position,
- name, tempbuf[3], DATATYPE_TXT, context);
- }
- else
- {
- name = (char*)"";
- }
- int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
- model_t *mp = modelNewEntry(force_id?targetID:CDI_UNDEFID,
- namespaceAdaptKey(tempbuf[1], originNamespace),
- tempbuf[2], name);
- if (tempbuf[3] != 0)
- Free(name);
- xassert(!force_id
- || (mp->self == namespaceAdaptKey(tempbuf[0], originNamespace)));
- reshSetStatus(mp->self, &modelOps,
- reshGetStatus(mp->self, &modelOps) & ~RESH_SYNC_BIT);
- return mp->self;
+ CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
+ cdiFallbackIterator_condestruct(me, NULL, 0);
}
/*
@@ -33330,1248 +32463,1499 @@ modelUnpack(void *buf, int size, int *position, int originNamespace, void *conte
* require-trailing-newline: t
* End:
*/
-#if defined (HAVE_CONFIG_H)
-#endif
+#ifndef _STREAM_GRB_H
+#define _STREAM_GRB_H
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
-#endif
+static inline bool gribbyte_get_bit(int number, int bit) { return (bool)((number >> (8-bit)) & 1); }
+static inline void gribbyte_set_bit(int *number, int bit) { *number |= 1 << (8-bit); }
+static inline void gribbyte_clear_bit(int *number, int bit) { *number &= ~(1 << (8-bit)); }
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
+int grbBitsPerValue(int datatype);
+int grbInqContents(stream_t *streamptr);
+int grbInqTimestep(stream_t *streamptr, int tsID);
-static unsigned nNamespaces = 1;
-static int activeNamespace = 0;
+int grbInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void grbDefRecord(stream_t *streamptr);
+void grb_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss);
+void grb_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss);
+void grbCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-#ifdef HAVE_LIBNETCDF
-#define CDI_NETCDF_SWITCHES \
- { .func = (void (*)()) nc__create }, \
- { .func = (void (*)()) cdf_def_var_serial }, \
- { .func = (void (*)()) cdfDefTimestep }, \
- { .func = (void (*)()) cdfDefVars }
+void grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss);
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss);
-#else
-#define CDI_NETCDF_SWITCHES
-#endif
+void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss);
+void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss);
-#define defaultSwitches { \
- { .func = (void (*)()) cdiAbortC_serial }, \
- { .func = (void (*)()) cdiWarning }, \
- { .func = (void (*)()) serializeGetSizeInCore }, \
- { .func = (void (*)()) serializePackInCore }, \
- { .func = (void (*)()) serializeUnpackInCore }, \
- { .func = (void (*)()) fileOpen_serial }, \
- { .func = (void (*)()) fileWrite }, \
- { .func = (void (*)()) fileClose_serial }, \
- { .func = (void (*)()) cdiStreamOpenDefaultDelegate }, \
- { .func = (void (*)()) cdiStreamDefVlist_ }, \
- { .func = (void (*)()) cdiStreamSetupVlist_ }, \
- { .func = (void (*)()) cdiStreamWriteVar_ }, \
- { .func = (void (*)()) cdiStreamWriteVarChunk_ }, \
- { .func = (void (*)()) 0 }, \
- { .func = (void (*)()) 0 }, \
- { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
- { .func = (void (*)()) cdiStreamDefTimestep_ }, \
- { .func = (void (*)()) cdiStreamSync_ }, \
- CDI_NETCDF_SWITCHES \
- }
+int grib1ltypeToZaxisType(int grib_ltype);
+int grib2ltypeToZaxisType(int grib_ltype);
-#if defined (SX) || defined (__cplusplus)
-static const union namespaceSwitchValue
- defaultSwitches_[NUM_NAMESPACE_SWITCH] = defaultSwitches;
-#endif
+int zaxisTypeToGrib1ltype(int zaxistype);
+int zaxisTypeToGrib2ltype(int zaxistype);
-enum namespaceStatus {
- NAMESPACE_STATUS_INUSE,
- NAMESPACE_STATUS_UNUSED,
+struct cdiGribParamChange
+{
+ int code, ltype, lev;
+ bool active;
};
-static struct Namespace
+struct cdiGribModeChange
{
- enum namespaceStatus resStage;
- union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
-} initialNamespace = {
- .resStage = NAMESPACE_STATUS_INUSE,
- .switches = defaultSwitches
+ bool mode;
+ bool active;
+};
+
+struct cdiGribScanModeChange
+{
+ int value;
+ bool active;
};
-static struct Namespace *namespaces = &initialNamespace;
+extern struct cdiGribParamChange cdiGribChangeParameterID;
+extern struct cdiGribModeChange cdiGribChangeModeUvRelativeToGrid;
+extern struct cdiGribScanModeChange cdiGribDataScanningMode;
+
+// Used in CDO
+void streamGrbChangeParameterIdentification(int code, int ltype, int lev);
+void streamGrbChangeModeUvRelativeToGrid(int mode);
+void streamGrbDefDataScanningMode(int scanmode);
+int streamGrbInqDataScanningMode(void);
+
+#endif /* _STREAM_GRB_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _ZAXIS_H
+#define _ZAXIS_H
+
+
+typedef struct {
+ double value;
+ bool defined;
+}
+zkey_double_t;
+
+typedef struct {
+ char dimname[CDI_MAX_NAME];
+ char vdimname[CDI_MAX_NAME];
+ char name[CDI_MAX_NAME];
+ char longname[CDI_MAX_NAME];
+ char stdname[CDI_MAX_NAME];
+ char units[CDI_MAX_NAME];
+ char psname[CDI_MAX_NAME];
+ char p0name[CDI_MAX_NAME];
+ zkey_double_t p0value;
+ double *vals;
+ char **cvals;
+ int clength;
+ double *lbounds;
+ double *ubounds;
+ double *weights;
+ int self;
+ int datatype;
+ int scalar;
+ int type;
+ int ltype; /* GRIB level type */
+ int ltype2;
+ int size;
+ int direction;
+ int vctsize;
+ unsigned positive;
+ double *vct;
+ int number; /* Reference number to a generalized Z-axis */
+ int nhlev;
+ unsigned char uuid[CDI_UUID_SIZE];
+ cdi_atts_t atts;
+}
+zaxis_t;
+
-static unsigned namespacesSize = 1;
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit); //The returned const char* point to static storage. Don't free or modify them.
-#if defined (HAVE_LIBPTHREAD)
-# include <pthread.h>
+unsigned cdiZaxisCount(void);
-static pthread_once_t namespaceOnce = PTHREAD_ONCE_INIT;
-static pthread_mutex_t namespaceMutex;
+zaxis_t *zaxis_to_pointer(int zaxisID);
-static void
-namespaceInitialize(void)
-{
- pthread_mutexattr_t ma;
- pthread_mutexattr_init(&ma);
- pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&namespaceMutex, &ma);
- pthread_mutexattr_destroy(&ma);
-}
+void cdiZaxisGetIndexList(unsigned numIDs, int *IDs);
-# define NAMESPACE_LOCK() pthread_mutex_lock(&namespaceMutex)
-# define NAMESPACE_UNLOCK() pthread_mutex_unlock(&namespaceMutex)
-# define NAMESPACE_INIT() pthread_once(&namespaceOnce, \
- namespaceInitialize)
+void
+zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
+ int * unpackBufferPos, int originNamespace, void *context,
+ int force_id);
+void zaxisDefLtype2(int zaxisID, int ltype2);
-#else
+const resOps *getZaxisOps(void);
-# define NAMESPACE_INIT() do { } while (0)
-# define NAMESPACE_LOCK()
-# define NAMESPACE_UNLOCK()
+const char *zaxisInqNamePtr(int zaxisID);
+
+const double *zaxisInqLevelsPtr(int zaxisID);
+char **zaxisInqCValsPtr(int zaxisID);
+
+void zaxisResize(int zaxisID, int size);
#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
-enum {
- intbits = sizeof(int) * CHAR_BIT,
- nspbits = 4,
- idxbits = intbits - nspbits,
- nspmask = (int)((( (unsigned)1 << nspbits ) - 1) << idxbits),
- idxmask = ( 1 << idxbits ) - 1,
-};
-enum {
- NUM_NAMESPACES = 1 << nspbits,
- NUM_IDX = 1 << idxbits,
-};
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
-int namespaceIdxEncode ( namespaceTuple_t tin )
+#ifdef HAVE_LIBGRIB_API
+
+struct CdiGribIterator {
+ CdiIterator super;
+
+ CdiInputFile *file;
+ off_t fileOffset;
+ unsigned char *gribBuffer;
+ size_t bufferSize, curRecordSize;
+ grib_handle *gribHandle;
+};
+
+CdiIterator *cdiGribIterator_getSuper(CdiGribIterator *me)
{
- xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
- return ( tin.nsp << idxbits ) + tin.idx;
+ return &me->super;
}
-int namespaceIdxEncode2 ( int nsp, int idx )
+//Since the error handling in constructors is usually very closely related to the workings of a destructor,
+//this function combines both functions in one, using a centralized exit.
+//The mode of operation depends on whether me is a NULL pointer on entry:
+//If it is NULL, a new object is allocated and constructed, which is returned if construction is successful.
+//If a non-NULL pointer is passed in, the object is destructed and NULL is returned. In this case, the other arguments are ignored.
+static CdiGribIterator *cdiGribIterator_condestruct(CdiGribIterator *me, const char *path, int filetype)
{
- xassert(nsp < NUM_NAMESPACES && idx < NUM_IDX);
- return ( nsp << idxbits ) + idx;
-}
+#define super() (&me->super)
+ if(me) goto destruct;
+ me = (CdiGribIterator *) Malloc(sizeof(*me));
+ baseIterConstruct(super(), filetype);
+
+ me->file = cdiInputFile_make(path);
+ if(!me->file) goto destructSuper;
+ me->fileOffset = 0;
+ me->gribHandle = NULL;
+ me->gribBuffer = NULL;
+ me->bufferSize = me->curRecordSize = 0;
+ me->super.gridId = CDI_UNDEFID;
+ goto success;
-namespaceTuple_t namespaceResHDecode ( int resH )
-{
- namespaceTuple_t tin;
+// ^ constructor code ^
+// | |
+// v destructor/error-cleanup code v
- tin.idx = resH & idxmask;
- tin.nsp = (int)(((unsigned)( resH & nspmask )) >> idxbits);
+destruct:
+ if(me->super.gridId != CDI_UNDEFID) gridDestroy(me->super.gridId);
+ if(me->gribHandle) grib_handle_delete((struct grib_handle *)me->gribHandle);
+ Free(me->gribBuffer);
+ cdiRefObject_release(&me->file->super);
+destructSuper:
+ baseIterDestruct(super());
+ Free(me);
+ me = NULL;
- return tin;
+success:
+ return me;
+#undef super
}
-int
-namespaceNew()
+CdiIterator *cdiGribIterator_new(const char *path, int filetype)
{
- int newNamespaceID = -1;
- NAMESPACE_INIT();
- NAMESPACE_LOCK();
- if (namespacesSize > nNamespaces)
- {
- /* namespace is already available and only needs reinitialization */
- for (unsigned i = 0; i < namespacesSize; ++i)
- if (namespaces[i].resStage == NAMESPACE_STATUS_UNUSED)
- {
- newNamespaceID = (int)i;
- break;
- }
- }
- else if (namespacesSize == 1)
+ return &cdiGribIterator_condestruct(NULL, path, filetype)->super;
+}
+
+CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *super)
+{
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+
+ //Allocate memory and copy data. (operations that may fail)
+ CdiGribIterator *result = (struct CdiGribIterator *) Malloc(sizeof(*result));
+ if(!result) goto fail;
+
+ result->file = me->file;
+ result->fileOffset = me->fileOffset;
+ result->gribBuffer = NULL;
+ result->bufferSize = me->bufferSize;
+ result->curRecordSize = me->curRecordSize;
+ result->gribHandle = NULL;
+
+ if(me->gribBuffer)
{
- /* make room for additional namespace */
- struct Namespace *newNameSpaces
- = (struct Namespace *) Malloc(((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
- memcpy(newNameSpaces, namespaces, sizeof (namespaces[0]));
- namespaces = newNameSpaces;
- ++namespacesSize;
- newNamespaceID = 1;
+ result->gribBuffer = (unsigned char *) Malloc(me->bufferSize);
+ if(!result->gribBuffer) goto freeResult;
+ memcpy(result->gribBuffer, me->gribBuffer, me->curRecordSize);
}
- else if (namespacesSize < NUM_NAMESPACES)
+ if(me->gribHandle)
{
- /* make room for additional namespace */
- newNamespaceID = (int)namespacesSize;
- namespaces
- = (struct Namespace *) Realloc(namespaces, ((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
- ++namespacesSize;
+ result->gribHandle = grib_handle_new_from_message(NULL, result->gribBuffer, result->curRecordSize);
+ if(!result->gribHandle) goto freeBuffer;
}
- else /* implicit: namespacesSize >= NUM_NAMESPACES */
+ if(super->gridId != CDI_UNDEFID)
{
- NAMESPACE_UNLOCK();
- return -1;
+ result->super.gridId = gridDuplicate(super->gridId);
+ if(result->super.gridId == CDI_UNDEFID) goto deleteGribHandle;
}
- xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
- ++nNamespaces;
- namespaces[newNamespaceID].resStage = NAMESPACE_STATUS_INUSE;
-#if defined (SX) || defined (__cplusplus)
- memcpy(namespaces[newNamespaceID].switches,
- defaultSwitches_,
- sizeof (namespaces[newNamespaceID].switches));
-#else
- memcpy(namespaces[newNamespaceID].switches,
- (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
- sizeof (namespaces[newNamespaceID].switches));
-#endif
- reshListCreate(newNamespaceID);
- NAMESPACE_UNLOCK();
- return newNamespaceID;
-}
-
-void
-namespaceDelete(int namespaceID)
-{
- NAMESPACE_INIT();
- NAMESPACE_LOCK();
- xassert(namespaceID >= 0 && (unsigned)namespaceID < namespacesSize
- && nNamespaces);
- reshListDestruct(namespaceID);
- namespaces[namespaceID].resStage = NAMESPACE_STATUS_UNUSED;
- --nNamespaces;
- NAMESPACE_UNLOCK();
-}
-
-int namespaceGetNumber ()
-{
- return (int)nNamespaces;
-}
+ //Finish construction. (operations that cannot fail)
+ baseIterConstruct(&result->super, super->filetype);
+ result->super.datatype = super->datatype;
+ result->super.timesteptype = super->timesteptype;
+ result->super.param = super->param;
+ cdiRefObject_retain(&result->file->super);
-void namespaceSetActive ( int nId )
-{
- xassert((unsigned)nId < namespacesSize
- && namespaces[nId].resStage != NAMESPACE_STATUS_UNUSED);
- activeNamespace = nId;
-}
-
+ return result;
-int namespaceGetActive ()
-{
- return activeNamespace;
+ //Error handling.
+deleteGribHandle:
+ if(result->gribHandle) grib_handle_delete(result->gribHandle);
+freeBuffer:
+ Free(result->gribBuffer);
+freeResult:
+ Free(result);
+fail:
+ return NULL;
}
-int namespaceAdaptKey ( int originResH, int originNamespace )
+char *cdiGribIterator_serialize(CdiIterator *super)
{
- namespaceTuple_t tin;
- int nsp;
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
- if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
+ const char *path = cdiInputFile_getPath(me->file);
+ char *escapedPath = cdiEscapeSpaces(path);
+ char *result = (char *) Malloc(strlen(escapedPath) + 3 * sizeof(int) * CHAR_BIT/8);
+ sprintf(result, "%s %zu", escapedPath, (size_t)me->fileOffset);
+ Free(escapedPath);
+ return result;
+}
- tin.idx = originResH & idxmask;
- tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
- xassert ( tin.nsp == originNamespace );
+CdiGribIterator *cdiGribIterator_deserialize(const char *description)
+{
+ char *path;
+ CdiGribIterator *me = (CdiGribIterator *) Malloc(sizeof(*me));
+ if(!me) goto fail;
- nsp = namespaceGetActive ();
+ description = baseIter_constructFromString(&me->super, description);
- return namespaceIdxEncode2 ( nsp, tin.idx );
-}
+ while(*description == ' ') description++;
+ path = cdiUnescapeSpaces(description, &description);
+ if(!path) goto destructSuper;
+ me->file = cdiInputFile_make(path);
+ Free(path);
+ if(!me->file) goto destructSuper;
-int namespaceAdaptKey2 ( int originResH )
-{
- namespaceTuple_t tin;
- int nsp;
+ {
+ const char *savedStart = description;
+ char *description_ = (char *)description;
+ long long decodedOffset = strtoll(description, &description_, 0);
+ description = description_;
+ me->fileOffset = (off_t)decodedOffset;
+ if(savedStart == description) goto closeFile;
+ if((unsigned long long)decodedOffset > (unsigned long long)me->fileOffset) goto closeFile;
+ }
- if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
+ me->gribBuffer = NULL;
+ me->bufferSize = me->curRecordSize = 0;
+ me->gribHandle = NULL;
+ me->super.gridId = CDI_UNDEFID;
+ if(me->super.isAdvanced && cdiGribIterator_nextField(&me->super)) goto closeFile;
- tin.idx = originResH & idxmask;
- tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
+ return me;
- nsp = namespaceGetActive ();
- return namespaceIdxEncode2 ( nsp, tin.idx );
+closeFile:
+ cdiRefObject_release(&me->file->super);
+destructSuper:
+ baseIterDestruct(&me->super);
+ Free(me);
+fail:
+ return NULL;
}
-void namespaceSwitchSet(enum namespaceSwitch sw, union namespaceSwitchValue value)
+static void cdiGribIterator_ensureBuffer(CdiGribIterator *me, size_t requiredSize)
{
- xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
- int nsp = namespaceGetActive();
- namespaces[nsp].switches[sw] = value;
+ if(me->bufferSize < requiredSize)
+ {
+ me->bufferSize *= 2;
+ if(me->bufferSize < requiredSize) me->bufferSize = requiredSize;
+ me->gribBuffer = (unsigned char *) Realloc(me->gribBuffer, me->bufferSize);
+ }
}
-union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
+static bool isGrib1DualLevel(int levelType)
{
- xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
- int nsp = namespaceGetActive();
- return namespaces[nsp].switches[sw];
+ switch(levelType)
+ {
+ case 101: case 104: case 106: case 108: case 110: case 112:
+ case 114: case 116: case 120: case 121: case 128: case 141: //This is the complete list after grib_api-1.12.3/definitions/grib1/sections.1.def:106-117:, the code in cdi/src/stream_gribapi.c:grib1GetLevel() seems to be incomplete.
+ return true;
+ default:
+ return false;
+ }
}
-void cdiReset(void)
+static const unsigned char *positionOfGribMarker(const unsigned char *data, size_t size)
{
- NAMESPACE_INIT();
- NAMESPACE_LOCK();
- for (unsigned namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
- if (namespaces[namespaceID].resStage != NAMESPACE_STATUS_UNUSED)
- namespaceDelete((int)namespaceID);
- if (namespaces != &initialNamespace)
+ for(const unsigned char *currentPosition = data, *end = data + size; currentPosition < end; currentPosition++)
{
- Free(namespaces);
- namespaces = &initialNamespace;
- namespaces[0].resStage = NAMESPACE_STATUS_UNUSED;
+ currentPosition = (unsigned char *)memchr(currentPosition, 'G', size - (size_t)(currentPosition - data) - 3); //-3 to ensure that we don't overrun the buffer during the strncmp() call.
+ if(!currentPosition) return NULL;
+ if(!strncmp((const char*)currentPosition, "GRIB", 4)) return currentPosition;
}
- namespacesSize = 1;
- nNamespaces = 0;
- NAMESPACE_UNLOCK();
+ return NULL;
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-
-
-void cdiRefObject_construct(CdiReferencedObject* me)
+//This clobbers the contents of the gribBuffer!
+//Returns the file offset of the next 'GRIB' marker.
+static ssize_t scanToGribMarker(CdiGribIterator *me)
{
- me->destructor = cdiRefObject_destruct;
- me->refCount = 1;
-}
+ cdiGribIterator_ensureBuffer(me, 8*1024);
+ const size_t kMaxScanSize = 16*1024*1024;
+ for(size_t scannedBytes = 0, scanSize; scannedBytes < kMaxScanSize; scannedBytes += scanSize)
+ {
+ //Load a chunk of data into our buffer.
+ scanSize = me->bufferSize;
+ if(scannedBytes + scanSize > kMaxScanSize) scanSize = kMaxScanSize - scannedBytes;
+ assert(scanSize <= me->bufferSize);
+ int status = cdiInputFile_read(me->file, me->fileOffset + (off_t)scannedBytes, scanSize, &scanSize, me->gribBuffer);
+ if(status != CDI_NOERR && status != CDI_EEOF) return -1;
-void cdiRefObject_retain(CdiReferencedObject* me)
-{
- size_t oldCount = me->refCount++;
- xassert(oldCount && "A reference counted object was used after it was destructed.");
-}
+ const unsigned char *startPosition = positionOfGribMarker(me->gribBuffer, scanSize);
+ if(startPosition)
+ {
+ return (ssize_t)(me->fileOffset + (off_t)scannedBytes + (off_t)(startPosition - me->gribBuffer));
+ }
-void cdiRefObject_release(CdiReferencedObject* me)
-{
- size_t oldCount = me->refCount--;
- xassert(oldCount && "A reference counted object was released too often.");
- if(oldCount == 1)
- {
- me->destructor(me);
- Free(me);
+ //Get the offset for the next iteration if there is a next iteration.
+ scanSize -= 3; //so that we won't miss a 'GRIB' sequence that happens to be cut off
+ scanSize &= ~(size_t)0xf; //make 16 bytes aligned
+ if((ssize_t)scanSize <= 0) return -1; //ensure that we make progress
}
+ return -1;
}
-void cdiRefObject_destruct(CdiReferencedObject* me)
+static unsigned decode24(void *beData)
{
- (void)me;
- /* Empty for now, but that's no reason not to call it! */
+ unsigned char *bytes = (unsigned char *)beData;
+ return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-
-#if defined (HAVE_EXECINFO_H)
-#include <execinfo.h>
-#endif
-
-static
-void show_stackframe()
+static uint64_t decode64(void *beData)
{
-#if defined HAVE_EXECINFO_H && defined backtrace_size_t && defined HAVE_BACKTRACE
- void *trace[16];
- backtrace_size_t trace_size = backtrace(trace, 16);
- char **messages = backtrace_symbols(trace, trace_size);
-
- fprintf(stderr, "[bt] Execution path:\n");
- if ( messages ) {
- for ( backtrace_size_t i = 0; i < trace_size; ++i )
- fprintf(stderr, "[bt] %s\n", messages[i]);
- free(messages);
- }
-#endif
+ unsigned char *bytes = (unsigned char *)beData;
+ uint64_t result = 0;
+ for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
+ return result;
}
+//Determine the size of the GRIB record that begins at the given file offset.
+static int getRecordSize(CdiGribIterator *me, off_t gribFileOffset, size_t *outRecordSize)
+{
+ char buffer[16];
+ size_t readSize;
+ int status = cdiInputFile_read(me->file, gribFileOffset, sizeof(buffer), &readSize, buffer);
+ if(status != CDI_NOERR && status != CDI_EEOF) return status;
+ if(readSize < sizeof(buffer)) return CDI_EEOF;
+ *outRecordSize = 0;
+ switch(buffer[7])
+ {
+ case 1:
+ *outRecordSize = decode24(&buffer[4]);
+ if(*outRecordSize & (1 << 23))
+ {
+ *outRecordSize = 120*(*outRecordSize & ((1 << 23) - 1)); //Rescaling for long records.
+ //The corresponding code in cgribexlib.c:4532-4570: is much more complicated
+ //due to the fact that it subtracts the padding bytes that are inserted after section 4.
+ //However, we are only interested in the total size of data we need to read here,
+ //so we can ignore the presence of some padding bytes.
+ }
+ return CDI_NOERR;
-enum { MIN_LIST_SIZE = 128 };
-
-static void listInitialize(void);
+ case 2:
+ *outRecordSize = decode64(&buffer[8]);
+ return CDI_NOERR;
-typedef struct listElem {
- union
- {
- /* free-list management data */
- struct
- {
- int next, prev;
- } free;
- /* holding an actual value */
- struct
- {
- const resOps *ops;
- void *val;//ptr
- } v;
- } res;
- int status;
-} listElem_t;
+ default:
+ return CDI_EUFTYPE;
+ }
+}
-struct resHList_t
+#if 0
+static void hexdump(void *data, size_t size)
{
- int size, freeHead, hasDefaultRes;
- listElem_t *resources;
-};
-
-static struct resHList_t *resHList;
+ unsigned char *charData = data;
+ for(size_t offset = 0; offset < size; )
+ {
+ printf("%016zx:", offset);
+ for(size_t i = 0; i < 64 && offset < size; i++, offset++)
+ {
+ if((i & 63) && !(i & 15)) printf(" |");
+ if((i & 15) && !(i & 3)) printf(" ");
+ printf(" %02x", charData[offset]);
+ }
+ printf("\n");
+ }
+}
+#endif
-static int resHListSize = 0;
+//Read a record into memory and wrap it in a grib_handle.
+//XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this [...]
+static int readMessage(CdiGribIterator *me)
+{
+ //Destroy the old grib_handle.
+ if(me->gribHandle) grib_handle_delete(me->gribHandle), me->gribHandle = NULL;
+ me->fileOffset += (off_t)me->curRecordSize;
-#if defined (HAVE_LIBPTHREAD)
-# include <pthread.h>
+ //Find the next record and determine its size.
+ ssize_t gribFileOffset = scanToGribMarker(me);
+ int result = CDI_EEOF;
+ if(gribFileOffset < 0) goto fail;
+ result = getRecordSize(me, gribFileOffset, &me->curRecordSize);
+ if(result) goto fail;
-static pthread_once_t listInitThread = PTHREAD_ONCE_INIT;
-static pthread_mutex_t listMutex;
+ //Load the whole record into our buffer and create a grib_handle for it.
+ cdiGribIterator_ensureBuffer(me, me->curRecordSize);
+ result = cdiInputFile_read(me->file, gribFileOffset, me->curRecordSize, NULL, me->gribBuffer);
+ if(result) goto fail;
+ me->gribHandle = grib_handle_new_from_message(NULL, me->gribBuffer, me->curRecordSize);
+ result = CDI_EUFSTRUCT;
+ if(!me->gribHandle) goto fail;
-# define LIST_LOCK() pthread_mutex_lock(&listMutex)
-# define LIST_UNLOCK() pthread_mutex_unlock(&listMutex)
-# define LIST_INIT(init0) do { \
- pthread_once(&listInitThread, listInitialize); \
- pthread_mutex_lock(&listMutex); \
- if ((init0) && (!resHList || !resHList[0].resources)) \
- reshListCreate(0); \
- pthread_mutex_unlock(&listMutex); \
- } while (0)
+ return CDI_NOERR;
+fail:
+ me->curRecordSize = 0; //This ensures that we won't jump to an uncontrolled file position if cdiGribIterator_nextField() is called another time after it has returned an error.
+ return result;
+}
+int cdiGribIterator_nextField(CdiIterator *super)
+{
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
-#else
+ if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
-static int listInit = 0;
+ //Get the next GRIB message into our buffer.
+ int result = readMessage(me);
+ if(result) return result;
-# define LIST_LOCK()
-# define LIST_UNLOCK()
-# define LIST_INIT(init0) do { \
- if ( !listInit ) \
- { \
- listInitialize(); \
- if ((init0) && (!resHList || !resHList[0].resources)) \
- reshListCreate(0); \
- listInit = 1; \
- } \
- } while(0)
+ //Get the metadata that's published as variables in the base class.
+ super->datatype = gribGetDatatype(me->gribHandle);
+ super->timesteptype = gribapiGetTsteptype(me->gribHandle);
+ cdiDecodeParam(gribapiGetParam(me->gribHandle), &super->param.number, &super->param.category, &super->param.discipline);
+ grid_t grid;
+ gribapiGetGrid(me->gribHandle, &grid);
+ super->gridId = gridGenerate(&grid);
-#endif
+ return CDI_NOERR;
+}
-/**************************************************************/
+char *cdiGribIterator_inqTime(CdiIterator *super, CdiTimeType timeType)
+{
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+ return gribMakeTimeString(me->gribHandle, timeType);
+}
-static void
-listInitResources(int nsp)
+int cdiGribIterator_levelType(CdiIterator *super, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
{
- xassert(nsp < resHListSize && nsp >= 0);
- int size = resHList[nsp].size = MIN_LIST_SIZE;
- xassert(resHList[nsp].resources == NULL);
- resHList[nsp].resources = (listElem_t*) Calloc(MIN_LIST_SIZE, sizeof(listElem_t));
- listElem_t *p = resHList[nsp].resources;
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
- for (int i = 0; i < size; i++ )
+ //First determine the zaxis type corresponding to the given level.
+ int zaxisType = ZAXIS_GENERIC;
+ if(gribEditionNumber(me->gribHandle) <= 1)
{
- p[i].res.free.next = i + 1;
- p[i].res.free.prev = i - 1;
- p[i].status = RESH_UNUSED;
+ int levelType = (int)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", 255);
+ if(levelSelector && !isGrib1DualLevel(levelType)) levelType = 255;
+ zaxisType = grib1ltypeToZaxisType(levelType);
+ }
+ else
+ {
+ int levelType = (int)gribGetLongDefault(me->gribHandle, levelSelector ? "typeOfSecondFixedSurface" : "typeOfFirstFixedSurface", 255);
+ zaxisType = grib2ltypeToZaxisType(levelType);
}
- p[size-1].res.free.next = -1;
- resHList[nsp].freeHead = 0;
- int oldNsp = namespaceGetActive();
- namespaceSetActive(nsp);
- instituteDefaultEntries();
- modelDefaultEntries();
- namespaceSetActive(oldNsp);
-}
+ //Then lookup the requested names.
+ const char *name, *longName, *stdName, *unit;
+ zaxisGetTypeDescription(zaxisType, NULL, &name, &longName, &stdName, &unit);
+ if(outName) *outName = strdup(name);
+ if(outLongName) *outLongName = strdup(longName);
+ if(outStdName) *outStdName = strdup(stdName);
+ if(outUnit) *outUnit = strdup(unit);
-static inline void
-reshListClearEntry(int i)
-{
- resHList[i].size = 0;
- resHList[i].resources = NULL;
- resHList[i].freeHead = -1;
+ return zaxisType;
}
-void
-reshListCreate(int namespaceID)
+static double logicalLevelValue2(long gribType, long storedValue, long power)
{
- LIST_INIT(namespaceID != 0);
- LIST_LOCK();
- if (resHListSize <= namespaceID)
+ double factor = 1;
+ assert(power >= 0);
+ while(power--) factor *= 10; //this is precise up to factor == 22.
+ switch(gribType)
{
- resHList = (struct resHList_t *) Realloc(resHList, (size_t)(namespaceID + 1) * sizeof (resHList[0]));
- for (int i = resHListSize; i <= namespaceID; ++i)
- reshListClearEntry(i);
- resHListSize = namespaceID + 1;
- }
- listInitResources(namespaceID);
- LIST_UNLOCK();
-}
+ case GRIB2_LTYPE_LANDDEPTH:
+ case GRIB2_LTYPE_ISOBARIC:
+ case GRIB2_LTYPE_SIGMA:
+ return (double)storedValue * (1000.0/factor); //The evaluation order allows the factors of ten to cancel out before rounding.
+ case 255:
+ return 0;
-/**************************************************************/
+ default:
+ return (double)storedValue/factor;
+ }
+}
-void
-reshListDestruct(int namespaceID)
+//The output values must be preinitialized, this function does not always write them.
+static int readLevel2(grib_handle *gribHandle, const char *levelTypeKey, const char *powerKey, const char *valueKey, double *outValue1, double *outValue2)
{
- LIST_LOCK();
- xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
- int callerNamespaceID = namespaceGetActive();
- namespaceSetActive(namespaceID);
- if (resHList[namespaceID].resources)
+ assert(levelTypeKey && powerKey && valueKey && outValue1 && outValue2);
+
+ long levelType = gribGetLongDefault(gribHandle, levelTypeKey, 255); //1 byte
+ switch(levelType)
{
- for ( int j = 0; j < resHList[namespaceID].size; j++ )
+ case 255: break;
+
+ case 105: case 113:
{
- listElem_t *listElem = resHList[namespaceID].resources + j;
- if (listElem->status & RESH_IN_USE_BIT)
- listElem->res.v.ops->valDestroy(listElem->res.v.val);
+ unsigned long value = (unsigned long)gribGetLongDefault(gribHandle, valueKey, 0);
+ unsigned long coordinateCount = (unsigned long)gribGetLongDefault(gribHandle, "numberOfCoordinatesValues", 0);
+ if(value >= coordinateCount/2)
+ {
+ Error("Invalid level coordinate: Level has the hybrid coordinate index %lu, but only %lu coordinate pairs are present.", value, coordinateCount/2);
+ return CDI_EUFSTRUCT;
+ }
+ int status;
+ //XXX: I'm not 100% sure about how the coordinate pairs are stored in the file.
+ // I'm assuming an array of pairs due to the example code in grib_api-1.12.3/examples/F90/set_pv.f90, but that may be wrong.
+ if((status = grib_get_double_element(gribHandle, "pv", (int)value*2 , outValue1))) return status;
+ if((status = grib_get_double_element(gribHandle, "pv", (int)value*2 + 1, outValue2))) return status;
+ break;
+ }
+
+ default:
+ {
+ long power = 255 & gribGetLongDefault(gribHandle, powerKey, 0); //1 byte
+ if(power == 255) power = 0;
+ long value = gribGetLongDefault(gribHandle, valueKey, 0); //4 bytes
+ *outValue1 = logicalLevelValue2(levelType, value, power);
}
- Free(resHList[namespaceID].resources);
- resHList[namespaceID].resources = NULL;
- reshListClearEntry(namespaceID);
}
- if (resHList[callerNamespaceID].resources)
- namespaceSetActive(callerNamespaceID);
- LIST_UNLOCK();
+ return CDI_NOERR;
}
-
-static void listDestroy ( void )
+int cdiGribIterator_level(CdiIterator *super, int levelSelector, double *outValue1, double *outValue2)
{
- LIST_LOCK();
- for (int i = resHListSize; i > 0; --i)
- if (resHList[i-1].resources)
- namespaceDelete(i-1);
- resHListSize = 0;
- Free(resHList);
- resHList = NULL;
- cdiReset();
- LIST_UNLOCK();
-}
-
-/**************************************************************/
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+ double trash;
+ if(!outValue1) outValue1 = &trash;
+ if(!outValue2) outValue2 = &trash;
+ *outValue1 = *outValue2 = 0;
-static
-void listInitialize ( void )
-{
-#if defined (HAVE_LIBPTHREAD)
- pthread_mutexattr_t ma;
- pthread_mutexattr_init(&ma);
- pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
- /* initialize global API mutex lock */
- pthread_mutex_init ( &listMutex, &ma);
- pthread_mutexattr_destroy(&ma);
-#endif
- /* file is special and has its own table, which needs to be
- * created, before we register the listDestroy exit handler */
- {
- int null_id;
- null_id = fileOpen_serial("/dev/null", "r");
- if (null_id != -1)
- fileClose_serial(null_id);
- }
- atexit ( listDestroy );
+ if(gribEditionNumber(me->gribHandle) > 1)
+ {
+ if(levelSelector)
+ {
+ return readLevel2(me->gribHandle, "typeOfFirstFixedSurface", "scaleFactorOfFirstFixedSurface", "scaledValueOfFirstFixedSurface", outValue1, outValue2);
+ }
+ else
+ {
+ return readLevel2(me->gribHandle, "typeOfSecondFixedSurface", "scaleFactorOfSecondFixedSurface", "scaledValueOfSecondFixedSurface", outValue1, outValue2);
+ }
+ }
+ else
+ {
+ long levelType = (uint8_t)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", -1); //1 byte
+ if(levelType == 255)
+ {}
+ else if(isGrib1DualLevel((int)levelType))
+ {
+ *outValue1 = (double)(gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0));
+ }
+ else if(levelType == 100)
+ {
+ *outValue1 = 100 * (double)(gribGetLongDefault(me->gribHandle, "level", 0)); //2 bytes
+ }
+ else
+ {
+ *outValue1 = (double)(gribGetLongDefault(me->gribHandle, "level", 0)); //2 bytes
+ }
+ }
+ return CDI_NOERR;
}
-/**************************************************************/
-
-static
-void listSizeExtend()
+int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
{
- int nsp = namespaceGetActive ();
- int oldSize = resHList[nsp].size;
- size_t newListSize = (size_t)oldSize + MIN_LIST_SIZE;
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
- resHList[nsp].resources = (listElem_t*) Realloc(resHList[nsp].resources,
- newListSize * sizeof(listElem_t));
-
- listElem_t *r = resHList[nsp].resources;
- for (size_t i = (size_t)oldSize; i < newListSize; ++i)
+ if(outVgridNumber)
{
- r[i].res.free.next = (int)i + 1;
- r[i].res.free.prev = (int)i - 1;
- r[i].status = RESH_UNUSED;
+ long temp;
+ if(grib_get_long(me->gribHandle, "numberOfVGridUsed", &temp)) return CDI_EINVAL;
+ *outVgridNumber = (int)temp;
+ }
+ if(outLevelCount)
+ {
+ long temp;
+ if(grib_get_long(me->gribHandle, "nlev", &temp)) return CDI_EINVAL;
+ *outLevelCount = (int)temp;
+ }
+ if(outUuid)
+ {
+ size_t size = CDI_UUID_SIZE;
+ if(grib_get_bytes(me->gribHandle, "uuidOfVGrid", outUuid, &size)) return CDI_EINVAL;
+ if(size != CDI_UUID_SIZE) return CDI_EUFSTRUCT;
}
- if (resHList[nsp].freeHead != -1)
- r[resHList[nsp].freeHead].res.free.prev = (int)newListSize - 1;
- r[newListSize-1].res.free.next = resHList[nsp].freeHead;
- r[oldSize].res.free.prev = -1;
- resHList[nsp].freeHead = oldSize;
- resHList[nsp].size = (int)newListSize;
+ return CDI_NOERR;
}
-/**************************************************************/
-
-static void
-reshPut_(int nsp, int entry, void *p, const resOps *ops)
+int cdiGribIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
{
- listElem_t *newListElem = resHList[nsp].resources + entry;
- int next = newListElem->res.free.next,
- prev = newListElem->res.free.prev;
- if (next != -1)
- resHList[nsp].resources[next].res.free.prev = prev;
- if (prev != -1)
- resHList[nsp].resources[prev].res.free.next = next;
- else
- resHList[nsp].freeHead = next;
- newListElem->res.v.val = p;
- newListElem->res.v.ops = ops;
- newListElem->status = RESH_DESYNC_IN_USE;
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+ int trash;
+ if(!outTileIndex) outTileIndex = &trash;
+ if(!outTileAttribute) outTileAttribute = &trash;
+
+ //Get the values if possible.
+ int error = CDI_NOERR;
+ long value;
+ if(grib_get_long(me->gribHandle, "tileIndex", &value)) error = CDI_EINVAL;
+ *outTileIndex = (int)value;
+ if(grib_get_long(me->gribHandle, "tileAttribute", &value)) error = CDI_EINVAL;
+ *outTileAttribute = (int)value;
+
+ //Ensure defined return values in case of failure.
+ if(error) *outTileIndex = *outTileAttribute = -1;
+ return error;
}
-int reshPut ( void *p, const resOps *ops )
+int cdiGribIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
{
- xassert ( p && ops );
-
- LIST_INIT(1);
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+ int trash;
+ if(!outTileCount) outTileCount = &trash;
+ if(!outTileAttributeCount) outTileAttributeCount = &trash;
- LIST_LOCK();
+ //Get the values if possible.
+ int error = CDI_NOERR;
+ long value;
+ if(grib_get_long(me->gribHandle, "numberOfTiles", &value)) error = CDI_EINVAL;
+ *outTileCount = (int)value;
+ if(grib_get_long(me->gribHandle, "numberOfTileAttributes", &value)) error = CDI_EINVAL;
+ *outTileAttributeCount = (int)value;
- int nsp = namespaceGetActive ();
+ //Ensure defined return values in case of failure.
+ if(error) *outTileCount = *outTileAttributeCount = 0;
+ return error;
+}
- if ( resHList[nsp].freeHead == -1) listSizeExtend();
- int entry = resHList[nsp].freeHead;
- cdiResH resH = namespaceIdxEncode2(nsp, entry);
- reshPut_(nsp, entry, p, ops);
+char *cdiGribIterator_copyVariableName(CdiIterator *super)
+{
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+ return gribCopyString(me->gribHandle, "shortName");
+}
- LIST_UNLOCK();
+void cdiGribIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
+{
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
- return resH;
+ GRIB_CHECK(my_grib_set_double(me->gribHandle, "missingValue", cdiDefaultMissval), 0);
+ gribGetDoubleArray(me->gribHandle, "values", buffer);
+ long gridType = gribGetLong(me->gribHandle, "gridDefinitionTemplateNumber");
+ if(nmiss)
+ {
+ *nmiss = (gridType >= 50 && gridType <= 53) ? (size_t)0 : (size_t)gribGetLong(me->gribHandle, "numberOfMissing"); //The condition excludes harmonic data.
+ }
}
-/**************************************************************/
-
-static void
-reshRemove_(int nsp, int idx)
+void cdiGribIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
{
- int curFree = resHList[nsp].freeHead;
- listElem_t *r = resHList[nsp].resources;
- r[idx].res.free.next = curFree;
- r[idx].res.free.prev = -1;
- if (curFree != -1)
- r[curFree].res.free.prev = idx;
- r[idx].status = RESH_DESYNC_DELETED;
- resHList[nsp].freeHead = idx;
+ CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+
+ size_t valueCount = gribGetArraySize(me->gribHandle, "values");
+ double *temp = (double *) Malloc(valueCount*sizeof(*temp));
+ cdiGribIterator_readField(super, temp, nmiss);
+ for(size_t i = valueCount; i--; ) buffer[i] = (float)temp[i];
+ Free(temp);
}
+#endif
-void reshDestroy(cdiResH resH)
+/*
+ at Function cdiGribIterator_delete
+ at Title Dispose off a CdiGribIterator instance.
+
+ at Prototype void cdiGribIterator_delete(CdiGribIterator *me)
+ at Parameter
+ @item me The iterator to delete.
+
+ at Description
+ Combined destructor and deallocator. Make sure to match every call to cdiGribIterator_clone() with a call to this function.
+*/
+void cdiGribIterator_delete(CdiGribIterator *me)
{
- int nsp;
- namespaceTuple_t nspT;
+#ifdef HAVE_LIBGRIB_API
+ if(me) cdiGribIterator_condestruct(me, NULL, 0);
+#else
+ if (me)
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+#endif
+}
- LIST_LOCK();
- nsp = namespaceGetActive ();
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// callthroughs to provide direct access to the grib keys //////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
- nspT = namespaceResHDecode ( resH );
+/*
+ at Function cdiGribIterator_inqEdition
+ at Title Get the version of the GRIB standard that is used
- xassert ( nspT.nsp == nsp
- && nspT.idx >= 0
- && nspT.idx < resHList[nsp].size
- && resHList[nsp].resources[nspT.idx].res.v.ops);
+ at Prototype int cdiGribIterator_inqEdition(CdiGribIterator *me)
+ at Parameter
+ @item me The iterator to operate on.
- if (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
- reshRemove_(nsp, nspT.idx);
+ at Result The GRIB version.
- LIST_UNLOCK();
+ at Description
+ Returns the version of the file format.
+*/
+int cdiGribIterator_inqEdition(CdiGribIterator *me)
+{
+#ifdef HAVE_LIBGRIB_API
+ return (int)gribEditionNumber(me->gribHandle);
+#else
+ (void)me;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
-void reshRemove ( cdiResH resH, const resOps * ops )
+/*
+ at Function cdiGribIterator_getLong
+ at Title Access to grib_get_long()
+
+ at Prototype int cdiGribIterator_getLong(CdiGribIterator *me, const char *key, long *result)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+ Callthrough to grib_get_long().
+*/
+int cdiGribIterator_getLong(CdiGribIterator *me, const char *key, long *result)
{
- int nsp;
- namespaceTuple_t nspT;
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_long(me->gribHandle, key, result);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- LIST_LOCK();
+/*
+ at Function cdiGribIterator_getLength
+ at Title Access to grib_get_length()
- nsp = namespaceGetActive ();
+ at Prototype int cdiGribIterator_getLength(CdiGribIterator *me, const char *key, size_t *result)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
- nspT = namespaceResHDecode ( resH );
+ at Result An error code.
- xassert ( nspT.nsp == nsp
- && nspT.idx >= 0
- && nspT.idx < resHList[nsp].size
- && (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
- && resHList[nsp].resources[nspT.idx].res.v.ops
- && resHList[nsp].resources[nspT.idx].res.v.ops == ops );
+ at Description
+ Callthrough to grib_get_length().
+*/
+int cdiGribIterator_getLength(CdiGribIterator *me, const char *key, size_t *result)
+{
+#ifdef HAVE_GRIB_GET_LENGTH
+ return grib_get_length(me->gribHandle, key, result);
+#elif defined(HAVE_LIBGRIB_API)
+ (void)me;
+ (void)key;
+ (void)result;
+ Error("grib_get_length() is not available, so cdiGribIterator_getLength() can't be used");
+ return -1;
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- reshRemove_(nsp, nspT.idx);
+/*
+ at Function cdiGribIterator_getString
+ at Title Access to grib_get_string()
- LIST_UNLOCK();
-}
+ at Prototype int cdiGribIterator_getString(CdiGribIterator *me, const char *key, char *result, size_t *length)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
-/**************************************************************/
+ at Result An error code.
-void reshReplace(cdiResH resH, void *p, const resOps *ops)
+ at Description
+ Callthrough to grib_get_string().
+*/
+int cdiGribIterator_getString(CdiGribIterator *me, const char *key, char *result, size_t *length)
{
- xassert(p && ops);
- LIST_INIT(1);
- LIST_LOCK();
- int nsp = namespaceGetActive();
- namespaceTuple_t nspT = namespaceResHDecode(resH);
- while (resHList[nsp].size <= nspT.idx)
- listSizeExtend();
- listElem_t *q = resHList[nsp].resources + nspT.idx;
- if (q->status & RESH_IN_USE_BIT)
- {
- q->res.v.ops->valDestroy(q->res.v.val);
- reshRemove_(nsp, nspT.idx);
- }
- reshPut_(nsp, nspT.idx, p, ops);
- LIST_UNLOCK();
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_string(me->gribHandle, key, result, length);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ (void)length;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
+/*
+ at Function cdiGribIterator_inqLongValue
+ at Title Get the value of a GRIB-API key as a long
-static listElem_t *
-reshGetElem(const char *caller, const char* expressionString, cdiResH resH, const resOps *ops)
-{
- listElem_t *listElem;
- int nsp;
- namespaceTuple_t nspT;
- xassert ( ops );
+ at Prototype long cdiGribIterator_inqLongValue(CdiGribIterator *me, const char *key)
+ at Parameter
+ @item me The iterator to operate on.
+ @item key The GRIB-API key to retrieve.
- LIST_INIT(1);
+ at Result The value of the key.
- LIST_LOCK();
+ at Description
+ Use this to fetch a grib value if you are certain that the given key must be present.
+ This will abort the process if the key cannot be retrieved.
+*/
+long cdiGribIterator_inqLongValue(CdiGribIterator *me, const char *key)
+{
+#ifdef HAVE_LIBGRIB_API
+ return gribGetLong(me->gribHandle, key);
+#else
+ (void)me;
+ (void)key;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- nsp = namespaceGetActive ();
+/*
+ at Function cdiGribIterator_inqLongDefaultValue
+ at Title Get the value of a GRIB-API key as a long
- nspT = namespaceResHDecode ( resH );
- assert(nspT.idx >= 0);
+ at Prototype long cdiGribIterator_inqLongDefaultValue(CdiGribIterator *me, const char *key, long defaultValue)
+ at Parameter
+ @item me The iterator to operate on.
+ @item key The GRIB-API key to retrieve.
+ @item defaultValue The value to return if the key is not present.
- if (nspT.nsp == nsp &&
- nspT.idx < resHList[nsp].size)
- {
- listElem = resHList[nsp].resources + nspT.idx;
- LIST_UNLOCK();
- }
- else
- {
- LIST_UNLOCK();
- show_stackframe();
+ at Result The value of the key or the given default value.
- if ( resH == CDI_UNDEFID )
- {
- xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is CDI_UNDEFID (= %d).\n\tThis is most likely the result of a failed earlier call. Please check the IDs returned by CDI.", expressionString, caller, resH);
- }
- else
- {
- xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is garbage (= %d, which resolves to namespace = %d, index = %d).\n\tThis is either the result of using an uninitialized variable,\n\tof using a value as an ID that is not an ID,\n\tor of using an ID after it has been invalidated.", expressionString, caller, resH, nspT.nsp, nspT.idx);
- }
- }
+ at Description
+ Use this if you can handle failure to fetch the key by supplying a default value.
+ This function cannot fail.
+*/
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator *me, const char *key, long defaultValue)
+{
+#ifdef HAVE_LIBGRIB_API
+ return gribGetLongDefault(me->gribHandle, key, defaultValue);
+#else
+ (void)me;
+ (void)key;
+ (void)defaultValue;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- if ( !(listElem && listElem->res.v.ops == ops) )
- {
- show_stackframe();
+/*
+ at Function cdiGribIterator_inqStringValue
+ at Title Safely retrieve a GRIB-API key with a string value
- xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: list element not found. The failed ID is %d", expressionString, caller, (int)resH);
- }
+ at Prototype char *cdiGribIterator_inqStringValue(CdiGribIterator *me, const char *key)
+ at Parameter
+ @item me The iterator to operate on.
+ @item key The GRIB-API key to retrieve.
- return listElem;
-}
+ at Result A malloc'ed string or NULL.
-void *reshGetValue(const char * caller, const char* expressionString, cdiResH resH, const resOps * ops)
+ at Description
+ This will first call grib_get_length() to inquire the actual size of the string,
+ allocate memory accordingly, call grib_get_string(), and return the pointer to the new string.
+ Returns NULL on failure.
+*/
+char *cdiGribIterator_inqStringValue(CdiGribIterator *me, const char *key)
{
- return reshGetElem(caller, expressionString, resH, ops)->res.v.val;
+#ifdef HAVE_LIBGRIB_API
+ return gribCopyString(me->gribHandle, key);
+#else
+ (void)me;
+ (void)key;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return NULL;
+#endif
}
-/**************************************************************/
-
-void reshGetResHListOfType(unsigned numIDs, int resHs[], const resOps *ops)
-{
- xassert ( resHs && ops );
-
- LIST_INIT(1);
+/*
+ at Function cdiGribIterator_getDouble
+ at Title Access to grib_get_double()
- LIST_LOCK();
+ at Prototype int cdiGribIterator_getDouble(CdiGribIterator *me, const char *key, double *result)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
- int nsp = namespaceGetActive();
- unsigned j = 0;
- for (int i = 0; i < resHList[nsp].size && j < numIDs; i++ )
- if ((resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
- && resHList[nsp].resources[i].res.v.ops == ops)
- resHs[j++] = namespaceIdxEncode2(nsp, i);
+ at Result An error code.
- LIST_UNLOCK();
+ at Description
+ Callthrough to grib_get_double().
+*/
+int cdiGribIterator_getDouble(CdiGribIterator *me, const char *key, double *result)
+{
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_double(me->gribHandle, key, result);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
-enum cdiApplyRet
-cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
- void *data), void *data)
-{
- xassert(func);
+/*
+ at Function cdiGribIterator_getSize
+ at Title Access to grib_get_size()
- LIST_INIT(1);
+ at Prototype int cdiGribIterator_getSize(CdiGribIterator *me, const char *key, size_t *result)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
- LIST_LOCK();
+ at Result An error code.
- int nsp = namespaceGetActive ();
- enum cdiApplyRet ret = CDI_APPLY_GO_ON;
- for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
- if (resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
- ret = func(namespaceIdxEncode2(nsp, i),
- resHList[nsp].resources[i].res.v.val,
- resHList[nsp].resources[i].res.v.ops, data);
- LIST_UNLOCK();
- return ret;
+ at Description
+ Callthrough to grib_get_size().
+*/
+int cdiGribIterator_getSize(CdiGribIterator *me, const char *key, size_t *result)
+{
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_size(me->gribHandle, key, result);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
+/*
+ at Function cdiGribIterator_getLongArray
+ at Title Access to grib_get_long_array()
-enum cdiApplyRet
-cdiResHFilterApply(const resOps *p,
- enum cdiApplyRet (*func)(int id, void *res, void *data),
- void *data)
-{
- xassert(p && func);
-
- LIST_INIT(1);
+ at Prototype int cdiGribIterator_getLongArray(CdiGribIterator *me, const char *key, long *result, size_t *size)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
- LIST_LOCK();
+ at Result An error code.
- int nsp = namespaceGetActive ();
- enum cdiApplyRet ret = CDI_APPLY_GO_ON;
- listElem_t *r = resHList[nsp].resources;
- for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
- if ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == p)
- ret = func(namespaceIdxEncode2(nsp, i), r[i].res.v.val,
- data);
- LIST_UNLOCK();
- return ret;
+ at Description
+ Callthrough to grib_get_long_array().
+*/
+int cdiGribIterator_getLongArray(CdiGribIterator *me, const char *key, long *result, size_t *size)
+{
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_long_array(me->gribHandle, key, result, size);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ (void)size;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
+/*
+ at Function cdiGribIterator_getDoubleArray
+ at Title Access to grib_get_double_array()
+ at Prototype int cdiGribIterator_getDoubleArray(CdiGribIterator *me, const char *key, double *result, size_t *size)
+ at Parameter
+ @item me The iterator to operate on.
+ @item ... The arguments to the underlying GRIB-API function.
+ at Result An error code.
-/**************************************************************/
-
-unsigned reshCountType(const resOps *ops)
+ at Description
+ Callthrough to grib_get_double_array().
+*/
+int cdiGribIterator_getDoubleArray(CdiGribIterator *me, const char *key, double *result, size_t *size)
{
- unsigned countType = 0;
-
- xassert(ops);
+#ifdef HAVE_LIBGRIB_API
+ return grib_get_double_array(me->gribHandle, key, result, size);
+#else
+ (void)me;
+ (void)key;
+ (void)result;
+ (void)size;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- LIST_INIT(1);
+/*
+ at Function cdiGribIterator_inqDoubleValue
+ at Title Get the value of a GRIB-API key as a double
- LIST_LOCK();
+ at Prototype double cdiGribIterator_inqDoubleValue(CdiGribIterator *me, const char *key)
+ at Parameter
+ @item me The iterator to operate on.
+ @item key The GRIB-API key to retrieve.
- int nsp = namespaceGetActive ();
+ at Result The value of the key.
- listElem_t *r = resHList[nsp].resources;
- size_t len = (size_t)resHList[nsp].size;
- for (size_t i = 0; i < len; i++ )
- countType += ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == ops);
+ at Description
+ Use this to fetch a grib value if you are certain that the given key must be present.
+ This will abort the process if the key cannot be retrieved.
+*/
+double cdiGribIterator_inqDoubleValue(CdiGribIterator *me, const char *key)
+{
+#ifdef HAVE_LIBGRIB_API
+ return gribGetDouble(me->gribHandle, key);
+#else
+ (void)me;
+ (void)key;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
+}
- LIST_UNLOCK();
+/*
+ at Function cdiGribIterator_inqDoubleDefaultValue
+ at Title Get the value of a GRIB-API key as a double
- return countType;
-}
+ at Prototype double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator *me, const char *key, double defaultValue)
+ at Parameter
+ @item me The iterator to operate on.
+ @item key The GRIB-API key to retrieve.
+ @item defaultValue The value to return if the key is not present.
-/**************************************************************/
+ at Result The value of the key or the given default value.
-int
-reshResourceGetPackSize_intern(int resH, const resOps *ops, void *context, const char* caller, const char* expressionString)
+ at Description
+ Use this if you can handle failure to fetch the key by supplying a default value.
+ This function cannot fail.
+*/
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator *me, const char *key, double defaultValue)
{
- listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
- return curr->res.v.ops->valGetPackSize(curr->res.v.val, context);
+#ifdef HAVE_LIBGRIB_API
+ return gribGetDoubleDefault(me->gribHandle, key, defaultValue);
+#else
+ (void)me;
+ (void)key;
+ (void)defaultValue;
+ xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
+ return -4;
+#endif
}
-void
-reshPackResource_intern(int resH, const resOps *ops, void *buf, int buf_size, int *position, void *context,
- const char* caller, const char* expressionString)
-{
- listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
- curr->res.v.ops->valPack(curr->res.v.val, buf, buf_size, position, context);
-}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef MODEL_H
+#define MODEL_H
-enum {
- resHPackHeaderNInt = 2,
- resHDeleteNInt = 2,
-};
+int
+modelUnpack(void *buf, int size, int *position,
+ int originNamespace, void *context, int force_id);
-static int getPackBufferSize(void *context)
-{
- int intpacksize, packBufferSize = 0;
+void modelDefaultEntries(void);
- int nsp = namespaceGetActive ();
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- /* pack start marker, namespace and sererator marker */
- packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, DATATYPE_INT, context));
+#include <limits.h>
- /* pack resources, type marker and seperator marker */
- listElem_t *r = resHList[nsp].resources;
- for ( int i = 0; i < resHList[nsp].size; i++)
- if (r[i].status & RESH_SYNC_BIT)
- {
- if (r[i].status == RESH_DESYNC_DELETED)
- {
- packBufferSize += resHDeleteNInt * intpacksize;
- }
- else if (r[i].status == RESH_DESYNC_IN_USE)
- {
- xassert ( r[i].res.v.ops );
- /* packed resource plus 1 int for type */
- packBufferSize +=
- r[i].res.v.ops->valGetPackSize(r[i].res.v.val, context)
- + intpacksize;
- }
- }
- /* end marker */
- packBufferSize += intpacksize;
- return packBufferSize;
-}
+#undef CDI_UNDEFID
+#define CDI_UNDEFID -1
-/**************************************************************/
+static int ECHAM4 = CDI_UNDEFID,
+ ECHAM5 = CDI_UNDEFID,
+ COSMO = CDI_UNDEFID;
-void reshPackBufferDestroy ( char ** buffer )
+typedef struct
{
- if ( buffer ) free ( *buffer );
+ int self;
+ int used;
+ int instID;
+ int modelgribID;
+ char *name;
}
+model_t;
-/**************************************************************/
-int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
-{
- int i, packBufferPos = 0;
- int end = END;
+static int MODEL_Debug = 0; /* If set to 1, debugging */
- xassert ( packBuffer );
+static void modelInit(void);
- LIST_LOCK();
- int nsp = namespaceGetActive ();
+static int modelCompareP(void *modelptr1, void *modelptr2);
+static void modelDestroyP ( void * modelptr );
+static void modelPrintP ( void * modelptr, FILE * fp );
+static int modelGetSizeP ( void * modelptr, void *context);
+static void modelPackP ( void * modelptr, void * buff, int size,
+ int *position, void *context);
+static int modelTxCode ( void );
- int pBSize = *packBufferSize = getPackBufferSize(context);
- char *pB = *packBuffer = (char *) Malloc((size_t)pBSize);
+static const resOps modelOps = {
+ modelCompareP,
+ modelDestroyP,
+ modelPrintP,
+ modelGetSizeP,
+ modelPackP,
+ modelTxCode
+};
- {
- int header[resHPackHeaderNInt] = { START, nsp };
- serializePack(header, resHPackHeaderNInt, DATATYPE_INT, pB, pBSize, &packBufferPos, context);
- }
+static
+void modelDefaultValue ( model_t *modelptr )
+{
+ modelptr->self = CDI_UNDEFID;
+ modelptr->used = 0;
+ modelptr->instID = CDI_UNDEFID;
+ modelptr->modelgribID = CDI_UNDEFID;
+ modelptr->name = NULL;
+}
- listElem_t *r = resHList[nsp].resources;
- for ( i = 0; i < resHList[nsp].size; i++ )
- if (r[i].status & RESH_SYNC_BIT)
- {
- if (r[i].status == RESH_DESYNC_DELETED)
- {
- int temp[resHDeleteNInt]
- = { RESH_DELETE, namespaceIdxEncode2(nsp, i) };
- serializePack(temp, resHDeleteNInt, DATATYPE_INT,
- pB, pBSize, &packBufferPos, context);
- }
- else
- {
- listElem_t * curr = r + i;
- xassert ( curr->res.v.ops );
- int type = curr->res.v.ops->valTxCode();
- if ( ! type ) continue;
- serializePack(&type, 1, DATATYPE_INT, pB,
- pBSize, &packBufferPos, context);
- curr->res.v.ops->valPack(curr->res.v.val,
- pB, pBSize, &packBufferPos, context);
- }
- r[i].status &= ~RESH_SYNC_BIT;
- }
+static model_t *
+modelNewEntry(cdiResH resH, int instID, int modelgribID, const char *name)
+{
+ model_t *modelptr;
- LIST_UNLOCK();
+ modelptr = (model_t *) Malloc(sizeof(model_t));
+ modelDefaultValue ( modelptr );
+ if (resH == CDI_UNDEFID)
+ modelptr->self = reshPut(modelptr, &modelOps);
+ else
+ {
+ modelptr->self = resH;
+ reshReplace(resH, modelptr, &modelOps);
+ }
+ modelptr->used = 1;
+ modelptr->instID = instID;
+ modelptr->modelgribID = modelgribID;
+ if ( name && *name ) modelptr->name = strdupx(name);
- serializePack(&end, 1, DATATYPE_INT, pB, pBSize, &packBufferPos, context);
- return packBufferPos;
+ return (modelptr);
}
-/**************************************************************/
-
-/* for thread safety this feature would have to be integrated in reshPut */
-
-void reshSetStatus ( cdiResH resH, const resOps * ops, int status )
+void modelDefaultEntries ( void )
{
- int nsp;
- namespaceTuple_t nspT;
- listElem_t * listElem;
+ int instID, i;
+ enum { nDefModels = 10 };
+ cdiResH resH[nDefModels];
- xassert((ops != NULL) ^ !(status & RESH_IN_USE_BIT));
+ instID = institutInq( 0, 0, "ECMWF", NULL);
+ /* (void) modelDef(instID, 131, "ERA15"); */
+ /* (void) modelDef(instID, 199, "ERA40"); */
+ instID = institutInq( 0, 0, "MPIMET", NULL);
- LIST_INIT(1);
+ resH[0] = ECHAM5 = modelDef(instID, 64, "ECHAM5.4");
+ resH[1] = modelDef(instID, 63, "ECHAM5.3");
+ resH[2] = modelDef(instID, 62, "ECHAM5.2");
+ resH[3] = modelDef(instID, 61, "ECHAM5.1");
- LIST_LOCK();
+ instID = institutInq( 98, 255, "MPIMET", NULL);
+ resH[4] = modelDef(instID, 60, "ECHAM5.0");
+ resH[5] = ECHAM4 = modelDef(instID, 50, "ECHAM4");
+ resH[6] = modelDef(instID, 110, "MPIOM1");
- nsp = namespaceGetActive ();
+ instID = institutInq( 0, 0, "DWD", NULL);
+ resH[7] = modelDef(instID, 149, "GME");
- nspT = namespaceResHDecode ( resH );
+ instID = institutInq( 0, 0, "MCH", NULL);
+ //(void) = modelDef(instID, 137, "COSMO");
+ resH[8] = COSMO = modelDef(instID, 255, "COSMO");
- xassert ( nspT.nsp == nsp &&
- nspT.idx >= 0 &&
- nspT.idx < resHList[nsp].size );
+ instID = institutInq( 0, 1, "NCEP", NULL);
+ resH[9] = modelDef(instID, 80, "T62L28MRF");
- xassert ( resHList[nsp].resources );
- listElem = resHList[nsp].resources + nspT.idx;
+ /* pre-defined models are not synchronized */
+ for ( i = 0; i < nDefModels ; i++ )
+ reshSetStatus(resH[i], &modelOps, RESH_IN_USE);
+}
- xassert((!ops || (listElem->res.v.ops == ops))
- && (listElem->status & RESH_IN_USE_BIT) == (status & RESH_IN_USE_BIT));
+static
+void modelInit(void)
+{
+ static int modelInitialized = 0;
- listElem->status = status;
+ if (modelInitialized) return;
- LIST_UNLOCK();
+ modelInitialized = 1;
+ char *env = getenv("MODEL_DEBUG");
+ if ( env ) MODEL_Debug = atoi(env);
}
-/**************************************************************/
-
-int reshGetStatus ( cdiResH resH, const resOps * ops )
+struct modelLoc
{
- int nsp;
- namespaceTuple_t nspT;
-
- LIST_INIT(1);
+ const char *name;
+ int instID, modelgribID, resID;
+};
- LIST_LOCK();
+static enum cdiApplyRet
+findModelByID(int resID, void *res, void *data)
+{
+ model_t *modelptr = (model_t*) res;
+ struct modelLoc *ret = (struct modelLoc*) data;
+ int instID = ret->instID, modelgribID = ret->modelgribID;
+ if (modelptr->used
+ && modelptr->instID == instID
+ && modelptr->modelgribID == modelgribID)
+ {
+ ret->resID = resID;
+ return CDI_APPLY_STOP;
+ }
+ else
+ return CDI_APPLY_GO_ON;
+}
- nsp = namespaceGetActive ();
+static enum cdiApplyRet
+findModelByName(int resID, void *res, void *data)
+{
+ model_t *modelptr = (model_t*) res;
+ struct modelLoc *ret = (struct modelLoc*) data;
+ int instID = ret->instID, modelgribID = ret->modelgribID;
+ const char *name = ret->name;
+ if (modelptr->used
+ && (instID == -1 || modelptr->instID == instID)
+ && (modelgribID == 0 || modelptr->modelgribID == modelgribID)
+ && modelptr->name)
+ {
+ const char *p = name, *q = modelptr->name;
+ while (*p != '\0' && *p == *q)
+ ++p, ++q;
+ if (*p == '\0' || *q == '\0')
+ {
+ ret->resID = resID;
+ return CDI_APPLY_STOP;
+ }
+ }
+ return CDI_APPLY_GO_ON;
+}
- nspT = namespaceResHDecode ( resH );
+int modelInq(int instID, int modelgribID, const char *name)
+{
+ modelInit ();
- xassert ( nspT.nsp == nsp &&
- nspT.idx >= 0 &&
- nspT.idx < resHList[nsp].size );
+ struct modelLoc searchState = { .name = name, .instID = instID,
+ .modelgribID = modelgribID,
+ .resID = CDI_UNDEFID };
+ if (name && *name)
+ cdiResHFilterApply(&modelOps, findModelByName, &searchState);
+ else
+ cdiResHFilterApply(&modelOps, findModelByID, &searchState);
+ return searchState.resID;
+}
- listElem_t *listElem = resHList[nsp].resources + nspT.idx;
- const resOps *elemOps = listElem->res.v.ops;
+int modelDef(int instID, int modelgribID, const char *name)
+{
+ model_t *modelptr;
- LIST_UNLOCK();
+ modelInit ();
- xassert(listElem && (!(listElem->status & RESH_IN_USE_BIT) || elemOps == ops));
+ modelptr = modelNewEntry(CDI_UNDEFID, instID, modelgribID, name);
- return listElem->status;
+ return modelptr->self;
}
-/**************************************************************/
-void reshLock ()
+int modelInqInstitut(int modelID)
{
- LIST_LOCK();
-}
+ model_t *modelptr = NULL;
-/**************************************************************/
+ modelInit ();
-void reshUnlock ()
-{
- LIST_UNLOCK();
+ if ( modelID != CDI_UNDEFID )
+ modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+
+ return modelptr ? modelptr->instID : CDI_UNDEFID;
}
-/**************************************************************/
-int reshListCompare ( int nsp0, int nsp1 )
+int modelInqGribID(int modelID)
{
- LIST_INIT(1);
- LIST_LOCK();
-
- xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
- nsp0 >= 0 && nsp1 >= 0);
+ model_t *modelptr = NULL;
- int valCompare = 0;
- int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
- ? resHList[nsp0].size : resHList[nsp1].size;
- listElem_t *resources0 = resHList[nsp0].resources,
- *resources1 = resHList[nsp1].resources;
- for (i = 0; i < listSizeMin; i++)
- {
- int occupied0 = (resources0[i].status & RESH_IN_USE_BIT) != 0,
- occupied1 = (resources1[i].status & RESH_IN_USE_BIT) != 0;
- /* occupation mismatch ? */
- int diff = occupied0 ^ occupied1;
- valCompare |= (diff << cdiResHListOccupationMismatch);
- if (!diff && occupied0)
- {
- /* both occupied, do resource types match? */
- diff = (resources0[i].res.v.ops != resources1[i].res.v.ops
- || resources0[i].res.v.ops == NULL);
- valCompare |= (diff << cdiResHListResourceTypeMismatch);
- if (!diff)
- {
- /* types match, does content match also? */
- diff
- = resources0[i].res.v.ops->valCompare(resources0[i].res.v.val,
- resources1[i].res.v.val);
- valCompare |= (diff << cdiResHListResourceContentMismatch);
- }
- }
- }
- /* find resources in nsp 0 beyond end of nsp 1 */
- for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
- valCompare |= (((resources0[j].status & RESH_IN_USE_BIT) != 0)
- << cdiResHListOccupationMismatch);
- /* find resources in nsp 1 beyond end of nsp 0 */
- for (; i < resHList[nsp1].size; ++i)
- valCompare |= (((resources1[i].status & RESH_IN_USE_BIT) != 0)
- << cdiResHListOccupationMismatch);
+ modelInit ();
- LIST_UNLOCK();
+ if ( modelID != CDI_UNDEFID )
+ modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
- return valCompare;
+ return modelptr ? modelptr->modelgribID : CDI_UNDEFID;
}
-/**************************************************************/
-void reshListPrint(FILE *fp)
+const char *modelInqNamePtr(int modelID)
{
- int i, j, temp;
- listElem_t * curr;
-
- LIST_INIT(1);
-
+ model_t *modelptr = NULL;
- temp = namespaceGetActive ();
+ modelInit ();
- fprintf ( fp, "\n\n##########################################\n#\n# print " \
- "global resource list \n#\n" );
+ if ( modelID != CDI_UNDEFID )
+ modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
- for ( i = 0; i < namespaceGetNumber (); i++ )
- {
- namespaceSetActive ( i );
+ return modelptr ? modelptr->name : NULL;
+}
- fprintf ( fp, "\n" );
- fprintf ( fp, "##################################\n" );
- fprintf ( fp, "#\n" );
- fprintf ( fp, "# namespace=%d\n", i );
- fprintf ( fp, "#\n" );
- fprintf ( fp, "##################################\n\n" );
- fprintf ( fp, "resHList[%d].size=%d\n", i, resHList[i].size );
+static int
+modelCompareP(void *modelptr1, void *modelptr2)
+{
+ model_t *model1 = (model_t *)modelptr1, *model2 = (model_t *)modelptr2;
+ int diff = (namespaceResHDecode(model1->instID).idx
+ != namespaceResHDecode(model2->instID).idx)
+ | (model1->modelgribID != model2->modelgribID)
+ | (strcmp(model1->name, model2->name) != 0);
+ return diff;
+}
- for ( j = 0; j < resHList[i].size; j++ )
- {
- curr = resHList[i].resources + j;
- if (!(curr->status & RESH_IN_USE_BIT))
- {
- curr->res.v.ops->valPrint(curr->res.v.val, fp);
- fprintf ( fp, "\n" );
- }
- }
- }
- fprintf ( fp, "#\n# end global resource list" \
- "\n#\n##########################################\n\n" );
- namespaceSetActive ( temp );
+void modelDestroyP ( void * modelptr )
+{
+ model_t *mp = (model_t*) modelptr;
+ if (mp->name)
+ Free(mp->name);
+ Free(mp);
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
+void modelPrintP ( void * modelptr, FILE * fp )
+{
+ model_t *mp = (model_t*) modelptr;
+ if ( !mp ) return;
-int
-serializeGetSize(int count, int datatype, void *context)
-{
- int (*serialize_get_size_p)(int count, int datatype, void *context)
- = (int (*)(int, int, void *))
- namespaceSwitchGet(NSSWITCH_SERIALIZE_GET_SIZE).func;
- return serialize_get_size_p(count, datatype, context);
+ fprintf ( fp, "#\n");
+ fprintf ( fp, "# modelID %d\n", mp->self);
+ fprintf ( fp, "#\n");
+ fprintf ( fp, "self = %d\n", mp->self );
+ fprintf ( fp, "used = %d\n", mp->used );
+ fprintf ( fp, "instID = %d\n", mp->instID );
+ fprintf ( fp, "modelgribID = %d\n", mp->modelgribID );
+ fprintf ( fp, "name = %s\n", mp->name ? mp->name : "NN" );
}
-void serializePack(const void *data, int count, int datatype,
- void *buf, int buf_size, int *position, void *context)
-{
- void (*serialize_pack_p)(const void *data, int count, int datatype,
- void *buf, int buf_size, int *position, void *context)
- = (void (*)(const void *, int, int, void *, int, int *, void *))
- namespaceSwitchGet(NSSWITCH_SERIALIZE_PACK).func;
- serialize_pack_p(data, count, datatype, buf, buf_size, position, context);
-}
-void serializeUnpack(const void *buf, int buf_size, int *position,
- void *data, int count, int datatype, void *context)
+static int
+modelTxCode ( void )
{
- void (*serialize_unpack_p)(const void *buf, int buf_size, int *position,
- void *data, int count, int datatype, void *context)
- = (void (*)(const void *, int, int *, void *, int, int, void *))
- namespaceSwitchGet(NSSWITCH_SERIALIZE_UNPACK).func;
- serialize_unpack_p(buf, buf_size, position, data, count, datatype, context);
+ return MODEL;
}
+enum {
+ model_nints = 4,
+};
-int
-serializeGetSizeInCore(int count, int datatype, void *context)
+static int modelGetSizeP(void * modelptr, void *context)
{
- int elemSize;
- (void)context;
- switch (datatype)
- {
- case DATATYPE_INT8:
- elemSize = sizeof (int8_t);
- break;
- case DATATYPE_INT16:
- elemSize = sizeof (int16_t);
- break;
- case DATATYPE_UINT32:
- elemSize = sizeof (uint32_t);
- break;
- case DATATYPE_INT:
- elemSize = sizeof (int);
- break;
- case DATATYPE_FLT:
- case DATATYPE_FLT64:
- elemSize = sizeof (double);
- break;
- case DATATYPE_TXT:
- case DATATYPE_UCHAR:
- elemSize = 1;
- break;
- case DATATYPE_LONG:
- elemSize = sizeof (long);
- break;
- default:
- xabort("Unexpected datatype");
- }
- return count * elemSize;
+ model_t *p = (model_t*)modelptr;
+ size_t txsize = (size_t)serializeGetSize(model_nints, CDI_DATATYPE_INT, context)
+ + (size_t)serializeGetSize(p->name?(int)strlen(p->name) + 1:0, CDI_DATATYPE_TXT, context);
+ xassert(txsize <= INT_MAX);
+ return (int)txsize;
}
-void serializePackInCore(const void *data, int count, int datatype,
- void *buf, int buf_size, int *position, void *context)
+
+static void modelPackP(void * modelptr, void * buf, int size, int *position, void *context)
{
- int size = serializeGetSize(count, datatype, context);
- int pos = *position;
- xassert(INT_MAX - pos >= size && buf_size - pos >= size);
- memcpy((unsigned char *)buf + pos, data, (size_t)size);
- pos += size;
- *position = pos;
+ model_t *p = (model_t*) modelptr;
+ int tempbuf[model_nints];
+ tempbuf[0] = p->self;
+ tempbuf[1] = p->instID;
+ tempbuf[2] = p->modelgribID;
+ tempbuf[3] = p->name ? (int)strlen(p->name) + 1 : 0;
+ serializePack(tempbuf, model_nints, CDI_DATATYPE_INT, buf, size, position, context);
+ if (p->name)
+ serializePack(p->name, tempbuf[3], CDI_DATATYPE_TXT, buf, size, position, context);
}
-void serializeUnpackInCore(const void *buf, int buf_size, int *position,
- void *data, int count, int datatype, void *context)
+int
+modelUnpack(void *buf, int size, int *position, int originNamespace, void *context,
+ int force_id)
{
- int size = serializeGetSize(count, datatype, context);
- int pos = *position;
- xassert(INT_MAX - pos >= size && buf_size - pos >= size);
- memcpy(data, (unsigned char *)buf + pos, (size_t)size);
- pos += size;
- *position = pos;
+ int tempbuf[model_nints];
+ char *name;
+ serializeUnpack(buf, size, position, tempbuf, model_nints, CDI_DATATYPE_INT, context);
+ if (tempbuf[3] != 0)
+ {
+ name = (char *) Malloc((size_t)tempbuf[3]);
+ serializeUnpack(buf, size, position,
+ name, tempbuf[3], CDI_DATATYPE_TXT, context);
+ }
+ else
+ {
+ name = (char*)"";
+ }
+ int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
+ model_t *mp = modelNewEntry(force_id?targetID:CDI_UNDEFID,
+ namespaceAdaptKey(tempbuf[1], originNamespace),
+ tempbuf[2], name);
+ if (tempbuf[3] != 0)
+ Free(name);
+ xassert(!force_id
+ || (mp->self == namespaceAdaptKey(tempbuf[0], originNamespace)));
+ reshSetStatus(mp->self, &modelOps,
+ reshGetStatus(mp->self, &modelOps) & ~RESH_SYNC_BIT);
+ return mp->self;
}
/*
@@ -34586,10460 +33970,11092 @@ void serializeUnpackInCore(const void *buf, int buf_size, int *position,
#if defined (HAVE_CONFIG_H)
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
-
-
-enum {
- SRV_HEADER_LEN = 8,
-};
-
-
-static int initSrvLib = 0;
-static int srvDefaultHprec = 0;
-static int srvDefaultDprec = 0;
-
-
-/*
- * A version string.
- */
-#undef LIBVERSION
-#define LIBVERSION 1.4.0
-#define XSTRING(x) #x
-#define STRING(x) XSTRING(x)
-static const char srv_libvers[] = STRING(LIBVERSION) " of " __DATE__" " __TIME__;
-
-const char *srvLibraryVersion(void)
-{
- return srv_libvers;
-}
-
-
-static int SRV_Debug = 0; /* If set to 1, debugging */
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
-void srvDebug(int debug)
-{
- SRV_Debug = debug;
- if ( SRV_Debug )
- Message("debug level %d", debug);
-}
+static unsigned nNamespaces = 1;
+static int activeNamespace = 0;
-static
-void srvLibInit()
-{
- const char *envName = "SRV_PRECISION";
+#ifdef HAVE_LIBNETCDF
+#define CDI_NETCDF_SWITCHES \
+ { .func = (void (*)()) nc__create }, \
+ { .func = (void (*)()) cdf_def_var_serial }, \
+ { .func = (void (*)()) cdfDefTimestep }, \
+ { .func = (void (*)()) cdfDefVars }
- char *envString = getenv(envName);
- if ( envString )
- {
- int nrun;
- if ( strlen(envString) == 2 ) nrun = 1;
- else nrun = 2;
+#else
+#define CDI_NETCDF_SWITCHES
+#endif
- int pos = 0;
- while ( nrun-- )
- {
- switch ( tolower((int) envString[pos]) )
- {
- case 'i':
- {
- switch ( (int) envString[pos+1] )
- {
- case '4': srvDefaultHprec = EXSE_SINGLE_PRECISION; break;
- case '8': srvDefaultHprec = EXSE_DOUBLE_PRECISION; break;
- default:
- Message("Invalid digit in %s: %s", envName, envString);
- }
- break;
- }
- case 'r':
- {
- switch ( (int) envString[pos+1] )
- {
- case '4': srvDefaultDprec = EXSE_SINGLE_PRECISION; break;
- case '8': srvDefaultDprec = EXSE_DOUBLE_PRECISION; break;
- default:
- Message("Invalid digit in %s: %s", envName, envString);
- }
- break;
- }
- default:
- {
- Message("Invalid character in %s: %s", envName, envString);
- break;
- }
- }
- pos += 2;
- }
+#define defaultSwitches { \
+ { .func = (void (*)()) cdiAbortC_serial }, \
+ { .func = (void (*)()) cdiWarning }, \
+ { .func = (void (*)()) serializeGetSizeInCore }, \
+ { .func = (void (*)()) serializePackInCore }, \
+ { .func = (void (*)()) serializeUnpackInCore }, \
+ { .func = (void (*)()) fileOpen_serial }, \
+ { .func = (void (*)()) fileWrite }, \
+ { .func = (void (*)()) fileClose_serial }, \
+ { .func = (void (*)()) cdiStreamOpenDefaultDelegate }, \
+ { .func = (void (*)()) cdiStreamDefVlist_ }, \
+ { .func = (void (*)()) cdiStreamSetupVlist_ }, \
+ { .func = (void (*)()) cdiStreamWriteVar_ }, \
+ { .func = (void (*)()) cdiStreamWriteVarChunk_ }, \
+ { .func = (void (*)()) 0 }, \
+ { .func = (void (*)()) 0 }, \
+ { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
+ { .func = (void (*)()) cdiStreamDefTimestep_ }, \
+ { .func = (void (*)()) cdiStreamSync_ }, \
+ CDI_NETCDF_SWITCHES \
}
- initSrvLib = 1;
-}
-
-static
-void srvInit(srvrec_t *srvp)
-{
- srvp->checked = 0;
- srvp->byteswap = 0;
- srvp->hprec = 0;
- srvp->dprec = 0;
- srvp->datasize = 0;
- srvp->buffersize = 0;
- srvp->buffer = NULL;
-}
-
+#if defined (SX) || defined (__cplusplus)
+static const union namespaceSwitchValue
+ defaultSwitches_[NUM_NAMESPACE_SWITCH] = defaultSwitches;
+#endif
-void *srvNew(void)
+enum namespaceStatus {
+ NAMESPACE_STATUS_INUSE,
+ NAMESPACE_STATUS_UNUSED,
+};
+
+static struct Namespace
{
- if ( ! initSrvLib ) srvLibInit();
+ enum namespaceStatus resStage;
+ union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
+} initialNamespace = {
+ .resStage = NAMESPACE_STATUS_INUSE,
+ .switches = defaultSwitches
+};
- srvrec_t *srvp = (srvrec_t *) Malloc(sizeof(srvrec_t));
+static struct Namespace *namespaces = &initialNamespace;
- srvInit(srvp);
+static unsigned namespacesSize = 1;
- return (void*)srvp;
-}
+#if defined (HAVE_LIBPTHREAD)
+# include <pthread.h>
+static pthread_once_t namespaceOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t namespaceMutex;
-void srvDelete(void *srv)
+static void
+namespaceInitialize(void)
{
- srvrec_t *srvp = (srvrec_t *) srv;
-
- if ( srvp )
- {
- if ( srvp->buffer ) Free(srvp->buffer);
- Free(srvp);
- }
+ pthread_mutexattr_t ma;
+ pthread_mutexattr_init(&ma);
+ pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&namespaceMutex, &ma);
+ pthread_mutexattr_destroy(&ma);
}
+# define NAMESPACE_LOCK() pthread_mutex_lock(&namespaceMutex)
+# define NAMESPACE_UNLOCK() pthread_mutex_unlock(&namespaceMutex)
+# define NAMESPACE_INIT() pthread_once(&namespaceOnce, \
+ namespaceInitialize)
-int srvCheckFiletype(int fileID, int *swap)
-{
- size_t data = 0;
- size_t dimx = 0, dimy = 0;
- size_t fact = 0;
- int found = 0;
- unsigned char buffer[72], *pbuf;
- if ( fileRead(fileID, buffer, 4) != 4 ) return found;
+#else
- size_t blocklen = (size_t) get_UINT32(buffer);
- size_t sblocklen = (size_t) get_SUINT32(buffer);
+# define NAMESPACE_INIT() do { } while (0)
+# define NAMESPACE_LOCK()
+# define NAMESPACE_UNLOCK()
- if ( SRV_Debug )
- Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+#endif
- if ( blocklen == 32 )
- {
- *swap = 0;
- fact = blocklen>>3;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
- pbuf = buffer+4*fact; dimx = (size_t) get_UINT32(pbuf);
- pbuf = buffer+5*fact; dimy = (size_t) get_UINT32(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
- }
- else if ( blocklen == 64 )
- {
- *swap = 0;
- fact = blocklen>>3;
- if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
- pbuf = buffer+4*fact; dimx = (size_t) get_UINT64(pbuf);
- pbuf = buffer+5*fact; dimy = (size_t) get_UINT64(pbuf);
- pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
- }
- else if ( sblocklen == 32 )
- {
- *swap = 1;
- fact = sblocklen>>3;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
- pbuf = buffer+4*fact; dimx = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+5*fact; dimy = (size_t) get_SUINT32(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
- }
- else if ( sblocklen == 64 )
- {
- *swap = 1;
- fact = sblocklen>>3;
- if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
- pbuf = buffer+4*fact; dimx = (size_t) get_SUINT64(pbuf);
- pbuf = buffer+5*fact; dimy = (size_t) get_SUINT64(pbuf);
- pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
- }
- fileRewind(fileID);
+enum {
+ intbits = sizeof(int) * CHAR_BIT,
+ nspbits = 4,
+ idxbits = intbits - nspbits,
+ nspmask = (int)((( (unsigned)1 << nspbits ) - 1) << idxbits),
+ idxmask = ( 1 << idxbits ) - 1,
+};
- if ( data && dimx*dimy*fact == data ) found = 1;
- else if ( data && dimx*dimy*8 == data ) found = 1;
+enum {
+ NUM_NAMESPACES = 1 << nspbits,
+ NUM_IDX = 1 << idxbits,
+};
- if ( SRV_Debug )
- {
- Message("swap = %d fact = %d", *swap, fact);
- Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
- }
- return found;
+int namespaceIdxEncode ( namespaceTuple_t tin )
+{
+ xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
+ return ( tin.nsp << idxbits ) + tin.idx;
}
-
-int srvInqHeader(void *srv, int *header)
+int namespaceIdxEncode2 ( int nsp, int idx )
{
- srvrec_t *srvp = (srvrec_t *) srv;
-
- for ( size_t i = 0; i < SRV_HEADER_LEN; i++ )
- header[i] = srvp->header[i];
-
- if ( SRV_Debug )
- Message("datasize = %lu", srvp->datasize);
-
- return 0;
+ xassert(nsp < NUM_NAMESPACES && idx < NUM_IDX);
+ return ( nsp << idxbits ) + idx;
}
-int srvDefHeader(void *srv, const int *header)
+namespaceTuple_t namespaceResHDecode ( int resH )
{
- srvrec_t *srvp = (srvrec_t *) srv;
-
- for ( size_t i = 0; i < SRV_HEADER_LEN; i++ )
- srvp->header[i] = header[i];
-
- srvp->datasize = (size_t)(header[4] * header[5]);
+ namespaceTuple_t tin;
- if ( SRV_Debug )
- Message("datasize = %lu", srvp->datasize);
+ tin.idx = resH & idxmask;
+ tin.nsp = (int)(((unsigned)( resH & nspmask )) >> idxbits);
- return 0;
+ return tin;
}
-static
-int srvInqData(srvrec_t *srvp, int prec, void *data)
+int
+namespaceNew()
{
- size_t i;
- int ierr = 0;
- int byteswap = srvp->byteswap;
- size_t datasize = srvp->datasize;
- void *buffer = srvp->buffer;
- int dprec = srvp->dprec;
-
- switch ( dprec )
+ int newNamespaceID = -1;
+ NAMESPACE_INIT();
+ NAMESPACE_LOCK();
+ if (namespacesSize > nNamespaces)
{
- case EXSE_SINGLE_PRECISION:
- {
- if ( sizeof(FLT32) == 4 )
- {
- if ( byteswap ) swap4byte(buffer, datasize);
-
- if ( dprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT32));
- else
- for ( i = 0; i < datasize; i++ )
- ((double *) data)[i] = (double) ((float *) buffer)[i];
- }
- else
- {
- Error("not implemented for %d byte float", sizeof(FLT32));
- }
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- if ( sizeof(FLT64) == 8 )
- {
- if ( byteswap ) swap8byte(buffer, datasize);
-
- if ( dprec == prec )
- memcpy(data, buffer, datasize*sizeof(FLT64));
- else
- for ( i = 0; i < datasize; i++ )
- ((float *) data)[i] = (float) ((double *) buffer)[i];
- }
- else
- {
- Error("not implemented for %d byte float", sizeof(FLT64));
- }
- break;
- default:
- {
- Error("unexpected data precision %d", dprec);
- break;
- }
+ /* namespace is already available and only needs reinitialization */
+ for (unsigned i = 0; i < namespacesSize; ++i)
+ if (namespaces[i].resStage == NAMESPACE_STATUS_UNUSED)
+ {
+ newNamespaceID = (int)i;
+ break;
+ }
}
-
- return ierr;
+ else if (namespacesSize == 1)
+ {
+ /* make room for additional namespace */
+ struct Namespace *newNameSpaces
+ = (struct Namespace *) Malloc(((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
+ memcpy(newNameSpaces, namespaces, sizeof (namespaces[0]));
+ namespaces = newNameSpaces;
+ ++namespacesSize;
+ newNamespaceID = 1;
+ }
+ else if (namespacesSize < NUM_NAMESPACES)
+ {
+ /* make room for additional namespace */
+ newNamespaceID = (int)namespacesSize;
+ namespaces
+ = (struct Namespace *) Realloc(namespaces, ((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
+ ++namespacesSize;
+ }
+ else /* implicit: namespacesSize >= NUM_NAMESPACES */
+ {
+ NAMESPACE_UNLOCK();
+ return -1;
+ }
+ xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
+ ++nNamespaces;
+ namespaces[newNamespaceID].resStage = NAMESPACE_STATUS_INUSE;
+#if defined (SX) || defined (__cplusplus)
+ memcpy(namespaces[newNamespaceID].switches,
+ defaultSwitches_,
+ sizeof (namespaces[newNamespaceID].switches));
+#else
+ memcpy(namespaces[newNamespaceID].switches,
+ (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
+ sizeof (namespaces[newNamespaceID].switches));
+#endif
+ reshListCreate(newNamespaceID);
+ NAMESPACE_UNLOCK();
+ return newNamespaceID;
}
-
-int srvInqDataSP(void *srv, float *data)
+void
+namespaceDelete(int namespaceID)
{
- return srvInqData((srvrec_t *)srv, EXSE_SINGLE_PRECISION, (void *) data);
+ NAMESPACE_INIT();
+ NAMESPACE_LOCK();
+ xassert(namespaceID >= 0 && (unsigned)namespaceID < namespacesSize
+ && nNamespaces);
+ reshListDestruct(namespaceID);
+ namespaces[namespaceID].resStage = NAMESPACE_STATUS_UNUSED;
+ --nNamespaces;
+ NAMESPACE_UNLOCK();
}
-
-int srvInqDataDP(void *srv, double *data)
+int namespaceGetNumber ()
{
- return srvInqData((srvrec_t *)srv, EXSE_DOUBLE_PRECISION, (void *) data);
+ return (int)nNamespaces;
}
-static int
-srvDefData(void *srv, int prec, const void *data)
+void namespaceSetActive ( int nId )
{
- srvrec_t *srvp = (srvrec_t *) srv;
- size_t i;
- int dprec, hprec;
- void *buffer;
+ xassert((unsigned)nId < namespacesSize
+ && namespaces[nId].resStage != NAMESPACE_STATUS_UNUSED);
+ activeNamespace = nId;
+}
- if ( srvDefaultDprec ) dprec = srvDefaultDprec;
- else dprec = srvp->dprec;
- if ( ! dprec ) dprec = prec;
+int namespaceGetActive ()
+{
+ return activeNamespace;
+}
- srvp->dprec = dprec;
+int namespaceAdaptKey ( int originResH, int originNamespace )
+{
+ namespaceTuple_t tin;
+ int nsp;
- if ( srvDefaultHprec ) hprec = srvDefaultHprec;
- else hprec = srvp->hprec;
+ if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
- if ( ! hprec ) hprec = dprec;
+ tin.idx = originResH & idxmask;
+ tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
- srvp->hprec = hprec;
+ xassert ( tin.nsp == originNamespace );
- int *header = srvp->header;
+ nsp = namespaceGetActive ();
- size_t datasize = (size_t)(header[4] * header[5]);
- size_t blocklen = datasize * (size_t)dprec;
+ return namespaceIdxEncode2 ( nsp, tin.idx );
+}
- srvp->datasize = datasize;
- size_t buffersize = srvp->buffersize;
+int namespaceAdaptKey2 ( int originResH )
+{
+ namespaceTuple_t tin;
+ int nsp;
- if ( buffersize != blocklen )
- {
- buffersize = blocklen;
- buffer = srvp->buffer;
- buffer = Realloc(buffer, buffersize);
- srvp->buffer = buffer;
- srvp->buffersize = buffersize;
- }
- else
- buffer = srvp->buffer;
+ if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
- switch ( dprec )
- {
- case EXSE_SINGLE_PRECISION:
- {
- if ( dprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT32));
- else
- for ( i = 0; i < datasize; i++ )
- ((float *) buffer)[i] = (float) ((double *) data)[i];
+ tin.idx = originResH & idxmask;
+ tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- if ( dprec == prec )
- memcpy(buffer, data, datasize*sizeof(FLT64));
- else
- for ( i = 0; i < datasize; i++ )
- ((double *) buffer)[i] = (double) ((float *) data)[i];
+ nsp = namespaceGetActive ();
- break;
- }
- default:
- {
- Error("unexpected data precision %d", dprec);
- break;
- }
- }
+ return namespaceIdxEncode2 ( nsp, tin.idx );
+}
- return 0;
+void namespaceSwitchSet(enum namespaceSwitch sw, union namespaceSwitchValue value)
+{
+ xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
+ int nsp = namespaceGetActive();
+ namespaces[nsp].switches[sw] = value;
}
+union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
+{
+ xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
+ int nsp = namespaceGetActive();
+ return namespaces[nsp].switches[sw];
+}
-int srvDefDataSP(void *srv, const float *data)
+void cdiReset(void)
{
- return srvDefData(srv, EXSE_SINGLE_PRECISION, (void *) data);
+ NAMESPACE_INIT();
+ NAMESPACE_LOCK();
+ for (unsigned namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
+ if (namespaces[namespaceID].resStage != NAMESPACE_STATUS_UNUSED)
+ namespaceDelete((int)namespaceID);
+ if (namespaces != &initialNamespace)
+ {
+ Free(namespaces);
+ namespaces = &initialNamespace;
+ namespaces[0].resStage = NAMESPACE_STATUS_UNUSED;
+ }
+ namespacesSize = 1;
+ nNamespaces = 0;
+ NAMESPACE_UNLOCK();
}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+
-int srvDefDataDP(void *srv, const double *data)
+void cdiRefObject_construct(CdiReferencedObject* me)
{
- return srvDefData(srv, EXSE_DOUBLE_PRECISION, (void *) data);
+ me->destructor = cdiRefObject_destruct;
+ me->refCount = 1;
}
-
-int srvRead(int fileID, void *srv)
+void cdiRefObject_retain(CdiReferencedObject* me)
{
- srvrec_t *srvp = (srvrec_t *) srv;
- size_t i;
- union {
- INT32 i32[SRV_HEADER_LEN];
- INT64 i64[SRV_HEADER_LEN];
- } tempheader;
- void *buffer;
- int status;
+ size_t oldCount = me->refCount++;
+ xassert(oldCount && "A reference counted object was used after it was destructed.");
+}
- if ( ! srvp->checked )
+void cdiRefObject_release(CdiReferencedObject* me)
+{
+ size_t oldCount = me->refCount--;
+ xassert(oldCount && "A reference counted object was released too often.");
+ if(oldCount == 1)
{
- status = srvCheckFiletype(fileID, &srvp->byteswap);
- if ( status == 0 ) Error("Not a SERVICE file!");
- srvp->checked = 1;
+ me->destructor(me);
+ Free(me);
}
+}
- int byteswap = srvp->byteswap;
+void cdiRefObject_destruct(CdiReferencedObject* me)
+{
+ (void)me;
+ /* Empty for now, but that's no reason not to call it! */
+}
- /* read header record */
- size_t blocklen = binReadF77Block(fileID, byteswap);
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- if ( fileEOF(fileID) ) return -1;
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
- if ( SRV_Debug )
- Message("blocklen = %lu", blocklen);
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
- size_t hprec = blocklen / SRV_HEADER_LEN;
+#if defined (HAVE_EXECINFO_H)
+#include <execinfo.h>
+#endif
- srvp->hprec = (int)hprec;
+static
+void show_stackframe()
+{
+#if defined HAVE_EXECINFO_H && defined backtrace_size_t && defined HAVE_BACKTRACE
+ void *trace[16];
+ backtrace_size_t trace_size = backtrace(trace, 16);
+ char **messages = backtrace_symbols(trace, trace_size);
- switch ( hprec )
- {
- case EXSE_SINGLE_PRECISION:
- {
- binReadInt32(fileID, byteswap, SRV_HEADER_LEN, tempheader.i32);
+ fprintf(stderr, "[bt] Execution path:\n");
+ if ( messages ) {
+ for ( backtrace_size_t i = 0; i < trace_size; ++i )
+ fprintf(stderr, "[bt] %s\n", messages[i]);
+ free(messages);
+ }
+#endif
+}
- for ( i = 0; i < SRV_HEADER_LEN; i++ )
- srvp->header[i] = (int)tempheader.i32[i];
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- binReadInt64(fileID, byteswap, SRV_HEADER_LEN, tempheader.i64);
+enum { MIN_LIST_SIZE = 128 };
- for ( i = 0; i < SRV_HEADER_LEN; i++ )
- srvp->header[i] = (int)tempheader.i64[i];
+static void listInitialize(void);
- break;
- }
- default:
- {
- Error("Unexpected header precision %d", hprec);
- break;
- }
- }
+typedef struct listElem {
+ union
+ {
+ /* free-list management data */
+ struct
+ {
+ int next, prev;
+ } free;
+ /* holding an actual value */
+ struct
+ {
+ const resOps *ops;
+ void *val;//ptr
+ } v;
+ } res;
+ int status;
+} listElem_t;
- size_t blocklen2 = binReadF77Block(fileID, byteswap);
+struct resHList_t
+{
+ int size, freeHead, hasDefaultRes;
+ listElem_t *resources;
+};
- if ( blocklen2 != blocklen )
- {
- Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
- if ( blocklen2 != 0 ) return -1;
- }
+static struct resHList_t *resHList;
- srvp->datasize = (size_t)(srvp->header[4] * srvp->header[5]);
+static int resHListSize = 0;
- if ( SRV_Debug )
- Message("datasize = %lu", srvp->datasize);
+#if defined (HAVE_LIBPTHREAD)
+# include <pthread.h>
- blocklen = binReadF77Block(fileID, byteswap);
+static pthread_once_t listInitThread = PTHREAD_ONCE_INIT;
+static pthread_mutex_t listMutex;
- size_t buffersize = srvp->buffersize;
+# define LIST_LOCK() pthread_mutex_lock(&listMutex)
+# define LIST_UNLOCK() pthread_mutex_unlock(&listMutex)
+# define LIST_INIT(init0) do { \
+ pthread_once(&listInitThread, listInitialize); \
+ pthread_mutex_lock(&listMutex); \
+ if ((init0) && (!resHList || !resHList[0].resources)) \
+ reshListCreate(0); \
+ pthread_mutex_unlock(&listMutex); \
+ } while (0)
- if ( buffersize < blocklen )
- {
- buffersize = blocklen;
- buffer = srvp->buffer;
- buffer = Realloc(buffer, buffersize);
- srvp->buffer = buffer;
- srvp->buffersize = buffersize;
- }
- else
- buffer = srvp->buffer;
- size_t datasize = srvp->datasize;
- size_t dprec = blocklen / datasize;
+#else
- srvp->dprec = (int)dprec;
+static int listInit = 0;
- if ( dprec != EXSE_SINGLE_PRECISION && dprec != EXSE_DOUBLE_PRECISION )
- {
- Warning("Unexpected data precision %d", dprec);
- return -1;
- }
+# define LIST_LOCK()
+# define LIST_UNLOCK()
+# define LIST_INIT(init0) do { \
+ if ( !listInit ) \
+ { \
+ listInitialize(); \
+ if ((init0) && (!resHList || !resHList[0].resources)) \
+ reshListCreate(0); \
+ listInit = 1; \
+ } \
+ } while(0)
- fileRead(fileID, buffer, blocklen);
+#endif
- blocklen2 = binReadF77Block(fileID, byteswap);
+/**************************************************************/
- if ( blocklen2 != blocklen )
+static void
+listInitResources(int nsp)
+{
+ xassert(nsp < resHListSize && nsp >= 0);
+ int size = resHList[nsp].size = MIN_LIST_SIZE;
+ xassert(resHList[nsp].resources == NULL);
+ resHList[nsp].resources = (listElem_t*) Calloc(MIN_LIST_SIZE, sizeof(listElem_t));
+ listElem_t *p = resHList[nsp].resources;
+
+ for (int i = 0; i < size; i++ )
{
- Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
- if ( blocklen2 != 0 ) return -1;
+ p[i].res.free.next = i + 1;
+ p[i].res.free.prev = i - 1;
+ p[i].status = RESH_UNUSED;
}
- return 0;
+ p[size-1].res.free.next = -1;
+ resHList[nsp].freeHead = 0;
+ int oldNsp = namespaceGetActive();
+ namespaceSetActive(nsp);
+ instituteDefaultEntries();
+ modelDefaultEntries();
+ namespaceSetActive(oldNsp);
}
+static inline void
+reshListClearEntry(int i)
+{
+ resHList[i].size = 0;
+ resHList[i].resources = NULL;
+ resHList[i].freeHead = -1;
+}
-void srvWrite(int fileID, void *srv)
+void
+reshListCreate(int namespaceID)
{
- srvrec_t *srvp = (srvrec_t *) srv;
- size_t i;
- union
- {
- INT32 i32[SRV_HEADER_LEN];
- INT64 i64[SRV_HEADER_LEN];
- } tempheader;
- int byteswap = srvp->byteswap;
- int dprec = srvp->dprec;
- int hprec = srvp->hprec;
- int *restrict header = srvp->header;
+ LIST_INIT(namespaceID != 0);
+ LIST_LOCK();
+ if (resHListSize <= namespaceID)
+ {
+ resHList = (struct resHList_t *) Realloc(resHList, (size_t)(namespaceID + 1) * sizeof (resHList[0]));
+ for (int i = resHListSize; i <= namespaceID; ++i)
+ reshListClearEntry(i);
+ resHListSize = namespaceID + 1;
+ }
+ listInitResources(namespaceID);
+ LIST_UNLOCK();
+}
- /* write header record */
- size_t blocklen = SRV_HEADER_LEN * (size_t)hprec;
- binWriteF77Block(fileID, byteswap, blocklen);
+/**************************************************************/
- switch ( hprec )
+void
+reshListDestruct(int namespaceID)
+{
+ LIST_LOCK();
+ xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
+ int callerNamespaceID = namespaceGetActive();
+ namespaceSetActive(namespaceID);
+ if (resHList[namespaceID].resources)
{
- case EXSE_SINGLE_PRECISION:
- {
- for (i = 0; i < SRV_HEADER_LEN; i++)
- tempheader.i32[i] = (INT32) header[i];
-
- binWriteInt32(fileID, byteswap, SRV_HEADER_LEN, tempheader.i32);
-
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- for (i = 0; i < SRV_HEADER_LEN; i++)
- tempheader.i64[i] = (INT64) header[i];
+ for ( int j = 0; j < resHList[namespaceID].size; j++ )
+ {
+ listElem_t *listElem = resHList[namespaceID].resources + j;
+ if (listElem->status & RESH_IN_USE_BIT)
+ listElem->res.v.ops->valDestroy(listElem->res.v.val);
+ }
+ Free(resHList[namespaceID].resources);
+ resHList[namespaceID].resources = NULL;
+ reshListClearEntry(namespaceID);
+ }
+ if (resHList[callerNamespaceID].resources)
+ namespaceSetActive(callerNamespaceID);
+ LIST_UNLOCK();
+}
- binWriteInt64(fileID, byteswap, SRV_HEADER_LEN, tempheader.i64);
- break;
- }
- default:
- {
- Error("unexpected header precision %d", hprec);
- break;
- }
- }
+static void listDestroy ( void )
+{
+ LIST_LOCK();
+ for (int i = resHListSize; i > 0; --i)
+ if (resHList[i-1].resources)
+ namespaceDelete(i-1);
+ resHListSize = 0;
+ Free(resHList);
+ resHList = NULL;
+ cdiReset();
+ LIST_UNLOCK();
+}
- binWriteF77Block(fileID, byteswap, blocklen);
+/**************************************************************/
- size_t datasize = (size_t)(header[4] * header[5]);
- blocklen = datasize * (size_t)dprec;
+static
+void listInitialize ( void )
+{
+#if defined (HAVE_LIBPTHREAD)
+ pthread_mutexattr_t ma;
+ pthread_mutexattr_init(&ma);
+ pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+ /* initialize global API mutex lock */
+ pthread_mutex_init ( &listMutex, &ma);
+ pthread_mutexattr_destroy(&ma);
+#endif
+ /* file is special and has its own table, which needs to be
+ * created, before we register the listDestroy exit handler */
+ {
+ int null_id;
+ null_id = fileOpen_serial("/dev/null", "r");
+ if (null_id != -1)
+ fileClose_serial(null_id);
+ }
+ atexit ( listDestroy );
+}
- binWriteF77Block(fileID, byteswap, blocklen);
+/**************************************************************/
- srvp->datasize = datasize;
+static
+void listSizeExtend()
+{
+ int nsp = namespaceGetActive ();
+ int oldSize = resHList[nsp].size;
+ size_t newListSize = (size_t)oldSize + MIN_LIST_SIZE;
- void *buffer = srvp->buffer;
+ resHList[nsp].resources = (listElem_t*) Realloc(resHList[nsp].resources,
+ newListSize * sizeof(listElem_t));
- switch ( dprec )
+ listElem_t *r = resHList[nsp].resources;
+ for (size_t i = (size_t)oldSize; i < newListSize; ++i)
{
- case EXSE_SINGLE_PRECISION:
- {
- binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
- break;
- }
- case EXSE_DOUBLE_PRECISION:
- {
- binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
- break;
- }
- default:
- {
- Error("unexpected data precision %d", dprec);
- break;
- }
+ r[i].res.free.next = (int)i + 1;
+ r[i].res.free.prev = (int)i - 1;
+ r[i].status = RESH_UNUSED;
}
- binWriteF77Block(fileID, byteswap, blocklen);
+ if (resHList[nsp].freeHead != -1)
+ r[resHList[nsp].freeHead].res.free.prev = (int)newListSize - 1;
+ r[newListSize-1].res.free.next = resHList[nsp].freeHead;
+ r[oldSize].res.free.prev = -1;
+ resHList[nsp].freeHead = oldSize;
+ resHList[nsp].size = (int)newListSize;
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_SRV_H
-#define _STREAM_SRV_H
-#ifndef _SERVICE_H
-#endif
+/**************************************************************/
-int srvInqContents(stream_t *streamptr);
-int srvInqTimestep(stream_t *streamptr, int tsID);
+static void
+reshPut_(int nsp, int entry, void *p, const resOps *ops)
+{
+ listElem_t *newListElem = resHList[nsp].resources + entry;
+ int next = newListElem->res.free.next,
+ prev = newListElem->res.free.prev;
+ if (next != -1)
+ resHList[nsp].resources[next].res.free.prev = prev;
+ if (prev != -1)
+ resHList[nsp].resources[prev].res.free.next = next;
+ else
+ resHList[nsp].freeHead = next;
+ newListElem->res.v.val = p;
+ newListElem->res.v.ops = ops;
+ newListElem->status = RESH_DESYNC_IN_USE;
+}
-int srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void srvDefRecord(stream_t *streamptr);
-void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void srvWriteRecord(stream_t *streamptr, const double *data);
+int reshPut ( void *p, const resOps *ops )
+{
+ xassert ( p && ops );
-void srvReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
-void srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
+ LIST_INIT(1);
-void srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
-void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+ LIST_LOCK();
-#endif /* _STREAM_SRV_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_EXT_H
-#define _STREAM_EXT_H
+ int nsp = namespaceGetActive ();
-#ifndef _EXTRA_H
-#endif
+ if ( resHList[nsp].freeHead == -1) listSizeExtend();
+ int entry = resHList[nsp].freeHead;
+ cdiResH resH = namespaceIdxEncode2(nsp, entry);
+ reshPut_(nsp, entry, p, ops);
-int extInqContents(stream_t *streamptr);
-int extInqTimestep(stream_t *streamptr, int tsID);
+ LIST_UNLOCK();
-int extInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void extDefRecord(stream_t *streamptr);
-void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void extReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void extWriteRecord(stream_t *streamptr, const double *data);
+ return resH;
+}
-void extReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
-void extWriteVarDP(stream_t *streamptr, int varID, const double *data);
+/**************************************************************/
-void extReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
-void extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+static void
+reshRemove_(int nsp, int idx)
+{
+ int curFree = resHList[nsp].freeHead;
+ listElem_t *r = resHList[nsp].resources;
+ r[idx].res.free.next = curFree;
+ r[idx].res.free.prev = -1;
+ if (curFree != -1)
+ r[curFree].res.free.prev = idx;
+ r[idx].status = RESH_DESYNC_DELETED;
+ resHList[nsp].freeHead = idx;
+}
-#endif /* _STREAM_EXT_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_IEG_H
-#define _STREAM_IEG_H
+void reshDestroy(cdiResH resH)
+{
+ int nsp;
+ namespaceTuple_t nspT;
-#ifndef _IEG_H
-#endif
+ LIST_LOCK();
-int iegInqContents(stream_t *streamptr);
-int iegInqTimestep(stream_t *streamptr, int tsID);
+ nsp = namespaceGetActive ();
-int iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void iegDefRecord(stream_t *streamptr);
-void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void iegWriteRecord(stream_t *streamptr, const double *data);
+ nspT = namespaceResHDecode ( resH );
-void iegReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
-void iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
+ xassert ( nspT.nsp == nsp
+ && nspT.idx >= 0
+ && nspT.idx < resHList[nsp].size
+ && resHList[nsp].resources[nspT.idx].res.v.ops);
-void iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
-void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+ if (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
+ reshRemove_(nsp, nspT.idx);
-#endif /* _STREAM_IEG_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ LIST_UNLOCK();
+}
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-#endif
+void reshRemove ( cdiResH resH, const resOps * ops )
+{
+ int nsp;
+ namespaceTuple_t nspT;
-#include <ctype.h>
+ LIST_LOCK();
+ nsp = namespaceGetActive ();
+ nspT = namespaceResHDecode ( resH );
-static stream_t *stream_new_entry(int resH);
-static void stream_delete_entry(stream_t *streamptr);
-static int streamCompareP(void * streamptr1, void * streamptr2);
-static void streamDestroyP(void * streamptr);
-static void streamPrintP(void * streamptr, FILE * fp);
-static int streamGetPackSize(void * streamptr, void *context);
-static void streamPack(void * streamptr, void * buff, int size, int * position, void *context);
-static int streamTxCode(void);
+ xassert ( nspT.nsp == nsp
+ && nspT.idx >= 0
+ && nspT.idx < resHList[nsp].size
+ && (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
+ && resHList[nsp].resources[nspT.idx].res.v.ops
+ && resHList[nsp].resources[nspT.idx].res.v.ops == ops );
-const resOps streamOps = {
- streamCompareP,
- streamDestroyP,
- streamPrintP,
- streamGetPackSize,
- streamPack,
- streamTxCode
-};
+ reshRemove_(nsp, nspT.idx);
+ LIST_UNLOCK();
+}
+/**************************************************************/
-static
-int getByteorder(int byteswap)
+void reshReplace(cdiResH resH, void *p, const resOps *ops)
{
- int byteorder = -1;
-
- switch (HOST_ENDIANNESS)
+ xassert(p && ops);
+ LIST_INIT(1);
+ LIST_LOCK();
+ int nsp = namespaceGetActive();
+ namespaceTuple_t nspT = namespaceResHDecode(resH);
+ while (resHList[nsp].size <= nspT.idx)
+ listSizeExtend();
+ listElem_t *q = resHList[nsp].resources + nspT.idx;
+ if (q->status & RESH_IN_USE_BIT)
{
- case CDI_BIGENDIAN:
- byteorder = byteswap ? CDI_LITTLEENDIAN : CDI_BIGENDIAN;
- break;
- case CDI_LITTLEENDIAN:
- byteorder = byteswap ? CDI_BIGENDIAN : CDI_LITTLEENDIAN;
- break;
- /* FIXME: does not currently adjust for PDP endianness */
- case CDI_PDPENDIAN:
- default:
- Error("unhandled endianness");
+ q->res.v.ops->valDestroy(q->res.v.val);
+ reshRemove_(nsp, nspT.idx);
}
- return byteorder;
+ reshPut_(nsp, nspT.idx, p, ops);
+ LIST_UNLOCK();
}
-// used also in CDO
-int cdiGetFiletype(const char *filename, int *byteorder)
+
+static listElem_t *
+reshGetElem(const char *caller, const char* expressionString, cdiResH resH, const resOps *ops)
{
- int filetype = CDI_EUFTYPE;
- int swap = 0;
- int version;
- long recpos;
- char buffer[8];
+ listElem_t *listElem;
+ xassert ( ops );
- int fileID = fileOpen(filename, "r");
+ LIST_INIT(1);
- if ( fileID == CDI_UNDEFID )
- {
- if ( strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0 )
- return FILETYPE_NC;
- else
- return CDI_ESYSTEM;
- }
+ LIST_LOCK();
- if ( fileRead(fileID, buffer, 8) != 8 ) return CDI_EUFTYPE;
+ int nsp = namespaceGetActive ();
- fileRewind(fileID);
+ namespaceTuple_t nspT = namespaceResHDecode ( resH );
+ assert(nspT.idx >= 0);
- if ( memcmp(buffer, "GRIB", 4) == 0 )
- {
- version = buffer[7];
- if ( version <= 1 )
- {
- filetype = FILETYPE_GRB;
- if ( CDI_Debug ) Message("found GRIB file = %s, version %d", filename, version);
- }
- else if ( version == 2 )
- {
- filetype = FILETYPE_GRB2;
- if ( CDI_Debug ) Message("found GRIB2 file = %s", filename);
- }
- }
- else if ( memcmp(buffer, "CDF\001", 4) == 0 )
- {
- filetype = FILETYPE_NC;
- if ( CDI_Debug ) Message("found CDF1 file = %s", filename);
- }
- else if ( memcmp(buffer, "CDF\002", 4) == 0 )
- {
- filetype = FILETYPE_NC2;
- if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
- }
- else if ( memcmp(buffer+1, "HDF", 3) == 0 )
- {
- filetype = FILETYPE_NC4;
- if ( CDI_Debug ) Message("found HDF file = %s", filename);
- }
-#if defined (HAVE_LIBSERVICE)
- else if ( srvCheckFiletype(fileID, &swap) )
- {
- filetype = FILETYPE_SRV;
- if ( CDI_Debug ) Message("found SRV file = %s", filename);
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- else if ( extCheckFiletype(fileID, &swap) )
+ if (nspT.nsp == nsp &&
+ nspT.idx < resHList[nsp].size)
{
- filetype = FILETYPE_EXT;
- if ( CDI_Debug ) Message("found EXT file = %s", filename);
+ listElem = resHList[nsp].resources + nspT.idx;
+ LIST_UNLOCK();
}
-#endif
-#if defined (HAVE_LIBIEG)
- else if ( iegCheckFiletype(fileID, &swap) )
+ else
{
- filetype = FILETYPE_IEG;
- if ( CDI_Debug ) Message("found IEG file = %s", filename);
+ LIST_UNLOCK();
+ show_stackframe();
+
+ if ( resH == CDI_UNDEFID )
+ {
+ xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is CDI_UNDEFID (= %d).\n\tThis is most likely the result of a failed earlier call. Please check the IDs returned by CDI.", expressionString, caller, resH);
+ }
+ else
+ {
+ xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is garbage (= %d, which resolves to namespace = %d, index = %d).\n\tThis is either the result of using an uninitialized variable,\n\tof using a value as an ID that is not an ID,\n\tor of using an ID after it has been invalidated.", expressionString, caller, resH, nspT.nsp, nspT.idx);
+ }
}
-#endif
-#if defined (HAVE_LIBCGRIBEX)
- else if ( gribCheckSeek(fileID, &recpos, &version) == 0 )
+
+ if ( !(listElem && listElem->res.v.ops == ops) )
{
- if ( version <= 1 )
- {
- filetype = FILETYPE_GRB;
- if ( CDI_Debug ) Message("found seeked GRIB file = %s", filename);
- }
- else if ( version == 2 )
- {
- filetype = FILETYPE_GRB2;
- if ( CDI_Debug ) Message("found seeked GRIB2 file = %s", filename);
- }
- }
-#endif
+ show_stackframe();
- fileClose(fileID);
+ xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: list element not found. The failed ID is %d", expressionString, caller, (int)resH);
+ }
- *byteorder = getByteorder(swap);
+ return listElem;
+}
- return filetype;
+void *reshGetValue(const char * caller, const char* expressionString, cdiResH resH, const resOps * ops)
+{
+ return reshGetElem(caller, expressionString, resH, ops)->res.v.val;
}
-/*
- at Function streamInqFiletype
- at Title Get the filetype
+/**************************************************************/
- at Prototype int streamInqFiletype(int streamID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+void reshGetResHListOfType(unsigned numIDs, int resHs[], const resOps *ops)
+{
+ xassert ( resHs && ops );
- at Description
-The function @func{streamInqFiletype} returns the filetype of a stream.
+ LIST_INIT(1);
- at Result
- at func{streamInqFiletype} returns the type of the file format,
-one of the set of predefined CDI file format types.
-The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC}, @func{FILETYPE_NC2},
- at func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV}, @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
+ LIST_LOCK();
- at EndFunction
-*/
-int streamInqFiletype(int streamID)
+ int nsp = namespaceGetActive();
+ unsigned j = 0;
+ for (int i = 0; i < resHList[nsp].size && j < numIDs; i++ )
+ if ((resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
+ && resHList[nsp].resources[i].res.v.ops == ops)
+ resHs[j++] = namespaceIdxEncode2(nsp, i);
+
+ LIST_UNLOCK();
+}
+
+enum cdiApplyRet
+cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
+ void *data), void *data)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->filetype;
+ xassert(func);
+
+ LIST_INIT(1);
+
+ LIST_LOCK();
+
+ int nsp = namespaceGetActive ();
+ enum cdiApplyRet ret = CDI_APPLY_GO_ON;
+ for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
+ if (resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
+ ret = func(namespaceIdxEncode2(nsp, i),
+ resHList[nsp].resources[i].res.v.val,
+ resHList[nsp].resources[i].res.v.ops, data);
+ LIST_UNLOCK();
+ return ret;
}
-int getByteswap(int byteorder)
+enum cdiApplyRet
+cdiResHFilterApply(const resOps *p,
+ enum cdiApplyRet (*func)(int id, void *res, void *data),
+ void *data)
{
- int byteswap = -1;
+ xassert(p && func);
- switch (byteorder)
- {
- case CDI_BIGENDIAN:
- case CDI_LITTLEENDIAN:
- case CDI_PDPENDIAN:
- byteswap = (HOST_ENDIANNESS != byteorder);
- break;
- case -1:
- break;
- default:
- Error("unexpected byteorder %d query!", byteorder);
- }
+ LIST_INIT(1);
- return byteswap;
+ LIST_LOCK();
+
+ int nsp = namespaceGetActive ();
+ enum cdiApplyRet ret = CDI_APPLY_GO_ON;
+ listElem_t *r = resHList[nsp].resources;
+ for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
+ if ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == p)
+ ret = func(namespaceIdxEncode2(nsp, i), r[i].res.v.val,
+ data);
+ LIST_UNLOCK();
+ return ret;
}
-/*
- at Function streamDefByteorder
- at Title Define the byte order
- at Prototype void streamDefByteorder(int streamID, int byteorder)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item byteorder The byte order of a dataset, one of the CDI constants @func{CDI_BIGENDIAN} and
- @func{CDI_LITTLEENDIAN}.
- at Description
-The function @func{streamDefByteorder} defines the byte order of a binary dataset
-with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
- at EndFunction
-*/
-void streamDefByteorder(int streamID, int byteorder)
+/**************************************************************/
+
+unsigned reshCountType(const resOps *ops)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- streamptr->byteorder = byteorder;
- int filetype = streamptr->filetype;
+ unsigned countType = 0;
- switch (filetype)
- {
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
- srvp->byteswap = getByteswap(byteorder);
+ xassert(ops);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- extrec_t *extp = (extrec_t*) streamptr->record->exsep;
- extp->byteswap = getByteswap(byteorder);
+ LIST_INIT(1);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
- iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
- iegp->byteswap = getByteswap(byteorder);
+ LIST_LOCK();
- break;
- }
-#endif
- }
- reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
-}
+ int nsp = namespaceGetActive ();
-/*
- at Function streamInqByteorder
- at Title Get the byte order
+ listElem_t *r = resHList[nsp].resources;
+ size_t len = (size_t)resHList[nsp].size;
+ for (size_t i = 0; i < len; i++ )
+ countType += ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == ops);
- at Prototype int streamInqByteorder(int streamID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+ LIST_UNLOCK();
- at Description
-The function @func{streamInqByteorder} returns the byte order of a binary dataset
-with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
+ return countType;
+}
- at Result
- at func{streamInqByteorder} returns the type of the byte order.
-The valid CDI byte order types are @func{CDI_BIGENDIAN} and @func{CDI_LITTLEENDIAN}
+/**************************************************************/
- at EndFunction
-*/
-int streamInqByteorder(int streamID)
+int
+reshResourceGetPackSize_intern(int resH, const resOps *ops, void *context, const char* caller, const char* expressionString)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->byteorder;
+ listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
+ return curr->res.v.ops->valGetPackSize(curr->res.v.val, context);
}
-
-const char *streamFilesuffix(int filetype)
+void
+reshPackResource_intern(int resH, const resOps *ops, void *buf, int buf_size, int *position, void *context,
+ const char* caller, const char* expressionString)
{
- // static char *fileSuffix[] = {"", ".grb", ".g2", ".nc", ".nc", ".nc4", ".nc4", ".srv", ".ext", ".ieg"};
- /* note: the 2nd dimenstion of the fileSuffix array must be equal to or
- * larger than the length of the longest suffix (dot and \0 terminator
- * included) */
- static const char fileSuffix[][5] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
- int size = (int)(sizeof(fileSuffix)/sizeof(fileSuffix[0]));
-
- if ( filetype > 0 && filetype < size )
- return fileSuffix[filetype];
- else
- return fileSuffix[0];
+ listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
+ curr->res.v.ops->valPack(curr->res.v.val, buf, buf_size, position, context);
}
+enum {
+ resHPackHeaderNInt = 2,
+ resHDeleteNInt = 2,
+};
-const char *streamFilename(int streamID)
+static int getPackBufferSize(void *context)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->filename;
-}
+ int intpacksize, packBufferSize = 0;
-static
-long cdiInqTimeSize(int streamID)
-{
- int tsID = 0, nrecs;
- stream_t *streamptr = stream_to_pointer(streamID);
- long ntsteps = streamptr->ntsteps;
+ int nsp = namespaceGetActive ();
- if ( ntsteps == (long)CDI_UNDEFID )
- while ( (nrecs = streamInqTimestep(streamID, tsID++)) )
- ntsteps = streamptr->ntsteps;
+ /* pack start marker, namespace and sererator marker */
+ packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, CDI_DATATYPE_INT, context));
- return ntsteps;
+ /* pack resources, type marker and seperator marker */
+ listElem_t *r = resHList[nsp].resources;
+ for ( int i = 0; i < resHList[nsp].size; i++)
+ if (r[i].status & RESH_SYNC_BIT)
+ {
+ if (r[i].status == RESH_DESYNC_DELETED)
+ {
+ packBufferSize += resHDeleteNInt * intpacksize;
+ }
+ else if (r[i].status == RESH_DESYNC_IN_USE)
+ {
+ xassert ( r[i].res.v.ops );
+ /* packed resource plus 1 int for type */
+ packBufferSize +=
+ r[i].res.v.ops->valGetPackSize(r[i].res.v.val, context)
+ + intpacksize;
+ }
+ }
+ /* end marker */
+ packBufferSize += intpacksize;
+
+ return packBufferSize;
}
-static
-int cdiInqContents(stream_t * streamptr)
+/**************************************************************/
+
+void reshPackBufferDestroy ( char ** buffer )
{
- int status = 0;
+ if ( buffer ) free ( *buffer );
+}
- int filetype = streamptr->filetype;
+/**************************************************************/
- switch (filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- {
- status = grbInqContents(streamptr);
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- status = srvInqContents(streamptr);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- status = extInqContents(streamptr);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
- status = iegInqContents(streamptr);
- break;
- }
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- status = cdfInqContents(streamptr);
- break;
- }
-#endif
- default:
- {
- if ( CDI_Debug )
- Message("%s support not compiled in!", strfiletype(filetype));
+int reshGetTxCode(cdiResH resH)
+{
+ int type = 0;
- status = CDI_ELIBNAVAIL;
- break;
- }
- }
+ LIST_LOCK();
- if ( status == 0 )
+ int nsp = namespaceGetActive ();
+
+ namespaceTuple_t nspT = namespaceResHDecode ( resH );
+ assert(nspT.idx >= 0);
+
+ if (nspT.nsp == nsp &&
+ nspT.idx < resHList[nsp].size)
{
- int vlistID = streamptr->vlistID;
- int taxisID = vlistInqTaxis(vlistID);
- if ( taxisID != CDI_UNDEFID )
- {
- taxis_t *taxisptr1 = &streamptr->tsteps[0].taxis;
- taxis_t *taxisptr2 = taxisPtr(taxisID);
- ptaxisCopy(taxisptr2, taxisptr1);
- }
+ listElem_t *listElem = resHList[nsp].resources + nspT.idx;
+ xassert ( listElem->res.v.ops );
+ type = listElem->res.v.ops->valTxCode();
}
- return status;
+ LIST_UNLOCK();
+
+ return type;
}
-int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
- int filetype, stream_t *streamptr,
- int recordBufIsToBeCreated)
+/**************************************************************/
+
+int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
{
- int fileID;
- switch (filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+ int packBufferPos = 0;
+ int end = END;
+
+ xassert ( packBuffer );
+
+ LIST_LOCK();
+
+ int nsp = namespaceGetActive ();
+
+ int pBSize = *packBufferSize = getPackBufferSize(context);
+ char *pB = *packBuffer = (char *) Malloc((size_t)pBSize);
+
+ {
+ int header[resHPackHeaderNInt] = { START, nsp };
+ serializePack(header, resHPackHeaderNInt, CDI_DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+ }
+
+ listElem_t *r = resHList[nsp].resources;
+ for ( int i = 0; i < resHList[nsp].size; i++ )
+ if (r[i].status & RESH_SYNC_BIT)
{
-#ifndef __cplusplus
- fileID = gribOpen(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = gribOpen(filename, temp);
-#endif
- if ( fileID < 0 ) fileID = CDI_ESYSTEM;
- if (recordBufIsToBeCreated)
+ if (r[i].status == RESH_DESYNC_DELETED)
{
- streamptr->record = (Record *) Malloc(sizeof(Record));
- streamptr->record->buffer = NULL;
+ int temp[resHDeleteNInt]
+ = { RESH_DELETE, namespaceIdxEncode2(nsp, i) };
+ serializePack(temp, resHDeleteNInt, CDI_DATATYPE_INT,
+ pB, pBSize, &packBufferPos, context);
}
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
-#ifndef __cplusplus
- fileID = fileOpen(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = fileOpen(filename, temp);
-#endif
- if ( fileID < 0 ) fileID = CDI_ESYSTEM;
- if (recordBufIsToBeCreated)
+ else
{
- streamptr->record = (Record *) Malloc(sizeof(Record));
- streamptr->record->buffer = NULL;
- streamptr->record->exsep = srvNew();
+ listElem_t * curr = r + i;
+ xassert ( curr->res.v.ops );
+ int type = curr->res.v.ops->valTxCode();
+ if ( ! type ) continue;
+ serializePack(&type, 1, CDI_DATATYPE_INT, pB,
+ pBSize, &packBufferPos, context);
+ curr->res.v.ops->valPack(curr->res.v.val,
+ pB, pBSize, &packBufferPos, context);
}
- break;
+ r[i].status &= ~RESH_SYNC_BIT;
}
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
-#ifndef __cplusplus
- fileID = fileOpen(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = fileOpen(filename, temp);
-#endif
- if ( fileID < 0 ) fileID = CDI_ESYSTEM;
- if (recordBufIsToBeCreated)
- {
- streamptr->record = (Record *) Malloc(sizeof(Record));
- streamptr->record->buffer = NULL;
- streamptr->record->exsep = extNew();
- }
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
-#ifndef __cplusplus
- fileID = fileOpen(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = fileOpen(filename, temp);
-#endif
- if ( fileID < 0 ) fileID = CDI_ESYSTEM;
- if (recordBufIsToBeCreated)
- {
- streamptr->record = (Record *) Malloc(sizeof(Record));
- streamptr->record->buffer = NULL;
- streamptr->record->exsep = iegNew();
- }
- break;
- }
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- {
-#ifndef __cplusplus
- fileID = cdfOpen(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = cdfOpen(filename, temp);
-#endif
- break;
- }
- case FILETYPE_NC2:
- {
-#ifndef __cplusplus
- fileID = cdfOpen64(filename, (char [2]){filemode, 0});
-#else
- char temp[2] = { filemode, 0 };
- fileID = cdfOpen64(filename, temp);
-#endif
- break;
- }
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
-#ifndef __cplusplus
- fileID = cdf4Open(filename, (char [2]){filemode, 0}, &filetype);
-#else
- char temp[2] = { filemode, 0 };
- fileID = cdf4Open(filename, temp, &filetype);
-#endif
- break;
- }
-#endif
- default:
- {
- if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
- return CDI_ELIBNAVAIL;
- }
- }
+ LIST_UNLOCK();
- streamptr->filetype = filetype;
+ serializePack(&end, 1, CDI_DATATYPE_INT, pB, pBSize, &packBufferPos, context);
- return fileID;
+ return packBufferPos;
+}
+
+/**************************************************************/
+
+/* for thread safety this feature would have to be integrated in reshPut */
+
+void reshSetStatus ( cdiResH resH, const resOps * ops, int status )
+{
+ int nsp;
+ namespaceTuple_t nspT;
+ listElem_t * listElem;
+
+ xassert((ops != NULL) ^ !(status & RESH_IN_USE_BIT));
+
+ LIST_INIT(1);
+
+ LIST_LOCK();
+
+ nsp = namespaceGetActive ();
+
+ nspT = namespaceResHDecode ( resH );
+
+ xassert ( nspT.nsp == nsp &&
+ nspT.idx >= 0 &&
+ nspT.idx < resHList[nsp].size );
+
+ xassert ( resHList[nsp].resources );
+ listElem = resHList[nsp].resources + nspT.idx;
+
+ xassert((!ops || (listElem->res.v.ops == ops))
+ && (listElem->status & RESH_IN_USE_BIT) == (status & RESH_IN_USE_BIT));
+
+ listElem->status = status;
+
+ LIST_UNLOCK();
}
+/**************************************************************/
-int streamOpenID(const char *filename, char filemode, int filetype, int resH)
+int reshGetStatus ( cdiResH resH, const resOps * ops )
{
- if ( CDI_Debug )
- Message("Open %s mode %c file %s", strfiletype(filetype), filemode,
- filename?filename:"(NUL)");
+ int nsp;
+ namespaceTuple_t nspT;
- if ( ! filename || filetype < 0 ) return CDI_EINVAL;
+ LIST_INIT(1);
- stream_t *streamptr = stream_new_entry(resH);
- int streamID = CDI_ESYSTEM;
+ LIST_LOCK();
- int (*streamOpenDelegate)(const char *filename, char filemode,
- int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
- = (int (*)(const char *, char, int, stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
+ nsp = namespaceGetActive ();
- int fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
- if ( fileID < 0 )
- {
- streamID = fileID;
- }
- else
- {
- streamID = streamptr->self;
- if ( streamID < 0 ) return CDI_ELIMIT;
+ nspT = namespaceResHDecode ( resH );
- streamptr->filemode = filemode;
- streamptr->filename = strdupx(filename);
- streamptr->fileID = fileID;
+ xassert ( nspT.nsp == nsp &&
+ nspT.idx >= 0 &&
+ nspT.idx < resHList[nsp].size );
- if ( filemode == 'r' )
- {
- int vlistID = vlistCreate();
- if ( vlistID < 0 ) return CDI_ELIMIT;
+ listElem_t *listElem = resHList[nsp].resources + nspT.idx;
- cdiVlistMakeInternal(vlistID);
- streamptr->vlistID = vlistID;
- /* cdiReadByteorder(streamID); */
- int status = cdiInqContents(streamptr);
- if ( status < 0 )
- {
- streamID = status;
- }
- else
- {
- vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
- vlistptr->ntsteps = streamptr->ntsteps;
- cdiVlistMakeImmutable(vlistID);
- }
- }
- }
+ const resOps *elemOps = listElem->res.v.ops;
- if ( streamID < 0 )
- {
- Free(streamptr->record);
- stream_delete_entry(streamptr);
- }
+ LIST_UNLOCK();
- return streamID;
+ xassert(listElem && (!(listElem->status & RESH_IN_USE_BIT) || elemOps == ops));
+
+ return listElem->status;
}
-static int streamOpen(const char *filename, const char *filemode, int filetype)
+/**************************************************************/
+
+void reshLock ()
{
- if (!filemode || strlen(filemode) != 1) return CDI_EINVAL;
- return streamOpenID(filename, (char)tolower(filemode[0]),
- filetype, CDI_UNDEFID);
+ LIST_LOCK();
}
-static int streamOpenA(const char *filename, const char *filemode, int filetype)
+/**************************************************************/
+
+void reshUnlock ()
{
- int fileID = CDI_UNDEFID;
- int streamID = CDI_ESYSTEM;
- int status;
- stream_t *streamptr = stream_new_entry(CDI_UNDEFID);
- vlist_t *vlistptr;
+ LIST_UNLOCK();
+}
- if ( CDI_Debug )
- Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
- if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
+/**************************************************************/
- if ( ! filename || ! filemode || filetype < 0 ) return CDI_EINVAL;
+int reshListCompare ( int nsp0, int nsp1 )
+{
+ LIST_INIT(1);
+ LIST_LOCK();
- {
- int (*streamOpenDelegate)(const char *filename, char filemode,
- int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
- = (int (*)(const char *, char, int, stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
+ xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
+ nsp0 >= 0 && nsp1 >= 0);
- fileID = streamOpenDelegate(filename, 'r', filetype, streamptr, 1);
- }
+ int valCompare = 0;
+ int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
+ ? resHList[nsp0].size : resHList[nsp1].size;
+ listElem_t *resources0 = resHList[nsp0].resources,
+ *resources1 = resHList[nsp1].resources;
+ for (i = 0; i < listSizeMin; i++)
+ {
+ int occupied0 = (resources0[i].status & RESH_IN_USE_BIT) != 0,
+ occupied1 = (resources1[i].status & RESH_IN_USE_BIT) != 0;
+ /* occupation mismatch ? */
+ int diff = occupied0 ^ occupied1;
+ valCompare |= (diff << cdiResHListOccupationMismatch);
+ if (!diff && occupied0)
+ {
+ /* both occupied, do resource types match? */
+ diff = (resources0[i].res.v.ops != resources1[i].res.v.ops
+ || resources0[i].res.v.ops == NULL);
+ valCompare |= (diff << cdiResHListResourceTypeMismatch);
+ if (!diff)
+ {
+ /* types match, does content match also? */
+ diff
+ = resources0[i].res.v.ops->valCompare(resources0[i].res.v.val,
+ resources1[i].res.v.val);
+ valCompare |= (diff << cdiResHListResourceContentMismatch);
+ }
+ }
+ }
+ /* find resources in nsp 0 beyond end of nsp 1 */
+ for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
+ valCompare |= (((resources0[j].status & RESH_IN_USE_BIT) != 0)
+ << cdiResHListOccupationMismatch);
+ /* find resources in nsp 1 beyond end of nsp 0 */
+ for (; i < resHList[nsp1].size; ++i)
+ valCompare |= (((resources1[i].status & RESH_IN_USE_BIT) != 0)
+ << cdiResHListOccupationMismatch);
- if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return fileID;
+ LIST_UNLOCK();
- streamID = streamptr->self;
+ return valCompare;
+}
- streamptr->filemode = tolower(*filemode);
- streamptr->filename = strdupx(filename);
- streamptr->fileID = fileID;
+/**************************************************************/
- streamptr->vlistID = vlistCreate();
- cdiVlistMakeInternal(streamptr->vlistID);
- /* cdiReadByteorder(streamID); */
- status = cdiInqContents(streamptr);
- if ( status < 0 ) return status;
- vlistptr = vlist_to_pointer(streamptr->vlistID);
- vlistptr->ntsteps = (int)cdiInqTimeSize(streamID);
- if(!strcmp(filemode, "r")) cdiVlistMakeImmutable(streamptr->vlistID);
+void reshListPrint(FILE *fp)
+{
+ int i, j, temp;
+ listElem_t * curr;
- {
- void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
- = (void (*)(stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+ LIST_INIT(1);
- streamCloseDelegate(streamptr, 0);
- }
- switch (filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- {
- fileID = gribOpen(filename, filemode);
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- fileID = fileOpen(filename, filemode);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- fileID = fileOpen(filename, filemode);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
- fileID = fileOpen(filename, filemode);
- break;
- }
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- {
- fileID = cdfOpen(filename, filemode);
- streamptr->ncmode = 2;
- break;
- }
- case FILETYPE_NC2:
- {
- fileID = cdfOpen64(filename, filemode);
- streamptr->ncmode = 2;
- break;
- }
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- fileID = cdf4Open(filename, filemode, &filetype);
- streamptr->ncmode = 2;
- break;
- }
-#endif
- default:
- {
- if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
- return CDI_ELIBNAVAIL;
- }
- }
+ temp = namespaceGetActive ();
- if ( fileID == CDI_UNDEFID )
- streamID = CDI_UNDEFID;
- else
- streamptr->fileID = fileID;
+ fprintf ( fp, "\n\n##########################################\n#\n# print " \
+ "global resource list \n#\n" );
- return streamID;
-}
+ for ( i = 0; i < namespaceGetNumber (); i++ )
+ {
+ namespaceSetActive ( i );
-/*
- at Function streamOpenRead
- at Title Open a dataset for reading
+ fprintf ( fp, "\n" );
+ fprintf ( fp, "##################################\n" );
+ fprintf ( fp, "#\n" );
+ fprintf ( fp, "# namespace=%d\n", i );
+ fprintf ( fp, "#\n" );
+ fprintf ( fp, "##################################\n\n" );
- at Prototype int streamOpenRead(const char *path)
- at Parameter
- @Item path The name of the dataset to be read.
+ fprintf ( fp, "resHList[%d].size=%d\n", i, resHList[i].size );
- at Description
-The function @func{streamOpenRead} opens an existing dataset for reading.
+ for ( j = 0; j < resHList[i].size; j++ )
+ {
+ curr = resHList[i].resources + j;
+ if (!(curr->status & RESH_IN_USE_BIT))
+ {
+ curr->res.v.ops->valPrint(curr->res.v.val, fp);
+ fprintf ( fp, "\n" );
+ }
+ }
+ }
+ fprintf ( fp, "#\n# end global resource list" \
+ "\n#\n##########################################\n\n" );
- at Result
-Upon successful completion @func{streamOpenRead} returns an identifier to the
-open stream. Otherwise, a negative number with the error status is returned.
+ namespaceSetActive ( temp );
+}
- at Errors
- at List
- @Item CDI_ESYSTEM Operating system error.
- @Item CDI_EINVAL Invalid argument.
- @Item CDI_EUFILETYPE Unsupported file type.
- @Item CDI_ELIBNAVAIL Library support not compiled in.
- at EndList
- at Example
-Here is an example using @func{streamOpenRead} to open an existing NetCDF
-file named @func{foo.nc} for reading:
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#include <inttypes.h>
+#include <limits.h>
+#include <string.h>
- at Source
- ...
-int streamID;
- ...
-streamID = streamOpenRead("foo.nc");
-if ( streamID < 0 ) handle_error(streamID);
- ...
- at EndSource
- at EndFunction
-*/
-int streamOpenRead(const char *filename)
+
+int
+serializeGetSize(int count, int datatype, void *context)
{
- cdiInitialize();
+ int (*serialize_get_size_p)(int count, int datatype, void *context)
+ = (int (*)(int, int, void *))
+ namespaceSwitchGet(NSSWITCH_SERIALIZE_GET_SIZE).func;
+ return serialize_get_size_p(count, datatype, context);
+}
- int byteorder = 0;
- int filetype = cdiGetFiletype(filename, &byteorder);
+void serializePack(const void *data, int count, int datatype,
+ void *buf, int buf_size, int *position, void *context)
+{
+ void (*serialize_pack_p)(const void *data, int count, int datatype,
+ void *buf, int buf_size, int *position, void *context)
+ = (void (*)(const void *, int, int, void *, int, int *, void *))
+ namespaceSwitchGet(NSSWITCH_SERIALIZE_PACK).func;
+ serialize_pack_p(data, count, datatype, buf, buf_size, position, context);
+}
- if ( filetype < 0 ) return filetype;
+void serializeUnpack(const void *buf, int buf_size, int *position,
+ void *data, int count, int datatype, void *context)
+{
+ void (*serialize_unpack_p)(const void *buf, int buf_size, int *position,
+ void *data, int count, int datatype, void *context)
+ = (void (*)(const void *, int, int *, void *, int, int, void *))
+ namespaceSwitchGet(NSSWITCH_SERIALIZE_UNPACK).func;
+ serialize_unpack_p(buf, buf_size, position, data, count, datatype, context);
+}
- int streamID = streamOpen(filename, "r", filetype);
- if ( streamID >= 0 )
- {
- stream_t *streamptr = stream_to_pointer(streamID);
- streamptr->byteorder = byteorder;
- }
- return streamID;
+int
+serializeGetSizeInCore(int count, int datatype, void *context)
+{
+ int elemSize;
+ (void)context;
+ switch (datatype)
+ {
+ case CDI_DATATYPE_INT8:
+ elemSize = sizeof (int8_t);
+ break;
+ case CDI_DATATYPE_INT16:
+ elemSize = sizeof (int16_t);
+ break;
+ case CDI_DATATYPE_UINT32:
+ elemSize = sizeof (uint32_t);
+ break;
+ case CDI_DATATYPE_INT:
+ elemSize = sizeof (int);
+ break;
+ case CDI_DATATYPE_FLT:
+ case CDI_DATATYPE_FLT64:
+ elemSize = sizeof (double);
+ break;
+ case CDI_DATATYPE_TXT:
+ case CDI_DATATYPE_UCHAR:
+ elemSize = 1;
+ break;
+ case CDI_DATATYPE_LONG:
+ elemSize = sizeof (long);
+ break;
+ default:
+ xabort("Unexpected datatype");
+ }
+ return count * elemSize;
}
+void serializePackInCore(const void *data, int count, int datatype,
+ void *buf, int buf_size, int *position, void *context)
+{
+ int size = serializeGetSize(count, datatype, context);
+ int pos = *position;
+ xassert(INT_MAX - pos >= size && buf_size - pos >= size);
+ memcpy((unsigned char *)buf + pos, data, (size_t)size);
+ pos += size;
+ *position = pos;
+}
-int streamOpenAppend(const char *filename)
+void serializeUnpackInCore(const void *buf, int buf_size, int *position,
+ void *data, int count, int datatype, void *context)
{
- cdiInitialize();
+ int size = serializeGetSize(count, datatype, context);
+ int pos = *position;
+ xassert(INT_MAX - pos >= size && buf_size - pos >= size);
+ memcpy(data, (unsigned char *)buf + pos, (size_t)size);
+ pos += size;
+ *position = pos;
+}
- int byteorder = 0;
- int filetype = cdiGetFiletype(filename, &byteorder);
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- if ( filetype < 0 ) return filetype;
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
- int streamID = streamOpenA(filename, "a", filetype);
- if ( streamID >= 0 )
- {
- stream_t *streamptr = stream_to_pointer(streamID);
- streamptr->byteorder = byteorder;
- }
- return streamID;
-}
+enum {
+ SRV_HEADER_LEN = 8,
+};
+
+
+static int initSrvLib = 0;
+static int srvDefaultHprec = 0;
+static int srvDefaultDprec = 0;
+
/*
- at Function streamOpenWrite
- at Title Create a new dataset
+ * A version string.
+ */
+#undef LIBVERSION
+#define LIBVERSION 1.4.0
+#define XSTRING(x) #x
+#define STRING(x) XSTRING(x)
+static const char srv_libvers[] = STRING(LIBVERSION) " of " __DATE__" " __TIME__;
- at Prototype int streamOpenWrite(const char *path, int filetype)
- at Parameter
- @Item path The name of the new dataset.
- @Item filetype The type of the file format, one of the set of predefined CDI file format types.
- The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC},
- @func{FILETYPE_NC2}, @func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV},
- @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
+const char *srvLibraryVersion(void)
+{
+ return srv_libvers;
+}
- at Description
-The function @func{streamOpenWrite} creates a new datset.
- at Result
-Upon successful completion @func{streamOpenWrite} returns an identifier to the
-open stream. Otherwise, a negative number with the error status is returned.
- at Errors
- at List
- @Item CDI_ESYSTEM Operating system error.
- @Item CDI_EINVAL Invalid argument.
- @Item CDI_EUFILETYPE Unsupported file type.
- @Item CDI_ELIBNAVAIL Library support not compiled in.
- at EndList
+static int SRV_Debug = 0; /* If set to 1, debugging */
- at Example
-Here is an example using @func{streamOpenWrite} to create a new NetCDF file named @func{foo.nc} for writing:
- at Source
- ...
-int streamID;
- ...
-streamID = streamOpenWrite("foo.nc", FILETYPE_NC);
-if ( streamID < 0 ) handle_error(streamID);
- ...
- at EndSource
- at EndFunction
-*/
-int streamOpenWrite(const char *filename, int filetype)
+void srvDebug(int debug)
{
- cdiInitialize();
+ SRV_Debug = debug;
- return streamOpen(filename, "w", filetype);
+ if ( SRV_Debug )
+ Message("debug level %d", debug);
}
static
-void streamDefaultValue ( stream_t * streamptr )
+void srvLibInit()
{
- streamptr->self = CDI_UNDEFID;
- streamptr->accesstype = CDI_UNDEFID;
- streamptr->accessmode = 0;
- streamptr->filetype = FILETYPE_UNDEF;
- streamptr->byteorder = CDI_UNDEFID;
- streamptr->fileID = 0;
- streamptr->filemode = 0;
- streamptr->numvals = 0;
- streamptr->filename = NULL;
- streamptr->record = NULL;
- streamptr->varsAllocated = 0;
- streamptr->nrecs = 0;
- streamptr->nvars = 0;
- streamptr->vars = NULL;
- streamptr->ncmode = 0;
- streamptr->curTsID = CDI_UNDEFID;
- streamptr->rtsteps = 0;
- streamptr->ntsteps = CDI_UNDEFID;
- streamptr->tsteps = NULL;
- streamptr->tstepsTableSize = 0;
- streamptr->tstepsNextID = 0;
- streamptr->historyID = CDI_UNDEFID;
- streamptr->vlistID = CDI_UNDEFID;
- streamptr->globalatts = 0;
- streamptr->localatts = 0;
- streamptr->vct.ilev = 0;
- streamptr->vct.mlev = 0;
- streamptr->vct.ilevID = CDI_UNDEFID;
- streamptr->vct.mlevID = CDI_UNDEFID;
- streamptr->unreduced = cdiDataUnreduced;
- streamptr->sortname = cdiSortName;
- streamptr->have_missval = cdiHaveMissval;
- streamptr->comptype = COMPRESS_NONE;
- streamptr->complevel = 0;
+ const char *envName = "SRV_PRECISION";
- basetimeInit(&streamptr->basetime);
+ char *envString = getenv(envName);
+ if ( envString )
+ {
+ int nrun;
+ if ( strlen(envString) == 2 ) nrun = 1;
+ else nrun = 2;
+
+ int pos = 0;
+ while ( nrun-- )
+ {
+ switch ( tolower((int) envString[pos]) )
+ {
+ case 'i':
+ {
+ switch ( (int) envString[pos+1] )
+ {
+ case '4': srvDefaultHprec = EXSE_SINGLE_PRECISION; break;
+ case '8': srvDefaultHprec = EXSE_DOUBLE_PRECISION; break;
+ default:
+ Message("Invalid digit in %s: %s", envName, envString);
+ }
+ break;
+ }
+ case 'r':
+ {
+ switch ( (int) envString[pos+1] )
+ {
+ case '4': srvDefaultDprec = EXSE_SINGLE_PRECISION; break;
+ case '8': srvDefaultDprec = EXSE_DOUBLE_PRECISION; break;
+ default:
+ Message("Invalid digit in %s: %s", envName, envString);
+ }
+ break;
+ }
+ default:
+ {
+ Message("Invalid character in %s: %s", envName, envString);
+ break;
+ }
+ }
+ pos += 2;
+ }
+ }
- int i;
- for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->xdimID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ydimID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->nczvarID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncxvarID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncyvarID[i] = CDI_UNDEFID;
- for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncavarID[i] = CDI_UNDEFID;
+ initSrvLib = 1;
+}
- streamptr->gribContainers = NULL;
+static
+void srvInit(srvrec_t *srvp)
+{
+ srvp->checked = 0;
+ srvp->byteswap = 0;
+ srvp->hprec = 0;
+ srvp->dprec = 0;
+ srvp->datasize = 0;
+ srvp->buffersize = 0;
+ srvp->buffer = NULL;
}
-static stream_t *stream_new_entry(int resH)
+void *srvNew(void)
{
- stream_t *streamptr;
+ if ( ! initSrvLib ) srvLibInit();
- cdiInitialize(); /* ***************** make MT version !!! */
+ srvrec_t *srvp = (srvrec_t *) Malloc(sizeof(srvrec_t));
- streamptr = (stream_t *) Malloc(sizeof(stream_t));
- streamDefaultValue ( streamptr );
- if (resH == CDI_UNDEFID)
- streamptr->self = reshPut(streamptr, &streamOps);
- else
- {
- streamptr->self = resH;
- reshReplace(resH, streamptr, &streamOps);
- }
+ srvInit(srvp);
- return streamptr;
+ return (void*)srvp;
}
-void
-cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
+void srvDelete(void *srv)
{
- int fileID = streamptr->fileID;
- int filetype = streamptr->filetype;
- if ( fileID == CDI_UNDEFID )
- Warning("File %s not open!", streamptr->filename);
- else
- switch (filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- {
- gribClose(fileID);
- if (recordBufIsToBeDeleted)
- gribContainersDelete(streamptr);
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- fileClose(fileID);
- if (recordBufIsToBeDeleted)
- srvDelete(streamptr->record->exsep);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- fileClose(fileID);
- if (recordBufIsToBeDeleted)
- extDelete(streamptr->record->exsep);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
- fileClose(fileID);
- if (recordBufIsToBeDeleted)
- iegDelete(streamptr->record->exsep);
- break;
- }
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- cdfClose(fileID);
- break;
- }
-#endif
- default:
- {
- Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
- break;
- }
- }
-}
-
+ srvrec_t *srvp = (srvrec_t *) srv;
-static void deallocate_sleveltable_t(sleveltable_t *entry)
-{
- if (entry->recordID) Free(entry->recordID);
- if (entry->lindex) Free(entry->lindex);
- entry->recordID = NULL;
- entry->lindex = NULL;
+ if ( srvp )
+ {
+ if ( srvp->buffer ) Free(srvp->buffer);
+ Free(srvp);
+ }
}
-/*
- at Function streamClose
- at Title Close an open dataset
-
- at Prototype void streamClose(int streamID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
-
- at Description
-The function @func{streamClose} closes an open dataset.
-
- at EndFunction
-*/
-void streamClose(int streamID)
+int srvCheckFiletype(int fileID, int *swap)
{
- int index;
- stream_t *streamptr = stream_to_pointer(streamID);
-
- if ( CDI_Debug )
- Message("streamID = %d filename = %s", streamID, streamptr->filename);
+ size_t data = 0;
+ size_t dimx = 0, dimy = 0;
+ size_t fact = 0;
+ int found = 0;
+ unsigned char buffer[72], *pbuf;
- int vlistID = streamptr->vlistID;
+ if ( fileRead(fileID, buffer, 4) != 4 ) return found;
- void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
- = (void (*)(stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+ size_t blocklen = (size_t) get_UINT32(buffer);
+ size_t sblocklen = (size_t) get_SUINT32(buffer);
- if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
+ if ( SRV_Debug )
+ Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
- if ( streamptr->record )
+ if ( blocklen == 32 )
{
- if ( streamptr->record->buffer )
- Free(streamptr->record->buffer);
-
- Free(streamptr->record);
+ *swap = 0;
+ fact = blocklen>>3;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
+ pbuf = buffer+4*fact; dimx = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+5*fact; dimy = (size_t) get_UINT32(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
}
-
- streamptr->filetype = 0;
- if ( streamptr->filename ) Free(streamptr->filename);
-
- for ( index = 0; index < streamptr->nvars; index++ )
+ else if ( blocklen == 64 )
{
- sleveltable_t *pslev = streamptr->vars[index].recordTable;
- unsigned nsub = streamptr->vars[index].subtypeSize >= 0
- ? (unsigned)streamptr->vars[index].subtypeSize : 0U;
- for (size_t isub=0; isub < nsub; isub++)
- {
- deallocate_sleveltable_t(pslev + isub);
- }
- if (pslev) Free(pslev);
+ *swap = 0;
+ fact = blocklen>>3;
+ if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return found;
+ pbuf = buffer+4*fact; dimx = (size_t) get_UINT64(pbuf);
+ pbuf = buffer+5*fact; dimy = (size_t) get_UINT64(pbuf);
+ pbuf = buffer+blocklen+4; data = (size_t) get_UINT32(pbuf);
}
- Free(streamptr->vars);
- streamptr->vars = NULL;
-
- for ( index = 0; index < streamptr->ntsteps; ++index )
+ else if ( sblocklen == 32 )
{
- if ( streamptr->tsteps[index].records )
- Free(streamptr->tsteps[index].records);
- if ( streamptr->tsteps[index].recIDs )
- Free(streamptr->tsteps[index].recIDs);
- taxisDestroyKernel(&streamptr->tsteps[index].taxis);
+ *swap = 1;
+ fact = sblocklen>>3;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
+ pbuf = buffer+4*fact; dimx = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+5*fact; dimy = (size_t) get_SUINT32(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
+ }
+ else if ( sblocklen == 64 )
+ {
+ *swap = 1;
+ fact = sblocklen>>3;
+ if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return found;
+ pbuf = buffer+4*fact; dimx = (size_t) get_SUINT64(pbuf);
+ pbuf = buffer+5*fact; dimy = (size_t) get_SUINT64(pbuf);
+ pbuf = buffer+sblocklen+4; data = (size_t) get_SUINT32(pbuf);
}
- if ( streamptr->tsteps ) Free(streamptr->tsteps);
+ fileRewind(fileID);
- if ( streamptr->basetime.timevar_cache ) Free(streamptr->basetime.timevar_cache);
+ if ( data && dimx*dimy*fact == data ) found = 1;
+ else if ( data && dimx*dimy*8 == data ) found = 1;
- if ( vlistID != -1 )
+ if ( SRV_Debug )
{
- if ( streamptr->filemode != 'w' )
- if ( vlistInqTaxis(vlistID) != -1 )
- {
- taxisDestroy(vlistInqTaxis(vlistID));
- }
-
- cdiVlistDestroy_(vlistID);
+ Message("swap = %d fact = %d", *swap, fact);
+ Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
}
- stream_delete_entry(streamptr);
+ return found;
}
-static void stream_delete_entry(stream_t *streamptr)
+
+int srvInqHeader(void *srv, int *header)
{
- int idx;
+ srvrec_t *srvp = (srvrec_t *) srv;
- xassert ( streamptr );
+ for ( size_t i = 0; i < SRV_HEADER_LEN; i++ )
+ header[i] = srvp->header[i];
- idx = streamptr->self;
- Free( streamptr );
- reshRemove ( idx, &streamOps );
+ if ( SRV_Debug )
+ Message("datasize = %lu", srvp->datasize);
- if ( CDI_Debug )
- Message("Removed idx %d from stream list", idx);
+ return 0;
}
-void cdiStreamSync_(stream_t *streamptr)
+int srvDefHeader(void *srv, const int *header)
{
- int fileID = streamptr->fileID;
- int filetype = streamptr->filetype;
- int vlistID = streamptr->vlistID;
- int nvars = vlistNvars(vlistID);
+ srvrec_t *srvp = (srvrec_t *) srv;
- if ( fileID == CDI_UNDEFID )
- Warning("File %s not open!", streamptr->filename);
- else if ( vlistID == CDI_UNDEFID )
- Warning("Vlist undefined for file %s!", streamptr->filename);
- else if ( nvars == 0 )
- Warning("No variables defined!");
- else
+ for ( size_t i = 0; i < SRV_HEADER_LEN; i++ )
+ srvp->header[i] = header[i];
+
+ srvp->datasize = (size_t)(header[4] * header[5]);
+
+ if ( SRV_Debug )
+ Message("datasize = %lu", srvp->datasize);
+
+ return 0;
+}
+
+static
+int srvInqData(srvrec_t *srvp, int prec, void *data)
+{
+ size_t i;
+ int ierr = 0;
+ int byteswap = srvp->byteswap;
+ size_t datasize = srvp->datasize;
+ void *buffer = srvp->buffer;
+ int dprec = srvp->dprec;
+
+ switch ( dprec )
{
- if ( streamptr->filemode == 'w' || streamptr->filemode == 'a' )
- {
- switch (filetype)
- {
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- void cdf_sync(int ncid);
- if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
- break;
- }
-#endif
- default:
- {
- fileFlush(fileID);
- break;
- }
- }
- }
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( sizeof(FLT32) == 4 )
+ {
+ if ( byteswap ) swap4byte(buffer, datasize);
+
+ if ( dprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT32));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((double *) data)[i] = (double) ((float *) buffer)[i];
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT32));
+ }
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ if ( sizeof(FLT64) == 8 )
+ {
+ if ( byteswap ) swap8byte(buffer, datasize);
+
+ if ( dprec == prec )
+ memcpy(data, buffer, datasize*sizeof(FLT64));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((float *) data)[i] = (float) ((double *) buffer)[i];
+ }
+ else
+ {
+ Error("not implemented for %d byte float", sizeof(FLT64));
+ }
+ break;
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
}
+
+ return ierr;
}
-/*
- at Function streamSync
- at Title Synchronize an Open Dataset to Disk
- at Prototype void streamSync(int streamID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+int srvInqDataSP(void *srv, float *data)
+{
+ return srvInqData((srvrec_t *)srv, EXSE_SINGLE_PRECISION, (void *) data);
+}
- at Description
-The function @func{streamSync} offers a way to synchronize the disk copy of a dataset with in-memory buffers.
- at EndFunction
-*/
-void streamSync(int streamID)
+int srvInqDataDP(void *srv, double *data)
{
- stream_t *streamptr = stream_to_pointer(streamID);
-
- void (*myStreamSync_)(stream_t *streamptr)
- = (void (*)(stream_t *))namespaceSwitchGet(NSSWITCH_STREAM_SYNC).func;
- myStreamSync_(streamptr);
+ return srvInqData((srvrec_t *)srv, EXSE_DOUBLE_PRECISION, (void *) data);
}
-int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
+static int
+srvDefData(void *srv, int prec, const void *data)
{
- int taxisID = 0;
+ srvrec_t *srvp = (srvrec_t *) srv;
+ size_t i;
+ int dprec, hprec;
+ void *buffer;
- stream_check_ptr(__func__, streamptr);
+ if ( srvDefaultDprec ) dprec = srvDefaultDprec;
+ else dprec = srvp->dprec;
- if ( CDI_Debug )
- Message("streamID = %d tsID = %d", streamptr->self, tsID);
+ if ( ! dprec ) dprec = prec;
- int vlistID = streamptr->vlistID;
+ srvp->dprec = dprec;
- int time_is_varying = vlistHasTime(vlistID);
+ if ( srvDefaultHprec ) hprec = srvDefaultHprec;
+ else hprec = srvp->hprec;
- if ( time_is_varying )
- {
- taxisID = vlistInqTaxis(vlistID);
- if ( taxisID == CDI_UNDEFID )
- {
- Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
- taxisID = taxisCreate(TAXIS_ABSOLUTE);
- vlistDefTaxis(vlistID, taxisID);
- }
- }
+ if ( ! hprec ) hprec = dprec;
- int newtsID = tstepsNewEntry(streamptr);
+ srvp->hprec = hprec;
- if ( tsID != newtsID )
- Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
+ int *header = srvp->header;
- streamptr->curTsID = tsID;
+ size_t datasize = (size_t)(header[4] * header[5]);
+ size_t blocklen = datasize * (size_t)dprec;
- if ( time_is_varying )
- {
- taxis_t *taxisptr1 = taxisPtr(taxisID);
- taxis_t *taxisptr2 = &streamptr->tsteps[tsID].taxis;
- ptaxisCopy(taxisptr2, taxisptr1);
- }
+ srvp->datasize = datasize;
- streamptr->ntsteps = tsID + 1;
+ size_t buffersize = srvp->buffersize;
-#ifdef HAVE_LIBNETCDF
- if ((streamptr->filetype == FILETYPE_NC ||
- streamptr->filetype == FILETYPE_NC2 ||
- streamptr->filetype == FILETYPE_NC4 ||
- streamptr->filetype == FILETYPE_NC4C)
- && time_is_varying)
+ if ( buffersize != blocklen )
{
- void (*myCdfDefTimestep)(stream_t *streamptr, int tsID)
- = (void (*)(stream_t *, int))
- namespaceSwitchGet(NSSWITCH_CDF_DEF_TIMESTEP).func;
- myCdfDefTimestep(streamptr, tsID);
+ buffersize = blocklen;
+ buffer = srvp->buffer;
+ buffer = Realloc(buffer, buffersize);
+ srvp->buffer = buffer;
+ srvp->buffersize = buffersize;
}
-#endif
-
- cdi_create_records(streamptr, tsID);
+ else
+ buffer = srvp->buffer;
- return (int)streamptr->ntsteps;
-}
+ switch ( dprec )
+ {
+ case EXSE_SINGLE_PRECISION:
+ {
+ if ( dprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT32));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((float *) buffer)[i] = (float) ((double *) data)[i];
-/*
- at Function streamDefTimestep
- at Title Define time step
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ if ( dprec == prec )
+ memcpy(buffer, data, datasize*sizeof(FLT64));
+ else
+ for ( i = 0; i < datasize; i++ )
+ ((double *) buffer)[i] = (double) ((float *) data)[i];
- at Prototype int streamDefTimestep(int streamID, int tsID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item tsID Timestep identifier.
+ break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
+ }
- at Description
-The function @func{streamDefTimestep} defines the time step of a stream.
+ return 0;
+}
- at Result
- at func{streamDefTimestep} returns the number of records of the time step.
- at EndFunction
-*/
-int streamDefTimestep(int streamID, int tsID)
+int srvDefDataSP(void *srv, const float *data)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- int (*myStreamDefTimestep_)(stream_t *streamptr, int tsID)
- = (int (*)(stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_DEF_TIMESTEP_).func;
- return myStreamDefTimestep_(streamptr, tsID);
+ return srvDefData(srv, EXSE_SINGLE_PRECISION, (void *) data);
}
-int streamInqCurTimestepID(int streamID)
+
+int srvDefDataDP(void *srv, const double *data)
{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->curTsID;
+ return srvDefData(srv, EXSE_DOUBLE_PRECISION, (void *) data);
}
-/*
- at Function streamInqTimestep
- at Title Get time step
-
- at Prototype int streamInqTimestep(int streamID, int tsID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
- @Item tsID Timestep identifier.
-
- at Description
-The function @func{streamInqTimestep} returns the time step of a stream.
-
- at Result
- at func{streamInqTimestep} returns the number of records of the time step.
-
- at EndFunction
-*/
-int streamInqTimestep(int streamID, int tsID)
+int srvRead(int fileID, void *srv)
{
- int nrecs = 0;
- int taxisID;
- stream_t *streamptr = stream_to_pointer(streamID);
- int vlistID = streamptr->vlistID;
+ srvrec_t *srvp = (srvrec_t *) srv;
+ size_t i;
+ union {
+ INT32 i32[SRV_HEADER_LEN];
+ INT64 i64[SRV_HEADER_LEN];
+ } tempheader;
+ void *buffer;
+ int status;
- if ( tsID < streamptr->rtsteps )
+ if ( ! srvp->checked )
{
- streamptr->curTsID = tsID;
- nrecs = streamptr->tsteps[tsID].nrecs;
- streamptr->tsteps[tsID].curRecID = CDI_UNDEFID;
- taxisID = vlistInqTaxis(vlistID);
- if ( taxisID == -1 )
- Error("Timestep undefined for fileID = %d", streamID);
- ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
-
- return nrecs;
+ status = srvCheckFiletype(fileID, &srvp->byteswap);
+ if ( status == 0 ) Error("Not a SERVICE file!");
+ srvp->checked = 1;
}
- if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
- {
- return 0;
- }
+ int byteswap = srvp->byteswap;
- int filetype = streamptr->filetype;
+ /* read header record */
+ size_t blocklen = binReadF77Block(fileID, byteswap);
- if ( CDI_Debug )
- Message("streamID = %d tsID = %d filetype = %d", streamID, tsID, filetype);
+ if ( fileEOF(fileID) ) return -1;
- switch (filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- {
- nrecs = grbInqTimestep(streamptr, tsID);
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- nrecs = srvInqTimestep(streamptr, tsID);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- nrecs = extInqTimestep(streamptr, tsID);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+ if ( SRV_Debug )
+ Message("blocklen = %lu", blocklen);
+
+ size_t hprec = blocklen / SRV_HEADER_LEN;
+
+ srvp->hprec = (int)hprec;
+
+ switch ( hprec )
+ {
+ case EXSE_SINGLE_PRECISION:
{
- nrecs = iegInqTimestep(streamptr, tsID);
+ binReadInt32(fileID, byteswap, SRV_HEADER_LEN, tempheader.i32);
+
+ for ( i = 0; i < SRV_HEADER_LEN; i++ )
+ srvp->header[i] = (int)tempheader.i32[i];
+
break;
}
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+ case EXSE_DOUBLE_PRECISION:
{
- nrecs = cdfInqTimestep(streamptr, tsID);
+ binReadInt64(fileID, byteswap, SRV_HEADER_LEN, tempheader.i64);
+
+ for ( i = 0; i < SRV_HEADER_LEN; i++ )
+ srvp->header[i] = (int)tempheader.i64[i];
+
break;
}
-#endif
default:
{
- Error("%s support not compiled in!", strfiletype(filetype));
- break;
+ Error("Unexpected header precision %d", hprec);
+ break;
}
}
- taxisID = vlistInqTaxis(vlistID);
- if ( taxisID == -1 )
- Error("Timestep undefined for fileID = %d", streamID);
+ size_t blocklen2 = binReadF77Block(fileID, byteswap);
- ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
+ if ( blocklen2 != blocklen )
+ {
+ Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+ if ( blocklen2 != 0 ) return -1;
+ }
- return nrecs;
-}
+ srvp->datasize = (size_t)(srvp->header[4] * srvp->header[5]);
-#if 0
-void streamWriteContents(int streamID, char *cname)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
+ if ( SRV_Debug )
+ Message("datasize = %lu", srvp->datasize);
- int vlistID = streamptr->vlistID;
+ blocklen = binReadF77Block(fileID, byteswap);
- FILE *cnp = fopen(cname, "w");
+ size_t buffersize = srvp->buffersize;
- if ( cnp == NULL ) SysError(cname);
+ if ( buffersize < blocklen )
+ {
+ buffersize = blocklen;
+ buffer = srvp->buffer;
+ buffer = Realloc(buffer, buffersize);
+ srvp->buffer = buffer;
+ srvp->buffersize = buffersize;
+ }
+ else
+ buffer = srvp->buffer;
- fprintf(cnp, "#CDI library version %s\n", cdiLibraryVersion());
- fprintf(cnp, "#\n");
+ size_t datasize = srvp->datasize;
- fprintf(cnp, "filename: %s\n", streamptr->filename);
- int filetype = streamptr->filetype;
- fprintf(cnp, "filetype: %s\n", strfiletype(filetype));
+ size_t dprec = blocklen / datasize;
- fprintf(cnp, "#\n");
- fprintf(cnp, "#grids:\n");
+ srvp->dprec = (int)dprec;
- int ngrids = vlistNgrids(vlistID);
- for ( int i = 0; i < ngrids; i++ )
+ if ( dprec != EXSE_SINGLE_PRECISION && dprec != EXSE_DOUBLE_PRECISION )
{
- int gridID = vlistGrid(vlistID, i);
- int gridtype = gridInqType(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
- fprintf(cnp, "%4d:%4d:%4d:%4d\n", i+1, gridtype, xsize, ysize);
+ Warning("Unexpected data precision %d", dprec);
+ return -1;
}
- fprintf(cnp, "#\n");
+ fileRead(fileID, buffer, blocklen);
- fprintf(cnp, "varID:code:gridID:zaxisID:tsteptype:datatype\n");
+ blocklen2 = binReadF77Block(fileID, byteswap);
- int nvars = vlistNvars(vlistID);
- for ( int varID = 0; varID < nvars; varID++ )
+ if ( blocklen2 != blocklen )
{
- int code = vlistInqVarCode(vlistID, varID);
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
- int datatype = vlistInqVarDatatype(vlistID, varID);
- fprintf(cnp, "%4d:%4d:%4d:%4d:%4d:%4d:\n",
- varID+1, code, gridID, zaxisID, tsteptype, datatype);
+ Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+ if ( blocklen2 != 0 ) return -1;
}
- fprintf(cnp, "#\n");
+ return 0;
+}
- fprintf(cnp, "tsID:nrecs:date:time\n");
- int tsID = 0;
- while (1)
+void srvWrite(int fileID, void *srv)
+{
+ srvrec_t *srvp = (srvrec_t *) srv;
+ size_t i;
+ union
+ {
+ INT32 i32[SRV_HEADER_LEN];
+ INT64 i64[SRV_HEADER_LEN];
+ } tempheader;
+ int byteswap = srvp->byteswap;
+ int dprec = srvp->dprec;
+ int hprec = srvp->hprec;
+ int *restrict header = srvp->header;
+
+ /* write header record */
+ size_t blocklen = SRV_HEADER_LEN * (size_t)hprec;
+
+ binWriteF77Block(fileID, byteswap, blocklen);
+
+ switch ( hprec )
{
- int nrecs = streamptr->tsteps[tsID].nallrecs;
- int date = streamptr->tsteps[tsID].taxis.vdate;
- int time = streamptr->tsteps[tsID].taxis.vtime;
- off_t position = streamptr->tsteps[tsID].position;
+ case EXSE_SINGLE_PRECISION:
+ {
+ for (i = 0; i < SRV_HEADER_LEN; i++)
+ tempheader.i32[i] = (INT32) header[i];
- fprintf(cnp, "%4d:%4d:%4d:%4d:%ld\n",
- tsID, nrecs, date, time, (long) position);
+ binWriteInt32(fileID, byteswap, SRV_HEADER_LEN, tempheader.i32);
+
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ for (i = 0; i < SRV_HEADER_LEN; i++)
+ tempheader.i64[i] = (INT64) header[i];
+
+ binWriteInt64(fileID, byteswap, SRV_HEADER_LEN, tempheader.i64);
- if ( streamptr->tsteps[tsID].next )
- tsID++;
- else
break;
+ }
+ default:
+ {
+ Error("unexpected header precision %d", hprec);
+ break;
+ }
}
- fprintf(cnp, "#\n");
+ binWriteF77Block(fileID, byteswap, blocklen);
- fprintf(cnp, "tsID:recID:varID:levID:size:pos\n");
+ size_t datasize = (size_t)(header[4] * header[5]);
+ blocklen = datasize * (size_t)dprec;
- tsID = 0;
- while (1)
- {
- int nrecs = streamptr->tsteps[tsID].nallrecs;
- for ( int recID = 0; recID < nrecs; recID++ )
- {
- int varID = streamptr->tsteps[tsID].records[recID].varID;
- int levelID = streamptr->tsteps[tsID].records[recID].levelID;
- off_t recpos = streamptr->tsteps[tsID].records[recID].position;
- long recsize = (long)streamptr->tsteps[tsID].records[recID].size;
- fprintf(cnp, "%4d:%4d:%4d:%4d:%4ld:%ld\n",
- tsID, recID, varID, levelID, recsize, (long) recpos);
- }
+ binWriteF77Block(fileID, byteswap, blocklen);
- if ( streamptr->tsteps[tsID].next )
- tsID++;
- else
+ srvp->datasize = datasize;
+
+ void *buffer = srvp->buffer;
+
+ switch ( dprec )
+ {
+ case EXSE_SINGLE_PRECISION:
+ {
+ binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
+ break;
+ }
+ case EXSE_DOUBLE_PRECISION:
+ {
+ binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
break;
+ }
+ default:
+ {
+ Error("unexpected data precision %d", dprec);
+ break;
+ }
}
- fclose(cnp);
+ binWriteF77Block(fileID, byteswap, blocklen);
}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_SRV_H
+#define _STREAM_SRV_H
+
+#ifndef _SERVICE_H
#endif
-// This function is used in CDO!
-off_t streamNvals(int streamID)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
+int srvInqContents(stream_t *streamptr);
+int srvInqTimestep(stream_t *streamptr, int tsID);
- return streamptr->numvals;
-}
+int srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void srvDefRecord(stream_t *streamptr);
+void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void srvReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
+void srvWriteRecord(stream_t *streamptr, const double *data);
-/*
- at Function streamDefVlist
- at Title Define the variable list
+void srvReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
- at Prototype void streamDefVlist(int streamID, int vlistID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
+void srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
+void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
- at Description
-The function @func{streamDefVlist} defines the variable list of a stream.
+#endif /* _STREAM_SRV_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_EXT_H
+#define _STREAM_EXT_H
-To safeguard against errors by modifying the wrong vlist object,
-this function makes the passed vlist object immutable.
-All further vlist changes have to use the vlist object returned by streamInqVlist().
+#ifndef _EXTRA_H
+#endif
- at EndFunction
-*/
-void streamDefVlist(int streamID, int vlistID)
-{
- void (*myStreamDefVlist)(int streamID, int vlistID)
- = (void (*)(int, int))namespaceSwitchGet(NSSWITCH_STREAM_DEF_VLIST_).func;
- myStreamDefVlist(streamID, vlistID);
-}
+int extInqContents(stream_t *streamptr);
+int extInqTimestep(stream_t *streamptr, int tsID);
-/* the single image implementation of streamDefVlist */
-void
-cdiStreamDefVlist_(int streamID, int vlistID)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
+int extInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void extDefRecord(stream_t *streamptr);
+void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void extReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
+void extWriteRecord(stream_t *streamptr, const double *data);
- if ( streamptr->vlistID == CDI_UNDEFID )
- {
- int vlistCopy = vlistDuplicate(vlistID);
- cdiVlistMakeInternal(vlistCopy);
- cdiVlistMakeImmutable(vlistID);
- cdiStreamSetupVlist(streamptr, vlistCopy);
- }
- else
- Warning("vlist already defined for %s!", streamptr->filename);
-}
+void extReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data);
+
+void extReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
+void extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+#endif /* _STREAM_EXT_H */
/*
- at Function streamInqVlist
- at Title Get the variable list
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_IEG_H
+#define _STREAM_IEG_H
- at Prototype int streamInqVlist(int streamID)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+#ifndef _IEG_H
+#endif
- at Description
-The function @func{streamInqVlist} returns the variable list of a stream.
+int iegInqContents(stream_t *streamptr);
+int iegInqTimestep(stream_t *streamptr, int tsID);
- at Result
- at func{streamInqVlist} returns an identifier to the variable list.
+int iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void iegDefRecord(stream_t *streamptr);
+void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void iegReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
+void iegWriteRecord(stream_t *streamptr, const double *data);
- at EndFunction
-*/
-int streamInqVlist(int streamID)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->vlistID;
-}
+void iegReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
+void iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
-void streamDefCompType(int streamID, int comptype)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
- if ( streamptr->comptype != comptype )
- {
- streamptr->comptype = comptype;
- reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
- }
-}
+#endif /* _STREAM_IEG_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
-void streamDefCompLevel(int streamID, int complevel)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
- if ( streamptr->complevel != complevel )
- {
- streamptr->complevel = complevel;
- reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
- }
-}
+#include <sys/stat.h> // struct stat
+#include <ctype.h>
-int streamInqCompType(int streamID)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->comptype;
-}
+static stream_t *stream_new_entry(int resH);
+static void stream_delete_entry(stream_t *streamptr);
+static int streamCompareP(void * streamptr1, void * streamptr2);
+static void streamDestroyP(void * streamptr);
+static void streamPrintP(void * streamptr, FILE * fp);
+static int streamGetPackSize(void * streamptr, void *context);
+static void streamPack(void * streamptr, void * buff, int size, int * position, void *context);
+static int streamTxCode(void);
-int streamInqCompLevel(int streamID)
-{
- stream_t *streamptr = stream_to_pointer(streamID);
- return streamptr->complevel;
-}
+const resOps streamOps = {
+ streamCompareP,
+ streamDestroyP,
+ streamPrintP,
+ streamGetPackSize,
+ streamPack,
+ streamTxCode
+};
-int streamInqFileID(int streamID)
-{
- stream_t *streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
- return streamptr->fileID;
-}
-void cdiDefAccesstype(int streamID, int type)
+static
+int getByteorder(int byteswap)
{
- stream_t *streamptr = (stream_t *)reshGetVal(streamID, &streamOps);
+ int byteorder = -1;
- if ( streamptr->accesstype == CDI_UNDEFID )
+ switch (HOST_ENDIANNESS)
{
- streamptr->accesstype = type;
+ case CDI_BIGENDIAN:
+ byteorder = byteswap ? CDI_LITTLEENDIAN : CDI_BIGENDIAN;
+ break;
+ case CDI_LITTLEENDIAN:
+ byteorder = byteswap ? CDI_BIGENDIAN : CDI_LITTLEENDIAN;
+ break;
+ /* FIXME: does not currently adjust for PDP endianness */
+ case CDI_PDPENDIAN:
+ default:
+ Error("unhandled endianness");
}
- else if ( streamptr->accesstype != type )
- Error("Changing access type from %s not allowed!",
- streamptr->accesstype == TYPE_REC ? "REC to VAR" : "VAR to REC");
-}
-
-
-int cdiInqAccesstype(int streamID)
-{
- stream_t *streamptr = (stream_t *) reshGetVal ( streamID, &streamOps );
- return streamptr->accesstype;
+ return byteorder;
}
-static
-int streamTxCode(void)
+// used also in CDO
+int cdiGetFiletype(const char *filename, int *byteorder)
{
- return STREAM;
-}
+ int filetype = CDI_EUFTYPE;
+ int swap = 0;
+ int version;
+ long recpos;
-void
-cdiStreamSetupVlist(stream_t *streamptr, int vlistID)
-{
- void (*myStreamSetupVlist)(stream_t *streamptr, int vlistID)
- = (void (*)(stream_t *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_SETUP_VLIST).func;
- myStreamSetupVlist(streamptr, vlistID);
-}
+ int fileID = fileOpen(filename, "r");
-void
-cdiStreamSetupVlist_(stream_t *streamptr, int vlistID)
-{
- int nvars = vlistNvars(vlistID);
- streamptr->vlistID = vlistID;
- for (int varID = 0; varID < nvars; varID++ )
+ if ( fileID == CDI_UNDEFID )
{
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tilesetID = vlistInqVarSubtype(vlistID, varID);
- stream_new_var(streamptr, gridID, zaxisID, tilesetID);
- if ( streamptr->have_missval )
- vlistDefVarMissval(vlistID, varID,
- vlistInqVarMissval(vlistID, varID));
+ if ( strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0 )
+ return CDI_FILETYPE_NC;
+ else
+ return CDI_ESYSTEM;
}
- if (streamptr->filemode == 'w')
- switch (streamptr->filetype)
- {
-#ifdef HAVE_LIBNETCDF
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+ char buffer[8];
+ if ( fileRead(fileID, buffer, 8) != 8 )
+ {
+ struct stat buf;
+ if ( stat(filename, &buf) == 0 )
{
- void (*myCdfDefVars)(stream_t *streamptr)
- = (void (*)(stream_t *))
- namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
- myCdfDefVars(streamptr);
+ if ( buf.st_size == 0 ) return CDI_EISEMPTY;
+ if ( buf.st_mode&S_IFDIR ) return CDI_EISDIR;
}
- break;
-#endif
-#ifdef HAVE_LIBGRIB
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- gribContainersNew(streamptr);
- break;
-#endif
- default:
- ;
- }
-}
+ return CDI_EUFTYPE;
+ }
-void cdiStreamGetIndexList(unsigned numIDs, int *IDs)
-{
- reshGetResHListOfType(numIDs, IDs, &streamOps);
+ fileRewind(fileID);
+
+ if ( memcmp(buffer, "GRIB", 4) == 0 )
+ {
+ version = buffer[7];
+ if ( version <= 1 )
+ {
+ filetype = CDI_FILETYPE_GRB;
+ if ( CDI_Debug ) Message("found GRIB file = %s, version %d", filename, version);
+ }
+ else if ( version == 2 )
+ {
+ filetype = CDI_FILETYPE_GRB2;
+ if ( CDI_Debug ) Message("found GRIB2 file = %s", filename);
+ }
+ }
+ else if ( memcmp(buffer, "CDF\001", 4) == 0 )
+ {
+ filetype = CDI_FILETYPE_NC;
+ if ( CDI_Debug ) Message("found CDF1 file = %s", filename);
+ }
+ else if ( memcmp(buffer, "CDF\002", 4) == 0 )
+ {
+ filetype = CDI_FILETYPE_NC2;
+ if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
+ }
+ else if ( memcmp(buffer, "CDF\005", 4) == 0 )
+ {
+ filetype = CDI_FILETYPE_NC5;
+ if ( CDI_Debug ) Message("found CDF5 file = %s", filename);
+ }
+ else if ( memcmp(buffer+1, "HDF", 3) == 0 )
+ {
+ filetype = CDI_FILETYPE_NC4;
+ if ( CDI_Debug ) Message("found HDF file = %s", filename);
+ }
+ else if ( srvCheckFiletype(fileID, &swap) )
+ {
+ filetype = CDI_FILETYPE_SRV;
+ if ( CDI_Debug ) Message("found SRV file = %s", filename);
+ }
+ else if ( extCheckFiletype(fileID, &swap) )
+ {
+ filetype = CDI_FILETYPE_EXT;
+ if ( CDI_Debug ) Message("found EXT file = %s", filename);
+ }
+ else if ( iegCheckFiletype(fileID, &swap) )
+ {
+ filetype = CDI_FILETYPE_IEG;
+ if ( CDI_Debug ) Message("found IEG file = %s", filename);
+ }
+ else if ( gribCheckSeek(fileID, &recpos, &version) == 0 )
+ {
+ if ( version <= 1 )
+ {
+ filetype = CDI_FILETYPE_GRB;
+ if ( CDI_Debug ) Message("found seeked GRIB file = %s", filename);
+ }
+ else if ( version == 2 )
+ {
+ filetype = CDI_FILETYPE_GRB2;
+ if ( CDI_Debug ) Message("found seeked GRIB2 file = %s", filename);
+ }
+ }
+
+ fileClose(fileID);
+
+ *byteorder = getByteorder(swap);
+
+ return filetype;
}
-int streamInqNvars ( int streamID )
+/*
+ at Function streamInqFiletype
+ at Title Get the filetype
+
+ at Prototype int streamInqFiletype(int streamID)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+
+ at Description
+The function @func{streamInqFiletype} returns the filetype of a stream.
+
+ at Result
+ at func{streamInqFiletype} returns the type of the file format,
+one of the set of predefined CDI file format types.
+The valid CDI file format types are @func{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC}, @func{CDI_FILETYPE_NC2},
+ at func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_NC5}, @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
+
+ at EndFunction
+*/
+int streamInqFiletype(int streamID)
{
- stream_t *streamptr = (stream_t *)reshGetVal(streamID, &streamOps);
- return streamptr->nvars;
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->filetype;
}
-static int streamCompareP(void * streamptr1, void * streamptr2)
+int getByteswap(int byteorder)
{
- stream_t * s1 = ( stream_t * ) streamptr1;
- stream_t * s2 = ( stream_t * ) streamptr2;
- enum {
- differ = -1,
- equal = 0,
- };
-
- xassert ( s1 );
- xassert ( s2 );
-
- if ( s1->filetype != s2->filetype ) return differ;
- if ( s1->byteorder != s2->byteorder ) return differ;
- if ( s1->comptype != s2->comptype ) return differ;
- if ( s1->complevel != s2->complevel ) return differ;
+ int byteswap = -1;
- if ( s1->filename )
+ switch (byteorder)
{
- if (strcmp(s1->filename, s2->filename))
- return differ;
+ case CDI_BIGENDIAN:
+ case CDI_LITTLEENDIAN:
+ case CDI_PDPENDIAN:
+ byteswap = (HOST_ENDIANNESS != byteorder);
+ break;
+ case -1:
+ break;
+ default:
+ Error("unexpected byteorder %d query!", byteorder);
}
- else if ( s2->filename )
- return differ;
- return equal;
+ return byteswap;
}
+/*
+ at Function streamDefByteorder
+ at Title Define the byte order
-void streamDestroyP ( void * streamptr )
-{
- stream_t * sp = ( stream_t * ) streamptr;
-
- xassert ( sp );
-
- int id = sp->self;
- streamClose ( id );
-}
+ at Prototype void streamDefByteorder(int streamID, int byteorder)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item byteorder The byte order of a dataset, one of the CDI constants @func{CDI_BIGENDIAN} and
+ @func{CDI_LITTLEENDIAN}.
+ at Description
+The function @func{streamDefByteorder} defines the byte order of a binary dataset
+with the file format type @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} or @func{CDI_FILETYPE_IEG}.
-void streamPrintP ( void * streamptr, FILE * fp )
+ at EndFunction
+*/
+void streamDefByteorder(int streamID, int byteorder)
{
- stream_t * sp = ( stream_t * ) streamptr;
+ stream_t *streamptr = stream_to_pointer(streamID);
+ streamptr->byteorder = byteorder;
+ int filetype = streamptr->filetype;
- if ( !sp ) return;
+ switch (filetype)
+ {
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+ {
+ srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+ srvp->byteswap = getByteswap(byteorder);
- fprintf(fp, "#\n"
- "# streamID %d\n"
- "#\n"
- "self = %d\n"
- "accesstype = %d\n"
- "accessmode = %d\n"
- "filetype = %d\n"
- "byteorder = %d\n"
- "fileID = %d\n"
- "filemode = %d\n"
- "filename = %s\n"
- "nrecs = %d\n"
- "nvars = %d\n"
- "varsAllocated = %d\n"
- "curTsID = %d\n"
- "rtsteps = %d\n"
- "ntsteps = %ld\n"
- "tstepsTableSize= %d\n"
- "tstepsNextID = %d\n"
- "ncmode = %d\n"
- "vlistID = %d\n"
- "historyID = %d\n"
- "globalatts = %d\n"
- "localatts = %d\n"
- "unreduced = %d\n"
- "sortname = %d\n"
- "have_missval = %d\n"
- "ztype = %d\n"
- "zlevel = %d\n",
- sp->self, sp->self, sp->accesstype, sp->accessmode,
- sp->filetype, sp->byteorder, sp->fileID, sp->filemode,
- sp->filename, sp->nrecs, sp->nvars, sp->varsAllocated,
- sp->curTsID, sp->rtsteps, sp->ntsteps, sp->tstepsTableSize,
- sp->tstepsNextID, sp->ncmode, sp->vlistID, sp->historyID,
- sp->globalatts, sp->localatts, sp->unreduced, sp->sortname,
- sp->have_missval, sp->comptype, sp->complevel);
-}
+ break;
+ }
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+ {
+ extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+ extp->byteswap = getByteswap(byteorder);
-enum {
- streamNint = 10,
-};
+ break;
+ }
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+ {
+ iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+ iegp->byteswap = getByteswap(byteorder);
-static int
-streamGetPackSize(void * voidP, void *context)
-{
- stream_t * streamP = ( stream_t * ) voidP;
- int packBufferSize
- = serializeGetSize(streamNint, DATATYPE_INT, context)
- + serializeGetSize(2, DATATYPE_UINT32, context)
- + serializeGetSize((int)strlen(streamP->filename) + 1,
- DATATYPE_TXT, context)
- + serializeGetSize(1, DATATYPE_FLT64, context);
- return packBufferSize;
+ break;
+ }
+#endif
+ }
+ reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
}
+/*
+ at Function streamInqByteorder
+ at Title Get the byte order
-static void
-streamPack(void * streamptr, void * packBuffer, int packBufferSize,
- int * packBufferPos, void *context)
-{
- stream_t * streamP = ( stream_t * ) streamptr;
- int intBuffer[streamNint];
+ at Prototype int streamInqByteorder(int streamID)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
- intBuffer[0] = streamP->self;
- intBuffer[1] = streamP->filetype;
- intBuffer[2] = (int)strlen(streamP->filename) + 1;
- intBuffer[3] = streamP->vlistID;
- intBuffer[4] = streamP->byteorder;
- intBuffer[5] = streamP->comptype;
- intBuffer[6] = streamP->complevel;
- intBuffer[7] = streamP->unreduced;
- intBuffer[8] = streamP->sortname;
- intBuffer[9] = streamP->have_missval;
+ at Description
+The function @func{streamInqByteorder} returns the byte order of a binary dataset
+with the file format type @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} or @func{CDI_FILETYPE_IEG}.
- serializePack(intBuffer, streamNint, DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
- uint32_t d = cdiCheckSum(DATATYPE_INT, streamNint, intBuffer);
- serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+ at Result
+ at func{streamInqByteorder} returns the type of the byte order.
+The valid CDI byte order types are @func{CDI_BIGENDIAN} and @func{CDI_LITTLEENDIAN}
- serializePack(&cdiDefaultMissval, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
- serializePack(streamP->filename, intBuffer[2], DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_TXT, intBuffer[2], streamP->filename);
- serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+ at EndFunction
+*/
+int streamInqByteorder(int streamID)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->byteorder;
}
-struct streamAssoc
-streamUnpack(char * unpackBuffer, int unpackBufferSize,
- int * unpackBufferPos, int originNamespace, void *context)
+
+const char *streamFilesuffix(int filetype)
{
- int intBuffer[streamNint];
- uint32_t d;
- char filename[CDI_MAX_NAME];
+ // static char *fileSuffix[] = {"", ".grb", ".g2", ".nc", ".nc", ".nc4", ".nc4", ".srv", ".ext", ".ieg"};
+ /* note: the 2nd dimenstion of the fileSuffix array must be equal to or
+ * larger than the length of the longest suffix (dot and \0 terminator
+ * included) */
+ static const char fileSuffix[][5] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
+ int size = (int)(sizeof(fileSuffix)/sizeof(fileSuffix[0]));
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- intBuffer, streamNint, DATATYPE_INT, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
+ if ( filetype > 0 && filetype < size )
+ return fileSuffix[filetype];
+ else
+ return fileSuffix[0];
+}
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &filename, intBuffer[2], DATATYPE_TXT, context);
- serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(d == cdiCheckSum(DATATYPE_TXT, intBuffer[2], filename));
- int targetStreamID = namespaceAdaptKey(intBuffer[0], originNamespace),
- streamID = streamOpenID(filename, 'w', intBuffer[1], targetStreamID);
- xassert(streamID >= 0 && targetStreamID == streamID);
- streamDefByteorder(streamID, intBuffer[4]);
- streamDefCompType(streamID, intBuffer[5]);
- streamDefCompLevel(streamID, intBuffer[6]);
+
+const char *streamFilename(int streamID)
+{
stream_t *streamptr = stream_to_pointer(streamID);
- streamptr->unreduced = intBuffer[7];
- streamptr->sortname = intBuffer[8];
- streamptr->have_missval = intBuffer[9];
- struct streamAssoc retval = { streamID, intBuffer[3] };
- return retval;
+ return streamptr->filename;
}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
+static
+long cdiInqTimeSize(int streamID)
+{
+ int tsID = 0, nrecs;
+ stream_t *streamptr = stream_to_pointer(streamID);
+ long ntsteps = streamptr->ntsteps;
+ if ( ntsteps == (long)CDI_UNDEFID )
+ while ( (nrecs = streamInqTimestep(streamID, tsID++)) )
+ ntsteps = streamptr->ntsteps;
+ return ntsteps;
+}
-/* the single image implementation */
-int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss)
+static
+int cdiInqContents(stream_t *streamptr)
{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
- // A value > 0 is returned in this case, otherwise it returns zero.
int status = 0;
-
- if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
-
- check_parg(data);
-
- stream_t *streamptr = stream_to_pointer(streamID);
- if (subtypeInqActiveIndex(streamptr->vars[varID].subtypeID) != 0)
- Error("Writing of non-trivial subtypes not yet implemented!");
-
- // check taxis
- if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
-
int filetype = streamptr->filetype;
switch (filetype)
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
{
- grb_write_var(streamptr, varID, memtype, data, nmiss);
+ status = grbInqContents(streamptr);
break;
}
#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvWriteVarDP(streamptr, varID, (double *)data);
+ status = srvInqContents(streamptr);
break;
}
#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extWriteVarDP(streamptr, varID, (double *)data);
+ status = extInqContents(streamptr);
break;
}
#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegWriteVarDP(streamptr, varID, (double *)data);
+ status = iegInqContents(streamptr);
break;
}
#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
{
- cdf_write_var(streamptr, varID, memtype, data, nmiss);
+ status = cdfInqContents(streamptr);
break;
}
#endif
default:
{
- Error("%s support not compiled in!", strfiletype(filetype));
- break;
+ if ( CDI_Debug )
+ Message("%s support not compiled in!", strfiletype(filetype));
+
+ status = CDI_ELIBNAVAIL;
+ break;
}
}
+ if ( status == 0 )
+ {
+ int vlistID = streamptr->vlistID;
+ int taxisID = vlistInqTaxis(vlistID);
+ if ( taxisID != CDI_UNDEFID )
+ {
+ taxis_t *taxisptr1 = &streamptr->tsteps[0].taxis;
+ taxis_t *taxisptr2 = taxisPtr(taxisID);
+ ptaxisCopy(taxisptr2, taxisptr1);
+ }
+ }
+
return status;
}
-/*
- at Function streamWriteVar
- at Title Write a variable
+int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
+ int filetype, stream_t *streamptr,
+ int recordBufIsToBeCreated)
+{
+ int fileID;
+ switch (filetype)
+ {
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB2:
+#endif
+ {
+#ifndef __cplusplus
+ fileID = gribOpen(filename, (char [2]){filemode, 0});
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = gribOpen(filename, temp);
+#endif
+ if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+ if (recordBufIsToBeCreated)
+ {
+ streamptr->record = (Record *) Malloc(sizeof(Record));
+ streamptr->record->buffer = NULL;
+ }
+ break;
+ }
+#endif
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+ {
+#ifndef __cplusplus
+ fileID = fileOpen(filename, (char [2]){filemode, 0});
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = fileOpen(filename, temp);
+#endif
+ if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+ if (recordBufIsToBeCreated)
+ {
+ streamptr->record = (Record *) Malloc(sizeof(Record));
+ streamptr->record->buffer = NULL;
+ streamptr->record->exsep = srvNew();
+ }
+ break;
+ }
+#endif
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+ {
+#ifndef __cplusplus
+ fileID = fileOpen(filename, (char [2]){filemode, 0});
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = fileOpen(filename, temp);
+#endif
- at Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item varID Variable identifier.
- @Item data Pointer to a block of double precision floating point data values to be written.
- @Item nmiss Number of missing values.
+ if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+ if (recordBufIsToBeCreated)
+ {
+ streamptr->record = (Record *) Malloc(sizeof(Record));
+ streamptr->record->buffer = NULL;
+ streamptr->record->exsep = extNew();
+ }
+ break;
+ }
+#endif
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+ {
+#ifndef __cplusplus
+ fileID = fileOpen(filename, (char [2]){filemode, 0});
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = fileOpen(filename, temp);
+#endif
+ if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+ if (recordBufIsToBeCreated)
+ {
+ streamptr->record = (Record *) Malloc(sizeof(Record));
+ streamptr->record->buffer = NULL;
+ streamptr->record->exsep = iegNew();
+ }
+ break;
+ }
+#endif
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC5:
+ {
+#ifndef __cplusplus
+ fileID = cdfOpen(filename, (char [2]){filemode, 0}, filetype);
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = cdfOpen(filename, temp, filetype);
+#endif
+ break;
+ }
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ {
+#ifndef __cplusplus
+ fileID = cdf4Open(filename, (char [2]){filemode, 0}, &filetype);
+#else
+ char temp[2] = { filemode, 0 };
+ fileID = cdf4Open(filename, temp, &filetype);
+#endif
+ break;
+ }
+#endif
+ default:
+ {
+ if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
+ return CDI_ELIBNAVAIL;
+ }
+ }
- at Description
-The function streamWriteVar writes the values of one time step of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
- at EndFunction
-*/
-void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
-{
- void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
- const void *data, int nmiss)
- = (void (*)(int, int, int, const void *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
+ streamptr->filetype = filetype;
- myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+ return fileID;
}
-/*
- at Function streamWriteVarF
- at Title Write a variable
-
- at Prototype void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item varID Variable identifier.
- @Item data Pointer to a block of single precision floating point data values to be written.
- @Item nmiss Number of missing values.
- at Description
-The function streamWriteVarF writes the values of one time step of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
- at EndFunction
-*/
-void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+int streamOpenID(const char *filename, char filemode, int filetype, int resH)
{
- int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
- const void *data, int nmiss)
- = (int (*)(int, int, int, const void *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
-
- if ( myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
+ if ( CDI_Debug )
+ Message("Open %s mode %c file %s", strfiletype(filetype), filemode,
+ filename?filename:"(NUL)");
+
+ if ( ! filename || filetype < 0 ) return CDI_EINVAL;
+
+ stream_t *streamptr = stream_new_entry(resH);
+ int streamID = CDI_ESYSTEM;
+
+ int (*streamOpenDelegate)(const char *filename, char filemode,
+ int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+ = (int (*)(const char *, char, int, stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
+
+ int fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
+ if ( fileID < 0 )
{
- // In case the file format does not support single precision writing,
- // we fall back to double precision writing, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
- myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) conversionBuffer, nmiss);
- Free(conversionBuffer);
+ streamID = fileID;
+ }
+ else
+ {
+ streamID = streamptr->self;
+ if ( streamID < 0 ) return CDI_ELIMIT;
+
+ streamptr->filemode = filemode;
+ streamptr->filename = strdupx(filename);
+ streamptr->fileID = fileID;
+
+ if ( filemode == 'r' )
+ {
+ int vlistID = vlistCreate();
+ if ( vlistID < 0 ) return CDI_ELIMIT;
+
+ cdiVlistMakeInternal(vlistID);
+ streamptr->vlistID = vlistID;
+ /* cdiReadByteorder(streamID); */
+ int status = cdiInqContents(streamptr);
+ if ( status < 0 )
+ {
+ streamID = status;
+ }
+ else
+ {
+ vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
+ vlistptr->ntsteps = streamptr->ntsteps;
+ cdiVlistMakeImmutable(vlistID);
+ }
+ }
+ }
+
+ if ( streamID < 0 )
+ {
+ Free(streamptr->record);
+ stream_delete_entry(streamptr);
}
+
+ return streamID;
+}
+
+static
+int streamOpen(const char *filename, const char *filemode, int filetype)
+{
+ if ( !filemode || strlen(filemode) != 1 ) return CDI_EINVAL;
+ return streamOpenID(filename, (char)tolower(filemode[0]), filetype, CDI_UNDEFID);
}
-static
-int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
-{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
- // A value > 0 is returned in this case, otherwise it returns zero.
- int status = 0;
+static
+int streamOpenA(const char *filename, const char *filemode, int filetype)
+{
+ if ( CDI_Debug )
+ Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
+ if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
+
+ if ( ! filename || ! filemode || filetype < 0 ) return CDI_EINVAL;
+
+ stream_t *streamptr = stream_new_entry(CDI_UNDEFID);
+ int fileID = CDI_UNDEFID;
+
+ {
+ int (*streamOpenDelegate)(const char *filename, char filemode,
+ int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+ = (int (*)(const char *, char, int, stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
+
+ fileID = streamOpenDelegate(filename, 'r', filetype, streamptr, 1);
+ }
+
+ if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return fileID;
+
+ int streamID = streamptr->self;
- if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+ streamptr->filemode = tolower(*filemode);
+ streamptr->filename = strdupx(filename);
+ streamptr->fileID = fileID;
- check_parg(data);
+ streamptr->vlistID = vlistCreate();
+ cdiVlistMakeInternal(streamptr->vlistID);
+ /* cdiReadByteorder(streamID); */
+ int status = cdiInqContents(streamptr);
+ if ( status < 0 ) return status;
+ vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
+ vlistptr->ntsteps = (int)cdiInqTimeSize(streamID);
- stream_t *streamptr = stream_to_pointer(streamID);
- if (subtypeInqActiveIndex(streamptr->vars[varID].subtypeID) != 0)
- Error("Writing of non-trivial subtypes not yet implemented!");
+ // Needed for NetCDF4
+ for ( int varID = 0; varID < vlistptr->nvars; ++varID )
+ streamptr->vars[varID].defmiss = true;
- // check taxis
- if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+ if ( !strcmp(filemode, "r") ) cdiVlistMakeImmutable(streamptr->vlistID);
- int filetype = streamptr->filetype;
+ {
+ void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
+ = (void (*)(stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+
+ streamCloseDelegate(streamptr, 0);
+ }
switch (filetype)
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+#ifdef HAVE_LIBGRIB_API
+ case CDI_FILETYPE_GRB2:
+#endif
{
- grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ fileID = gribOpen(filename, filemode);
+ if ( fileID != CDI_UNDEFID ) gribContainersNew(streamptr);
break;
}
#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ fileID = fileOpen(filename, filemode);
break;
}
#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ fileID = fileOpen(filename, filemode);
break;
}
#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ fileID = fileOpen(filename, filemode);
break;
}
#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
- break;
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC5:
+ {
+ fileID = cdfOpen(filename, filemode, filetype);
+ streamptr->ncmode = 2;
+ break;
+ }
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ {
+ fileID = cdf4Open(filename, filemode, &filetype);
+ streamptr->ncmode = 2;
+ break;
+ }
#endif
default:
{
- Error("%s support not compiled in!", strfiletype(filetype));
- break;
+ if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
+ return CDI_ELIBNAVAIL;
}
}
- return status;
+ if ( fileID == CDI_UNDEFID )
+ streamID = CDI_UNDEFID;
+ else
+ streamptr->fileID = fileID;
+
+ return streamID;
}
/*
- at Function streamWriteVarSlice
- at Title Write a horizontal slice of a variable
+ at Function streamOpenRead
+ at Title Open a dataset for reading
- at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+ at Prototype int streamOpenRead(const char *path)
@Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item varID Variable identifier.
- @Item levelID Level identifier.
- @Item data Pointer to a block of double precision floating point data values to be written.
- @Item nmiss Number of missing values.
+ @Item path The name of the dataset to be read.
@Description
-The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
+The function @func{streamOpenRead} opens an existing dataset for reading.
+
+ at Result
+Upon successful completion @func{streamOpenRead} returns an identifier to the
+open stream. Otherwise, a negative number with the error status is returned.
+
+ at Errors
+ at List
+ @Item CDI_ESYSTEM Operating system error.
+ @Item CDI_EINVAL Invalid argument.
+ @Item CDI_EUFILETYPE Unsupported file type.
+ @Item CDI_ELIBNAVAIL Library support not compiled in.
+ at EndList
+
+ at Example
+Here is an example using @func{streamOpenRead} to open an existing NetCDF
+file named @func{foo.nc} for reading:
+
+ at Source
+ ...
+int streamID;
+ ...
+streamID = streamOpenRead("foo.nc");
+if ( streamID < 0 ) handle_error(streamID);
+ ...
+ at EndSource
@EndFunction
*/
-void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+int streamOpenRead(const char *filename)
{
- cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+ cdiInitialize();
+
+ int byteorder = 0;
+ int filetype = cdiGetFiletype(filename, &byteorder);
+
+ if ( filetype < 0 ) return filetype;
+
+ int streamID = streamOpen(filename, "r", filetype);
+
+ if ( streamID >= 0 )
+ {
+ stream_t *streamptr = stream_to_pointer(streamID);
+ streamptr->byteorder = byteorder;
+ }
+
+ return streamID;
+}
+
+
+int streamOpenAppend(const char *filename)
+{
+ cdiInitialize();
+
+ int byteorder = 0;
+ int filetype = cdiGetFiletype(filename, &byteorder);
+
+ if ( filetype < 0 ) return filetype;
+
+ int streamID = streamOpenA(filename, "a", filetype);
+
+ if ( streamID >= 0 )
+ {
+ stream_t *streamptr = stream_to_pointer(streamID);
+ streamptr->byteorder = byteorder;
+ }
+
+ return streamID;
}
/*
- at Function streamWriteVarSliceF
- at Title Write a horizontal slice of a variable
+ at Function streamOpenWrite
+ at Title Create a new dataset
- at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
+ at Prototype int streamOpenWrite(const char *path, int filetype)
@Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item varID Variable identifier.
- @Item levelID Level identifier.
- @Item data Pointer to a block of single precision floating point data values to be written.
- @Item nmiss Number of missing values.
+ @Item path The name of the new dataset.
+ @Item filetype The type of the file format, one of the set of predefined CDI file format types.
+ The valid CDI file format types are @func{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC},
+ @func{CDI_FILETYPE_NC2}, @func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_NC5}, @func{CDI_FILETYPE_SRV},
+ @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
@Description
-The function streamWriteVarSliceF writes the values of a horizontal slice of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
+The function @func{streamOpenWrite} creates a new datset.
+ at Result
+Upon successful completion @func{streamOpenWrite} returns an identifier to the
+open stream. Otherwise, a negative number with the error status is returned.
+
+ at Errors
+ at List
+ @Item CDI_ESYSTEM Operating system error.
+ @Item CDI_EINVAL Invalid argument.
+ @Item CDI_EUFILETYPE Unsupported file type.
+ @Item CDI_ELIBNAVAIL Library support not compiled in.
+ at EndList
+
+ at Example
+Here is an example using @func{streamOpenWrite} to create a new NetCDF file named @func{foo.nc} for writing:
+
+ at Source
+ ...
+int streamID;
+ ...
+streamID = streamOpenWrite("foo.nc", CDI_FILETYPE_NC);
+if ( streamID < 0 ) handle_error(streamID);
+ ...
+ at EndSource
@EndFunction
*/
-void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
+int streamOpenWrite(const char *filename, int filetype)
{
- if ( cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
- {
- // In case the file format does not support single precision writing,
- // we fall back to double precision writing, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
- streamWriteVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
- Free(conversionBuffer);
- }
-}
-
+ cdiInitialize();
-void
-streamWriteVarChunk(int streamID, int varID,
- const int rect[][2], const double *data, int nmiss)
-{
- void (*myCdiStreamWriteVarChunk_)(int streamID, int varID, int memtype,
- const int rect[][2], const void *data,
- int nmiss)
- = (void (*)(int, int, int, const int [][2], const void *, int))
- namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_CHUNK_).func;
- myCdiStreamWriteVarChunk_(streamID, varID, MEMTYPE_DOUBLE, rect, data, nmiss);
+ return streamOpen(filename, "w", filetype);
}
-/* single image implementation */
-void
-cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss)
+static
+void streamDefaultValue ( stream_t * streamptr )
{
- if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
-
- stream_t *streamptr = stream_to_pointer(streamID);
+ streamptr->self = CDI_UNDEFID;
+ streamptr->accesstype = CDI_UNDEFID;
+ streamptr->accessmode = 0;
+ streamptr->filetype = CDI_FILETYPE_UNDEF;
+ streamptr->byteorder = CDI_UNDEFID;
+ streamptr->fileID = 0;
+ streamptr->filemode = 0;
+ streamptr->numvals = 0;
+ streamptr->filename = NULL;
+ streamptr->record = NULL;
+ streamptr->varsAllocated = 0;
+ streamptr->nrecs = 0;
+ streamptr->nvars = 0;
+ streamptr->vars = NULL;
+ streamptr->ncmode = 0;
+ streamptr->curTsID = CDI_UNDEFID;
+ streamptr->rtsteps = 0;
+ streamptr->ntsteps = CDI_UNDEFID;
+ streamptr->tsteps = NULL;
+ streamptr->tstepsTableSize = 0;
+ streamptr->tstepsNextID = 0;
+ streamptr->historyID = CDI_UNDEFID;
+ streamptr->vlistID = CDI_UNDEFID;
+ streamptr->globalatts = 0;
+ streamptr->localatts = 0;
+ streamptr->unreduced = cdiDataUnreduced;
+ streamptr->sortname = cdiSortName > 0;
+ streamptr->sortparam = cdiSortParam > 0;
+ streamptr->have_missval = cdiHaveMissval;
+ streamptr->comptype = CDI_COMPRESS_NONE;
+ streamptr->complevel = 0;
- // streamDefineTaxis(streamID);
+ basetimeInit(&streamptr->basetime);
- int filetype = streamptr->filetype;
+#ifdef HAVE_LIBNETCDF
+ for ( int i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i] = CDI_UNDEFID;
+ for ( int i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->nczvarID[i] = CDI_UNDEFID;
- switch (filetype)
+ for ( int i = 0; i < MAX_GRIDS_PS; i++ )
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
-#endif
-#if defined (HAVE_LIBGRIB) || defined (HAVE_LIBSERVICE) \
- || defined (HAVE_LIBEXTRA) || defined (HAVE_LIBIEG)
- xabort("streamWriteVarChunk not implemented for filetype %s!",
- strfiletype(filetype));
- break;
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
- break;
-#endif
- default:
- Error("%s support not compiled in!", strfiletype(filetype));
- break;
+ streamptr->ncgrid[i].gridID = CDI_UNDEFID;
+ for (size_t j = 0; j < CDF_SIZE_ncIDs; ++j)
+ streamptr->ncgrid[i].ncIDs[j] = CDI_UNDEFID;
}
+
+ streamptr->vct.ilev = 0;
+ streamptr->vct.mlev = 0;
+ streamptr->vct.ilevID = CDI_UNDEFID;
+ streamptr->vct.mlevID = CDI_UNDEFID;
+#endif
+
+ streamptr->gribContainers = NULL;
}
static
-int stream_write_record(int streamID, int memtype, const void *data, int nmiss)
+stream_t *stream_new_entry(int resH)
{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
- // A value > 0 is returned in this case, otherwise it returns zero.
- int status = 0;
-
- check_parg(data);
+ cdiInitialize(); /* ***************** make MT version !!! */
- stream_t *streamptr = stream_to_pointer(streamID);
+ stream_t *streamptr = (stream_t *) Malloc(sizeof(stream_t));
+ streamDefaultValue ( streamptr );
- switch (streamptr->filetype)
+ if (resH == CDI_UNDEFID)
+ streamptr->self = reshPut(streamptr, &streamOps);
+ else
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- grb_write_record(streamptr, memtype, data, nmiss);
- break;
+ streamptr->self = resH;
+ reshReplace(resH, streamptr, &streamOps);
+ }
+
+ return streamptr;
+}
+
+
+void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
+{
+ int fileID = streamptr->fileID;
+ int filetype = streamptr->filetype;
+ if ( fileID == CDI_UNDEFID )
+ Warning("File %s not open!", streamptr->filename);
+ else
+ switch (filetype)
+ {
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ {
+ gribClose(fileID);
+ if ( recordBufIsToBeDeleted ) gribContainersDelete(streamptr);
+ break;
+ }
#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvWriteRecord(streamptr, (const double *)data);
- break;
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
+ {
+ fileClose(fileID);
+ if ( recordBufIsToBeDeleted ) srvDelete(streamptr->record->exsep);
+ break;
+ }
#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extWriteRecord(streamptr, (const double *)data);
- break;
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
+ {
+ fileClose(fileID);
+ if ( recordBufIsToBeDeleted ) extDelete(streamptr->record->exsep);
+ break;
+ }
#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegWriteRecord(streamptr, (const double *)data);
- break;
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
+ {
+ fileClose(fileID);
+ if ( recordBufIsToBeDeleted ) iegDelete(streamptr->record->exsep);
+ break;
+ }
#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- cdf_write_record(streamptr, memtype, data, nmiss);
- break;
- }
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ cdfClose(fileID);
+ if (streamptr->ntsteps == 0)
+ {
+ if ( streamptr->tsteps[0].records )
+ {
+ Free(streamptr->tsteps[0].records);
+ streamptr->tsteps[0].records = NULL;
+ }
+ if ( streamptr->tsteps[0].recIDs )
+ {
+ Free(streamptr->tsteps[0].recIDs);
+ streamptr->tsteps[0].recIDs = NULL;
+ }
+ }
+ break;
+ }
#endif
- default:
- {
- Error("%s support not compiled in!", strfiletype(streamptr->filetype));
- break;
+ default:
+ {
+ Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
+ break;
+ }
}
- }
+}
- return status;
+
+static
+void deallocate_sleveltable_t(sleveltable_t *entry)
+{
+ if (entry->recordID) Free(entry->recordID);
+ if (entry->lindex) Free(entry->lindex);
+ entry->recordID = NULL;
+ entry->lindex = NULL;
}
+
/*
- at Function streamWriteRecord
- at Title Write a horizontal slice of a variable
+ at Function streamClose
+ at Title Close an open dataset
- at Prototype void streamWriteRecord(int streamID, const double *data, int nmiss)
+ at Prototype void streamClose(int streamID)
@Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
- @Item data Pointer to a block of double precision floating point data values to be written.
- @Item nmiss Number of missing values.
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
@Description
-The function streamWriteRecord writes the values of a horizontal slice (record) of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
+The function @func{streamClose} closes an open dataset.
+
@EndFunction
*/
-void streamWriteRecord(int streamID, const double *data, int nmiss)
+void streamClose(int streamID)
{
- stream_write_record(streamID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+ stream_t *streamptr = stream_to_pointer(streamID);
+
+ if ( CDI_Debug )
+ Message("streamID = %d filename = %s", streamID, streamptr->filename);
+
+ int vlistID = streamptr->vlistID;
+
+ void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
+ = (void (*)(stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+
+ if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
+
+ if ( streamptr->record )
+ {
+ if ( streamptr->record->buffer )
+ Free(streamptr->record->buffer);
+
+ Free(streamptr->record);
+ }
+
+ streamptr->filetype = 0;
+ if ( streamptr->filename ) Free(streamptr->filename);
+
+ for ( int index = 0; index < streamptr->nvars; index++ )
+ {
+ sleveltable_t *pslev = streamptr->vars[index].recordTable;
+ unsigned nsub = streamptr->vars[index].subtypeSize >= 0
+ ? (unsigned)streamptr->vars[index].subtypeSize : 0U;
+ for (size_t isub=0; isub < nsub; isub++)
+ {
+ deallocate_sleveltable_t(pslev + isub);
+ }
+ if (pslev) Free(pslev);
+ }
+ Free(streamptr->vars);
+ streamptr->vars = NULL;
+
+ for ( int index = 0; index < streamptr->ntsteps; ++index )
+ {
+ if ( streamptr->tsteps[index].records ) Free(streamptr->tsteps[index].records);
+ if ( streamptr->tsteps[index].recIDs ) Free(streamptr->tsteps[index].recIDs);
+ taxisDestroyKernel(&streamptr->tsteps[index].taxis);
+ }
+
+ if ( streamptr->tsteps ) Free(streamptr->tsteps);
+
+ if ( streamptr->basetime.timevar_cache ) Free(streamptr->basetime.timevar_cache);
+
+ if ( vlistID != -1 )
+ {
+ if ( streamptr->filemode != 'w' && vlistInqTaxis(vlistID) != -1 )
+ taxisDestroy(vlistInqTaxis(vlistID));
+
+ cdiVlistDestroy_(vlistID);
+ }
+
+ stream_delete_entry(streamptr);
+}
+
+static
+void stream_delete_entry(stream_t *streamptr)
+{
+ xassert ( streamptr );
+
+ int idx = streamptr->self;
+ Free(streamptr);
+ reshRemove ( idx, &streamOps );
+
+ if ( CDI_Debug )
+ Message("Removed idx %d from stream list", idx);
}
-void streamWriteRecordF(int streamID, const float *data, int nmiss)
+void cdiStreamSync_(stream_t *streamptr)
{
- if ( stream_write_record(streamID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
+ int fileID = streamptr->fileID;
+ int filetype = streamptr->filetype;
+ int vlistID = streamptr->vlistID;
+ int nvars = vlistNvars(vlistID);
+
+ if ( fileID == CDI_UNDEFID ) Warning("File %s not open!", streamptr->filename);
+ else if ( vlistID == CDI_UNDEFID ) Warning("Vlist undefined for file %s!", streamptr->filename);
+ else if ( nvars == 0 ) Warning("No variables defined!");
+ else
{
- // In case the file format does not support single precision writing,
- // we fall back to double precision writing, converting the data on the fly.
- stream_t *streamptr = stream_to_pointer(streamID);
- int varID = streamptr->record->varID;
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
- streamWriteRecord(streamID, conversionBuffer, nmiss);
- Free(conversionBuffer);
+ if ( streamptr->filemode == 'w' || streamptr->filemode == 'a' )
+ {
+ switch (filetype)
+ {
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ void cdf_sync(int ncid);
+ if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
+ break;
+ }
+#endif
+ default:
+ {
+ fileFlush(fileID);
+ break;
+ }
+ }
+ }
}
}
-#ifdef HAVE_CONFIG_H
-#endif
+/*
+ at Function streamSync
+ at Title Synchronize an Open Dataset to Disk
+ at Prototype void streamSync(int streamID)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ at Description
+The function @func{streamSync} offers a way to synchronize the disk copy of a dataset with in-memory buffers.
-/* the single image implementation */
-static
-int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmiss)
+ at EndFunction
+*/
+void streamSync(int streamID)
{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
- // A value > 0 is returned in this case, otherwise it returns zero.
- int status = 0;
+ stream_t *streamptr = stream_to_pointer(streamID);
- if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+ void (*myStreamSync_)(stream_t *streamptr)
+ = (void (*)(stream_t *))namespaceSwitchGet(NSSWITCH_STREAM_SYNC).func;
+ myStreamSync_(streamptr);
+}
- check_parg(data);
- check_parg(nmiss);
- stream_t *streamptr = stream_to_pointer(streamID);
- int filetype = streamptr->filetype;
+int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
+{
+ stream_check_ptr(__func__, streamptr);
+
+ if ( CDI_Debug ) Message("streamID = %d tsID = %d", streamptr->self, tsID);
+
+ int vlistID = streamptr->vlistID;
+ int time_is_varying = vlistHasTime(vlistID);
+ int taxisID = vlistInqTaxis(vlistID) ;
+
+ /* moved to cdiStreamSetupVlist
+ int taxisID = time_is_varying ? vlistInqTaxis(vlistID) : CDI_UNDEFID;
+ if ( time_is_varying )
+ {
+ if ( taxisID == CDI_UNDEFID )
+ {
+ Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
+ taxisID = taxisCreate(TAXIS_ABSOLUTE);
+ vlistDefTaxis(vlistID, taxisID);
+ }
+ }
+ */
+ if ( tsID > 0 )
+ {
+ int newtsID = tstepsNewEntry(streamptr);
+ if ( tsID != newtsID )
+ Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
+ }
+
+ if ( time_is_varying )
+ ptaxisCopy(&streamptr->tsteps[tsID].taxis, taxisPtr(taxisID));
- *nmiss = 0;
+ streamptr->curTsID = tsID;
+ streamptr->ntsteps = tsID + 1;
- switch (filetype)
+#ifdef HAVE_LIBNETCDF
+ if ((streamptr->filetype == CDI_FILETYPE_NC ||
+ streamptr->filetype == CDI_FILETYPE_NC2 ||
+ streamptr->filetype == CDI_FILETYPE_NC5 ||
+ streamptr->filetype == CDI_FILETYPE_NC4 ||
+ streamptr->filetype == CDI_FILETYPE_NC4C)
+ && time_is_varying)
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- {
- grb_read_var(streamptr, varID, memtype, data, nmiss);
- break;
- }
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- {
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvReadVarDP(streamptr, varID, (double *)data, nmiss);
- break;
- }
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- {
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extReadVarDP(streamptr, varID, (double *)data, nmiss);
- break;
- }
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- {
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegReadVarDP(streamptr, varID, (double *)data, nmiss);
- break;
- }
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- {
- cdf_read_var(streamptr, varID, memtype, data, nmiss);
- break;
- }
-#endif
- default:
- {
- Error("%s support not compiled in!", strfiletype(filetype));
- break;
- }
+ void (*myCdfDefTimestep)(stream_t *streamptr, int tsID)
+ = (void (*)(stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_CDF_DEF_TIMESTEP).func;
+ myCdfDefTimestep(streamptr, tsID);
}
+#endif
- return status;
+ cdi_create_records(streamptr, tsID);
+
+ return (int)streamptr->ntsteps;
}
/*
- at Function streamReadVar
- at Title Read a variable
+ at Function streamDefTimestep
+ at Title Define a timestep
- at Prototype void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+ at Prototype int streamDefTimestep(int streamID, int tsID)
@Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
- @Item varID Variable identifier.
- @Item data Pointer to the location into which the data values are read.
- The caller must allocate space for the returned values.
- @Item nmiss Number of missing values.
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item tsID Timestep identifier.
@Description
-The function streamReadVar reads all the values of one time step of a variable
-from an open dataset.
+The function @func{streamDefTimestep} defines a timestep of a stream by the identifier tsID.
+The identifier tsID is the timestep index starting at 0 for the first timestep.
+Before calling this function the functions @func{taxisDefVdate} and @func{taxisDefVtime} should be used
+to define the timestamp for this timestep. All calls to write the data refer to this timestep.
+
+ at Result
+ at func{streamDefTimestep} returns the number of expected records of the timestep.
+
@EndFunction
*/
-void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+int streamDefTimestep(int streamID, int tsID)
{
- cdiStreamReadVar(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int (*myStreamDefTimestep_)(stream_t *streamptr, int tsID)
+ = (int (*)(stream_t *, int))
+ namespaceSwitchGet(NSSWITCH_STREAM_DEF_TIMESTEP_).func;
+ return myStreamDefTimestep_(streamptr, tsID);
+}
+
+
+int streamInqCurTimestepID(int streamID)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->curTsID;
}
/*
- at Function streamReadVarF
- at Title Read a variable
+ at Function streamInqTimestep
+ at Title Get timestep information
- at Prototype void streamReadVar(int streamID, int varID, float *data, int *nmiss)
+ at Prototype int streamInqTimestep(int streamID, int tsID)
@Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
- @Item varID Variable identifier.
- @Item data Pointer to the location into which the data values are read.
- The caller must allocate space for the returned values.
- @Item nmiss Number of missing values.
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+ @Item tsID Timestep identifier.
@Description
-The function streamReadVar reads all the values of one time step of a variable
-from an open dataset.
+The function @func{streamInqTimestep} sets the next timestep to the identifier tsID.
+The identifier tsID is the timestep index starting at 0 for the first timestep.
+After a call to this function the functions @func{taxisInqVdate} and @func{taxisInqVtime} can be used
+to read the timestamp for this timestep. All calls to read the data refer to this timestep.
+
+ at Result
+ at func{streamInqTimestep} returns the number of records of the timestep or 0, if the end of the file is reached.
+
@EndFunction
*/
-void streamReadVarF(int streamID, int varID, float *data, int *nmiss)
+int streamInqTimestep(int streamID, int tsID)
{
- if ( cdiStreamReadVar(streamID, varID, MEMTYPE_FLOAT, data, nmiss) )
- {
- // In case the file format does not support single precision reading,
- // we fall back to double precision reading, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- streamReadVar(streamID, varID, conversionBuffer, nmiss);
- for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
- Free(conversionBuffer);
- }
-}
-
+ int nrecs = 0;
+ int taxisID;
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int vlistID = streamptr->vlistID;
-static
-int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, int *nmiss)
-{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
- // A value > 0 is returned in this case, otherwise it returns zero.
- int status = 0;
+ if ( tsID < streamptr->rtsteps )
+ {
+ streamptr->curTsID = tsID;
+ nrecs = streamptr->tsteps[tsID].nrecs;
+ streamptr->tsteps[tsID].curRecID = CDI_UNDEFID;
+ taxisID = vlistInqTaxis(vlistID);
+ if ( taxisID == -1 )
+ Error("Timestep undefined for fileID = %d", streamID);
+ ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
- if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+ return nrecs;
+ }
- check_parg(data);
- check_parg(nmiss);
+ if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+ {
+ return 0;
+ }
- stream_t *streamptr = stream_to_pointer(streamID);
int filetype = streamptr->filetype;
- *nmiss = 0;
+ if ( CDI_Debug )
+ Message("streamID = %d tsID = %d filetype = %d", streamID, tsID, filetype);
switch (filetype)
{
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
{
- grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ nrecs = grbInqTimestep(streamptr, tsID);
break;
}
#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
+#ifdef HAVE_LIBSERVICE
+ case CDI_FILETYPE_SRV:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ nrecs = srvInqTimestep(streamptr, tsID);
break;
}
#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
+#ifdef HAVE_LIBEXTRA
+ case CDI_FILETYPE_EXT:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ nrecs = extInqTimestep(streamptr, tsID);
break;
}
#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+#ifdef HAVE_LIBIEG
+ case CDI_FILETYPE_IEG:
{
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ nrecs = iegInqTimestep(streamptr, tsID);
break;
}
#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
{
- cdf_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
- break;
+ nrecs = cdfInqTimestep(streamptr, tsID);
+ break;
}
#endif
default:
{
Error("%s support not compiled in!", strfiletype(filetype));
- status = 2;
break;
}
}
- return status;
-}
-
-/*
- at Function streamReadVarSlice
- at Title Read a horizontal slice of a variable
-
- at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
- @Item varID Variable identifier.
- @Item levelID Level identifier.
- @Item data Pointer to the location into which the data values are read.
- The caller must allocate space for the returned values.
- @Item nmiss Number of missing values.
-
- at Description
-The function streamReadVarSlice reads all the values of a horizontal slice of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
-{
- if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss) )
- {
- Warning("Unexpected error returned from cdiStreamReadVarSlice()!");
- size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- memset(data, 0, elementCount * sizeof(*data));
- }
-}
-
-/*
- at Function streamReadVarSliceF
- at Title Read a horizontal slice of a variable
+ taxisID = vlistInqTaxis(vlistID);
+ if ( taxisID == -1 )
+ Error("Timestep undefined for fileID = %d", streamID);
- at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
- at Parameter
- @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
- @Item varID Variable identifier.
- @Item levelID Level identifier.
- @Item data Pointer to the location into which the data values are read.
- The caller must allocate space for the returned values.
- @Item nmiss Number of missing values.
+ ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
- at Description
-The function streamReadVarSliceF reads all the values of a horizontal slice of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
-{
- if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss) )
- {
- // In case the file format does not support single precision reading,
- // we fall back to double precision reading, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- streamReadVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
- for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
- Free(conversionBuffer);
- }
+ return nrecs;
}
-static
-int stream_read_record(int streamID, int memtype, void *data, int *nmiss)
+#if 0
+void streamWriteContents(int streamID, char *cname)
{
- // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
- // A value > 0 is returned in this case, otherwise it returns zero.
- int status = 0;
-
- check_parg(data);
- check_parg(nmiss);
-
stream_t *streamptr = stream_to_pointer(streamID);
- *nmiss = 0;
+ int vlistID = streamptr->vlistID;
- switch (streamptr->filetype)
- {
-#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
- grb_read_record(streamptr, memtype, data, nmiss);
- break;
-#endif
-#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- srvReadRecord(streamptr, (double *)data, nmiss);
- break;
-#endif
-#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- extReadRecord(streamptr, (double *)data, nmiss);
- break;
-#endif
-#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
- if ( memtype == MEMTYPE_FLOAT ) return 1;
- iegReadRecord(streamptr, (double *)data, nmiss);
- break;
-#endif
-#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- cdf_read_record(streamptr, memtype, data, nmiss);
- break;
-#endif
- default:
- {
- Error("%s support not compiled in!", strfiletype(streamptr->filetype));
- break;
- }
- }
+ FILE *cnp = fopen(cname, "w");
- return status;
-}
+ if ( cnp == NULL ) SysError(cname);
+ fprintf(cnp, "#CDI library version %s\n"
+ "#\n", cdiLibraryVersion());
-void streamReadRecord(int streamID, double *data, int *nmiss)
-{
- stream_read_record(streamID, MEMTYPE_DOUBLE, (void *) data, nmiss);
-}
+ int filetype = streamptr->filetype;
+ fprintf(cnp, "filename: %s\n"
+ "filetype: %s\n", streamptr->filename, strfiletype(filetype));
+ fputs("#\n#grids:\n", cnp);
-void streamReadRecordF(int streamID, float *data, int *nmiss)
-{
- if ( stream_read_record(streamID, MEMTYPE_FLOAT, (void *) data, nmiss) )
+ int ngrids = vlistNgrids(vlistID);
+ for ( int i = 0; i < ngrids; i++ )
{
- // In case the file format does not support single precision reading,
- // we fall back to double precision reading, converting the data on the fly.
- stream_t *streamptr = stream_to_pointer(streamID);
- int tsID = streamptr->curTsID;
- int vrecID = streamptr->tsteps[tsID].curRecID;
- int recID = streamptr->tsteps[tsID].recIDs[vrecID];
- int varID = streamptr->tsteps[tsID].records[recID].varID;
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
- double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
- streamReadRecord(streamID, conversionBuffer, nmiss);
- for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
- Free(conversionBuffer);
+ int gridID = vlistGrid(vlistID, i);
+ int gridtype = gridInqType(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
+ fprintf(cnp, "%4d:%4d:%4zu:%4zu\n", i+1, gridtype, xsize, ysize);
}
-}
-#ifndef _VARSCAN_H
-#define _VARSCAN_H
-
-#ifndef _GRID_H
-#endif
-
-
-void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
- int level1, int level2, int level_sf, int level_unit, int prec,
- int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
- const char *name, const char *stdname, const char *longname, const char *units,
- const var_tile_t *tiles, int *tile_index);
-
-void varDefVCT(size_t vctsize, double *vctptr);
-void varDefZAxisReference(int nlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]);
-int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, int lbounds,
- const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
- const char *longname, const char *units, int prec, int mode, int ltype);
+ fputs("#\nvarID:code:gridID:zaxisID:tsteptype:datatype\n", cnp);
-void varDefMissval(int varID, double missval);
-void varDefCompType(int varID, int comptype);
-void varDefCompLevel(int varID, int complevel);
-void varDefInst(int varID, int instID);
-int varInqInst(int varID);
-void varDefModel(int varID, int modelID);
-int varInqModel(int varID);
-void varDefTable(int varID, int tableID);
-int varInqTable(int varID);
-void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
+ int nvars = vlistNvars(vlistID);
+ for ( int varID = 0; varID < nvars; varID++ )
+ {
+ int code = vlistInqVarCode(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+ int datatype = vlistInqVarDatatype(vlistID, varID);
+ fprintf(cnp, "%4d:%4d:%4d:%4d:%4d:%4d:\n",
+ varID+1, code, gridID, zaxisID, tsteptype, datatype);
+ }
-void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess);
-void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate);
+ fputs("#\ntsID:nrecs:date:time\n", cnp);
+ int tsID = 0;
+ while (1)
+ {
+ int nrecs = streamptr->tsteps[tsID].nallrecs;
+ int date = streamptr->tsteps[tsID].taxis.vdate;
+ int time = streamptr->tsteps[tsID].taxis.vtime;
+ off_t position = streamptr->tsteps[tsID].position;
-void varDefOptGribInt(int varID, int tile_index, long lval, const char *keyword);
-void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keyword);
-int varOptGribNentries(int varID);
+ fprintf(cnp, "%4d:%4d:%4d:%4d:%ld\n",
+ tsID, nrecs, date, time, (long) position);
-int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, const char *longname, const char *units, int ltype);
+ if ( streamptr->tsteps[tsID].next )
+ tsID++;
+ else
+ break;
+ }
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ fputs("#\ntsID:recID:varID:levID:size:pos\n", cnp);
-#ifdef HAVE_LIBNETCDF
+ tsID = 0;
+ while (1)
+ {
+ int nrecs = streamptr->tsteps[tsID].nallrecs;
+ for ( int recID = 0; recID < nrecs; recID++ )
+ {
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ int levelID = streamptr->tsteps[tsID].records[recID].levelID;
+ off_t recpos = streamptr->tsteps[tsID].records[recID].position;
+ long recsize = (long)streamptr->tsteps[tsID].records[recID].size;
+ fprintf(cnp, "%4d:%4d:%4d:%4d:%4ld:%ld\n",
+ tsID, recID, varID, levelID, recsize, (long) recpos);
+ }
-//#define TEST_GROUPS 1
+ if ( streamptr->tsteps[tsID].next )
+ tsID++;
+ else
+ break;
+ }
-#include <limits.h>
-#include <ctype.h>
-#include <math.h>
-#include <float.h>
-#ifdef HAVE_MMAP
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIBPTHREAD
-#include <pthread.h>
+ fclose(cnp);
+}
#endif
-#include <netcdf.h>
-
-
-//#define PROJECTION_TEST
+// This function is used in CDO!
+size_t streamNvals(int streamID)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->numvals;
+}
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
+/*
+ at Function streamDefVlist
+ at Title Define the variable list
-static const char bndsName[] = "bnds";
+ at Prototype void streamDefVlist(int streamID, int vlistID)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
-#define X_AXIS 1
-#define Y_AXIS 2
-#define Z_AXIS 3
-#define T_AXIS 4
+ at Description
+The function @func{streamDefVlist} defines the variable list of a stream.
-#define POSITIVE_UP 1
-#define POSITIVE_DOWN 2
+To safeguard against errors by modifying the wrong vlist object,
+this function makes the passed vlist object immutable.
+All further vlist changes have to use the vlist object returned by streamInqVlist().
-typedef struct {
- int ncvarid;
- int dimtype;
- size_t len;
- char name[CDI_MAX_NAME];
+ at EndFunction
+*/
+void streamDefVlist(int streamID, int vlistID)
+{
+ void (*myStreamDefVlist)(int streamID, int vlistID)
+ = (void (*)(int, int))namespaceSwitchGet(NSSWITCH_STREAM_DEF_VLIST_).func;
+ myStreamDefVlist(streamID, vlistID);
}
-ncdim_t;
-#define MAX_COORDVARS 4
-#define MAX_AUXVARS 4
-typedef struct {
- int ncid;
- int ignore;
- short isvar;
- short islon;
- int islat;
- int islev;
- int istime;
- int warn;
- int tsteptype;
- int param;
- int code;
- int tabnum;
- int climatology;
- int bounds;
- int lformula;
- int lformulaterms;
- int gridID;
- int zaxisID;
- int gridtype;
- int zaxistype;
- int xdim;
- int ydim;
- int zdim;
- int xvarid;
- int yvarid;
- int zvarid;
- int tvarid;
- int psvarid;
- int p0varid;
- int ncoordvars;
- int coordvarids[MAX_COORDVARS];
- int nauxvars;
- int auxvarids[MAX_AUXVARS];
- int cellarea;
- int calendar;
- int tableID;
- int truncation;
- int position;
- int defmissval;
- int deffillval;
- int xtype;
- int ndims;
- int gmapid;
- int positive;
- int dimids[8];
- int dimtype[8];
- int chunks[8];
- int chunked;
- int chunktype;
- int natts;
- int deflate;
- int lunsigned;
- int lvalidrange;
- int *atts;
- size_t vctsize;
- double *vct;
- double missval;
- double fillval;
- double addoffset;
- double scalefactor;
- double validrange[2];
- char name[CDI_MAX_NAME];
- char longname[CDI_MAX_NAME];
- char stdname[CDI_MAX_NAME];
- char units[CDI_MAX_NAME];
- char extra[CDI_MAX_NAME];
- ensinfo_t *ensdata; /* Ensemble information */
+/* the single image implementation of streamDefVlist */
+void cdiStreamDefVlist_(int streamID, int vlistID)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+
+ if ( streamptr->vlistID == CDI_UNDEFID )
+ {
+ int vlistCopy = vlistDuplicate(vlistID);
+ cdiVlistMakeInternal(vlistCopy);
+ cdiVlistMakeImmutable(vlistID);
+ cdiStreamSetupVlist(streamptr, vlistCopy);
+ }
+ else
+ Warning("vlist already defined for %s!", streamptr->filename);
}
-ncvar_t;
-static
-void strtolower(char *str)
+/*
+ at Function streamInqVlist
+ at Title Get the variable list
+
+ at Prototype int streamInqVlist(int streamID)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+
+ at Description
+The function @func{streamInqVlist} returns the variable list of a stream.
+
+ at Result
+ at func{streamInqVlist} returns an identifier to the variable list.
+
+ at EndFunction
+*/
+int streamInqVlist(int streamID)
{
- if ( str )
- for (size_t i = 0; str[i]; ++i)
- str[i] = (char)tolower((int)str[i]);
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->vlistID;
}
-static
-int get_timeunit(size_t len, const char *ptu)
-{
- int timeunit = -1;
- if ( len > 2 )
+void streamDefCompType(int streamID, int comptype)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ if ( streamptr->comptype != comptype )
{
- if ( memcmp(ptu, "sec", 3) == 0 ) timeunit = TUNIT_SECOND;
- else if ( memcmp(ptu, "minute", 6) == 0 ) timeunit = TUNIT_MINUTE;
- else if ( memcmp(ptu, "hour", 4) == 0 ) timeunit = TUNIT_HOUR;
- else if ( memcmp(ptu, "day", 3) == 0 ) timeunit = TUNIT_DAY;
- else if ( memcmp(ptu, "month", 5) == 0 ) timeunit = TUNIT_MONTH;
- else if ( memcmp(ptu, "calendar_month", 14) == 0 ) timeunit = TUNIT_MONTH;
- else if ( memcmp(ptu, "year", 4) == 0 ) timeunit = TUNIT_YEAR;
+ streamptr->comptype = comptype;
+ reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
}
- else if ( len == 1 )
+}
+
+
+void streamDefCompLevel(int streamID, int complevel)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ if ( streamptr->complevel != complevel )
{
- if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
+ streamptr->complevel = complevel;
+ reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
}
+}
- return timeunit;
+
+int streamInqCompType(int streamID)
+{
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->comptype;
}
-static
-bool isTimeUnits(const char *timeunits)
+
+int streamInqCompLevel(int streamID)
{
- bool status = strncmp(timeunits, "sec", 3) == 0
- || strncmp(timeunits, "minute", 6) == 0
- || strncmp(timeunits, "hour", 4) == 0
- || strncmp(timeunits, "day", 3) == 0
- || strncmp(timeunits, "month", 5) == 0;
- return status;
+ stream_t *streamptr = stream_to_pointer(streamID);
+ return streamptr->complevel;
}
-static
-bool isTimeAxisUnits(const char *timeunits)
+int streamInqFileID(int streamID)
{
- bool status = false;
+ stream_t *streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
+ return streamptr->fileID;
+}
- size_t len = strlen(timeunits);
- char *tu = (char *) Malloc((len+1)*sizeof(char));
- memcpy(tu, timeunits, (len+1) * sizeof(char));
- char *ptu = tu;
- for (size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
+void cdiDefAccesstype(int streamID, int type)
+{
+ stream_t *streamptr = (stream_t *)reshGetVal(streamID, &streamOps);
- int timeunit = get_timeunit(len, ptu);
- if ( timeunit != -1 )
+ if ( streamptr->accesstype == CDI_UNDEFID )
{
-
- while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
- if ( *ptu )
- {
- while ( isspace(*ptu) ) ptu++;
-
- int timetype = memcmp(ptu, "as", 2) == 0 ? TAXIS_ABSOLUTE :
- memcmp(ptu, "since", 5) == 0 ? TAXIS_RELATIVE : -1;
-
- status = timetype != -1;
- }
+ streamptr->accesstype = type;
}
+ else if ( streamptr->accesstype != type )
+ Error("Changing access type from %s not allowed!",
+ streamptr->accesstype == TYPE_REC ? "REC to VAR" : "VAR to REC");
+}
- Free(tu);
- return status;
+int cdiInqAccesstype(int streamID)
+{
+ stream_t *streamptr = (stream_t *) reshGetVal ( streamID, &streamOps );
+ return streamptr->accesstype;
}
static
-void scanTimeString(const char *ptu, int *rdate, int *rtime)
+int streamTxCode(void)
{
- int year = 1, month = 1, day = 1;
- int hour = 0, minute = 0, second = 0;
- int v1 = 1, v2 = 1, v3 = 1;
+ return STREAM;
+}
- *rdate = 0;
- *rtime = 0;
+void cdiStreamSetupVlist(stream_t *streamptr, int vlistID)
+{
+ void (*myStreamSetupVlist)(stream_t *streamptr, int vlistID)
+ = (void (*)(stream_t *, int)) namespaceSwitchGet(NSSWITCH_STREAM_SETUP_VLIST).func;
+ myStreamSetupVlist(streamptr, vlistID);
+}
- if ( *ptu )
+
+void cdiStreamSetupVlist_(stream_t *streamptr, int vlistID)
+{
+ streamptr->vlistID = vlistID;
+ int nvars = vlistNvars(vlistID);
+ for ( int varID = 0; varID < nvars; varID++ )
{
- v1 = atoi(ptu);
- if ( v1 < 0 ) ptu++;
- while ( isdigit((int) *ptu) ) ptu++;
- if ( *ptu )
- {
- v2 = atoi(++ptu);
- while ( isdigit((int) *ptu) ) ptu++;
- if ( *ptu )
- {
- v3 = atoi(++ptu);
- while ( isdigit((int) *ptu) ) ptu++;
- }
- }
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int tilesetID = vlistInqVarSubtype(vlistID, varID);
+ stream_new_var(streamptr, gridID, zaxisID, tilesetID);
+ if ( streamptr->have_missval )
+ vlistDefVarMissval(vlistID, varID, vlistInqVarMissval(vlistID, varID));
}
- if ( v3 > 999 && v1 < 32 )
- { year = v3; month = v2; day = v1; }
- else
- { year = v1; month = v2; day = v3; }
-
- while ( isspace((int) *ptu) ) ptu++;
-
- if ( *ptu )
+ if (streamptr->filemode == 'w')
{
- while ( ! isdigit((int) *ptu) ) ptu++;
-
- hour = atoi(ptu);
- while ( isdigit((int) *ptu) ) ptu++;
- if ( *ptu == ':' )
+ tstepsNewEntry(streamptr); // timestep 0
+ int vlistID = streamptr->vlistID;
+ int time_is_varying = vlistHasTime(vlistID);
+ if ( time_is_varying )
{
- ptu++;
- minute = atoi(ptu);
- while ( isdigit((int) *ptu) ) ptu++;
- if ( *ptu == ':' )
+ int taxisID = vlistInqTaxis(vlistID);
+ if ( taxisID == CDI_UNDEFID )
{
- ptu++;
- second = atoi(ptu);
+ Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
+ taxisID = taxisCreate(TAXIS_ABSOLUTE);
+ vlistDefTaxis(vlistID, taxisID);
}
+
+ if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
+ switch (streamptr->filetype)
+ {
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ taxis_t *taxisptr = taxisPtr(taxisID);
+ if ( taxisptr->rdate == -1 ) taxisDefRdate(taxisID, 10101);
+ }
+ break;
+#endif
+ default:
+ ;
+ }
+ ptaxisCopy(&streamptr->tsteps[0].taxis, taxisPtr(taxisID));
}
- }
- *rdate = cdiEncodeDate(year, month, day);
- *rtime = cdiEncodeTime(hour, minute, second);
+ switch (streamptr->filetype)
+ {
+#ifdef HAVE_LIBNETCDF
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ /* calls cdfDefVars in serial mode but
+ * cdiPioClientStreamNOP (i.e. nothing) on client ranks
+ * and cdiPioServerCdfDefVars on server ranks in parallel mode*/
+ void (*myCdfDefVars)(stream_t *streamptr)
+ = (void (*)(stream_t *)) namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
+ myCdfDefVars(streamptr);
+ }
+ break;
+#endif
+#ifdef HAVE_LIBGRIB
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ gribContainersNew(streamptr);
+ break;
+#endif
+ default:
+ ;
+ }
+ }
}
-static
-int scanTimeUnit(const char *unitstr)
-{
- size_t len = strlen(unitstr);
- int timeunit = get_timeunit(len, unitstr);
- if ( timeunit == -1 )
- Message("Unsupported TIMEUNIT: %s!", unitstr);
- return timeunit;
+void cdiStreamGetIndexList(unsigned numIDs, int *IDs)
+{
+ reshGetResHListOfType(numIDs, IDs, &streamOps);
}
-static
-void setForecastTime(const char *timestr, taxis_t *taxis)
+int streamInqNvars ( int streamID )
{
- (*taxis).fdate = 0;
- (*taxis).ftime = 0;
-
- int len = (int) strlen(timestr);
- if ( len == 0 ) return;
-
- int fdate = 0, ftime = 0;
- scanTimeString(timestr, &fdate, &ftime);
-
- (*taxis).fdate = fdate;
- (*taxis).ftime = ftime;
+ stream_t *streamptr = (stream_t *)reshGetVal(streamID, &streamOps);
+ return streamptr->nvars;
}
-static
-int setBaseTime(const char *timeunits, taxis_t *taxis)
+
+static int streamCompareP(void * streamptr1, void * streamptr2)
{
- int timetype = TAXIS_ABSOLUTE;
- int rdate = -1, rtime = -1;
+ stream_t * s1 = ( stream_t * ) streamptr1;
+ stream_t * s2 = ( stream_t * ) streamptr2;
+ enum {
+ differ = -1,
+ equal = 0,
+ };
- size_t len = strlen(timeunits);
- char *tu = (char *) Malloc((len+1) * sizeof (char));
- memcpy(tu, timeunits, (len+1) * sizeof (char));
- char *ptu = tu;
+ xassert ( s1 );
+ xassert ( s2 );
- for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int) ptu[i]);
+ if ( s1->filetype != s2->filetype ) return differ;
+ if ( s1->byteorder != s2->byteorder ) return differ;
+ if ( s1->comptype != s2->comptype ) return differ;
+ if ( s1->complevel != s2->complevel ) return differ;
- int timeunit = get_timeunit(len, ptu);
- if ( timeunit == -1 )
+ if ( s1->filename )
{
- Message("Unsupported TIMEUNIT: %s!", timeunits);
- return (1);
+ if (strcmp(s1->filename, s2->filename))
+ return differ;
}
+ else if ( s2->filename )
+ return differ;
- while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
- if ( *ptu )
- {
- while ( isspace(*ptu) ) ptu++;
-
- if ( memcmp(ptu, "as", 2) == 0 )
- timetype = TAXIS_ABSOLUTE;
- else if ( memcmp(ptu, "since", 5) == 0 )
- timetype = TAXIS_RELATIVE;
+ return equal;
+}
- while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
- if ( *ptu )
- {
- while ( isspace(*ptu) ) ptu++;
- if ( timetype == TAXIS_ABSOLUTE )
- {
- if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
- {
- Message("Unsupported format %s for TIMEUNIT day!", ptu);
- timeunit = -1;
- }
- else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
- {
- Message("Unsupported format %s for TIMEUNIT month!", ptu);
- timeunit = -1;
- }
- }
- else if ( timetype == TAXIS_RELATIVE )
- {
- scanTimeString(ptu, &rdate, &rtime);
+void streamDestroyP ( void * streamptr )
+{
+ stream_t *sp = ( stream_t * ) streamptr;
- (*taxis).rdate = rdate;
- (*taxis).rtime = rtime;
+ xassert ( sp );
- if ( CDI_Debug )
- Message("rdate = %d rtime = %d", rdate, rtime);
- }
- }
- }
+ int id = sp->self;
+ streamClose ( id );
+}
- (*taxis).type = timetype;
- (*taxis).unit = timeunit;
- Free(tu);
+void streamPrintP ( void * streamptr, FILE * fp )
+{
+ stream_t * sp = ( stream_t * ) streamptr;
- if ( CDI_Debug )
- Message("timetype = %d unit = %d", timetype, timeunit);
+ if ( !sp ) return;
- return 0;
+ fprintf(fp, "#\n"
+ "# streamID %d\n"
+ "#\n"
+ "self = %d\n"
+ "accesstype = %d\n"
+ "accessmode = %d\n"
+ "filetype = %d\n"
+ "byteorder = %d\n"
+ "fileID = %d\n"
+ "filemode = %d\n"
+ "filename = %s\n"
+ "nrecs = %d\n"
+ "nvars = %d\n"
+ "varsAllocated = %d\n"
+ "curTsID = %d\n"
+ "rtsteps = %d\n"
+ "ntsteps = %ld\n"
+ "tstepsTableSize= %d\n"
+ "tstepsNextID = %d\n"
+ "ncmode = %d\n"
+ "vlistID = %d\n"
+ "historyID = %d\n"
+ "globalatts = %d\n"
+ "localatts = %d\n"
+ "unreduced = %d\n"
+ "sortname = %d\n"
+ "have_missval = %d\n"
+ "ztype = %d\n"
+ "zlevel = %d\n",
+ sp->self, sp->self, sp->accesstype, sp->accessmode,
+ sp->filetype, sp->byteorder, sp->fileID, sp->filemode,
+ sp->filename, sp->nrecs, sp->nvars, sp->varsAllocated,
+ sp->curTsID, sp->rtsteps, sp->ntsteps, sp->tstepsTableSize,
+ sp->tstepsNextID, sp->ncmode, sp->vlistID, sp->historyID,
+ sp->globalatts, sp->localatts, sp->unreduced, sp->sortname,
+ sp->have_missval, sp->comptype, sp->complevel);
}
-static
-void cdfGetAttInt(int fileID, int ncvarid, const char *attname, int attlen, int *attint)
+enum {
+ streamNint = 10,
+};
+
+static int
+streamGetPackSize(void * voidP, void *context)
{
- nc_type atttype;
- size_t nc_attlen;
+ stream_t * streamP = ( stream_t * ) voidP;
+ int packBufferSize
+ = serializeGetSize(streamNint, CDI_DATATYPE_INT, context)
+ + serializeGetSize(2, CDI_DATATYPE_UINT32, context)
+ + serializeGetSize((int)strlen(streamP->filename) + 1,
+ CDI_DATATYPE_TXT, context)
+ + serializeGetSize(1, CDI_DATATYPE_FLT64, context);
+ return packBufferSize;
+}
- *attint = 0;
- cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
- cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+static void
+streamPack(void * streamptr, void * packBuffer, int packBufferSize,
+ int * packBufferPos, void *context)
+{
+ stream_t * streamP = ( stream_t * ) streamptr;
+ int intBuffer[streamNint];
- if ( atttype != NC_CHAR )
- {
- int *pintatt = (int)nc_attlen > attlen
- ? (int *)(Malloc(nc_attlen * sizeof (int))) : attint;
+ intBuffer[0] = streamP->self;
+ intBuffer[1] = streamP->filetype;
+ intBuffer[2] = (int)strlen(streamP->filename) + 1;
+ intBuffer[3] = streamP->vlistID;
+ intBuffer[4] = streamP->byteorder;
+ intBuffer[5] = streamP->comptype;
+ intBuffer[6] = streamP->complevel;
+ intBuffer[7] = streamP->unreduced;
+ intBuffer[8] = streamP->sortname;
+ intBuffer[9] = streamP->have_missval;
- cdf_get_att_int(fileID, ncvarid, attname, pintatt);
+ serializePack(intBuffer, streamNint, CDI_DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
+ uint32_t d = cdiCheckSum(CDI_DATATYPE_INT, streamNint, intBuffer);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
- if ( (int)nc_attlen > attlen )
- {
- memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
- Free(pintatt);
- }
- }
+ serializePack(&cdiDefaultMissval, 1, CDI_DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+ serializePack(streamP->filename, intBuffer[2], CDI_DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
+ d = cdiCheckSum(CDI_DATATYPE_TXT, intBuffer[2], streamP->filename);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
}
-static
-void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
+struct streamAssoc
+streamUnpack(char * unpackBuffer, int unpackBufferSize,
+ int * unpackBufferPos, int originNamespace, void *context)
{
- nc_type atttype;
- size_t nc_attlen;
-
- *attdouble = 0;
+ int intBuffer[streamNint];
+ uint32_t d;
+ char filename[CDI_MAX_NAME];
- cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
- cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ intBuffer, streamNint, CDI_DATATYPE_INT, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_INT, streamNint, intBuffer) == d);
- if ( atttype != NC_CHAR )
- {
- double *pdoubleatt = NULL;
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &cdiDefaultMissval, 1, CDI_DATATYPE_FLT64, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &filename, intBuffer[2], CDI_DATATYPE_TXT, context);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(d == cdiCheckSum(CDI_DATATYPE_TXT, intBuffer[2], filename));
+ int targetStreamID = namespaceAdaptKey(intBuffer[0], originNamespace),
+ streamID = streamOpenID(filename, 'w', intBuffer[1], targetStreamID);
+ xassert(streamID >= 0 && targetStreamID == streamID);
+ streamDefByteorder(streamID, intBuffer[4]);
+ streamDefCompType(streamID, intBuffer[5]);
+ streamDefCompLevel(streamID, intBuffer[6]);
+ stream_t *streamptr = stream_to_pointer(streamID);
+ streamptr->unreduced = intBuffer[7];
+ streamptr->sortname = intBuffer[8];
+ streamptr->have_missval = intBuffer[9];
+ struct streamAssoc retval = { streamID, intBuffer[3] };
+ return retval;
+}
- if ( (int)nc_attlen > attlen )
- pdoubleatt = (double *) Malloc(nc_attlen * sizeof (double));
- else
- pdoubleatt = attdouble;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
+#endif
- cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
- if ( (int)nc_attlen > attlen )
- {
- memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
- Free(pdoubleatt);
- }
- }
-}
-static
-void cdfGetAttText(int fileID, int ncvarid,const char *attname, int attlen, char *atttext)
+/* the single image implementation */
+int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, size_t nmiss)
{
- nc_type atttype;
- size_t nc_attlen;
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
- cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
- if ( atttype == NC_CHAR )
- {
- char attbuf[65636];
- if ( nc_attlen < sizeof(attbuf) )
- {
- cdf_get_att_text(fileID, ncvarid, attname, attbuf);
+ check_parg(data);
- if ( (int) nc_attlen > (attlen-1) ) nc_attlen = (size_t)(attlen-1);
+ stream_t *streamptr = stream_to_pointer(streamID);
+ if (subtypeInqActiveIndex(streamptr->vars[varID].subtypeID) != 0)
+ Error("Writing of non-trivial subtypes not yet implemented!");
- attbuf[nc_attlen++] = 0;
- memcpy(atttext, attbuf, nc_attlen);
- }
- else
- {
- atttext[0] = 0;
- }
- }
-#if defined (HAVE_NETCDF4)
- else if ( atttype == NC_STRING )
- {
- if ( nc_attlen == 1 )
- {
- char *attbuf = NULL;
- cdf_get_att_string(fileID, ncvarid, attname, &attbuf);
+ // check taxis
+ if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
- size_t ssize = strlen(attbuf) + 1;
+ int filetype = streamptr->filetype;
- if ( ssize > (size_t)attlen ) ssize = (size_t)attlen;
- memcpy(atttext, attbuf, ssize);
- atttext[ssize - 1] = 0;
- Free(attbuf);
- }
- else
- {
- atttext[0] = 0;
- }
- }
+ switch (filetype)
+ {
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ {
+ grb_write_var(streamptr, varID, memtype, data, nmiss);
+ break;
+ }
#endif
-}
-
-static
-int xtypeIsText(int xtype)
-{
- int isText = FALSE;
-
- if ( xtype == NC_CHAR )
- isText = TRUE;
-#if defined (HAVE_NETCDF4)
- else if ( xtype == NC_STRING )
- isText = TRUE;
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvWriteVarDP(streamptr, varID, (double *)data);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extWriteVarDP(streamptr, varID, (double *)data);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegWriteVarDP(streamptr, varID, (double *)data);
+ break;
+ }
#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ cdf_write_var(streamptr, varID, memtype, data, nmiss);
+ break;
+ }
+#endif
+ default:
+ {
+ Error("%s support not compiled in!", strfiletype(filetype));
+ break;
+ }
+ }
- return isText;
+ return status;
}
-static
-int xtypeIsFloat(int xtype)
+/*
+ at Function streamWriteVar
+ at Title Write a variable
+
+ at Prototype void streamWriteVar(int streamID, int varID, const double *data, size_t nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item varID Variable identifier.
+ @Item data Pointer to a block of double precision floating point data values to be written.
+ @Item nmiss Number of missing values.
+
+ at Description
+The function streamWriteVar writes the values of one time step of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteVar(int streamID, int varID, const double *data, size_t nmiss)
{
- int isFloat = xtype == NC_FLOAT || xtype == NC_DOUBLE;
- return isFloat;
+ void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, size_t nmiss)
+ = (void (*)(int, int, int, const void *, size_t))
+ namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
+
+ myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
}
-static
-int cdfInqDatatype(int xtype, int lunsigned)
-{
- int datatype = -1;
+/*
+ at Function streamWriteVarF
+ at Title Write a variable
-#if defined (HAVE_NETCDF4)
- if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
-#endif
+ at Prototype void streamWriteVarF(int streamID, int varID, const float *data, size_t nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item varID Variable identifier.
+ @Item data Pointer to a block of single precision floating point data values to be written.
+ @Item nmiss Number of missing values.
- if ( xtype == NC_BYTE ) datatype = DATATYPE_INT8;
- /* else if ( xtype == NC_CHAR ) datatype = DATATYPE_UINT8; */
- else if ( xtype == NC_SHORT ) datatype = DATATYPE_INT16;
- else if ( xtype == NC_INT ) datatype = DATATYPE_INT32;
- else if ( xtype == NC_FLOAT ) datatype = DATATYPE_FLT32;
- else if ( xtype == NC_DOUBLE ) datatype = DATATYPE_FLT64;
-#if defined (HAVE_NETCDF4)
- else if ( xtype == NC_UBYTE ) datatype = DATATYPE_UINT8;
- else if ( xtype == NC_LONG ) datatype = DATATYPE_INT32;
- else if ( xtype == NC_USHORT ) datatype = DATATYPE_UINT16;
- else if ( xtype == NC_UINT ) datatype = DATATYPE_UINT32;
- else if ( xtype == NC_INT64 ) datatype = DATATYPE_FLT64;
- else if ( xtype == NC_UINT64 ) datatype = DATATYPE_FLT64;
-#endif
+ at Description
+The function streamWriteVarF writes the values of one time step of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteVarF(int streamID, int varID, const float *data, size_t nmiss)
+{
+ int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, size_t nmiss)
+ = (int (*)(int, int, int, const void *, size_t))
+ namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
- return datatype;
+ if ( myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
+ {
+ // In case the file format does not support single precision writing,
+ // we fall back to double precision writing, converting the data
+ // on the fly.
+ int vlistID = streamInqVlist(streamID);
+ size_t elementCount = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
+ myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) conversionBuffer, nmiss);
+ Free(conversionBuffer);
+ }
}
-
-void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+static
+int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
- int vlistID1 = streamptr1->vlistID;
- int tsID = streamptr1->curTsID;
- int vrecID = streamptr1->tsteps[tsID].curRecID;
- int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
- int ivarID = streamptr1->tsteps[tsID].records[recID].varID;
- int gridID = vlistInqVarGrid(vlistID1, ivarID);
- int datasize = gridInqSize(gridID);
- int datatype = vlistInqVarDatatype(vlistID1, ivarID);
- int memtype = datatype != DATATYPE_FLT32 ? MEMTYPE_DOUBLE : MEMTYPE_FLOAT;
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- void *data
- = Malloc((size_t)datasize
- * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
- int nmiss;
- cdf_read_record(streamptr1, memtype, data, &nmiss);
- cdf_write_record(streamptr2, memtype, data, nmiss);
+ check_parg(data);
- Free(data);
-}
+ stream_t *streamptr = stream_to_pointer(streamID);
+ if (subtypeInqActiveIndex(streamptr->vars[varID].subtypeID) != 0)
+ Error("Writing of non-trivial subtypes not yet implemented!");
-/* not used
-int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
-{
- int tsID, recID;
+ // check taxis
+ if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
- recID = streamptr->tsteps[0].curRecID++;
- printf("cdfInqRecord recID %d %d\n", recID, streamptr->tsteps[0].curRecID);
- printf("cdfInqRecord tsID %d\n", streamptr->curTsID);
+ int filetype = streamptr->filetype;
- if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
+ switch (filetype)
{
- streamptr->tsteps[0].curRecID = 0;
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ {
+ grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ break;
+#endif
+ default:
+ {
+ Error("%s support not compiled in!", strfiletype(filetype));
+ break;
+ }
}
- *varID = streamptr->tsteps[0].records[recID].varID;
- *levelID = streamptr->tsteps[0].records[recID].levelID;
+ return status;
+}
- streamptr->record->varID = *varID;
- streamptr->record->levelID = *levelID;
+/*
+ at Function streamWriteVarSlice
+ at Title Write a horizontal slice of a variable
- if ( CDI_Debug )
- Message("recID = %d varID = %d levelID = %d", recID, *varID, *levelID);
+ at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, size_t nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item varID Variable identifier.
+ @Item levelID Level identifier.
+ @Item data Pointer to a block of double precision floating point data values to be written.
+ @Item nmiss Number of missing values.
- return (recID+1);
-}
+ at Description
+The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
*/
-
-
-void cdfDefRecord(stream_t *streamptr)
+void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, size_t nmiss)
{
- (void)streamptr;
+ cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
}
-#if defined(NC_SZIP_NN_OPTION_MASK)
-static
-void cdfDefVarSzip(int ncid, int ncvarid)
-{
- int retval;
- /* Set options_mask and bits_per_pixel. */
- int options_mask = NC_SZIP_NN_OPTION_MASK;
- int bits_per_pixel = 16;
-
- if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
- {
- if ( retval == NC_EINVAL )
- {
- static int lwarn = TRUE;
+/*
+ at Function streamWriteVarSliceF
+ at Title Write a horizontal slice of a variable
- if ( lwarn )
- {
- lwarn = FALSE;
- Warning("NetCDF4/Szip compression not compiled in!");
- }
- }
- else
- Error("nc_def_var_szip failed, status = %d", retval);
- }
-}
-#endif
+ at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, size_t nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item varID Variable identifier.
+ @Item levelID Level identifier.
+ @Item data Pointer to a block of single precision floating point data values to be written.
+ @Item nmiss Number of missing values.
-static
-void cdfDefTimeValue(stream_t *streamptr, int tsID)
+ at Description
+The function streamWriteVarSliceF writes the values of a horizontal slice of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, size_t nmiss)
{
- int fileID = streamptr->fileID;
-
- if ( CDI_Debug )
- Message("streamID = %d, fileID = %d", streamptr->self, fileID);
-
- taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
-
- if ( streamptr->ncmode == 1 )
+ if ( cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
{
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ // In case the file format does not support single precision writing,
+ // we fall back to double precision writing, converting the data on the fly.
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
+ streamWriteVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
+ Free(conversionBuffer);
}
+}
- size_t index = (size_t)tsID;
-
- double timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
- if ( CDI_Debug ) Message("tsID = %d timevalue = %f", tsID, timevalue);
- int ncvarid = streamptr->basetime.ncvarid;
- cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+void streamWriteVarChunk(int streamID, int varID,
+ const int rect[][2], const double *data, size_t nmiss)
+{
+ void (*myCdiStreamWriteVarChunk_)(int streamID, int varID, int memtype,
+ const int rect[][2], const void *data, size_t nmiss)
+ = (void (*)(int, int, int, const int [][2], const void *, size_t))
+ namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_CHUNK_).func;
+ myCdiStreamWriteVarChunk_(streamID, varID, MEMTYPE_DOUBLE, rect, data, nmiss);
+}
- if ( taxis->has_bounds )
- {
- size_t start[2], count[2];
+/* single image implementation */
+void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
+ const int rect[][2], const void *data, size_t nmiss)
+{
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
- ncvarid = streamptr->basetime.ncvarboundsid;
+ stream_t *streamptr = stream_to_pointer(streamID);
- timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
- start[0] = (size_t)tsID; count[0] = 1; start[1] = 0; count[1] = 1;
- cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+ // streamDefineTaxis(streamID);
- timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
- start[0] = (size_t)tsID; count[0] = 1; start[1] = 1; count[1] = 1;
- cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
- }
+ int filetype = streamptr->filetype;
- ncvarid = streamptr->basetime.leadtimeid;
- if ( taxis->type == TAXIS_FORECAST && ncvarid != UNDEFID )
+ switch (filetype)
{
- timevalue = taxis->fc_period;
- cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+#endif
+#if defined (HAVE_LIBGRIB) || defined (HAVE_LIBSERVICE) \
+ || defined (HAVE_LIBEXTRA) || defined (HAVE_LIBIEG)
+ xabort("streamWriteVarChunk not implemented for filetype %s!",
+ strfiletype(filetype));
+ break;
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
+ break;
+#endif
+ default:
+ Error("%s support not compiled in!", strfiletype(filetype));
+ break;
}
-
- /*
-printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
- */
}
static
-int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *taxis_name, taxis_t* taxis)
+int stream_write_record(int streamID, int memtype, const void *data, size_t nmiss)
{
- int time_bndsid = -1;
- int dims[2];
-
- dims[0] = nctimedimid;
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- /* fprintf(stderr, "time has bounds\n"); */
+ check_parg(data);
- if ( nc_inq_dimid(fileID, bndsName, &dims[1]) != NC_NOERR )
- cdf_def_dim(fileID, bndsName, 2, &dims[1]);
+ stream_t *streamptr = stream_to_pointer(streamID);
- const char *bndsAttName, *bndsAttVal;
- size_t bndsAttValLen;
- char tmpstr[CDI_MAX_NAME];
- if ( taxis->climatology )
- {
- static const char climatology_bndsName[] = "climatology_bnds",
- climatology_bndsAttName[] = "climatology";
- bndsAttName = climatology_bndsAttName;
- bndsAttValLen = sizeof (climatology_bndsName) - 1;
- bndsAttVal = climatology_bndsName;
- }
- else
+ switch (streamptr->filetype)
{
- size_t taxisnameLen = strlen(taxis_name);
- memcpy(tmpstr, taxis_name, taxisnameLen);
- tmpstr[taxisnameLen] = '_';
- memcpy(tmpstr + taxisnameLen + 1, bndsName, sizeof (bndsName));
- size_t tmpstrLen = taxisnameLen + sizeof (bndsName);
- static const char generic_bndsAttName[] = "bounds";
- bndsAttName = generic_bndsAttName;
- bndsAttValLen = tmpstrLen;
- bndsAttVal = tmpstr;
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ grb_write_record(streamptr, memtype, data, nmiss);
+ break;
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvWriteRecord(streamptr, (const double *)data);
+ break;
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extWriteRecord(streamptr, (const double *)data);
+ break;
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegWriteRecord(streamptr, (const double *)data);
+ break;
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ cdf_write_record(streamptr, memtype, data, nmiss);
+ break;
+ }
+#endif
+ default:
+ {
+ Error("%s support not compiled in!", strfiletype(streamptr->filetype));
+ break;
+ }
}
- cdf_def_var(fileID, bndsAttVal, NC_DOUBLE, 2, dims, &time_bndsid);
- cdf_put_att_text(fileID, nctimevarid, bndsAttName, bndsAttValLen, bndsAttVal);
- return (time_bndsid);
+ return status;
}
-static
-void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
+/*
+ at Function streamWriteRecord
+ at Title Write a horizontal slice of a variable
+
+ at Prototype void streamWriteRecord(int streamID, const double *data, size_t nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+ @Item data Pointer to a block of double precision floating point data values to be written.
+ @Item nmiss Number of missing values.
+
+ at Description
+The function streamWriteRecord writes the values of a horizontal slice (record) of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteRecord(int streamID, const double *data, size_t nmiss)
{
- unitstr[0] = 0;
+ stream_write_record(streamID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+}
+
- if ( taxis0->type == TAXIS_ABSOLUTE )
+void streamWriteRecordF(int streamID, const float *data, size_t nmiss)
+{
+ if ( stream_write_record(streamID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
{
- if ( taxis0->unit == TUNIT_YEAR )
- sprintf(unitstr, "year as %s", "%Y.%f");
- else if ( taxis0->unit == TUNIT_MONTH )
- sprintf(unitstr, "month as %s", "%Y%m.%f");
- else
- sprintf(unitstr, "day as %s", "%Y%m%d.%f");
+ // In case the file format does not support single precision writing,
+ // we fall back to double precision writing, converting the data on the fly.
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int varID = streamptr->record->varID;
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
+ streamWriteRecord(streamID, conversionBuffer, nmiss);
+ Free(conversionBuffer);
}
- else
- {
- int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
- int rdate = taxis->rdate;
- int rtime = taxis->rtime;
- if ( rdate == -1 )
- {
- rdate = taxis->vdate;
- rtime = taxis->vtime;
- }
+}
- int year, month, day, hour, minute, second;
- cdiDecodeDate(rdate, &year, &month, &day);
- cdiDecodeTime(rtime, &hour, &minute, &second);
+#ifdef HAVE_CONFIG_H
+#endif
- if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
- if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
- if ( timeunit == TUNIT_3HOURS ||
- timeunit == TUNIT_6HOURS ||
- timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
- sprintf(unitstr, "%s since %d-%d-%d %02d:%02d:%02d",
- tunitNamePtr(timeunit), year, month, day, hour, minute, second);
- }
-}
+/* the single image implementation */
static
-void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
+int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, size_t *nmiss)
{
- unitstr[0] = 0;
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
- if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
- if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
- if ( timeunit == TUNIT_3HOURS ||
- timeunit == TUNIT_6HOURS ||
- timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
+ check_parg(data);
+ check_parg(nmiss);
- strcpy(unitstr, tunitNamePtr(timeunit));
-}
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int filetype = streamptr->filetype;
-static
-void cdfDefCalendar(int fileID, int ncvarid, int calendar)
-{
- static const struct { int calCode; const char *calStr; } calTab[] = {
- { CALENDAR_STANDARD, "standard" },
- { CALENDAR_PROLEPTIC, "proleptic_gregorian" },
- { CALENDAR_NONE, "none" },
- { CALENDAR_360DAYS, "360_day" },
- { CALENDAR_365DAYS, "365_day" },
- { CALENDAR_366DAYS, "366_day" },
- };
- enum { calTabSize = sizeof calTab / sizeof calTab[0] };
+ *nmiss = 0;
- for (size_t i = 0; i < calTabSize; ++i)
- if (calTab[i].calCode == calendar)
+ switch (filetype)
+ {
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
{
- const char *calstr = calTab[i].calStr;
- size_t len = strlen(calstr);
- cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
- break;
+ grb_read_var(streamptr, varID, memtype, data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvReadVarDP(streamptr, varID, (double *)data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extReadVarDP(streamptr, varID, (double *)data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegReadVarDP(streamptr, varID, (double *)data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ {
+ cdf_read_var(streamptr, varID, memtype, data, nmiss);
+ break;
+ }
+#endif
+ default:
+ {
+ Error("%s support not compiled in!", strfiletype(filetype));
+ break;
}
+ }
+
+ return status;
}
+/*
+ at Function streamReadVar
+ at Title Read a variable
-void cdfDefTime(stream_t* streamptr)
-{
- int time_varid;
- int time_dimid;
- int time_bndsid = -1;
- static const char default_name[] = "time";
+ at Prototype void streamReadVar(int streamID, int varID, double *data, size_t *nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
+ @Item varID Variable identifier.
+ @Item data Pointer to the location into which the data values are read.
+ The caller must allocate space for the returned values.
+ @Item nmiss Number of missing values.
- if ( streamptr->basetime.ncvarid != UNDEFID ) return;
+ at Description
+The function streamReadVar reads all the values of one time step of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVar(int streamID, int varID, double *data, size_t *nmiss)
+{
+ cdiStreamReadVar(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
+}
- int fileID = streamptr->fileID;
+/*
+ at Function streamReadVarF
+ at Title Read a variable
- if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ at Prototype void streamReadVar(int streamID, int varID, float *data, size_t *nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
+ @Item varID Variable identifier.
+ @Item data Pointer to the location into which the data values are read.
+ The caller must allocate space for the returned values.
+ @Item nmiss Number of missing values.
- taxis_t *taxis = &streamptr->tsteps[0].taxis;
+ at Description
+The function streamReadVar reads all the values of one time step of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarF(int streamID, int varID, float *data, size_t *nmiss)
+{
+ if ( cdiStreamReadVar(streamID, varID, MEMTYPE_FLOAT, data, nmiss) )
+ {
+ // In case the file format does not support single precision reading,
+ // we fall back to double precision reading, converting the data on the fly.
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(streamInqVlist(streamID), varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ streamReadVar(streamID, varID, conversionBuffer, nmiss);
+ for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
+ Free(conversionBuffer);
+ }
+}
- const char *taxis_name = (taxis->name && taxis->name[0]) ? taxis->name : default_name ;
- cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
- streamptr->basetime.ncdimid = time_dimid;
+static
+int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, size_t *nmiss)
+{
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- cdf_def_var(fileID, taxis_name, NC_DOUBLE, 1, &time_dimid, &time_varid);
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
- streamptr->basetime.ncvarid = time_varid;
+ check_parg(data);
+ check_parg(nmiss);
- {
- static const char timeStr[] = "time";
- cdf_put_att_text(fileID, time_varid, "standard_name", sizeof(timeStr) - 1, timeStr);
- }
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int filetype = streamptr->filetype;
- if ( taxis->longname && taxis->longname[0] )
- cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
+ *nmiss = 0;
- if ( taxis->has_bounds )
+ switch (filetype)
{
- time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
- streamptr->basetime.ncvarboundsid = time_bndsid;
- }
-
- {
- char unitstr[CDI_MAX_NAME];
- cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
- size_t len = strlen(unitstr);
- if ( len )
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
{
- cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
- /*
- if ( taxis->has_bounds )
- cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
- */
+ grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ break;
}
- }
-
- if ( taxis->calendar != -1 )
- {
- cdfDefCalendar(fileID, time_varid, taxis->calendar);
- /*
- if ( taxis->has_bounds )
- cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
- */
- }
-
- if ( taxis->type == TAXIS_FORECAST )
- {
- int leadtimeid;
-
- cdf_def_var(fileID, "leadtime", NC_DOUBLE, 1, &time_dimid, &leadtimeid);
-
- streamptr->basetime.leadtimeid = leadtimeid;
-
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ {
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ break;
+ }
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
{
- static const char stdname[] = "forecast_period";
- cdf_put_att_text(fileID, leadtimeid, "standard_name", sizeof(stdname) - 1, stdname);
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
+ break;
}
-
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
{
- static const char lname[] = "Time elapsed since the start of the forecast";
- cdf_put_att_text(fileID, leadtimeid, "long_name", sizeof(lname) - 1, lname);
+ cdf_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ break;
}
-
+#endif
+ default:
{
- char unitstr[CDI_MAX_NAME];
- cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
- size_t len = strlen(unitstr);
- if ( len )
- cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
+ Error("%s support not compiled in!", strfiletype(filetype));
+ status = 2;
+ break;
}
}
- cdf_put_att_text(fileID, time_varid, "axis", 1, "T");
-
- if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+ return status;
}
+/*
+ at Function streamReadVarSlice
+ at Title Read a horizontal slice of a variable
-void cdfDefTimestep(stream_t *streamptr, int tsID)
-{
- int vlistID = streamptr->vlistID;
-
- if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
- cdfDefTimeValue(streamptr, tsID);
-}
+ at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, size_t *nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
+ @Item varID Variable identifier.
+ @Item levelID Level identifier.
+ @Item data Pointer to the location into which the data values are read.
+ The caller must allocate space for the returned values.
+ @Item nmiss Number of missing values.
-static
-void cdfDefComplex(stream_t *streamptr, int gridID)
+ at Description
+The function streamReadVarSlice reads all the values of a horizontal slice of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarSlice(int streamID, int varID, int levelID, double *data, size_t *nmiss)
{
- static const char axisname[] = "nc2";
- int dimID = UNDEFID;
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
-
- int ngrids = vlistNgrids(vlistID);
-
- for ( int index = 0; index < ngrids; index++ )
+ if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss) )
{
- if ( streamptr->xdimID[index] != UNDEFID )
- {
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
- {
- dimID = streamptr->xdimID[index];
- break;
- }
- }
+ Warning("Unexpected error returned from cdiStreamReadVarSlice()!");
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ memset(data, 0, elementCount * sizeof(*data));
}
+}
- if ( dimID == UNDEFID )
- {
- size_t dimlen = 2;
-
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+/*
+ at Function streamReadVarSliceF
+ at Title Read a horizontal slice of a variable
- cdf_def_dim(fileID, axisname, dimlen, &dimID);
+ at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, size_t *nmiss)
+ at Parameter
+ @Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
+ @Item varID Variable identifier.
+ @Item levelID Level identifier.
+ @Item data Pointer to the location into which the data values are read.
+ The caller must allocate space for the returned values.
+ @Item nmiss Number of missing values.
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ at Description
+The function streamReadVarSliceF reads all the values of a horizontal slice of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, size_t *nmiss)
+{
+ if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss) )
+ {
+ // In case the file format does not support single precision reading,
+ // we fall back to double precision reading, converting the data on the fly.
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ streamReadVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
+ for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
+ Free(conversionBuffer);
}
-
- int gridindex = vlistGridIndex(vlistID, gridID);
- streamptr->xdimID[gridindex] = dimID;
}
-static void
-cdfDefSPorFC(stream_t *streamptr, int gridID,
- char *restrict axisname, int gridRefType)
+static
+int stream_read_record(int streamID, int memtype, void *data, size_t *nmiss)
{
- int index, iz = 0;
- int dimID = UNDEFID;
-
- int vlistID = streamptr->vlistID;
+ // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
+ // A value > 0 is returned in this case, otherwise it returns zero.
+ int status = 0;
- int ngrids = vlistNgrids(vlistID);
+ check_parg(data);
+ check_parg(nmiss);
- size_t dimlen = (size_t)gridInqSize(gridID)/2;
+ stream_t *streamptr = stream_to_pointer(streamID);
- for ( index = 0; index < ngrids; index++ )
- {
- if ( streamptr->ydimID[index] != UNDEFID )
- {
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == gridRefType )
- {
- size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
- if ( dimlen == dimlen0 )
- {
- dimID = streamptr->ydimID[index];
- break;
- }
- else
- iz++;
- }
- }
- }
+ *nmiss = 0;
- if ( dimID == UNDEFID )
+ switch (streamptr->filetype)
{
- int fileID = streamptr->fileID;
- if ( iz == 0 ) axisname[3] = '\0';
- else sprintf(&axisname[3], "%1d", iz+1);
-
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
- cdf_def_dim(fileID, axisname, dimlen, &dimID);
-
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+#if defined (HAVE_LIBGRIB)
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
+ grb_read_record(streamptr, memtype, data, nmiss);
+ break;
+#endif
+#if defined (HAVE_LIBSERVICE)
+ case CDI_FILETYPE_SRV:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ srvReadRecord(streamptr, (double *)data, nmiss);
+ break;
+#endif
+#if defined (HAVE_LIBEXTRA)
+ case CDI_FILETYPE_EXT:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ extReadRecord(streamptr, (double *)data, nmiss);
+ break;
+#endif
+#if defined (HAVE_LIBIEG)
+ case CDI_FILETYPE_IEG:
+ if ( memtype == MEMTYPE_FLOAT ) return 1;
+ iegReadRecord(streamptr, (double *)data, nmiss);
+ break;
+#endif
+#if defined (HAVE_LIBNETCDF)
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ cdf_read_record(streamptr, memtype, data, nmiss);
+ break;
+#endif
+ default:
+ {
+ Error("%s support not compiled in!", strfiletype(streamptr->filetype));
+ break;
+ }
}
- int gridindex = vlistGridIndex(vlistID, gridID);
- streamptr->ydimID[gridindex] = dimID;
+ return status;
}
-static
-void cdfDefSP(stream_t *streamptr, int gridID)
+
+void streamReadRecord(int streamID, double *data, size_t *nmiss)
{
- /*
- char longname[] = "Spherical harmonic coefficient";
- */
- char axisname[5] = "nspX";
- cdfDefSPorFC(streamptr, gridID, axisname, GRID_SPECTRAL);
+ stream_read_record(streamID, MEMTYPE_DOUBLE, (void *) data, nmiss);
}
-static
-void cdfDefFC(stream_t *streamptr, int gridID)
+void streamReadRecordF(int streamID, float *data, size_t *nmiss)
{
- char axisname[5] = "nfcX";
- cdfDefSPorFC(streamptr, gridID, axisname, GRID_FOURIER);
+ if ( stream_read_record(streamID, MEMTYPE_FLOAT, (void *) data, nmiss) )
+ {
+ // In case the file format does not support single precision reading,
+ // we fall back to double precision reading, converting the data on the fly.
+ stream_t *streamptr = stream_to_pointer(streamID);
+ int tsID = streamptr->curTsID;
+ int vrecID = streamptr->tsteps[tsID].curRecID;
+ int recID = streamptr->tsteps[tsID].recIDs[vrecID];
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
+ streamReadRecord(streamID, conversionBuffer, nmiss);
+ for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
+ Free(conversionBuffer);
+ }
}
+#ifndef _VARSCAN_H
+#define _VARSCAN_H
-static const struct cdfDefGridAxisInqs {
- int (*axisSize)(int gridID);
- void (*axisName)(int gridID, char *dimname);
- const char *(*axisNamePtr)(int gridID);
- void (*axisStdname)(int gridID, char *dimstdname);
- void (*axisLongname)(int gridID, char *dimlongname);
- void (*axisUnits)(int gridID, char *dimunits);
- double (*axisVal)(int gridID, int index);
- const double *(*axisValsPtr)(int gridID);
- const double *(*axisBoundsPtr)(int gridID);
-} gridInqsX = {
- .axisSize = gridInqXsize,
- .axisName = gridInqXname,
- .axisNamePtr = gridInqXnamePtr,
- .axisStdname = gridInqXstdname,
- .axisLongname = gridInqXlongname,
- .axisUnits = gridInqXunits,
- .axisVal = gridInqXval,
- .axisValsPtr = gridInqXvalsPtr,
- .axisBoundsPtr = gridInqXboundsPtr,
-}, gridInqsY = {
- .axisSize = gridInqYsize,
- .axisName = gridInqYname,
- .axisNamePtr = gridInqYnamePtr,
- .axisStdname = gridInqYstdname,
- .axisLongname = gridInqYlongname,
- .axisUnits = gridInqYunits,
- .axisVal = gridInqYval,
- .axisValsPtr = gridInqYvalsPtr,
- .axisBoundsPtr = gridInqYboundsPtr,
-}, gridInqsZ = {
- .axisStdname = zaxisInqStdname,
- .axisLongname = zaxisInqLongname,
- .axisUnits = zaxisInqUnits,
-};
+#ifndef _GRID_H
+#endif
-static void
-cdfPutGridStdAtts(int fileID, int ncvarid,
- int gridID, const struct cdfDefGridAxisInqs *inqs)
-{
- size_t len;
- {
- char stdname[CDI_MAX_NAME];
- inqs->axisStdname(gridID, stdname);
- if ( (len = strlen(stdname)) )
- cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
- }
- {
- char longname[CDI_MAX_NAME];
- inqs->axisLongname(gridID, longname);
- if ( (len = strlen(longname)) )
- cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
- }
- {
- char units[CDI_MAX_NAME];
- inqs->axisUnits(gridID, units);
- if ( (len = strlen(units)) )
- cdf_put_att_text(fileID, ncvarid, "units", len, units);
- }
-}
-static void
-cdfDefTrajLatLon(stream_t *streamptr, int gridID,
- const struct cdfDefGridAxisInqs *inqs,
- int *dimID, const char *sizeName)
-{
- nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
+void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
+ int level1, int level2, int level_sf, int level_unit, int prec,
+ int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
+ const char *name, const char *stdname, const char *longname, const char *units,
+ const var_tile_t *tiles, int *tile_index);
- int vlistID = streamptr->vlistID;
- int dimlen = inqs->axisSize(gridID);
- if ( dimlen != 1 )
- Error("%s isn't 1 for %s grid!", sizeName, gridNamePtr(gridInqType(gridID)));
+void varDefVCT(size_t vctsize, double *vctptr);
+void varDefZAxisReference(int nlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]);
- int gridindex = vlistGridIndex(vlistID, gridID);
- int ncvarid = dimID[gridindex];
+int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,
+ const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
+ const char *longname, const char *units, int prec, int mode, int ltype);
- if ( ncvarid == UNDEFID )
- {
- int dimNcID = streamptr->basetime.ncvarid;
- int fileID = streamptr->fileID;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+void varDefMissval(int varID, double missval);
+void varDefCompType(int varID, int comptype);
+void varDefCompLevel(int varID, int complevel);
+void varDefInst(int varID, int instID);
+int varInqInst(int varID);
+void varDefModel(int varID, int modelID);
+int varInqModel(int varID);
+void varDefTable(int varID, int tableID);
+int varInqTable(int varID);
+void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
- const char *axisname = inqs->axisNamePtr(gridID);
- cdf_def_var(fileID, axisname, xtype, 1, &dimNcID, &ncvarid);
- cdfPutGridStdAtts(fileID, ncvarid, gridID, inqs);
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
- }
+void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess);
+void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate);
- dimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
-}
-static
-void cdfDefTrajLon(stream_t *streamptr, int gridID)
-{
- cdfDefTrajLatLon(streamptr, gridID, &gridInqsX, streamptr->xdimID, "Xsize");
-}
+void varDefOptGribInt(int varID, int tile_index, long lval, const char *keyword);
+void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keyword);
+int varOptGribNentries(int varID);
+bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const double *levels, const char *longname, const char *units, int ltype);
-static
-void cdfDefTrajLat(stream_t *streamptr, int gridID)
-{
- cdfDefTrajLatLon(streamptr, gridID, &gridInqsY, streamptr->ydimID, "Ysize");
-}
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
-static
-int checkDimName(int fileID, size_t dimlen, char *dimname)
-{
- /* check whether the dimenion name is already defined with the same length */
- unsigned iz = 0;
- int dimid = UNDEFID;
- char name[CDI_MAX_NAME];
+#ifdef HAVE_LIBNETCDF
- size_t len = strlen(dimname);
- memcpy(name, dimname, len + 1);
+//#define TEST_GROUPS 1
- do
- {
- if ( iz ) sprintf(name + len, "_%u", iz+1);
+#include <ctype.h>
+#include <limits.h>
- int dimid0, status = nc_inq_dimid(fileID, name, &dimid0);
- if ( status != NC_NOERR )
- break;
- size_t dimlen0;
- cdf_inq_dimlen(fileID, dimid0, &dimlen0);
- if ( dimlen0 == dimlen )
- {
- dimid = dimid0;
- break;
- }
- iz++;
- }
- while ( iz <= 99 );
- if ( iz ) sprintf(dimname + len, "_%u", iz+1);
+#define X_AXIS 1
+#define Y_AXIS 2
+#define Z_AXIS 3
+#define T_AXIS 4
- return dimid;
+#define POSITIVE_UP 1
+#define POSITIVE_DOWN 2
+
+typedef struct {
+ int ncvarid;
+ int dimtype;
+ size_t len;
+ char name[CDI_MAX_NAME];
+}
+ncdim_t;
+#define MAX_COORDVARS 4
+#define MAX_AUXVARS 4
+
+typedef struct {
+ int ncid;
+ int isvar;
+ bool ignore;
+ bool isx;
+ bool isy;
+ bool isc;
+ bool islon;
+ bool islat;
+ bool islev;
+ bool istime;
+ bool warn;
+ bool calendar;
+ bool climatology;
+ bool lformulaterms;
+ int param;
+ int code;
+ int tabnum;
+ int bounds;
+ int gridID;
+ int zaxisID;
+ int timetype;
+ int gridtype;
+ int zaxistype;
+ int xdim;
+ int ydim;
+ int zdim;
+ int xvarid;
+ int yvarid;
+ int zvarid;
+ int cvarids[MAX_COORDVARS];
+ int tvarid;
+ int psvarid;
+ int p0varid;
+ int ncoordvars;
+ int coordvarids[MAX_COORDVARS];
+ int nauxvars;
+ int auxvarids[MAX_AUXVARS];
+ int cellarea;
+ int tableID;
+ int truncation;
+ int position;
+ bool defmissval;
+ bool deffillval;
+ int xtype;
+ int gmapid;
+ int positive;
+ int ndims;
+ int dimids[8];
+ int dimtype[8];
+ size_t chunks[8];
+ int chunked;
+ int chunktype;
+ int natts;
+ int deflate;
+ bool lunsigned;
+ bool lvalidrange;
+ int *atts;
+ size_t vctsize;
+ double *vct;
+ double missval;
+ double fillval;
+ double addoffset;
+ double scalefactor;
+ double validrange[2];
+ char name[CDI_MAX_NAME];
+ char longname[CDI_MAX_NAME];
+ char stdname[CDI_MAX_NAME];
+ char units[CDI_MAX_NAME];
+ char extra[CDI_MAX_NAME];
+ ensinfo_t *ensdata; /* Ensemble information */
}
+ncvar_t;
+
static
-void checkGridName(char *axisname, int fileID, int vlistID, int gridID, int ngrids, int mode)
+void scanTimeString(const char *ptu, int *rdate, int *rtime)
{
- int ncdimid;
- char axisname2[CDI_MAX_NAME];
+ int year = 1, month = 1, day = 1;
+ int hour = 0, minute = 0, second = 0;
+ int v1 = 1, v2 = 1, v3 = 1;
- /* check that the name is not already defined */
- unsigned iz = 0;
+ *rdate = 0;
+ *rtime = 0;
- size_t axisnameLen = strlen(axisname);
- memcpy(axisname2, axisname, axisnameLen + 1);
- do
+ if ( *ptu )
{
- if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
-
- int status = nc_inq_varid(fileID, axisname2, &ncdimid);
-
- if ( status != NC_NOERR )
+ v1 = atoi(ptu);
+ if ( v1 < 0 ) ptu++;
+ while ( isdigit((int) *ptu) ) ptu++;
+ if ( *ptu )
{
- if ( iz )
+ v2 = atoi(++ptu);
+ while ( isdigit((int) *ptu) ) ptu++;
+ if ( *ptu )
{
- /* check that the name does not exist for other grids */
- for ( int index = 0; index < ngrids; index++ )
- {
- int gridID0 = vlistGrid(vlistID, index);
- if ( gridID != gridID0 )
- {
- /* mode X or Y */
- const char *(*query)(int)
- = mode == 'X' ? gridInqXnamePtr : gridInqYnamePtr;
- const char *axisname0 = query(gridID0);
- if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
- }
- }
+ v3 = atoi(++ptu);
+ while ( isdigit((int) *ptu) ) ptu++;
}
- break;
}
- nextSuffix:
- ++iz;
}
- while ( iz <= 99 );
-
- if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
-}
-
-static
-int checkZaxisName(char *axisname, int fileID, int vlistID, int zaxisID, int nzaxis)
-{
- char axisname2[CDI_MAX_NAME];
+ if ( v3 > 999 && v1 < 32 )
+ { year = v3; month = v2; day = v1; }
+ else
+ { year = v1; month = v2; day = v3; }
- /* check that the name is not already defined */
- unsigned iz = 0;
+ while ( isspace((int) *ptu) ) ptu++;
- size_t axisnameLen = strlen(axisname);
- memcpy(axisname2, axisname, axisnameLen + 1);
- do
+ if ( *ptu )
{
- if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
-
- int ncdimid, status = nc_inq_varid(fileID, axisname2, &ncdimid);
+ while ( ! isdigit((int) *ptu) ) ptu++;
- if ( status != NC_NOERR )
+ hour = atoi(ptu);
+ while ( isdigit((int) *ptu) ) ptu++;
+ if ( *ptu == ':' )
{
- if ( iz )
+ ptu++;
+ minute = atoi(ptu);
+ while ( isdigit((int) *ptu) ) ptu++;
+ if ( *ptu == ':' )
{
- /* check that the name does not exist for other zaxes */
- for ( int index = 0; index < nzaxis; index++ )
- {
- int zaxisID0 = vlistZaxis(vlistID, index);
- if ( zaxisID != zaxisID0 )
- {
- const char *axisname0 = zaxisInqNamePtr(zaxisID0);
- if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
- }
- }
+ ptu++;
+ second = atoi(ptu);
}
- break;
}
- nextSuffix:
- ++iz;
}
- while (iz <= 99);
-
- if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
-
- return (int)iz;
+ *rdate = cdiEncodeDate(year, month, day);
+ *rtime = cdiEncodeTime(hour, minute, second);
}
-static void
-cdfDefAxisCommon(stream_t *streamptr, int gridID, int ndims,
- const struct cdfDefGridAxisInqs *gridAxisInq,
- int *axisDimIDs, int dimKey, char axisLetter,
- void (*finishCyclicBounds)(double *pbounds, size_t dimlen,
- const double *pvals),
- int *ncAxisVarIDs)
-{
- int dimID = UNDEFID;
- int ngrids = 0;
- int ncvarid = UNDEFID, ncbvarid = UNDEFID;
- int nvdimID = UNDEFID;
- nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
-
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
-
- if ( ndims ) ngrids = vlistNgrids(vlistID);
-
- size_t dimlen = (size_t)gridAxisInq->axisSize(gridID);
- int gridindex = vlistGridIndex(vlistID, gridID);
-
- const char *axisname = gridAxisInq->axisNamePtr(gridID);
- size_t axisnameLen = strlen(axisname);
-
- if ( axisname[0] == 0 ) Error("axis name undefined!");
-
- for ( int index = 0; index < ngrids; index++ )
- {
- if ( axisDimIDs[index] != UNDEFID )
- {
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_GAUSSIAN ||
- gridtype0 == GRID_LONLAT ||
- gridtype0 == GRID_CURVILINEAR ||
- gridtype0 == GRID_GENERIC )
- {
- size_t dimlen0 = (size_t)gridAxisInq->axisSize(gridID0);
- if ( dimlen == dimlen0 )
- {
- double (*inqVal)(int gridID, int index)
- = gridAxisInq->axisVal;
- if ( IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) &&
- IS_EQUAL(inqVal(gridID0, (int)dimlen-1), inqVal(gridID, (int)dimlen-1)) )
- {
- dimID = axisDimIDs[index];
- break;
- }
- }
- }
- }
- }
+static
+int scanTimeUnit(const char *unitstr)
+{
+ size_t len = strlen(unitstr);
+ int timeunit = get_timeunit(len, unitstr);
+ if ( timeunit == -1 )
+ Message("Unsupported TIMEUNIT: %s!", unitstr);
- if ( dimID == UNDEFID )
- {
- const double *pvals = gridAxisInq->axisValsPtr(gridID);
+ return timeunit;
+}
- /* enough to append _ plus up to 100 decimal and trailing \0 */
- char extendedAxisname[axisnameLen + 4 + 1];
- memcpy(extendedAxisname, axisname, axisnameLen + 1);
- checkGridName(extendedAxisname, fileID, vlistID, gridID, ngrids, axisLetter);
- size_t extendedAxisnameLen
- = axisnameLen + strlen(extendedAxisname + axisnameLen);
+static
+void setForecastTime(const char *timestr, taxis_t *taxis)
+{
+ size_t len = strlen(timestr);
+ if ( len != 0 )
+ scanTimeString(timestr, &taxis->fdate, &taxis->ftime);
+ else
+ taxis->fdate = taxis->ftime = 0;
+}
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+static
+int setBaseTime(const char *timeunits, taxis_t *taxis)
+{
+ int taxistype = TAXIS_ABSOLUTE;
+ int rdate = -1, rtime = -1;
- if ( ndims )
- {
- char dimname[CDI_MAX_NAME+3];
- dimname[0] = 0;
+ size_t len = strlen(timeunits);
+ while ( isspace(*timeunits) && len ) { timeunits++; len--; }
- if ( pvals == NULL )
- cdiGridInqString(gridID, dimKey, CDI_MAX_NAME, dimname);
+ char *restrict tu = (char *)Malloc((len+1) * sizeof(char));
- if ( dimname[0] == 0 ) strcpy(dimname, extendedAxisname);
- dimID = checkDimName(fileID, dimlen, dimname);
+ for ( size_t i = 0; i < len; i++ ) tu[i] = (char)tolower((int)timeunits[i]);
+ tu[len] = 0;
- if ( dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
- }
+ int timeunit = get_timeunit(len, tu);
+ if ( timeunit == -1 )
+ {
+ Message("Unsupported TIMEUNIT: %s!", timeunits);
+ return 1;
+ }
- bool gen_bounds = false;
- int grid_is_cyclic = gridIsCircular(gridID);
- double *pbounds = NULL;
- if ( pvals )
- {
- cdf_def_var(fileID, extendedAxisname, xtype, ndims, &dimID, &ncvarid);
+ size_t pos = 0;
+ while ( pos < len && !isspace(tu[pos]) ) ++pos;
+ if ( tu[pos] )
+ {
+ while ( isspace(tu[pos]) ) ++pos;
- cdfPutGridStdAtts(fileID, ncvarid, gridID, gridAxisInq);
- {
- char axisStr[2] = { axisLetter, '\0' };
- cdf_put_att_text(fileID, ncvarid, "axis", 1, axisStr);
- }
+ if ( str_is_equal(tu+pos, "since") )
+ taxistype = TAXIS_RELATIVE;
- pbounds = (double *)gridAxisInq->axisBoundsPtr(gridID);
+ while ( pos < len && !isspace(tu[pos]) ) ++pos;
+ if ( tu[pos] )
+ {
+ while ( isspace(tu[pos]) ) ++pos;
- if ( CDI_cmor_mode && grid_is_cyclic && !pbounds )
+ if ( taxistype == TAXIS_ABSOLUTE )
{
- gen_bounds = true;
- pbounds = (double*) Malloc(2*dimlen*sizeof(double));
- for ( size_t i = 0; i < dimlen-1; ++i )
+ if ( timeunit == TUNIT_DAY )
{
- pbounds[i*2+1] = (pvals[i] + pvals[i+1])/2;
- pbounds[(i+1)*2] = (pvals[i] + pvals[i+1])/2;
+ if ( !str_is_equal(tu+pos, "%y%m%d.%f") )
+ {
+ Message("Unsupported format %s for TIMEUNIT day!", tu+pos);
+ timeunit = -1;
+ }
+ }
+ else if ( timeunit == TUNIT_MONTH )
+ {
+ if ( !str_is_equal(tu+pos, "%y%m.%f") )
+ {
+ Message("Unsupported format %s for TIMEUNIT month!", tu+pos);
+ timeunit = -1;
+ }
}
- finishCyclicBounds(pbounds, dimlen, pvals);
- }
- if ( pbounds )
- {
- size_t nvertex = 2;
- if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
- cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
}
- if ( pbounds && nvdimID != UNDEFID )
+ else if ( taxistype == TAXIS_RELATIVE )
{
- char boundsname[extendedAxisnameLen + 1 + sizeof (bndsName)];
- memcpy(boundsname, axisname, extendedAxisnameLen);
- boundsname[extendedAxisnameLen] = '_';
- memcpy(boundsname + extendedAxisnameLen + 1, bndsName, sizeof bndsName);
- int dimIDs[2] = { dimID, nvdimID };
- cdf_def_var(fileID, boundsname, xtype, 2, dimIDs, &ncbvarid);
- cdf_put_att_text(fileID, ncvarid, "bounds", extendedAxisnameLen + sizeof (bndsName), boundsname);
+ scanTimeString(tu+pos, &rdate, &rtime);
+
+ taxis->rdate = rdate;
+ taxis->rtime = rtime;
+
+ if ( CDI_Debug )
+ Message("rdate = %d rtime = %d", rdate, rtime);
}
}
+ }
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ taxis->type = taxistype;
+ taxis->unit = timeunit;
- if ( ncvarid != UNDEFID ) cdf_put_var_double(fileID, ncvarid, pvals);
- if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, pbounds);
- if ( gen_bounds ) Free(pbounds);
+ Free(tu);
- if ( ndims == 0 ) ncAxisVarIDs[gridindex] = ncvarid;
- }
+ if ( CDI_Debug )
+ Message("taxistype = %d unit = %d", taxistype, timeunit);
- axisDimIDs[gridindex] = dimID;
+ return 0;
}
-static void
-finishCyclicXBounds(double *pbounds, size_t dimlen, const double *pvals)
+static
+bool xtypeIsText(int xtype)
{
- pbounds[0] = (pvals[0] + pvals[dimlen-1]-360)*0.5;
- pbounds[2*dimlen-1] = (pvals[dimlen-1] + pvals[0]+360)*0.5;
+ bool isText = ( xtype == NC_CHAR )
+#if defined (HAVE_NETCDF4)
+ || ( xtype == NC_STRING )
+#endif
+ ;
+ return isText;
}
static
-void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
+bool xtypeIsFloat(nc_type xtype)
{
- cdfDefAxisCommon(streamptr, gridID, ndims, &gridInqsX, streamptr->xdimID,
- CDI_GRID_XDIMNAME, 'X', finishCyclicXBounds,
- streamptr->ncxvarID);
-}
+ bool isFloat = xtype == NC_FLOAT || xtype == NC_DOUBLE;
-static void
-finishCyclicYBounds(double *pbounds, size_t dimlen, const double *pvals)
-{
- pbounds[0] = copysign(90.0, pvals[0]);
- pbounds[2*dimlen-1] = copysign(90.0, pvals[dimlen-1]);
+ return isFloat;
}
static
-void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
+bool xtypeIsInt(nc_type xtype)
{
- cdfDefAxisCommon(streamptr, gridID, ndims, &gridInqsY, streamptr->ydimID,
- CDI_GRID_YDIMNAME, 'Y', finishCyclicYBounds,
- streamptr->ncyvarID);
+ bool isInt = xtype == NC_SHORT || xtype == NC_INT
+ || xtype == NC_BYTE
+#if defined (HAVE_NETCDF4)
+ || xtype == NC_USHORT || xtype == NC_UINT
+ || xtype == NC_UBYTE
+#endif
+ ;
+
+ return isInt;
}
static
-void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
+int cdfInqDatatype(int xtype, bool lunsigned)
{
+ int datatype = -1;
+
#if defined (HAVE_NETCDF4)
- if ( gridsize > 1 && comptype == COMPRESS_ZIP && (filetype == FILETYPE_NC4 || filetype == FILETYPE_NC4C) )
- {
- nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
- cdfDefVarDeflate(fileID, ncvarid, 1);
- }
+ if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
#endif
+
+ if ( xtype == NC_BYTE ) datatype = CDI_DATATYPE_INT8;
+ else if ( xtype == NC_CHAR ) datatype = CDI_DATATYPE_UINT8;
+ else if ( xtype == NC_SHORT ) datatype = CDI_DATATYPE_INT16;
+ else if ( xtype == NC_INT ) datatype = CDI_DATATYPE_INT32;
+ else if ( xtype == NC_FLOAT ) datatype = CDI_DATATYPE_FLT32;
+ else if ( xtype == NC_DOUBLE ) datatype = CDI_DATATYPE_FLT64;
+#if defined (HAVE_NETCDF4)
+ else if ( xtype == NC_UBYTE ) datatype = CDI_DATATYPE_UINT8;
+ else if ( xtype == NC_LONG ) datatype = CDI_DATATYPE_INT32;
+ else if ( xtype == NC_USHORT ) datatype = CDI_DATATYPE_UINT16;
+ else if ( xtype == NC_UINT ) datatype = CDI_DATATYPE_UINT32;
+ else if ( xtype == NC_INT64 ) datatype = CDI_DATATYPE_FLT64;
+ else if ( xtype == NC_UINT64 ) datatype = CDI_DATATYPE_FLT64;
+#endif
+
+ return datatype;
}
static
-void cdfDefCurvilinear(stream_t *streamptr, int gridID)
+void cdfGetAttInt(int fileID, int ncvarid, const char *attname, size_t attlen, int *attint)
{
- int xdimID = UNDEFID;
- int ydimID = UNDEFID;
- int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
- int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
- nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
+ *attint = 0;
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
+ nc_type atttype;
+ size_t nc_attlen;
+ cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+ cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
- int ngrids = vlistNgrids(vlistID);
+ if ( xtypeIsFloat(atttype) || xtypeIsInt(atttype) )
+ {
+ bool lalloc = nc_attlen > attlen;
+ int *pintatt = lalloc ? (int *)(Malloc(nc_attlen*sizeof(int))) : attint;
+ cdf_get_att_int(fileID, ncvarid, attname, pintatt);
+ if ( lalloc )
+ {
+ memcpy(attint, pintatt, attlen*sizeof(int));
+ Free(pintatt);
+ }
+ }
+}
- size_t dimlen = (size_t)gridInqSize(gridID);
- size_t xdimlen = (size_t)gridInqXsize(gridID);
- size_t ydimlen = (size_t)gridInqYsize(gridID);
- int gridindex = vlistGridIndex(vlistID, gridID);
+static
+void cdfGetAttDouble(int fileID, int ncvarid, char *attname, size_t attlen, double *attdouble)
+{
+ *attdouble = 0;
+
+ nc_type atttype;
+ size_t nc_attlen;
+ cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+ cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
- for ( int index = 0; index < ngrids; index++ )
+ if ( xtypeIsFloat(atttype) || xtypeIsInt(atttype) )
{
- if ( streamptr->xdimID[index] != UNDEFID )
+ bool lalloc = nc_attlen > attlen;
+ double *pdoubleatt = lalloc ? (double*)Malloc(nc_attlen*sizeof(double)) : attdouble;
+ cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
+ if ( lalloc )
{
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_CURVILINEAR )
- {
- size_t dimlen0 = (size_t)gridInqSize(gridID0);
- if ( dimlen == dimlen0 )
- if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
- IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) &&
- IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
- IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
- {
- xdimID = streamptr->xdimID[index];
- ydimID = streamptr->ydimID[index];
- ncxvarid = streamptr->ncxvarID[index];
- ncyvarid = streamptr->ncyvarID[index];
- break;
- }
- }
+ memcpy(attdouble, pdoubleatt, attlen*sizeof(double));
+ Free(pdoubleatt);
}
}
+}
+
+static
+bool cdfCheckAttText(int fileID, int ncvarid, const char *attname)
+{
+ bool status = false;
+ nc_type atttype;
+
+ int status_nc = nc_inq_atttype(fileID, ncvarid, attname, &atttype);
+
+ if ( status_nc == NC_NOERR
+ && (atttype == NC_CHAR
+#if defined (HAVE_NETCDF4)
+ || atttype == NC_STRING
+#endif
+ ) )
+ {
+ status = true;
+ }
+
+ return status;
+}
+
+static
+void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen, char *atttext)
+{
+ nc_type atttype;
+ size_t nc_attlen;
+
+ cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+ cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
- if ( xdimID == UNDEFID || ydimID == UNDEFID )
+ if ( atttype == NC_CHAR )
{
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- {
- char xdimname[CDI_MAX_NAME+3];
- xdimname[0] = 0;
- cdiGridInqString(gridID, CDI_GRID_XDIMNAME, CDI_MAX_NAME, xdimname);
- if ( xdimname[0] == 0 ) { xdimname[0] = 'x'; xdimname[1] = 0; }
- xdimID = checkDimName(fileID, xdimlen, xdimname);
- if ( xdimID == UNDEFID ) cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
- }
- {
- char ydimname[CDI_MAX_NAME+3];
- ydimname[0] = 0;
- cdiGridInqString(gridID, CDI_GRID_YDIMNAME, CDI_MAX_NAME, ydimname);
- if ( ydimname[0] == 0 ) { ydimname[0] = 'y'; ydimname[1] = 0; }
- ydimID = checkDimName(fileID, ydimlen, ydimname);
- if ( ydimID == UNDEFID ) cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
- }
+ char attbuf[65636];
+ if ( nc_attlen < sizeof(attbuf) )
+ {
+ cdf_get_att_text(fileID, ncvarid, attname, attbuf);
+
+ if ( nc_attlen > (attlen-1) ) nc_attlen = (attlen-1);
- int nvdimID = UNDEFID;
- int dimIDs[3];
- if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
+ attbuf[nc_attlen++] = 0;
+ memcpy(atttext, attbuf, nc_attlen);
+ }
+ else
{
- char vdimname[CDI_MAX_NAME+3];
- vdimname[0] = 0;
- cdiGridInqString(gridID, CDI_GRID_VDIMNAME, CDI_MAX_NAME, vdimname);
- if ( vdimname[0] == 0 ) strcpy(vdimname, "nv4");
- size_t nvertex = 4;
- nvdimID = checkDimName(fileID, nvertex, vdimname);
- if ( nvdimID == UNDEFID ) cdf_def_dim(fileID, vdimname, nvertex, &nvdimID);
+ atttext[0] = 0;
}
+ }
+#if defined (HAVE_NETCDF4)
+ else if ( atttype == NC_STRING )
+ {
+ if ( nc_attlen == 1 )
+ {
+ char *attbuf = NULL;
+ cdf_get_att_string(fileID, ncvarid, attname, &attbuf);
- dimIDs[0] = ydimID;
- dimIDs[1] = xdimID;
- dimIDs[2] = nvdimID;
+ size_t ssize = strlen(attbuf) + 1;
- if ( gridInqXvalsPtr(gridID) )
+ if ( ssize > attlen ) ssize = attlen;
+ memcpy(atttext, attbuf, ssize);
+ atttext[ssize - 1] = 0;
+ Free(attbuf);
+ }
+ else
{
- char xaxisname[CDI_MAX_NAME];
- gridInqXname(gridID, xaxisname);
- checkGridName(xaxisname, fileID, vlistID, gridID, ngrids, 'X');
+ atttext[0] = 0;
+ }
+ }
+#endif
+}
+
+
+void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor)
+{
+ bool laddoffset = IS_NOT_EQUAL(addoffset, 0);
+ bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+
+ if ( laddoffset && lscalefactor )
+ {
+ for (size_t i = 0; i < size; ++i )
+ data[i] = data[i] * scalefactor + addoffset;
+ }
+ else if (lscalefactor)
+ {
+ for (size_t i = 0; i < size; ++i )
+ data[i] *= scalefactor;
+ }
+ else if (laddoffset)
+ {
+ for (size_t i = 0; i < size; ++i )
+ data[i] += addoffset;
+ }
+}
+
+static
+void cdfCreateRecords(stream_t *streamptr, int tsID)
+{
+ if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
- cdf_def_var(fileID, xaxisname, xtype, 2, dimIDs, &ncxvarid);
- cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
- cdfPutGridStdAtts(fileID, ncxvarid, gridID, &gridInqsX);
+ int vlistID = streamptr->vlistID;
- /* attribute for Panoply */
- cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
+ tsteps_t* sourceTstep = streamptr->tsteps;
+ tsteps_t* destTstep = sourceTstep + tsID;
- if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
- {
- size_t xaxisnameLen = strlen(xaxisname);
- xaxisname[xaxisnameLen] = '_';
- memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
- cdf_def_var(fileID, xaxisname, xtype, 3, dimIDs, &ncbxvarid);
- cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ int nvars = vlistNvars(vlistID);
+ int nrecs = vlistNrecs(vlistID);
+
+ if ( nrecs <= 0 ) return;
+
+ if ( tsID == 0 )
+ {
+ int nvrecs = nrecs; /* use all records at first timestep */
+
+ streamptr->nrecs += nrecs;
+
+ destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+ destTstep->nrecs = nrecs;
+ destTstep->nallrecs = nrecs;
+ destTstep->recordSize = nrecs;
+ destTstep->curRecID = CDI_UNDEFID;
+ destTstep->recIDs = (int *) Malloc((size_t)nvrecs*sizeof (int));;
+ for ( int recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
+
+ record_t *records = destTstep->records;
- cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
+ for ( int varID = 0, recID = 0; varID < nvars; varID++ )
+ {
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int nlev = zaxisInqSize(zaxisID);
+ for ( int levelID = 0; levelID < nlev; levelID++ )
+ {
+ recordInitEntry(&records[recID]);
+ records[recID].varID = (short)varID;
+ records[recID].levelID = (short)levelID;
+ recID++;
}
}
-
- if ( gridInqYvalsPtr(gridID) )
+ }
+ else if ( tsID == 1 )
+ {
+ int nvrecs = 0;
+ for ( int varID = 0; varID < nvars; varID++ )
{
- char yaxisname[CDI_MAX_NAME];
- gridInqYname(gridID, yaxisname);
- checkGridName(yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
+ if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT )
+ {
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ nvrecs += zaxisInqSize(zaxisID);
+ }
+ }
- cdf_def_var(fileID, yaxisname, xtype, 2, dimIDs, &ncyvarid);
- cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ streamptr->nrecs += nvrecs;
- cdfPutGridStdAtts(fileID, ncyvarid, gridID, &gridInqsY);
+ destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+ destTstep->nrecs = nvrecs;
+ destTstep->nallrecs = nrecs;
+ destTstep->recordSize = nrecs;
+ destTstep->curRecID = CDI_UNDEFID;
- /* attribute for Panoply */
- cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
+ memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
- if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+ if ( nvrecs )
+ {
+ destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof (int));
+ for ( int recID = 0, vrecID = 0; recID < nrecs; recID++ )
{
- size_t yaxisnameLen = strlen(yaxisname);
- yaxisname[yaxisnameLen] = '_';
- memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
- cdf_def_var(fileID, yaxisname, xtype, 3, dimIDs, &ncbyvarid);
- cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
-
- cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
+ int varID = destTstep->records[recID].varID;
+ if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT )
+ {
+ destTstep->recIDs[vrecID++] = recID;
+ }
}
}
+ }
+ else
+ {
+ if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
- if ( gridInqAreaPtr(gridID) )
- {
- static const char yaxisname_[] = "cell_area";
- static const char units[] = "m2";
- static const char longname[] = "area of grid cell";
- static const char stdname[] = "cell_area";
+ int nvrecs = streamptr->tsteps[1].nrecs;
- cdf_def_var(fileID, yaxisname_, xtype, 2, dimIDs, &ncavarid);
+ streamptr->nrecs += nvrecs;
- cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
- cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
- cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
- }
+ destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+ destTstep->nrecs = nvrecs;
+ destTstep->nallrecs = nrecs;
+ destTstep->recordSize = nrecs;
+ destTstep->curRecID = CDI_UNDEFID;
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
- if ( ncxvarid != UNDEFID ) cdf_put_var_double(fileID, ncxvarid, gridInqXvalsPtr(gridID));
- if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
- if ( ncyvarid != UNDEFID ) cdf_put_var_double(fileID, ncyvarid, gridInqYvalsPtr(gridID));
- if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
- if ( ncavarid != UNDEFID ) cdf_put_var_double(fileID, ncavarid, gridInqAreaPtr(gridID));
- }
+ destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof(int));
- streamptr->xdimID[gridindex] = xdimID;
- streamptr->ydimID[gridindex] = ydimID;
- streamptr->ncxvarID[gridindex] = ncxvarid;
- streamptr->ncyvarID[gridindex] = ncyvarid;
- streamptr->ncavarID[gridindex] = ncavarid;
+ memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
+ }
}
static
-void cdfDefRgrid(stream_t *streamptr, int gridID)
+int cdf_time_dimid(int fileID, int ndims, int nvars)
{
- int dimID = UNDEFID;
-
- int vlistID = streamptr->vlistID;
- int ngrids = vlistNgrids(vlistID);
-
- size_t dimlen = (size_t)gridInqSize(gridID);
+ char dimname[80];
+ for ( int dimid = 0; dimid < ndims; ++dimid )
+ {
+ dimname[0] = 0;
+ cdf_inq_dimname(fileID, dimid, dimname);
+ if ( str_is_equal(dimname, "time") || str_is_equal(dimname, "Time") ) return dimid;
+ }
- int iz = 0;
- for ( int index = 0; index < ngrids; index++ )
+ for ( int varid = 0; varid < nvars; ++varid )
{
- if ( streamptr->xdimID[index] != UNDEFID )
+ nc_type xtype;
+ int nvdims, nvatts, dimids[9];
+ cdf_inq_var(fileID, varid, NULL, &xtype, &nvdims, dimids, &nvatts);
+ if ( nvdims == 1 )
{
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_GAUSSIAN_REDUCED )
+ char sbuf[CDI_MAX_NAME];
+ for ( int iatt = 0; iatt < nvatts; ++iatt )
{
- size_t dimlen0 = (size_t)gridInqSize(gridID0);
-
- if ( dimlen == dimlen0 )
+ sbuf[0] = 0;
+ cdf_inq_attname(fileID, varid, iatt, sbuf);
+ if ( strncmp(sbuf, "units", 5) == 0 )
{
- dimID = streamptr->xdimID[index];
- break;
+ cdfGetAttText(fileID, varid, "units", sizeof(sbuf), sbuf);
+ str_tolower(sbuf);
+
+ if ( is_time_units(sbuf) ) return dimids[0];
}
- iz++;
}
}
}
- if ( dimID == UNDEFID )
+ return CDI_UNDEFID;
+}
+
+static
+void init_ncdims(long ndims, ncdim_t *ncdims)
+{
+ for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ {
+ ncdims[ncdimid].ncvarid = CDI_UNDEFID;
+ ncdims[ncdimid].dimtype = CDI_UNDEFID;
+ ncdims[ncdimid].len = 0;
+ ncdims[ncdimid].name[0] = 0;
+ }
+}
+
+static
+void init_ncvars(long nvars, ncvar_t *ncvars)
+{
+ for ( long ncvarid = 0; ncvarid < nvars; ++ncvarid )
{
- int fileID = streamptr->fileID;
- static bool lwarn = true;
- if ( lwarn )
+ ncvars[ncvarid].ncid = CDI_UNDEFID;
+ ncvars[ncvarid].isvar = CDI_UNDEFID;
+ ncvars[ncvarid].ignore = false;
+ ncvars[ncvarid].isx = false;
+ ncvars[ncvarid].isy = false;
+ ncvars[ncvarid].isc = false;
+ ncvars[ncvarid].islon = false;
+ ncvars[ncvarid].islat = false;
+ ncvars[ncvarid].islev = false;
+ ncvars[ncvarid].istime = false;
+ ncvars[ncvarid].warn = false;
+ ncvars[ncvarid].calendar = false;
+ ncvars[ncvarid].climatology = false;
+ ncvars[ncvarid].lformulaterms = false;
+ ncvars[ncvarid].timetype = TIME_CONSTANT;
+ ncvars[ncvarid].param = CDI_UNDEFID;
+ ncvars[ncvarid].code = CDI_UNDEFID;
+ ncvars[ncvarid].tabnum = 0;
+ ncvars[ncvarid].bounds = CDI_UNDEFID;
+ ncvars[ncvarid].gridID = CDI_UNDEFID;
+ ncvars[ncvarid].zaxisID = CDI_UNDEFID;
+ ncvars[ncvarid].gridtype = CDI_UNDEFID;
+ ncvars[ncvarid].zaxistype = CDI_UNDEFID;
+ ncvars[ncvarid].xdim = CDI_UNDEFID;
+ ncvars[ncvarid].ydim = CDI_UNDEFID;
+ ncvars[ncvarid].zdim = CDI_UNDEFID;
+ ncvars[ncvarid].xvarid = CDI_UNDEFID;
+ ncvars[ncvarid].yvarid = CDI_UNDEFID;
+ ncvars[ncvarid].zvarid = CDI_UNDEFID;
+ ncvars[ncvarid].tvarid = CDI_UNDEFID;
+ ncvars[ncvarid].psvarid = CDI_UNDEFID;
+ ncvars[ncvarid].p0varid = CDI_UNDEFID;
+ ncvars[ncvarid].ncoordvars = 0;
+ for ( int i = 0; i < MAX_COORDVARS; ++i )
{
- Warning("Creating a NetCDF file with data on a gaussian reduced grid.");
- Warning("The further processing of the resulting file is unsupported!");
- lwarn = false;
+ ncvars[ncvarid].coordvarids[i] = CDI_UNDEFID;
+ ncvars[ncvarid].cvarids[i] = CDI_UNDEFID;
}
+ ncvars[ncvarid].nauxvars = 0;
+ for ( int i = 0; i < MAX_AUXVARS; ++i )
+ ncvars[ncvarid].auxvarids[i] = CDI_UNDEFID;
+ ncvars[ncvarid].cellarea = CDI_UNDEFID;
+ ncvars[ncvarid].tableID = CDI_UNDEFID;
+ ncvars[ncvarid].xtype = 0;
+ ncvars[ncvarid].ndims = 0;
+ ncvars[ncvarid].gmapid = CDI_UNDEFID;
+ ncvars[ncvarid].vctsize = 0;
+ ncvars[ncvarid].vct = NULL;
+ ncvars[ncvarid].truncation = 0;
+ ncvars[ncvarid].position = 0;
+ ncvars[ncvarid].positive = 0;
+ ncvars[ncvarid].chunked = 0;
+ ncvars[ncvarid].chunktype = CDI_UNDEFID;
+ ncvars[ncvarid].defmissval = false;
+ ncvars[ncvarid].deffillval = false;
+ ncvars[ncvarid].missval = 0;
+ ncvars[ncvarid].fillval = 0;
+ ncvars[ncvarid].addoffset = 0;
+ ncvars[ncvarid].scalefactor = 1;
+ ncvars[ncvarid].natts = 0;
+ ncvars[ncvarid].atts = NULL;
+ ncvars[ncvarid].deflate = 0;
+ ncvars[ncvarid].lunsigned = false;
+ ncvars[ncvarid].lvalidrange = false;
+ ncvars[ncvarid].validrange[0] = VALIDMISS;
+ ncvars[ncvarid].validrange[1] = VALIDMISS;
+ ncvars[ncvarid].ensdata = NULL;
+ memset(ncvars[ncvarid].name, 0, CDI_MAX_NAME);
+ memset(ncvars[ncvarid].longname, 0, CDI_MAX_NAME);
+ memset(ncvars[ncvarid].stdname, 0, CDI_MAX_NAME);
+ memset(ncvars[ncvarid].units, 0, CDI_MAX_NAME);
+ memset(ncvars[ncvarid].extra, 0, CDI_MAX_NAME);
+ }
+}
- char axisname[7] = "rgridX";
- if ( iz == 0 ) axisname[5] = '\0';
- else sprintf(&axisname[5], "%1d", iz+1);
+static
+void cdf_set_var(ncvar_t *ncvars, int ncvarid, short isvar)
+{
+ if ( ncvars[ncvarid].isvar != CDI_UNDEFID &&
+ ncvars[ncvarid].isvar != isvar &&
+ ncvars[ncvarid].warn == false )
+ {
+ if ( ! ncvars[ncvarid].ignore )
+ Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ ncvars[ncvarid].warn = true;
+ isvar = FALSE;
+ }
- cdf_def_dim(fileID, axisname, dimlen, &dimID);
+ ncvars[ncvarid].isvar = isvar;
+}
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+static
+void cdf_set_dim(ncvar_t *ncvars, int ncvarid, int dimid, int dimtype)
+{
+ if ( ncvars[ncvarid].dimtype[dimid] != CDI_UNDEFID &&
+ ncvars[ncvarid].dimtype[dimid] != dimtype )
+ {
+ Warning("Inconsistent dimension definition for %s! dimid = %d; type = %d; newtype = %d",
+ ncvars[ncvarid].name, dimid, ncvars[ncvarid].dimtype[dimid], dimtype);
}
- int gridindex = vlistGridIndex(vlistID, gridID);
- streamptr->xdimID[gridindex] = dimID;
+ ncvars[ncvarid].dimtype[dimid] = dimtype;
}
static
-void cdfDefGdim(stream_t *streamptr, int gridID)
+void scan_hybrid_formulaterms(int ncid, int ncfvarid, int *avarid, int *bvarid, int *psvarid, int *p0varid)
{
- int iz = 0;
- int dimID = UNDEFID;
+ *avarid = -1;
+ *bvarid = -1;
+ *psvarid = -1;
+ *p0varid = -1;
- int vlistID = streamptr->vlistID;
- int ngrids = vlistNgrids(vlistID);
+ char attstring[1024];
+ cdfGetAttText(ncid, ncfvarid, "formula_terms", sizeof(attstring), attstring);
+ char *pstring = attstring;
- size_t dimlen = (size_t)gridInqSize(gridID);
+ bool lstop = false;
+ for ( int i = 0; i < 4; i++ )
+ {
+ while ( isspace((int) *pstring) ) pstring++;
+ if ( *pstring == 0 ) break;
+ char *tagname = pstring;
+ while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+ if ( *pstring == 0 ) lstop = true;
+ *pstring++ = 0;
- if ( gridInqYsize(gridID) == 0 )
- for ( int index = 0; index < ngrids; index++ )
- {
- if ( streamptr->xdimID[index] != UNDEFID )
- {
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_GENERIC )
- {
- size_t dimlen0 = (size_t)gridInqSize(gridID0);
- if ( dimlen == dimlen0 )
- {
- dimID = streamptr->xdimID[index];
- break;
- }
- else
- iz++;
- }
- }
- }
+ while ( isspace((int) *pstring) ) pstring++;
+ if ( *pstring == 0 ) break;
+ char *varname = pstring;
+ while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+ if ( *pstring == 0 ) lstop = true;
+ *pstring++ = 0;
- if ( gridInqXsize(gridID) == 0 )
- for ( int index = 0; index < ngrids; index++ )
- {
- if ( streamptr->ydimID[index] != UNDEFID )
- {
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_GENERIC )
- {
- size_t dimlen0 = (size_t)gridInqSize(gridID0);
- if ( dimlen == dimlen0 )
- {
- dimID = streamptr->ydimID[index];
- break;
- }
- else
- iz++;
- }
- }
- }
+ int dimvarid;
+ int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
+ if ( status_nc == NC_NOERR )
+ {
+ if ( strcmp(tagname, "ap:") == 0 ) *avarid = dimvarid;
+ else if ( strcmp(tagname, "a:") == 0 ) *avarid = dimvarid;
+ else if ( strcmp(tagname, "b:") == 0 ) *bvarid = dimvarid;
+ else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
+ else if ( strcmp(tagname, "p0:") == 0 ) *p0varid = dimvarid;
+ }
+ else if ( strcmp(tagname, "ps:") != 0 )
+ {
+ Warning("%s - %s", nc_strerror(status_nc), varname);
+ }
+
+ if ( lstop ) break;
+ }
+}
+
+static
+bool isHybridSigmaPressureCoordinate(int ncid, int ncvarid, ncvar_t *ncvars, const ncdim_t *ncdims)
+{
+ bool status = false;
+ ncvar_t *ncvar = &ncvars[ncvarid];
- if ( dimID == UNDEFID )
+ if ( strcmp(ncvar->stdname, "atmosphere_hybrid_sigma_pressure_coordinate") == 0 )
{
- int fileID = streamptr->fileID;
- char dimname[CDI_MAX_NAME];
- strcpy(dimname, "gsize");
+ cdiConvention = CDI_CONVENTION_CF;
- dimID = checkDimName(fileID, dimlen, dimname);
+ status = true;
+ ncvar->zaxistype = ZAXIS_HYBRID;
+ //int ndims = ncvar->ndims;
+ int dimid = ncvar->dimids[0];
+ size_t dimlen = ncdims[dimid].len;
+ int avarid1 = -1, bvarid1 = -1, psvarid1 = -1, p0varid1 = -1;
+ int ncfvarid = ncvarid;
+ if ( ncvars[ncfvarid].lformulaterms )
+ scan_hybrid_formulaterms(ncid, ncfvarid, &avarid1, &bvarid1, &psvarid1, &p0varid1);
+ // printf("avarid1, bvarid1, psvarid1, p0varid1 %d %d %d %d\n", avarid1, bvarid1, psvarid1, p0varid1);
+ if ( avarid1 != -1 ) ncvars[avarid1].isvar = FALSE;
+ if ( bvarid1 != -1 ) ncvars[bvarid1].isvar = FALSE;
+ if ( psvarid1 != -1 ) ncvar->psvarid = psvarid1;
+ if ( p0varid1 != -1 ) ncvar->p0varid = p0varid1;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ if ( ncvar->bounds != CDI_UNDEFID && ncvars[ncvar->bounds].lformulaterms )
+ {
+ ncfvarid = ncvar->bounds;
+ int avarid2 = -1, bvarid2 = -1, psvarid2 = -1, p0varid2 = -1;
+ if ( ncvars[ncfvarid].lformulaterms )
+ scan_hybrid_formulaterms(ncid, ncfvarid, &avarid2, &bvarid2, &psvarid2, &p0varid2);
+ // printf("avarid2, bvarid2, psvarid2, p0varid2 %d %d %d %d\n", avarid2, bvarid2, psvarid2, p0varid2);
+ if ( avarid2 != -1 && bvarid2 != -1 )
+ {
+ ncvars[avarid2].isvar = FALSE;
+ ncvars[bvarid2].isvar = FALSE;
- if ( dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+ int ndims2 = ncvars[avarid2].ndims;
+ int dimid2 = ncvars[avarid2].dimids[0];
+ size_t dimlen2 = ncdims[dimid2].len;
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ if ( (ndims2 == 2 && dimid == ncvars[avarid2].dimids[0] ) ||
+ (ndims2 == 1 && dimlen == dimlen2-1 ) )
+ {
+ double px = 1;
+ if ( p0varid1 != -1 && p0varid1 == p0varid2 )
+ cdf_get_var_double(ncid, p0varid2, &px);
+
+ double abuf[dimlen*2], bbuf[dimlen*2];
+ cdf_get_var_double(ncid, avarid2, abuf);
+ cdf_get_var_double(ncid, bvarid2, bbuf);
+
+ size_t vctsize = (dimlen+1)*2;
+ double *vct = (double *) Malloc(vctsize*sizeof(double));
+ if ( ndims2 == 2 )
+ {
+ for ( size_t i = 0; i < dimlen; ++i )
+ {
+ vct[i] = abuf[i*2];
+ vct[i+dimlen+1] = bbuf[i*2];
+ }
+ vct[dimlen] = abuf[dimlen*2-1];
+ vct[dimlen*2+1] = bbuf[dimlen*2-1];
+ }
+ else
+ {
+ for ( size_t i = 0; i < dimlen2; ++i )
+ {
+ vct[i] = abuf[i];
+ vct[i+dimlen+1] = bbuf[i];
+ }
+ }
+
+ if ( p0varid1 != -1 && IS_NOT_EQUAL(px, 1) )
+ for ( size_t i = 0; i < dimlen+1; ++i ) vct[i] *= px;
+
+ ncvar->vct = vct;
+ ncvar->vctsize = vctsize;
+ }
+ }
+ }
}
- int gridindex = vlistGridIndex(vlistID, gridID);
- streamptr->xdimID[gridindex] = dimID;
+ return status;
}
static
-void cdfDefGridReference(stream_t *streamptr, int gridID)
+void cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID)
{
- int fileID = streamptr->fileID;
- int number = gridInqNumber(gridID);
+ nc_type atttype;
+ size_t attlen;
+ char attname[CDI_MAX_NAME];
+
+ cdf_inq_attname(ncid, ncvarid, attnum, attname);
+ cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+ cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
+ if ( xtypeIsInt(atttype) )
+ {
+ int attint[attlen];
+ cdfGetAttInt(ncid, ncvarid, attname, attlen, attint);
+ int datatype = (atttype == NC_SHORT) ? CDI_DATATYPE_INT16 :
+ (atttype == NC_BYTE) ? CDI_DATATYPE_INT8 :
+#if defined (HAVE_NETCDF4)
+ (atttype == NC_UBYTE) ? CDI_DATATYPE_UINT8 :
+ (atttype == NC_USHORT) ? CDI_DATATYPE_UINT16 :
+ (atttype == NC_UINT) ? CDI_DATATYPE_UINT32 :
+#endif
+ CDI_DATATYPE_INT32;
+ cdiDefAttInt(cdiID, varID, attname, datatype, (int)attlen, attint);
+ }
+ else if ( xtypeIsFloat(atttype) )
+ {
+ double attflt[attlen];
+ cdfGetAttDouble(ncid, ncvarid, attname, attlen, attflt);
+ int datatype = (atttype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
+ cdiDefAttFlt(cdiID, varID, attname, datatype, (int)attlen, attflt);
+ }
+ else if ( xtypeIsText(atttype) )
+ {
+ char attstring[8192];
+ cdfGetAttText(ncid, ncvarid, attname, sizeof(attstring), attstring);
+ cdiDefAttTxt(cdiID, varID, attname, (int)attlen, attstring);
+ }
+}
+
+static
+void cdf_print_vars(const ncvar_t *ncvars, int nvars, const char *oname)
+{
+ char axis[7];
+ static const char iaxis[] = {'t', 'z', 'y', 'x'};
+
+ fprintf(stderr, "%s:\n", oname);
+
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ int ndim = 0;
+ if ( ncvars[ncvarid].isvar )
+ {
+ axis[ndim++] = 'v';
+ axis[ndim++] = ':';
+ for ( int i = 0; i < ncvars[ncvarid].ndims; i++ )
+ {/*
+ if ( ncvars[ncvarid].tvarid != -1 ) axis[ndim++] = iaxis[0];
+ else if ( ncvars[ncvarid].zvarid != -1 ) axis[ndim++] = iaxis[1];
+ else if ( ncvars[ncvarid].yvarid != -1 ) axis[ndim++] = iaxis[2];
+ else if ( ncvars[ncvarid].xvarid != -1 ) axis[ndim++] = iaxis[3];
+ else
+ */
+ if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) axis[ndim++] = iaxis[0];
+ else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) axis[ndim++] = iaxis[1];
+ else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) axis[ndim++] = iaxis[2];
+ else if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) axis[ndim++] = iaxis[3];
+ else axis[ndim++] = '?';
+ }
+ }
+ else
+ {
+ axis[ndim++] = 'c';
+ axis[ndim++] = ':';
+ if ( ncvars[ncvarid].istime ) axis[ndim++] = iaxis[0];
+ else if ( ncvars[ncvarid].islev ) axis[ndim++] = iaxis[1];
+ else if ( ncvars[ncvarid].islat ) axis[ndim++] = iaxis[2];
+ else if ( ncvars[ncvarid].isy ) axis[ndim++] = iaxis[2];
+ else if ( ncvars[ncvarid].islon ) axis[ndim++] = iaxis[3];
+ else if ( ncvars[ncvarid].isx ) axis[ndim++] = iaxis[3];
+ else axis[ndim++] = '?';
+ }
- if ( number > 0 )
- {
- cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
- }
+ axis[ndim++] = 0;
- const char *gridfile = gridInqReferencePtr(gridID);
- if ( gridfile && gridfile[0] != 0 )
- cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
+ fprintf(stderr, "%3d %3d %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
+ }
}
static
-void cdfDefGridUUID(stream_t *streamptr, int gridID)
+void cdf_scan_attr_axis(ncvar_t *ncvars, ncdim_t *ncdims, int ncvarid, const char *attstring, size_t attlen,
+ int nvdims, int *dimidsp, const char *name)
{
- unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+ int i;
+ for ( i = 0; i < (int)attlen; ++i )
+ {
+ if ( attstring[i] != '-' && attstring[i] != 't' && attstring[i] != 'z' &&
+ attstring[i] != 'y' && attstring[i] != 'x' )
+ {
+ Warning("Unexpected character in axis attribute for %s, ignored!", name);
+ break;
+ }
+ }
- gridInqUUID(gridID, uuidOfHGrid);
- if ( !cdiUUIDIsNull(uuidOfHGrid) )
+ if ( i == (int) attlen && (int) attlen == nvdims )
{
- char uuidOfHGridStr[37];
- cdiUUID2Str(uuidOfHGrid, uuidOfHGridStr);
- if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+ while ( attlen-- )
{
- int fileID = streamptr->fileID;
- //if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
- //if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+ if ( (int) attstring[attlen] == 't' )
+ {
+ if ( attlen != 0 ) Warning("axis attribute 't' not on first position");
+ cdf_set_dim(ncvars, ncvarid, (int)attlen, T_AXIS);
+ }
+ else if ( (int) attstring[attlen] == 'z' )
+ {
+ ncvars[ncvarid].zdim = dimidsp[attlen];
+ cdf_set_dim(ncvars, ncvarid, (int)attlen, Z_AXIS);
+
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
+ }
+ }
+ else if ( (int) attstring[attlen] == 'y' )
+ {
+ ncvars[ncvarid].ydim = dimidsp[attlen];
+ cdf_set_dim(ncvars, ncvarid, (int)attlen, Y_AXIS);
+
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ ncdims[ncvars[ncvarid].dimids[0]].dimtype = Y_AXIS;
+ }
+ }
+ else if ( (int) attstring[attlen] == 'x' )
+ {
+ ncvars[ncvarid].xdim = dimidsp[attlen];
+ cdf_set_dim(ncvars, ncvarid, (int)attlen, X_AXIS);
+
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ ncdims[ncvars[ncvarid].dimids[0]].dimtype = X_AXIS;
+ }
+ }
}
}
}
static
-void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
-{
- unsigned char uuidOfVGrid[CDI_UUID_SIZE];
- zaxisInqUUID(zaxisID, uuidOfVGrid);
-
- if ( uuidOfVGrid[0] != 0 )
+int cdf_get_cell_varid(char *attstring, int ncid)
+{
+ int nc_cell_id = CDI_UNDEFID;
+
+ char *pstring = attstring;
+ while ( isspace((int) *pstring) ) pstring++;
+ char *cell_measures = pstring;
+ while ( isalnum((int) *pstring) ) pstring++;
+ *pstring++ = 0;
+ while ( isspace((int) *pstring) ) pstring++;
+ char *cell_var = pstring;
+ while ( ! isspace((int) *pstring) && *pstring != 0 ) pstring++;
+ *pstring++ = 0;
+ /*
+ printf("cell_measures >%s<\n", cell_measures);
+ printf("cell_var >%s<\n", cell_var);
+ */
+ if ( str_is_equal(cell_measures, "area") )
{
- char uuidOfVGridStr[37];
- cdiUUID2Str(uuidOfVGrid, uuidOfVGridStr);
- if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
- {
- int fileID = streamptr->fileID;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
- if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
- }
+ int nc_var_id;
+ int status = nc_inq_varid(ncid, cell_var, &nc_var_id);
+ if ( status == NC_NOERR )
+ nc_cell_id = nc_var_id;
+ /*
+ else
+ Warning("%s - %s", nc_strerror(status), cell_var);
+ */
}
+
+ return nc_cell_id;
}
static
-void cdfDefUnstructured(stream_t *streamptr, int gridID)
+void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, int modelID, int format)
{
- int dimID = UNDEFID;
- int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
- int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
- int nvdimID = UNDEFID;
- nc_type xtype = NC_DOUBLE;
+ int ncdimid;
+ int nvdims, nvatts;
+ int iatt;
+ nc_type xtype, atttype;
+ size_t attlen;
+ char name[CDI_MAX_NAME];
+ char attname[CDI_MAX_NAME];
+ char attstring[8192];
- if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+ int nchecked_vars = 0;
+ enum { max_check_vars = 9 };
+ char *checked_vars[max_check_vars];
+ for ( int i = 0; i < max_check_vars; ++i ) checked_vars[i] = NULL;
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ int ncid = ncvars[ncvarid].ncid;
+ int *dimidsp = ncvars[ncvarid].dimids;
- int ngrids = vlistNgrids(vlistID);
+ cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
+ strcpy(ncvars[ncvarid].name, name);
- size_t dimlen = (size_t)gridInqSize(gridID);
- int gridindex = vlistGridIndex(vlistID, gridID);
+ for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
+ ncvars[ncvarid].dimtype[ncdimid] = -1;
- for ( int index = 0; index < ngrids; index++ )
- {
- if ( streamptr->xdimID[index] != UNDEFID )
+ ncvars[ncvarid].xtype = xtype;
+ ncvars[ncvarid].ndims = nvdims;
+
+#if defined (HAVE_NETCDF4)
+ if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
{
- int gridID0 = vlistGrid(vlistID, index);
- int gridtype0 = gridInqType(gridID0);
- if ( gridtype0 == GRID_UNSTRUCTURED )
+ int shuffle, deflate, deflate_level;
+ size_t chunks[nvdims];
+ int storage_in;
+ nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflate_level);
+ if ( deflate > 0 ) ncvars[ncvarid].deflate = 1;
+ /*
+ size_t cache_size, nelems;
+ float preemption;
+ nc_get_chunk_cache(&cache_size, &nelems, &preemption);
+ printf("cache_size %lu nelems %lu preemption %g\n", cache_size, nelems, preemption);
+ nc_get_var_chunk_cache(ncid, ncvarid, &cache_size, &nelems, &preemption);
+ printf("varid %d cache_size %lu nelems %lu preemption %g\n", ncvarid, cache_size, nelems, preemption);
+ */
+ if ( nc_inq_var_chunking(ncid, ncvarid, &storage_in, chunks) == NC_NOERR )
{
- size_t dimlen0 = (size_t)gridInqSize(gridID0);
- if ( dimlen == dimlen0 )
- if ( gridInqNvertex(gridID0) == gridInqNvertex(gridID) &&
- IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
- IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) &&
- IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
- IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
- {
- dimID = streamptr->xdimID[index];
- ncxvarid = streamptr->ncxvarID[index];
- ncyvarid = streamptr->ncyvarID[index];
- ncavarid = streamptr->ncavarID[index];
- break;
- }
+ if ( storage_in == NC_CHUNKED )
+ {
+ ncvars[ncvarid].chunked = 1;
+ for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = chunks[i];
+ if ( CDI_Debug )
+ {
+ fprintf(stderr, "%s: chunking %d %d %d chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED);
+ for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%zu ", chunks[i]);
+ fprintf(stderr, "\n");
+ }
+ {
+ char *buf = ncvars[ncvarid].extra;
+ size_t pos = strlen(buf);
+ static const char prefix[] = "chunks=";
+ memcpy(buf + pos, prefix, sizeof (prefix));
+ pos += sizeof (prefix) - 1;
+ for ( int i = nvdims-1; i >= 0; --i )
+ {
+ pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i], i > 0 ? "x" : ""));
+ }
+ buf[pos] = ' '; buf[pos + 1] = 0;
+ }
+ }
}
}
- }
-
- if ( dimID == UNDEFID )
- {
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- {
- char xdimname[CDI_MAX_NAME+3];
- xdimname[0] = 0;
- cdiGridInqString(gridID, CDI_GRID_XDIMNAME, CDI_MAX_NAME, xdimname);
- if ( xdimname[0] == 0 ) strcpy(xdimname, "ncells");
- dimID = checkDimName(fileID, dimlen, xdimname);
- if ( dimID == UNDEFID ) cdf_def_dim(fileID, xdimname, dimlen, &dimID);
- }
+#endif
- size_t nvertex = (size_t)gridInqNvertex(gridID);
- if ( nvertex > 0 )
+ if ( nvdims > 0 )
{
- char vdimname[CDI_MAX_NAME+3];
- vdimname[0] = 0;
- cdiGridInqString(gridID, CDI_GRID_VDIMNAME, CDI_MAX_NAME, vdimname);
- if ( vdimname[0] == 0 ) strcpy(vdimname, "vertices");
- nvdimID = checkDimName(fileID, nvertex, vdimname);
- if ( nvdimID == UNDEFID ) cdf_def_dim(fileID, vdimname, nvertex, &nvdimID);
+ if ( timedimid == dimidsp[0] )
+ {
+ ncvars[ncvarid].timetype = TIME_VARYING;
+ cdf_set_dim(ncvars, ncvarid, 0, T_AXIS);
+ }
+ else
+ {
+ for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
+ {
+ if ( timedimid == dimidsp[ncdimid] )
+ {
+ Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+ ncvars[ncvarid].isvar = FALSE;
+ }
+ }
+ }
}
- cdfDefGridReference(streamptr, gridID);
-
- cdfDefGridUUID(streamptr, gridID);
-
- if ( gridInqXvalsPtr(gridID) )
+ for ( iatt = 0; iatt < nvatts; iatt++ )
{
- char xaxisname[CDI_MAX_NAME];
- gridInqXname(gridID, xaxisname);
- checkGridName(xaxisname, fileID, vlistID, gridID, ngrids, 'X');
- cdf_def_var(fileID, xaxisname, xtype, 1, &dimID, &ncxvarid);
- cdfGridCompress(fileID, ncxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+ int nc_cell_id = CDI_UNDEFID;
- cdfPutGridStdAtts(fileID, ncxvarid, gridID, &gridInqsX);
+ cdf_inq_attname(ncid, ncvarid, iatt, attname);
+ cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
+ cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
- if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+ size_t attstringsize = sizeof(attstring);
+ bool isText = xtypeIsText(atttype);
+ bool isNumber = xtypeIsFloat(atttype) || xtypeIsInt(atttype);
+ if ( isText )
{
- int dimIDs[2] = { dimID, nvdimID };
- size_t xaxisnameLen = strlen(xaxisname);
- xaxisname[xaxisnameLen] = '_';
- memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
- cdf_def_var(fileID, xaxisname, xtype, 2, dimIDs, &ncbxvarid);
- cdfGridCompress(fileID, ncbxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
-
- cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
+ cdfGetAttText(ncid, ncvarid, attname, sizeof(attstring), attstring);
+ attstringsize = strlen(attstring) + 1;
+ if ( attstringsize > CDI_MAX_NAME ) attstringsize = CDI_MAX_NAME;
}
- }
- if ( gridInqYvalsPtr(gridID) )
- {
- char yaxisname[CDI_MAX_NAME];
- gridInqYname(gridID, yaxisname);
- checkGridName(yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
- cdf_def_var(fileID, yaxisname, xtype, 1, &dimID, &ncyvarid);
- cdfGridCompress(fileID, ncyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+ if ( isText && strcmp(attname, "long_name") == 0 )
+ {
+ memcpy(ncvars[ncvarid].longname, attstring, attstringsize);
+ }
+ else if ( isText && strcmp(attname, "standard_name") == 0 )
+ {
+ memcpy(ncvars[ncvarid].stdname, attstring, attstringsize);
+ }
+ else if ( isText && strcmp(attname, "units") == 0 )
+ {
+ memcpy(ncvars[ncvarid].units, attstring, attstringsize);
+ }
+ else if ( strcmp(attname, "calendar") == 0 )
+ {
+ ncvars[ncvarid].calendar = true;
+ }
+ else if ( isText && strcmp(attname, "param") == 0 )
+ {
+ int pnum = 0, pcat = 255, pdis = 255;
+ sscanf(attstring, "%d.%d.%d", &pnum, &pcat, &pdis);
+ ncvars[ncvarid].param = cdiEncodeParam(pnum, pcat, pdis);
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isNumber && strcmp(attname, "code") == 0 )
+ {
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].code);
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isNumber && strcmp(attname, "table") == 0 )
+ {
+ int tablenum;
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &tablenum);
+ if ( tablenum > 0 )
+ {
+ ncvars[ncvarid].tabnum = tablenum;
+ ncvars[ncvarid].tableID = tableInq(modelID, tablenum, NULL);
+ if ( ncvars[ncvarid].tableID == CDI_UNDEFID )
+ ncvars[ncvarid].tableID = tableDef(modelID, tablenum, NULL);
+ }
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isText && strcmp(attname, "trunc_type") == 0 )
+ {
+ if ( str_is_equal(attstring, "Triangular") )
+ ncvars[ncvarid].gridtype = GRID_SPECTRAL;
+ }
+ else if ( isText && (strcmp(attname, "grid_type") == 0 || strcmp(attname, "CDI_grid_type") == 0) )
+ {
+ str_tolower(attstring);
+ set_gridtype(attstring, &ncvars[ncvarid].gridtype);
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isText && strcmp(attname, "level_type") == 0 )
+ {
+ str_tolower(attstring);
+ set_zaxistype(attstring, &ncvars[ncvarid].zaxistype);
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isNumber && strcmp(attname, "trunc_count") == 0 )
+ {
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
+ }
+ else if ( isNumber && strcmp(attname, "truncation") == 0 )
+ {
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
+ }
+ else if ( isNumber && strcmp(attname, "number_of_grid_in_reference") == 0 )
+ {
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].position);
+ }
+ else if ( isNumber && strcmp(attname, "add_offset") == 0 )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].addoffset);
+ /*
+ if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
+ if ( ncvars[ncvarid].addoffset != 0 )
+ Warning("attribute add_offset not supported for atttype %d", atttype);
+ */
+ /* (also used for lon/lat) cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( isNumber && strcmp(attname, "scale_factor") == 0 )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].scalefactor);
+ /*
+ if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
+ if ( ncvars[ncvarid].scalefactor != 1 )
+ Warning("attribute scale_factor not supported for atttype %d", atttype);
+ */
+ /* (also used for lon/lat) cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( isText && strcmp(attname, "climatology") == 0 )
+ {
+ int ncboundsid;
+ int status = nc_inq_varid(ncid, attstring, &ncboundsid);
+ if ( status == NC_NOERR )
+ {
+ ncvars[ncvarid].climatology = true;
+ ncvars[ncvarid].bounds = ncboundsid;
+ cdf_set_var(ncvars, ncvars[ncvarid].bounds, FALSE);
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ }
+ else
+ Warning("%s - %s", nc_strerror(status), attstring);
+ }
+ else if ( isText && strcmp(attname, "bounds") == 0 )
+ {
+ int ncboundsid;
+ int status = nc_inq_varid(ncid, attstring, &ncboundsid);
+ if ( status == NC_NOERR )
+ {
+ ncvars[ncvarid].bounds = ncboundsid;
+ cdf_set_var(ncvars, ncvars[ncvarid].bounds, FALSE);
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ }
+ else
+ Warning("%s - %s", nc_strerror(status), attstring);
+ }
+ else if ( isText && strcmp(attname, "formula_terms") == 0 )
+ {
+ ncvars[ncvarid].lformulaterms = true;
+ }
+ else if ( isText && strcmp(attname, "cell_measures") == 0 && (nc_cell_id=cdf_get_cell_varid(attstring, ncid)) != CDI_UNDEFID )
+ {
+ ncvars[ncvarid].cellarea = nc_cell_id;
+ ncvars[nc_cell_id].isvar = FALSE;
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ /*
+ else if ( strcmp(attname, "coordinates") == 0 )
+ {
+ char *pstring, *xvarname = NULL, *yvarname = NULL;
+ pstring = attstring;
- cdfPutGridStdAtts(fileID, ncyvarid, gridID, &gridInqsY);
+ while ( isspace((int) *pstring) ) pstring++;
+ xvarname = pstring;
+ while ( isgraph((int) *pstring) ) pstring++;
+ *pstring++ = 0;
+ while ( isspace((int) *pstring) ) pstring++;
+ yvarname = pstring;
+ while ( isgraph((int) *pstring) ) pstring++;
+ *pstring++ = 0;
- if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
- {
- int dimIDs[2] = { dimID, nvdimID };
- size_t yaxisnameLen = strlen(yaxisname);
- yaxisname[yaxisnameLen] = '_';
- memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
- cdf_def_var(fileID, yaxisname, xtype, 2, dimIDs, &ncbyvarid);
- cdfGridCompress(fileID, ncbyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+ cdf_inq_varid(ncid, xvarname, &ncvars[ncvarid].xvarid);
+ cdf_inq_varid(ncid, yvarname, &ncvars[ncvarid].yvarid);
- cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
+ cdf_set_var(ncvars, ncvars[ncvarid].xvarid, FALSE);
+ cdf_set_var(ncvars, ncvars[ncvarid].yvarid, FALSE);
+ cdf_set_var(ncvars, ncvarid, TRUE);
}
- }
-
- if ( gridInqAreaPtr(gridID) )
- {
- static const char yaxisname_[] = "cell_area";
- static const char units[] = "m2";
- static const char longname[] = "area of grid cell";
- static const char stdname[] = "cell_area";
+ */
+ else if ( isText && (strcmp(attname, "associate") == 0 || strcmp(attname, "coordinates") == 0) )
+ {
+ bool lstop = false;
+ char *pstring = attstring;
- cdf_def_var(fileID, yaxisname_, xtype, 1, &dimID, &ncavarid);
+ for ( int i = 0; i < MAX_COORDVARS; i++ )
+ {
+ while ( isspace((int) *pstring) ) pstring++;
+ if ( *pstring == 0 ) break;
+ char *varname = pstring;
+ while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+ if ( *pstring == 0 ) lstop = true;
+ if ( *(pstring-1) == ',' ) *(pstring-1) = 0;
+ *pstring++ = 0;
- cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
- cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
- cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
- }
+ int dimvarid;
+ int status = nc_inq_varid(ncid, varname, &dimvarid);
+ if ( status == NC_NOERR )
+ {
+ cdf_set_var(ncvars, dimvarid, FALSE);
+ if ( !cdiIgnoreAttCoordinates )
+ {
+ ncvars[ncvarid].coordvarids[i] = dimvarid;
+ ncvars[ncvarid].ncoordvars++;
+ }
+ }
+ else
+ {
+ int k;
+ for ( k = 0; k < nchecked_vars; ++k )
+ if ( strcmp(checked_vars[k], varname) == 0 ) break;
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ if ( k == nchecked_vars )
+ {
+ if ( nchecked_vars < max_check_vars ) checked_vars[nchecked_vars++] = strdup(varname);
+ Warning("%s - >%s<", nc_strerror(status), varname);
+ }
+ }
- if ( ncxvarid != UNDEFID ) cdf_put_var_double(fileID, ncxvarid, gridInqXvalsPtr(gridID));
- if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
- if ( ncyvarid != UNDEFID ) cdf_put_var_double(fileID, ncyvarid, gridInqYvalsPtr(gridID));
- if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
- if ( ncavarid != UNDEFID ) cdf_put_var_double(fileID, ncavarid, gridInqAreaPtr(gridID));
- }
+ if ( lstop ) break;
+ }
- streamptr->xdimID[gridindex] = dimID;
- streamptr->ncxvarID[gridindex] = ncxvarid;
- streamptr->ncyvarID[gridindex] = ncyvarid;
- streamptr->ncavarID[gridindex] = ncavarid;
-}
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isText && strcmp(attname, "auxiliary_variable") == 0 )
+ {
+ bool lstop = false;
+ char *pstring = attstring;
-struct attTxtTab2
-{
- const char *attName, *attVal;
- size_t valLen;
-};
+ for ( int i = 0; i < MAX_AUXVARS; i++ )
+ {
+ while ( isspace((int) *pstring) ) pstring++;
+ if ( *pstring == 0 ) break;
+ char *varname = pstring;
+ while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+ if ( *pstring == 0 ) lstop = true;
+ *pstring++ = 0;
-static
-void cdf_def_vct_echam(stream_t *streamptr, int zaxisID)
-{
- int type = zaxisInqType(zaxisID);
+ int dimvarid;
+ int status = nc_inq_varid(ncid, varname, &dimvarid);
+ if ( status == NC_NOERR )
+ {
+ cdf_set_var(ncvars, dimvarid, FALSE);
+ // if ( !cdiIgnoreAttCoordinates )
+ {
+ ncvars[ncvarid].auxvarids[i] = dimvarid;
+ ncvars[ncvarid].nauxvars++;
+ }
+ }
+ else
+ Warning("%s - %s", nc_strerror(status), varname);
- if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
- {
- int ilev = zaxisInqVctSize(zaxisID)/2;
- if ( ilev == 0 ) return;
+ if ( lstop ) break;
+ }
- int mlev = ilev - 1;
- size_t start;
- size_t count = 1;
- int ncdimid, ncdimid2;
- int hyaiid, hybiid, hyamid, hybmid;
- double mval;
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isText && strcmp(attname, "grid_mapping") == 0 )
+ {
+ int nc_gmap_id;
+ int status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
+ if ( status == NC_NOERR )
+ {
+ ncvars[ncvarid].gmapid = nc_gmap_id;
+ cdf_set_var(ncvars, ncvars[ncvarid].gmapid, FALSE);
+ }
+ else
+ Warning("%s - %s", nc_strerror(status), attstring);
- if ( streamptr->vct.ilev > 0 )
- {
- if ( streamptr->vct.ilev != ilev )
- Error("more than one VCT for each file unsupported!");
- return;
- }
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else if ( isText && strcmp(attname, "positive") == 0 )
+ {
+ str_tolower(attstring);
- int fileID = streamptr->fileID;
+ if ( str_is_equal(attstring, "down") ) ncvars[ncvarid].positive = POSITIVE_DOWN;
+ else if ( str_is_equal(attstring, "up") ) ncvars[ncvarid].positive = POSITIVE_UP;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, Z_AXIS);
+ ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
+ }
+ }
+ else if ( isNumber && strcmp(attname, "_FillValue") == 0 )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
+ ncvars[ncvarid].deffillval = true;
+ /* cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( isNumber && strcmp(attname, "missing_value") == 0 )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
+ ncvars[ncvarid].defmissval = true;
+ /* cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( isNumber && strcmp(attname, "valid_range") == 0 && attlen == 2 )
+ {
+ if ( ncvars[ncvarid].lvalidrange == false )
+ {
+ bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+ if ( !cdiIgnoreValidRange && lignore == false )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
+ ncvars[ncvarid].lvalidrange = true;
+ if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
+ ncvars[ncvarid].lunsigned = true;
+ /* cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( lignore )
+ {
+ Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
+ }
+ }
+ }
+ else if ( isNumber && strcmp(attname, "valid_min") == 0 && attlen == 1 )
+ {
+ if ( ncvars[ncvarid].lvalidrange == false )
+ {
+ bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+ if ( !cdiIgnoreValidRange && lignore == false )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
+ ncvars[ncvarid].lvalidrange = true;
+ }
+ else if ( lignore )
+ {
+ Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
+ }
+ }
+ }
+ else if ( isNumber && strcmp(attname, "valid_max") == 0 && attlen == 1 )
+ {
+ if ( ncvars[ncvarid].lvalidrange == false )
+ {
+ bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+ if ( !cdiIgnoreValidRange && lignore == false )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
+ ncvars[ncvarid].lvalidrange = true;
+ }
+ else if ( lignore )
+ {
+ Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
+ }
+ }
+ }
+ else if ( isText && strcmp(attname, "_Unsigned") == 0 )
+ {
+ str_tolower(attstring);
- cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
- cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
+ if ( str_is_equal(attstring, "true") )
+ {
+ ncvars[ncvarid].lunsigned = true;
+ /*
+ ncvars[ncvarid].lvalidrange = true;
+ ncvars[ncvarid].validrange[0] = 0;
+ ncvars[ncvarid].validrange[1] = 255;
+ */
+ }
+ /* cdf_set_var(ncvars, ncvarid, TRUE); */
+ }
+ else if ( isText && strcmp(attname, "cdi") == 0 )
+ {
+ str_tolower(attstring);
- streamptr->vct.mlev = mlev;
- streamptr->vct.ilev = ilev;
- streamptr->vct.mlevID = ncdimid;
- streamptr->vct.ilevID = ncdimid2;
+ if ( str_is_equal(attstring, "ignore") )
+ {
+ ncvars[ncvarid].ignore = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ }
+ }
+ else if ( isText && strcmp(attname, "axis") == 0 )
+ {
+ attlen = strlen(attstring);
- cdf_def_var(fileID, "hyai", NC_DOUBLE, 1, &ncdimid2, &hyaiid);
- cdf_def_var(fileID, "hybi", NC_DOUBLE, 1, &ncdimid2, &hybiid);
- cdf_def_var(fileID, "hyam", NC_DOUBLE, 1, &ncdimid, &hyamid);
- cdf_def_var(fileID, "hybm", NC_DOUBLE, 1, &ncdimid, &hybmid);
+ if ( (int) attlen > nvdims && nvdims > 0 && attlen > 1 )
+ {
+ Warning("Unexpected axis attribute length for %s, ignored!", name);
+ }
+ else if ( nvdims == 0 && attlen == 1 )
+ {
+ if ( attstring[0] == 'z' || attstring[0] == 'Z' )
+ {
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ ncvars[ncvarid].islev = true;
+ }
+ }
+ else
+ {
+ str_tolower(attstring);
+ cdf_scan_attr_axis(ncvars, ncdims, ncvarid, attstring, attlen, nvdims, dimidsp, name);
+ }
+ }
+ else if ( isNumber &&
+ (strcmp(attname, "realization") == 0 ||
+ strcmp(attname, "ensemble_members") == 0 ||
+ strcmp(attname, "forecast_init_type") == 0) )
+ {
+ int temp;
- {
- static const char lname_n[] = "long_name",
- lname_v_ai[] = "hybrid A coefficient at layer interfaces",
- units_n[] = "units",
- units_v_ai[] = "Pa",
- lname_v_bi[] = "hybrid B coefficient at layer interfaces",
- units_v_bi[] = "1",
- lname_v_am[] = "hybrid A coefficient at layer midpoints",
- units_v_am[] = "Pa",
- lname_v_bm[] = "hybrid B coefficient at layer midpoints",
- units_v_bm[] = "1";
- static const struct attTxtTab2 tab[]
- = {
- { lname_n, lname_v_ai, sizeof (lname_v_ai) - 1 },
- { units_n, units_v_ai, sizeof (units_v_ai) - 1 },
- { lname_n, lname_v_bi, sizeof (lname_v_bi) - 1 },
- { units_n, units_v_bi, sizeof (units_v_bi) - 1 },
- { lname_n, lname_v_am, sizeof (lname_v_am) - 1 },
- { units_n, units_v_am, sizeof (units_v_am) - 1 },
- { lname_n, lname_v_bm, sizeof (lname_v_bm) - 1 },
- { units_n, units_v_bm, sizeof (units_v_bm) - 1 },
- };
- enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
- int ids[tabLen] = { hyaiid, hyaiid, hybiid, hybiid,
- hyamid, hyamid, hybmid, hybmid };
- for ( size_t i = 0; i < tabLen; ++i )
- cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
- }
+ if( ncvars[ncvarid].ensdata == NULL )
+ ncvars[ncvarid].ensdata = (ensinfo_t *) Malloc( sizeof( ensinfo_t ) );
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
- const double *vctptr = zaxisInqVctPtr(zaxisID);
+ if( strcmp(attname, "realization") == 0 )
+ ncvars[ncvarid].ensdata->ens_index = temp;
+ else if( strcmp(attname, "ensemble_members") == 0 )
+ ncvars[ncvarid].ensdata->ens_count = temp;
+ else if( strcmp(attname, "forecast_init_type") == 0 )
+ ncvars[ncvarid].ensdata->forecast_init_type = temp;
- cdf_put_var_double(fileID, hyaiid, vctptr);
- cdf_put_var_double(fileID, hybiid, vctptr+ilev);
+ cdf_set_var(ncvars, ncvarid, TRUE);
+ }
+ else
+ {
+ if ( ncvars[ncvarid].natts == 0 )
+ ncvars[ncvarid].atts = (int*) Malloc((size_t)nvatts*sizeof(int));
- for ( int i = 0; i < mlev; i++ )
- {
- start = (size_t)i;
- mval = (vctptr[i] + vctptr[i+1]) * 0.5;
- cdf_put_vara_double(fileID, hyamid, &start, &count, &mval);
- mval = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
- cdf_put_vara_double(fileID, hybmid, &start, &count, &mval);
- }
+ ncvars[ncvarid].atts[ncvars[ncvarid].natts++] = iatt;
+ /*
+ int attrint;
+ double attrflt;
+ nc_type atttype;
+ cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+ cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
+ if ( attlen == 1 && (atttype == NC_INT || atttype == NC_SHORT) )
+ {
+ cdfGetAttInt(ncid, ncvarid, attname, 1, &attrint);
+ printf("int: %s.%s = %d\n", ncvars[ncvarid].name, attname, attrint);
+ }
+ else if ( attlen == 1 && (atttype == NC_FLOAT || atttype == NC_DOUBLE) )
+ {
+ cdfGetAttDouble(ncid, ncvarid, attname, 1, &attrflt);
+ printf("flt: %s.%s = %g\n", ncvars[ncvarid].name, attname, attrflt);
+ }
+ else if ( atttype == NC_CHAR )
+ {
+ attstring[attlen] = 0;
+ printf("txt: %s.%s = %s\n", ncvars[ncvarid].name, attname, attstring);
+ }
+ else
+ printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
+ */
+ }
+ }
}
+
+ for ( int i = 0; i < max_check_vars; ++i ) if ( checked_vars[i] ) Free(checked_vars[i]);
}
static
-void cdf_def_vct_cf(stream_t *streamptr, int zaxisID, int nclevID, int ncbndsID)
+void cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
{
- int type = zaxisInqType(zaxisID);
-
- if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- int ilev = zaxisInqVctSize(zaxisID)/2;
- if ( ilev == 0 ) return;
-
- int mlev = ilev - 1;
- int hyaiid = 0, hybiid = 0, hyamid, hybmid;
-
- if ( streamptr->vct.ilev > 0 )
- {
- if ( streamptr->vct.ilev != ilev )
- Error("more than one VCT for each file unsupported!");
- return;
- }
+ if ( ncvars[ncvarid].isvar == TRUE )
+ {
+ int ndims = ncvars[ncvarid].ndims;
+ for ( int i = 0; i < ndims; i++ )
+ {
+ int ncdimid = ncvars[ncvarid].dimids[i];
+ int dimtype = ncdims[ncdimid].dimtype;
+ if ( dimtype >= X_AXIS && dimtype <= T_AXIS )
+ cdf_set_dim(ncvars, ncvarid, i, dimtype);
+ }
- int fileID = streamptr->fileID;
+ if ( CDI_Debug )
+ {
+ Message("var %d %s", ncvarid, ncvars[ncvarid].name);
+ for ( int i = 0; i < ndims; i++ )
+ printf(" dim%d type=%d ", i, ncvars[ncvarid].dimtype[i]);
+ printf("\n");
+ }
+ }
+ }
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ if ( ncvars[ncvarid].isvar == TRUE )
+ {
+ bool lxdim = false, lydim = false, lzdim = false/* , ltdim = false */;
+ int lcdim = 0;
+ int ndims = ncvars[ncvarid].ndims;
+ for ( int i = 0; i < ndims; i++ )
+ {
+ int dimtype = ncvars[ncvarid].dimtype[i];
+ lxdim = lxdim | (dimtype == X_AXIS);
+ lydim = lydim | (dimtype == Y_AXIS);
+ lzdim = lzdim | (dimtype == Z_AXIS);
+ if ( ncvars[ncvarid].cvarids[i] != CDI_UNDEFID ) lcdim++;
+ /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = true; */
+ }
- int dimIDs[2];
- dimIDs[0] = nclevID;
- dimIDs[1] = ncbndsID;
+ int allcdims = lcdim;
- streamptr->vct.mlev = mlev;
- streamptr->vct.ilev = ilev;
- streamptr->vct.mlevID = nclevID;
- streamptr->vct.ilevID = nclevID;
+ if ( !lxdim && ncvars[ncvarid].xvarid != CDI_UNDEFID )
+ {
+ if ( ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = true;
+ }
- cdf_def_var(fileID, "ap", NC_DOUBLE, 1, dimIDs, &hyamid);
- cdf_def_var(fileID, "b", NC_DOUBLE, 1, dimIDs, &hybmid);
+ if ( !lydim && ncvars[ncvarid].yvarid != CDI_UNDEFID )
+ {
+ if ( ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = true;
+ }
- {
- static const char lname[] = "vertical coordinate formula term: ap(k)";
- cdf_put_att_text(fileID, hyamid, "long_name", sizeof (lname) - 1, lname);
- }
- {
- static const char units[] = "Pa";
- cdf_put_att_text(fileID, hyamid, "units", sizeof (units) - 1, units);
- }
- {
- static const char lname[] = "vertical coordinate formula term: b(k)";
- cdf_put_att_text(fileID, hybmid, "long_name", sizeof (lname) - 1, lname);
- }
- {
- static const char units[] = "1";
- cdf_put_att_text(fileID, hybmid, "units", sizeof (units) - 1, units);
- }
+ if ( lxdim && (lydim || ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED) )
+ for ( int i = ndims-1; i >= 0; i-- )
+ {
+ if ( ncvars[ncvarid].dimtype[i] == -1 )
+ {
+ if ( !lzdim )
+ {
+ if ( lcdim )
+ {
+ int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
+ ncvars[ncvarid].zvarid = cdimvar;
+ lcdim--;
+ ncvars[cdimvar].zaxistype = ZAXIS_CHAR;
+ }
+ cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
+ lzdim = true;
+ int ncdimid = ncvars[ncvarid].dimids[i];
+ if ( ncdims[ncdimid].dimtype == CDI_UNDEFID )
+ ncdims[ncdimid].dimtype = Z_AXIS;
+ }
+ }
+ }
+ }
+ }
- if ( ncbndsID != -1 )
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ int ndims = ncvars[ncvarid].ndims;
+ for ( int i = 0; i < ndims; i++ )
{
- cdf_def_var(fileID, "ap_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
- cdf_def_var(fileID, "b_bnds", NC_DOUBLE, 2, dimIDs, &hybiid);
- {
- static const char lname[] = "vertical coordinate formula term: ap(k+1/2)";
- cdf_put_att_text(fileID, hyaiid, "long_name", sizeof (lname) - 1, lname);
- }
- {
- static const char units[] = "Pa";
- cdf_put_att_text(fileID, hyaiid, "units", sizeof (units) - 1, units);
- }
- {
- static const char lname[] = "vertical coordinate formula term: b(k+1/2)";
- cdf_put_att_text(fileID, hybiid, "long_name", sizeof (lname) - 1, lname);
- }
- {
- static const char units[] = "1";
- cdf_put_att_text(fileID, hybiid, "units", sizeof (units) - 1, units);
- }
+ if ( ncvars[ncvarid].dimtype[i] == CDI_UNDEFID )
+ {
+ int ncdimid = ncvars[ncvarid].dimids[i];
+ if ( ncdims[ncdimid].dimtype == Z_AXIS )
+ {
+ ncvars[ncvarid].islev = true;
+ cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
+ }
+ }
}
+ }
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ if ( ncvars[ncvarid].isvar == TRUE )
+ {
+ bool lxdim = false, lydim = false, lzdim = false/* , ltdim = false */;
+ int lcdim = 0;
+ int ndims = ncvars[ncvarid].ndims;
+ for ( int i = 0; i < ndims; i++ )
+ {
+ if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) lxdim = true;
+ else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) lydim = true;
+ else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) lzdim = true;
+ else if ( ncvars[ncvarid].cvarids[i] != CDI_UNDEFID ) lcdim++;
+ /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = true; */
+ }
- const double *vctptr = zaxisInqVctPtr(zaxisID);
- double tarray[ilev*2];
+ int allcdims = lcdim;
- if ( ncbndsID != -1 )
- {
- for ( int i = 0; i < mlev; ++i )
+ if ( !lxdim && ncvars[ncvarid].xvarid != CDI_UNDEFID )
{
- tarray[2*i ] = vctptr[i];
- tarray[2*i+1] = vctptr[i+1];
+ if ( ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = true;
}
- cdf_put_var_double(fileID, hyaiid, tarray);
- for ( int i = 0; i < mlev; ++i )
+ if ( !lydim && ncvars[ncvarid].yvarid != CDI_UNDEFID )
{
- tarray[2*i ] = vctptr[ilev+i];
- tarray[2*i+1] = vctptr[ilev+i+1];
+ if ( ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = true;
}
- cdf_put_var_double(fileID, hybiid, tarray);
- }
-
- for ( int i = 0; i < mlev; ++i )
- tarray[i] = (vctptr[i] + vctptr[i+1]) * 0.5;
- cdf_put_var_double(fileID, hyamid, tarray);
- for ( int i = 0; i < mlev; ++i )
- tarray[i] = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
- cdf_put_var_double(fileID, hybmid, tarray);
+ // if ( ndims > 1 )
+ for ( int i = ndims-1; i >= 0; i-- )
+ {
+ if ( ncvars[ncvarid].dimtype[i] == -1 )
+ {
+ if ( !lxdim )
+ {
+ if ( lcdim && ncvars[ncvarid].xvarid == CDI_UNDEFID )
+ {
+ int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
+ ncvars[ncvarid].xvarid = cdimvar;
+ lcdim--;
+ }
+ cdf_set_dim(ncvars, ncvarid, i, X_AXIS);
+ lxdim = true;
+ }
+ else if ( !lydim && ncvars[ncvarid].gridtype != GRID_UNSTRUCTURED )
+ {
+ if ( lcdim && ncvars[ncvarid].yvarid == CDI_UNDEFID )
+ {
+ int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
+ ncvars[ncvarid].yvarid = cdimvar;
+ lcdim--;
+ }
+ cdf_set_dim(ncvars, ncvarid, i, Y_AXIS);
+ lydim = true;
+ }
+ else if ( !lzdim )
+ {
+ if ( lcdim > 0 )
+ {
+ int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
+ ncvars[ncvarid].zvarid = cdimvar;
+ lcdim--;
+ ncvars[cdimvar].zaxistype = ZAXIS_CHAR;
+ }
+ cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
+ lzdim = true;
+ }
+ }
+ }
+ }
}
}
-struct attTxtTab { const char *txt; size_t txtLen; };
-
+/* verify coordinate vars - first scan (dimname == varname) */
static
-void cdf_def_zaxis_hybrid_echam(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid, bool *lhybrid_cf)
{
- int fileID = streamptr->fileID;
-
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
- cdf_def_dim(fileID, axisname, dimlen, dimID);
- cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID, &ncvarid);
-
- {
- static const char sname[] = "hybrid_sigma_pressure";
- cdf_put_att_text(fileID, ncvarid, "standard_name", sizeof (sname) - 1, sname);
- }
- {
- static const char *attName[] = {
- "long_name",
- "formula",
- "formula_terms"
- };
- enum { nAtt = sizeof (attName) / sizeof (attName[0]) };
- static const char lname_m[] = "hybrid level at layer midpoints",
- formula_m[] = "hyam hybm (mlev=hyam+hybm*aps)",
- fterms_m[] = "ap: hyam b: hybm ps: aps",
- lname_i[] = "hybrid level at layer interfaces",
- formula_i[] = "hyai hybi (ilev=hyai+hybi*aps)",
- fterms_i[] = "ap: hyai b: hybi ps: aps";
- static const struct attTxtTab tab[2][nAtt] = {
- {
- { lname_i, sizeof (lname_i) - 1 },
- { formula_i, sizeof (formula_i) - 1 },
- { fterms_i, sizeof (fterms_i) - 1 }
- },
- {
- { lname_m, sizeof (lname_m) - 1 },
- { formula_m, sizeof (formula_m) - 1 },
- { fterms_m, sizeof (fterms_m) - 1 }
- }
- };
-
- size_t tabSelect = type == ZAXIS_HYBRID;
- for (size_t i = 0; i < nAtt; ++i)
- cdf_put_att_text(fileID, ncvarid, attName[i],
- tab[tabSelect][i].txtLen, tab[tabSelect][i].txt);
- }
-
- {
- static const char units[] = "level";
- cdf_put_att_text(fileID, ncvarid, "units", sizeof (units) - 1, units);
- }
- {
- static const char direction[] = "down";
- cdf_put_att_text(fileID, ncvarid, "positive", sizeof (direction) - 1, direction);
- }
+ for ( int ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ {
+ int ncvarid = ncdims[ncdimid].ncvarid;
+ if ( ncvarid != -1 )
+ {
+ if ( ncvars[ncvarid].dimids[0] == timedimid )
+ {
+ ncvars[ncvarid].istime = true;
+ ncdims[ncdimid].dimtype = T_AXIS;
+ continue;
+ }
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
+ if ( isHybridSigmaPressureCoordinate(ncid, ncvarid, ncvars, ncdims) )
+ {
+ *lhybrid_cf = true;
+ continue;
+ }
- cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+ if ( ncvars[ncvarid].units[0] != 0 )
+ {
+ if ( is_lon_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].islon = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
+ ncdims[ncdimid].dimtype = X_AXIS;
+ }
+ else if ( is_lat_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].islat = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
+ ncdims[ncdimid].dimtype = Y_AXIS;
+ }
+ else if ( is_x_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].isx = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
+ ncdims[ncdimid].dimtype = X_AXIS;
+ }
+ else if ( is_y_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].isy = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
+ ncdims[ncdimid].dimtype = Y_AXIS;
+ }
+ else if ( is_pressure_units(ncvars[ncvarid].units) )
+ {
+ ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
+ }
+ else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
+ {
+ if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+ else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+ else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+ else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+ else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
+ }
+ else if ( is_DBL_axis(ncvars[ncvarid].longname) )
+ {
+ ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+ }
+ else if ( is_height_units(ncvars[ncvarid].units) )
+ {
+ if ( is_depth_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+ ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
+ else if ( is_height_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+ ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
+ }
+ }
+ else
+ {
+ if ( (strcmp(ncvars[ncvarid].longname, "generalized_height") == 0 ||
+ strcmp(ncvars[ncvarid].longname, "generalized height") == 0) &&
+ strcmp(ncvars[ncvarid].stdname, "height") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_REFERENCE;
+ }
- cdf_def_vct_echam(streamptr, zaxisID);
+ if ( !ncvars[ncvarid].islon && ncvars[ncvarid].longname[0] != 0 &&
+ !ncvars[ncvarid].islat && ncvars[ncvarid].longname[1] != 0 )
+ {
+ if ( str_is_equal(ncvars[ncvarid].longname+1, "ongitude") )
+ {
+ ncvars[ncvarid].islon = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
+ ncdims[ncdimid].dimtype = X_AXIS;
+ continue;
+ }
+ else if ( str_is_equal(ncvars[ncvarid].longname+1, "atitude") )
+ {
+ ncvars[ncvarid].islat = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
+ ncdims[ncdimid].dimtype = Y_AXIS;
+ continue;
+ }
+ }
- if ( *dimID == UNDEFID )
- {
- if ( type == ZAXIS_HYBRID )
- streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
- else
- streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
+ if ( ncvars[ncvarid].zaxistype != CDI_UNDEFID )
+ {
+ ncvars[ncvarid].islev = true;
+ cdf_set_var(ncvars, ncvarid, FALSE);
+ cdf_set_dim(ncvars, ncvarid, 0, Z_AXIS);
+ ncdims[ncdimid].dimtype = Z_AXIS;
+ }
+ }
}
}
+/* verify coordinate vars - second scan (all other variables) */
static
-void cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
{
- char psname[CDI_MAX_NAME];
- psname[0] = 0;
- zaxisInqPsName(zaxisID, psname);
- if ( psname[0] == 0 ) strcpy(psname, "ps");
-
- int fileID = streamptr->fileID;
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
- strcpy(axisname, "lev");
-
- cdf_def_dim(fileID, axisname, dimlen, dimID);
- cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID, &ncvarid);
-
- {
- static const char sname[] = "standard_name",
- sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
- lname[] = "long_name",
- lname_v[] = "hybrid sigma pressure coordinate",
- formula[] = "formula",
- formula_v[] = "p = ap + b*ps",
- fterms[] = "formula_terms",
- fterms_v[] = "ap: ap b: b ps: ",
- units[] = "units",
- units_v[] = "1",
- axis[] = "axis",
- axis_v[] = "Z",
- direction[] = "positive",
- direction_v[] = "down";
- struct attTxtTab2 tab[] = {
- { sname, sname_v, sizeof (sname_v) - 1 },
- { lname, lname_v, sizeof (lname_v) - 1 },
- { formula, formula_v, sizeof (formula_v) - 1 },
- { fterms, fterms_v, sizeof (fterms_v) - 1 },
- { units, units_v, sizeof (units_v) - 1 },
- { axis, axis_v, sizeof (axis_v) - 1 },
- { direction, direction_v, sizeof (direction_v) - 1 },
- };
- enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
- for (size_t i = 0; i < nAtt; ++i)
- cdf_put_att_text(fileID, ncvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
- }
-
- int ncbvarid = UNDEFID;
- int nvdimID = UNDEFID;
-
- double lbounds[dimlen], ubounds[dimlen], levels[dimlen];
-
- zaxisInqLevels(zaxisID, levels);
-
- if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- zaxisInqLbounds(zaxisID, lbounds);
- zaxisInqUbounds(zaxisID, ubounds);
- }
- else
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- for ( size_t i = 0; i < dimlen; ++i ) lbounds[i] = levels[i];
- for ( size_t i = 0; i < dimlen-1; ++i ) ubounds[i] = levels[i+1];
- ubounds[dimlen-1] = levels[dimlen-1] + 1;
+ if ( ncvars[ncvarid].isvar == 0 )
+ {
+ if ( ncvars[ncvarid].units[0] != 0 )
+ {
+ if ( is_lon_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].islon = true;
+ continue;
+ }
+ else if ( is_lat_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].islat = true;
+ continue;
+ }
+ else if ( is_x_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].isx = true;
+ continue;
+ }
+ else if ( is_y_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+ {
+ ncvars[ncvarid].isy = true;
+ continue;
+ }
+ else if ( ncvars[ncvarid].zaxistype == CDI_UNDEFID &&
+ (strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0) )
+ {
+ if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+ else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+ else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+ else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+ else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
+ ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
+ continue;
+ }
+ else if ( ncvars[ncvarid].zaxistype == CDI_UNDEFID && is_pressure_units(ncvars[ncvarid].units) )
+ {
+ ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
+ continue;
+ }
+ else if ( is_DBL_axis(ncvars[ncvarid].longname) )
+ {
+ ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+ continue;
+ }
+ else if ( is_height_units(ncvars[ncvarid].units) )
+ {
+ if ( is_depth_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+ ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
+ else if ( is_height_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+ ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
+ continue;
+ }
+ }
+ else if ( strcmp(ncvars[ncvarid].stdname, "region") == 0 ||
+ strcmp(ncvars[ncvarid].stdname, "area_type") == 0 ||
+ cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == CDI_DATATYPE_UINT8 )
+ {
+ ncvars[ncvarid].isc = true;
+ }
+
+ /* not needed anymore for rotated grids */
+ if ( !ncvars[ncvarid].islon && ncvars[ncvarid].longname[0] != 0 &&
+ !ncvars[ncvarid].islat && ncvars[ncvarid].longname[1] != 0 )
+ {
+ if ( str_is_equal(ncvars[ncvarid].longname+1, "ongitude") )
+ {
+ ncvars[ncvarid].islon = true;
+ continue;
+ }
+ else if ( str_is_equal(ncvars[ncvarid].longname+1, "atitude") )
+ {
+ ncvars[ncvarid].islat = true;
+ continue;
+ }
+ }
+ }
}
+}
- //if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+static
+void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
+{
+ if ( ncvar->chunked )
{
- size_t nvertex = 2;
- if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
- cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+ int ndims = ncvar->ndims;
- if ( nvdimID != UNDEFID )
+ if ( grid->type == GRID_UNSTRUCTURED )
{
- size_t axisnameLen = strlen(axisname);
- axisname[axisnameLen] = '_';
- memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
- axisnameLen += sizeof (bndsName);
- int dimIDs[2] = { *dimID, nvdimID };
- cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
- cdf_put_att_text(fileID, ncvarid, "bounds", axisnameLen, axisname);
- {
- static const char sname[] = "standard_name",
- sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
- formula[] = "formula",
- formula_v[] = "p = ap + b*ps";
- struct attTxtTab2 tab[] = {
- { sname, sname_v, sizeof (sname_v) - 1 },
- { formula, formula_v, sizeof (formula_v) - 1 },
- };
- enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
- for (size_t i = 0; i < nAtt; ++i)
- cdf_put_att_text(fileID, ncbvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
- }
- {
- char txt[CDI_MAX_NAME];
- size_t len = (size_t)(sprintf(txt, "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname));
- cdf_put_att_text(fileID, ncbvarid, "formula_terms", len, txt);
- }
- {
- static const char units[] = "1";
- cdf_put_att_text(fileID, ncbvarid, "units", sizeof (units) - 1, units);
- }
+ ncvar->chunktype = ncvar->chunks[ndims-1] == grid->size
+ ? CDI_CHUNK_GRID : CDI_CHUNK_AUTO;
}
- }
-
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
-
- cdf_put_var_double(fileID, ncvarid, levels);
-
- if ( ncbvarid != UNDEFID )
- {
- double zbounds[2*dimlen];
- for ( size_t i = 0; i < dimlen; ++i )
+ else
{
- zbounds[2*i ] = lbounds[i];
- zbounds[2*i+1] = ubounds[i];
+ if ( grid->x.size > 1 && grid->y.size > 1 && ndims > 1 &&
+ grid->x.size == ncvar->chunks[ndims-1] &&
+ grid->y.size == ncvar->chunks[ndims-2] )
+ ncvar->chunktype = CDI_CHUNK_GRID;
+ else if ( grid->x.size > 1 && grid->x.size == ncvar->chunks[ndims-1] )
+ ncvar->chunktype = CDI_CHUNK_LINES;
+ else
+ ncvar->chunktype = CDI_CHUNK_AUTO;
}
- cdf_put_var_double(fileID, ncbvarid, zbounds);
}
+}
- cdf_def_vct_cf(streamptr, zaxisID, *dimID, nvdimID);
-
- if ( *dimID == UNDEFID )
+/* define all input grids */
+static
+void cdf_load_vals(size_t size, int ndims, int varid, ncvar_t *ncvar, double **gridvals, struct xyValGet *valsGet,
+ int ntdims, size_t *start, size_t *count)
+{
+ if ( CDI_netcdf_lazy_grid_load )
+ {
+ *valsGet = (struct xyValGet){
+ .scalefactor = ncvar->scalefactor,
+ .addoffset = ncvar->addoffset,
+ .start = { start[0], start[1], start[2] },
+ .count = { count[0], count[1], count[2] },
+ .size = size,
+ .datasetNCId = ncvar->ncid,
+ .varNCId = varid,
+ .ndims = (short)ndims,
+ };
+ *gridvals = cdfPendingLoad;
+ }
+ else
{
- if ( type == ZAXIS_HYBRID )
- streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
+ *gridvals = (double*) Malloc(size*sizeof(double));
+ if ( ntdims == 1 )
+ cdf_get_vara_double(ncvar->ncid, varid, start, count, *gridvals);
else
- streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
+ cdf_get_var_double(ncvar->ncid, varid, *gridvals);
+ cdf_scale_add(size, *gridvals, ncvar->addoffset, ncvar->scalefactor);
}
}
static
-void cdf_def_zaxis_hybrid(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+void cdf_load_cvals(size_t size, int varid, ncvar_t *ncvar, char ***gridvals, size_t dimlength)
{
- if ( (!CDI_cmor_mode && cdiConvention == CDI_CONVENTION_ECHAM) || type == ZAXIS_HYBRID_HALF )
- cdf_def_zaxis_hybrid_echam(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
- else
- cdf_def_zaxis_hybrid_cf(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
+ size_t startc[] = {0, 0};
+ size_t countc[] = {1, size/dimlength};
+ *gridvals = (char **) Malloc(dimlength * sizeof(char *));
+ for ( size_t i = 0; i < dimlength; i++ )
+ {
+ (*gridvals)[i] = (char*) Malloc((size/dimlength) * sizeof(char));
+ cdf_get_vara_text(ncvar->ncid, varid, startc, countc, (*gridvals)[i]);
+ startc[0] = i+1;
+ }
}
static
-void cdfDefZaxis(stream_t *streamptr, int zaxisID)
+void cdf_load_bounds(size_t size, ncvar_t *ncvar, double **gridbounds, struct cdfLazyGridIds *cellBoundsGet)
{
- /* char zaxisname0[CDI_MAX_NAME]; */
- char axisname[CDI_MAX_NAME];
- int dimID = UNDEFID;
- int dimIDs[2];
- int ncvarid = UNDEFID, ncbvarid = UNDEFID;
- int nvdimID = UNDEFID;
- int xtype = NC_DOUBLE;
-
- if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
-
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
-
- int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-
- int nzaxis = vlistNzaxis(vlistID);
-
- size_t dimlen = (size_t)zaxisInqSize(zaxisID);
- int type = zaxisInqType(zaxisID);
-
- int is_scalar = FALSE;
- if ( dimlen == 1 )
+ if ( CDI_netcdf_lazy_grid_load )
{
- is_scalar = zaxisInqScalar(zaxisID);
- if ( !is_scalar && CDI_cmor_mode )
- {
- is_scalar = TRUE;
- zaxisDefScalar(zaxisID);
- }
+ cellBoundsGet->datasetNCId = ncvar->ncid;
+ cellBoundsGet->varNCId = ncvar->bounds;
+ *gridbounds = cdfPendingLoad;
}
-
- int ndims = 1;
- if ( is_scalar ) ndims = 0;
-
- if ( dimlen == 1 )
- switch (type)
- {
- case ZAXIS_SURFACE:
- case ZAXIS_CLOUD_BASE:
- case ZAXIS_CLOUD_TOP:
- case ZAXIS_ISOTHERM_ZERO:
- case ZAXIS_TOA:
- case ZAXIS_SEA_BOTTOM:
- case ZAXIS_ATMOSPHERE:
- case ZAXIS_MEANSEA:
- case ZAXIS_LAKE_BOTTOM:
- case ZAXIS_SEDIMENT_BOTTOM:
- case ZAXIS_SEDIMENT_BOTTOM_TA:
- case ZAXIS_SEDIMENT_BOTTOM_TW:
- case ZAXIS_MIX_LAYER:
- return;
- }
-
- zaxisInqName(zaxisID, axisname);
-
- if ( dimID == UNDEFID )
+ else
{
- checkZaxisName(axisname, fileID, vlistID, zaxisID, nzaxis);
-
- char dimname[CDI_MAX_NAME+3];
- dimname[0] = 0;
- //cdiZaxisInqString(zaxisID, CDI_ZAXIS_DIMNAME, CDI_MAX_NAME, dimname);
- if ( dimname[0] == 0 ) strcpy(dimname, axisname);
-
- if ( type == ZAXIS_REFERENCE ) cdfDefZaxisUUID(streamptr, zaxisID);
-
- if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
- {
- cdf_def_zaxis_hybrid(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, &dimID, axisname);
- }
- else
- {
- dimID = checkDimName(fileID, dimlen, dimname);
-
- if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
- if ( ndims && dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
-
- cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
-
- cdfPutGridStdAtts(fileID, ncvarid, zaxisID, &gridInqsZ);
-
- {
- int positive = zaxisInqPositive(zaxisID);
- static const char positive_up[] = "up",
- positive_down[] = "down";
- static const struct attTxtTab tab[2] = {
- { positive_up, sizeof (positive_up) - 1 },
- { positive_down, sizeof (positive_down) - 1 },
- };
- if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
- {
- size_t select = positive == POSITIVE_DOWN;
- cdf_put_att_text(fileID, ncvarid, "positive",
- tab[select].txtLen, tab[select].txt);
- }
- }
- cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
-
- if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- size_t nvertex = 2;
- if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
- cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
-
- if ( nvdimID != UNDEFID )
- {
- size_t axisnameLen = strlen(axisname);
- axisname[axisnameLen] = '_';
- memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
- dimIDs[0] = dimID;
- dimIDs[ndims] = nvdimID;
- cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
- cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
- }
- }
-
- cdf_enddef(fileID);
- streamptr->ncmode = 2;
-
- cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
-
- if ( ncbvarid != UNDEFID )
- {
- double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
- zaxisInqLbounds(zaxisID, lbounds);
- zaxisInqUbounds(zaxisID, ubounds);
- for ( size_t i = 0; i < dimlen; ++i )
- {
- zbounds[2*i ] = lbounds[i];
- zbounds[2*i+1] = ubounds[i];
- }
-
- cdf_put_var_double(fileID, ncbvarid, zbounds);
- }
+ *gridbounds = (double*) Malloc(size*sizeof(double));
+ cdf_get_var_double(ncvar->ncid, ncvar->bounds, *gridbounds);
+ }
+}
- if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
- }
+static
+void cdf_load_cellarea(size_t size, ncvar_t *ncvar, double **gridarea, struct cdfLazyGridIds *cellAreaGet)
+{
+ if ( CDI_netcdf_lazy_grid_load )
+ {
+ cellAreaGet->datasetNCId = ncvar->ncid;
+ cellAreaGet->varNCId = ncvar->cellarea;
+ *gridarea = cdfPendingLoad;
+ }
+ else
+ {
+ *gridarea = (double*) Malloc(size*sizeof(double));
+ cdf_get_var_double(ncvar->ncid, ncvar->cellarea, *gridarea);
}
-
- if ( dimID != UNDEFID )
- streamptr->zaxisID[zaxisindex] = dimID;
}
static
-void cdfDefPole(stream_t *streamptr, int gridID)
+void cdf_copy_axis_attr(ncvar_t *ncvar, struct gridaxis_t *gridaxis)
{
- int ncvarid = UNDEFID;
- static const char varname[] = "rotated_pole";
- static const char mapname[] = "rotated_latitude_longitude";
-
- int fileID = streamptr->fileID;
+ strcpy(gridaxis->name, ncvar->name);
+ strcpy(gridaxis->longname, ncvar->longname);
+ strcpy(gridaxis->units, ncvar->units);
+ if ( gridaxis->cvals )
+ gridaxis->stdname = ncvar->stdname;
+}
- double ypole = gridInqYpole(gridID);
- double xpole = gridInqXpole(gridID);
- double angle = gridInqAngle(gridID);
+static
+int cdf_get_xydimid(int ndims, int *dimids, int *dimtype, int *xdimid, int *ydimid)
+{
+ int nxdims = 0, nydims = 0;
+ int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
- cdf_redef(fileID);
+ for ( int i = 0; i < ndims; i++ )
+ {
+ if ( dimtype[i] == X_AXIS && nxdims < 2 )
+ {
+ xdimids[nxdims] = dimids[i];
+ nxdims++;
+ }
+ else if ( dimtype[i] == Y_AXIS && nydims < 2 )
+ {
+ ydimids[nydims] = dimids[i];
+ nydims++;
+ }
+ }
- int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
- if ( ncerrcode == NC_NOERR )
+ if ( nxdims == 2 )
{
- cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", sizeof (mapname) - 1, mapname);
- cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
- cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
- if ( IS_NOT_EQUAL(angle, 0) )
- cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1, &angle);
+ *xdimid = xdimids[1];
+ *ydimid = xdimids[0];
+ }
+ else if ( nydims == 2 )
+ {
+ *xdimid = ydimids[1];
+ *ydimid = ydimids[0];
+ }
+ else
+ {
+ *xdimid = xdimids[0];
+ *ydimid = ydimids[0];
}
- cdf_enddef(fileID);
+ return nydims;
}
+static
+void cdf_check_gridtype(int *gridtype, bool islon, bool islat, size_t xsize, size_t ysize, grid_t *grid)
+{
+ if ( islat && (islon || xsize == 0) )
+ {
+ double yinc = 0;
+ if ( islon && ysize > 1 )
+ {
+ yinc = fabs(grid->y.vals[0] - grid->y.vals[1]);
+ for ( size_t i = 2; i < ysize; i++ )
+ if ( (fabs(grid->y.vals[i-1] - grid->y.vals[i]) - yinc) > (yinc/1000) )
+ {
+ yinc = 0;
+ break;
+ }
+ }
+ if ( ysize < 10000 && isGaussGrid(ysize, yinc, grid->y.vals) )
+ {
+ *gridtype = GRID_GAUSSIAN;
+ grid->np = (int)(ysize/2);
+ }
+ else
+ *gridtype = GRID_LONLAT;
+ }
+ else if ( islon && !islat && ysize == 0 )
+ {
+ *gridtype = GRID_LONLAT;
+ }
+ else
+ *gridtype = GRID_GENERIC;
+}
static
-void cdfDefMapping(stream_t *streamptr, int gridID)
+bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int xvarid, ncvar_t *axisvar,
+ size_t *xsize, size_t ysize, int ntdims, size_t *start, size_t *count, bool *islon)
{
- int ncvarid = UNDEFID;
- int fileID = streamptr->fileID;
+ grid_t *grid = &lazyGrid->base;
+ bool skipvar = true;
+ *islon = axisvar->islon;
+ int ndims = axisvar->ndims;
+ size_t size = 0;
+ int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
- if ( gridInqType(gridID) == GRID_SINUSOIDAL )
+ if ( (ndims - ntdims) == 2 )
{
- static const char varname[] = "sinusoidal";
- static const char mapname[] = "sinusoidal";
-
- cdf_redef(fileID);
+ /* Check size of 2 dimensional coordinate variables */
+ int dimid = axisvar->dimids[ndims-2];
+ size_t dimsize1 = ncdims[dimid].len;
+ dimid = axisvar->dimids[ndims-1];
+ size_t dimsize2 = ncdims[dimid].len;
- int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
- if ( ncerrcode == NC_NOERR )
+ if ( datatype == CDI_DATATYPE_UINT8 )
{
- cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
- /*
- cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
- cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
- */
+ ncvar->gridtype = GRID_CHARXY;
+ size = dimsize1*dimsize2;
+ skipvar = dimsize1 != *xsize;
+ }
+ else
+ {
+ ncvar->gridtype = GRID_CURVILINEAR;
+ size = (*xsize)*ysize;
+ skipvar = dimsize1*dimsize2 != size;
}
+ }
+ else if ( (ndims - ntdims) == 1 )
+ {
+ size = *xsize;
+ /* Check size of 1 dimensional coordinate variables */
+ int dimid = axisvar->dimids[ndims-1];
+ size_t dimsize = ncdims[dimid].len;
+ skipvar = dimsize != size;
+ }
+ else if ( ndims == 0 && *xsize == 0 )
+ {
+ size = *xsize = 1;
+ skipvar = false;
+ }
- cdf_enddef(fileID);
+ if ( skipvar )
+ {
+ Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
+ ncvar->isvar = -1;
+ return true;
}
- else if ( gridInqType(gridID) == GRID_LAEA )
+
+ if ( datatype != -1 ) grid->datatype = datatype;
+
+ if ( datatype == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
{
- static const char varname[] = "laea";
- static const char mapname[] = "lambert_azimuthal_equal_area";
+ cdf_load_cvals(size, xvarid, axisvar, &grid->x.cvals, *xsize);
+ grid->x.clength = size / (*xsize) ;
+ }
+ else
+ cdf_load_vals(size, ndims, xvarid, axisvar, &grid->x.vals, &lazyGrid->xValsGet, ntdims, start, count);
- cdf_redef(fileID);
+ cdf_copy_axis_attr(axisvar, &grid->x);
- int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
- if ( ncerrcode == NC_NOERR )
- {
- double a, lon_0, lat_0;
+ return false;
+}
+
+static
+bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int yvarid, ncvar_t *axisvar,
+ size_t xsize, size_t *ysize, int ntdims, size_t *start, size_t *count, bool *islat)
+{
+ grid_t *grid = &lazyGrid->base;
+ bool skipvar = true;
+ *islat = axisvar->islat;
+ int ndims = axisvar->ndims;
+ size_t size = 0;
+ int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
- gridInqLaea(gridID, &a, &lon_0, &lat_0);
+ if ( (ndims - ntdims) == 2 )
+ {
+ /* Check size of 2 dimensional coordinate variables */
+ int dimid = axisvar->dimids[ndims-2];
+ size_t dimsize1 = ncdims[dimid].len;
+ dimid = axisvar->dimids[ndims-1];
+ size_t dimsize2 = ncdims[dimid].len;
- cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
- cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &a);
- cdf_put_att_double(fileID, ncvarid, "longitude_of_projection_origin", NC_DOUBLE, 1, &lon_0);
- cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
+ if ( datatype == CDI_DATATYPE_UINT8 )
+ {
+ ncvar->gridtype = GRID_CHARXY;
+ size = dimsize1*dimsize2;
+ skipvar = dimsize1 != *ysize;
}
+ else
+ {
+ ncvar->gridtype = GRID_CURVILINEAR;
+ size = xsize*(*ysize);
+ skipvar = dimsize1*dimsize2 != size;
+ }
+ }
+ else if ( (ndims - ntdims) == 1 )
+ {
+ if ( *ysize == 0 ) size = xsize;
+ else size = *ysize;
- cdf_enddef(fileID);
+ int dimid = axisvar->dimids[ndims-1];
+ size_t dimsize = ncdims[dimid].len;
+ skipvar = dimsize != size;
}
- else if ( gridInqType(gridID) == GRID_LCC2 )
+ else if ( ndims == 0 && *ysize == 0 )
{
- static const char varname[] = "Lambert_Conformal";
- static const char mapname[] = "lambert_conformal_conic";
+ size = *ysize = 1;
+ skipvar = false;
+ }
- cdf_redef(fileID);
+ if ( skipvar )
+ {
+ Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
+ ncvar->isvar = -1;
+ return true;
+ }
- int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
- if ( ncerrcode == NC_NOERR )
- {
- double radius, lon_0, lat_0, lat_1, lat_2;
+ if ( datatype != -1 ) grid->datatype = datatype;
- gridInqLcc2(gridID, &radius, &lon_0, &lat_0, &lat_1, &lat_2);
+ if ( datatype == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
+ {
+ cdf_load_cvals(size, yvarid, axisvar, &grid->y.cvals, *ysize);
+ grid->y.clength = size / (*ysize) ;
+ }
+ else
+ cdf_load_vals(size, ndims, yvarid, axisvar, &grid->y.vals, &lazyGrid->yValsGet, ntdims, start, count);
- cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
- if ( radius > 0 )
- cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &radius);
- cdf_put_att_double(fileID, ncvarid, "longitude_of_central_meridian", NC_DOUBLE, 1, &lon_0);
- cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
- if ( IS_EQUAL(lat_1, lat_2) )
- cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 1, &lat_1);
- else
- {
- double lat_1_2[2];
- lat_1_2[0] = lat_1;
- lat_1_2[1] = lat_2;
- cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 2, lat_1_2);
- }
- }
+ cdf_copy_axis_attr(axisvar, &grid->y);
- cdf_enddef(fileID);
- }
+ return false;
}
-
static
-void cdfDefGrid(stream_t *streamptr, int gridID)
+bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ncvar_t *ncvars, ncdim_t *ncdims,
+ int timedimid, int xvarid, int yvarid, size_t xsize, size_t ysize, int *vdimid)
{
- int vlistID = streamptr->vlistID;
- int gridindex = vlistGridIndex(vlistID, gridID);
- if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
-
- int gridtype = gridInqType(gridID);
- int size = gridInqSize(gridID);
+ grid_t *grid = &lazyGrid->base;
+ size_t size = 0;
- if ( CDI_Debug )
- Message("gridtype = %d size = %d", gridtype, size);
+ grid->datatype = CDI_DATATYPE_FLT64;
- if ( gridtype == GRID_GAUSSIAN ||
- gridtype == GRID_LONLAT ||
- gridtype == GRID_GENERIC )
+ if ( ncvar->gridtype == GRID_TRAJECTORY )
{
- if ( gridtype == GRID_GENERIC )
+ if ( ncvar->xvarid == CDI_UNDEFID ) Error("Longitude coordinate undefined for %s!", ncvar->name);
+ if ( ncvar->yvarid == CDI_UNDEFID ) Error("Latitude coordinate undefined for %s!", ncvar->name);
+ }
+ else
+ {
+ static bool ltwarn = true;
+ size_t start[3], count[3];
+ int ntdims = 0;
+
+ if ( xvarid != CDI_UNDEFID && yvarid != CDI_UNDEFID )
{
- if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+ int ndims = ncvars[xvarid].ndims;
+ if ( ndims != ncvars[yvarid].ndims && !ncvars[xvarid].isc && !ncvars[yvarid].isc )
{
- /* no grid information */
+ Warning("Inconsistent grid structure for variable %s!", ncvar->name);
+ ncvar->xvarid = xvarid = CDI_UNDEFID;
+ ncvar->yvarid = yvarid = CDI_UNDEFID;
}
- else
+ if ( ndims > 1 )
{
- int lx = 0, ly = 0;
- if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+ if ( ndims <= 3 )
{
- cdfDefXaxis(streamptr, gridID, 1);
- lx = 1;
+ if ( ncvars[xvarid].dimids[0] == timedimid && ncvars[yvarid].dimids[0] == timedimid )
+ {
+ size_t ntsteps = 0;
+ cdf_inq_dimlen(ncvar->ncid, timedimid, &ntsteps);
+ if ( ltwarn && ntsteps > 1 ) Warning("Time varying grids unsupported, using grid at time step 1!");
+ ltwarn = false;
+ ntdims = 1;
+ start[0] = start[1] = start[2] = 0;
+ count[0] = 1; count[1] = ysize; count[ndims-1] = xsize;
+ }
}
-
- if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+ else
{
- cdfDefYaxis(streamptr, gridID, 1);
- ly = 1;
+ Warning("Unsupported grid structure for variable %s (grid dims > 2)!", ncvar->name);
+ ncvar->xvarid = xvarid = CDI_UNDEFID;
+ ncvar->yvarid = yvarid = CDI_UNDEFID;
}
-
- if ( lx == 0 && ly == 0 ) cdfDefGdim(streamptr, gridID);
}
}
- else
+
+ if ( xvarid != CDI_UNDEFID )
{
- int ndims = 1;
- if ( gridtype == GRID_LONLAT && size == 1 && gridInqHasDims(gridID) == FALSE )
- ndims = 0;
+ if ( (ncvars[xvarid].ndims - ntdims) > 2 )
+ {
+ Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[xvarid].name, ncvars[xvarid].ndims);
+ //ncvar->xvarid = CDI_UNDEFID;
+ xvarid = CDI_UNDEFID;
+ }
+ }
- if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, ndims);
- if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, ndims);
+ if ( yvarid != CDI_UNDEFID )
+ {
+ if ( (ncvars[yvarid].ndims - ntdims) > 2 )
+ {
+ Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
+ //ncvar->yvarid = CDI_UNDEFID;
+ yvarid = CDI_UNDEFID;
+ }
}
- if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
+ bool islon = false, islat = false;
+
+ if ( xvarid != CDI_UNDEFID )
+ if ( cdf_read_xcoord(lazyGrid, ncdims, ncvar, xvarid, &ncvars[xvarid],
+ &xsize, ysize, ntdims, start, count, &islon) )
+ return true;
+
+ if ( yvarid != CDI_UNDEFID )
+ if ( cdf_read_ycoord(lazyGrid, ncdims, ncvar, yvarid, &ncvars[yvarid],
+ xsize, &ysize, ntdims, start, count, &islat) )
+ return true;
+
+ if ( ysize == 0 ) size = xsize;
+ else if ( xsize == 0 ) size = ysize;
+ else if ( ncvar->gridtype == GRID_UNSTRUCTURED ) size = xsize;
+ else size = xsize*ysize;
+
+ if ( ncvar->gridtype == CDI_UNDEFID || ncvar->gridtype == GRID_GENERIC )
+ cdf_check_gridtype(&ncvar->gridtype, islon, islat, xsize, ysize, grid);
}
- else if ( gridtype == GRID_CURVILINEAR )
+
+ int gridtype = grid->type;
+ if ( gridtype != GRID_PROJECTION ) gridtype = ncvar->gridtype;
+ else if ( gridtype == GRID_PROJECTION && ncvar->gridtype == GRID_LONLAT )
{
- cdfDefCurvilinear(streamptr, gridID);
+ int gmapvarid = ncvar->gmapid;
+ if ( gmapvarid != CDI_UNDEFID && cdfCheckAttText(ncvar->ncid, gmapvarid, "grid_mapping_name") )
+ {
+ char attstring[CDI_MAX_NAME];
+ cdfGetAttText(ncvar->ncid, gmapvarid, "grid_mapping_name", CDI_MAX_NAME, attstring);
+ if ( strcmp(attstring, "latitude_longitude") == 0 ) gridtype = ncvar->gridtype;
+ }
}
- else if ( gridtype == GRID_UNSTRUCTURED )
+
+ switch (gridtype)
{
- cdfDefUnstructured(streamptr, gridID);
+ case GRID_GENERIC:
+ case GRID_LONLAT:
+ case GRID_GAUSSIAN:
+ case GRID_UNSTRUCTURED:
+ case GRID_CURVILINEAR:
+ case GRID_PROJECTION:
+ {
+ grid->size = size;
+ grid->x.size = xsize;
+ grid->y.size = ysize;
+ if ( xvarid != CDI_UNDEFID )
+ {
+ grid->x.flag = 1;
+ int bvarid = ncvars[xvarid].bounds;
+ if ( bvarid != CDI_UNDEFID )
+ {
+ int nbdims = ncvars[bvarid].ndims;
+ if ( nbdims == 2 || nbdims == 3 )
+ {
+ *vdimid = ncvars[bvarid].dimids[nbdims-1];
+ grid->nvertex = (int)ncdims[*vdimid].len;
+ cdf_load_bounds(size*(size_t)grid->nvertex, &ncvars[xvarid], &grid->x.bounds, &lazyGrid->xBoundsGet);
+ }
+ }
+ }
+ if ( yvarid != CDI_UNDEFID )
+ {
+ grid->y.flag = 1;
+ int bvarid = ncvars[yvarid].bounds;
+ if ( bvarid != CDI_UNDEFID )
+ {
+ int nbdims = ncvars[bvarid].ndims;
+ if ( nbdims == 2 || nbdims == 3 )
+ {
+ if ( *vdimid == CDI_UNDEFID )
+ {
+ *vdimid = ncvars[bvarid].dimids[nbdims-1];
+ grid->nvertex = (int)ncdims[*vdimid].len;
+ }
+ cdf_load_bounds(size*(size_t)grid->nvertex, &ncvars[yvarid], &grid->y.bounds, &lazyGrid->yBoundsGet);
+ }
+ }
+ }
+
+ if ( ncvar->cellarea != CDI_UNDEFID )
+ cdf_load_cellarea(size, ncvar, &grid->area, &lazyGrid->cellAreaGet);
+
+ break;
+ }
+ case GRID_SPECTRAL:
+ {
+ grid->size = size;
+ grid->lcomplex = 1;
+ grid->trunc = ncvar->truncation;
+ break;
+ }
+ case GRID_FOURIER:
+ {
+ grid->size = size;
+ grid->trunc = ncvar->truncation;
+ break;
+ }
+ case GRID_TRAJECTORY:
+ {
+ grid->size = 1;
+ break;
+ }
+ case GRID_CHARXY:
+ {
+ grid->size = size;
+ grid->x.size = xsize;
+ grid->y.size = ysize;
+ break;
+ }
}
- else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+
+ // if ( grid->type != GRID_PROJECTION && grid->type != ncvar->gridtype )
+ if ( grid->type != gridtype )
{
- cdfDefRgrid(streamptr, gridID);
+ // int gridtype = ncvar->gridtype;
+ grid->type = gridtype;
+ cdiGridTypeInit(grid, gridtype, grid->size);
}
- else if ( gridtype == GRID_SPECTRAL )
+
+ if ( grid->size == 0 )
{
- cdfDefComplex(streamptr, gridID);
- cdfDefSP(streamptr, gridID);
+ int ndims = ncvar->ndims;
+ int *dimtype = ncvar->dimtype;
+ if ( ndims == 0 ||
+ (ndims == 1 && dimtype[0] == T_AXIS) ||
+ (ndims == 1 && dimtype[0] == Z_AXIS) ||
+ (ndims == 2 && dimtype[0] == T_AXIS && dimtype[1] == Z_AXIS) )
+ {
+ grid->type = GRID_GENERIC;
+ grid->size = 1;
+ grid->x.size = 0;
+ grid->y.size = 0;
+ }
+ else
+ {
+ Warning("Unsupported grid, skipped variable %s!", ncvar->name);
+ ncvar->isvar = -1;
+ return true;
+ }
}
- else if ( gridtype == GRID_FOURIER )
+
+ return false;
+}
+
+static
+bool cdf_set_unstructured_par(ncvar_t *ncvar, grid_t *grid, int *xdimid, int *ydimid, int number_of_grid_used, unsigned char *uuidOfHGrid)
+{
+ int ndims = ncvar->ndims;
+ int *dimtype = ncvar->dimtype;
+
+ int zdimid = CDI_UNDEFID;
+ int xdimidx = CDI_UNDEFID, ydimidx = CDI_UNDEFID;
+
+ for ( int i = 0; i < ndims; i++ )
{
- cdfDefComplex(streamptr, gridID);
- cdfDefFC(streamptr, gridID);
+ if ( dimtype[i] == X_AXIS ) xdimidx = i;
+ else if ( dimtype[i] == Y_AXIS ) ydimidx = i;
+ else if ( dimtype[i] == Z_AXIS ) zdimid = ncvar->dimids[i];
}
- else if ( gridtype == GRID_TRAJECTORY )
+
+ if ( *xdimid != CDI_UNDEFID && *ydimid != CDI_UNDEFID && zdimid == CDI_UNDEFID )
{
- cdfDefTrajLon(streamptr, gridID);
- cdfDefTrajLat(streamptr, gridID);
+ if ( grid->x.size > grid->y.size && grid->y.size < 1000 )
+ {
+ dimtype[ydimidx] = Z_AXIS;
+ *ydimid = CDI_UNDEFID;
+ grid->size = grid->x.size;
+ grid->y.size = 0;
+ }
+ else if ( grid->y.size > grid->x.size && grid->x.size < 1000 )
+ {
+ dimtype[xdimidx] = Z_AXIS;
+ *xdimid = *ydimid;
+ *ydimid = CDI_UNDEFID;
+ grid->size = grid->y.size;
+ grid->x.size = grid->y.size;
+ grid->y.size = 0;
+ }
}
- else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
- {
- cdfDefXaxis(streamptr, gridID, 1);
- cdfDefYaxis(streamptr, gridID, 1);
- cdfDefMapping(streamptr, gridID);
+ if ( grid->size != grid->x.size )
+ {
+ Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
+ ncvar->isvar = -1;
+ return true;
}
- /*
- else if ( gridtype == GRID_LCC )
+
+ if ( number_of_grid_used != CDI_UNDEFID ) grid->number = number_of_grid_used;
+ if ( ncvar->position > 0 ) grid->position = ncvar->position;
+ if ( uuidOfHGrid[0] != 0 ) memcpy(grid->uuid, uuidOfHGrid, 16);
+
+ return false;
+}
+
+static
+void cdf_read_mapping_atts(int ncid, int gmapvarid, int projID, const char *varname)
+{
+ if ( cdfCheckAttText(ncid, gmapvarid, "grid_mapping_name") )
{
- cdfDefLcc(streamptr, gridID);
+ char attstring[CDI_MAX_NAME];
+ cdfGetAttText(ncid, gmapvarid, "grid_mapping_name", CDI_MAX_NAME, attstring);
+ cdiGridDefKeyStr(projID, CDI_KEY_MAPNAME, (int)(strlen(attstring)+1), attstring);
}
- */
else
{
- Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+ Warning("Text attribute %s:grid_mapping_name missing!", varname);
}
+
+ int nvatts;
+ cdf_inq_varnatts(ncid, gmapvarid, &nvatts);
+ for ( int attnum = 0; attnum < nvatts; ++attnum )
+ cdf_set_cdi_attr(ncid, gmapvarid, attnum, projID, CDI_GLOBAL);
}
static
-void scale_add(size_t size, double *data, double addoffset, double scalefactor)
+void cdf_set_grid_to_similar_vars(ncvar_t *ncvar1, ncvar_t *ncvar2, int gridtype, int xdimid, int ydimid)
{
- int laddoffset;
- int lscalefactor;
+ if ( ncvar2->isvar == TRUE && ncvar2->gridID == CDI_UNDEFID )
+ {
+ int xdimid2 = CDI_UNDEFID, ydimid2 = CDI_UNDEFID, zdimid2 = CDI_UNDEFID;
+ int xdimidx = CDI_UNDEFID, ydimidx = CDI_UNDEFID;
+ int ndims2 = ncvar2->ndims;
+
+ int *dimtype2 = ncvar2->dimtype;
+ int *dimids2 = ncvar2->dimids;
+ for ( int i = 0; i < ndims2; i++ )
+ {
+ if ( dimtype2[i] == X_AXIS ) { xdimid2 = dimids2[i]; xdimidx = i; }
+ else if ( dimtype2[i] == Y_AXIS ) { ydimid2 = dimids2[i]; ydimidx = i; }
+ else if ( dimtype2[i] == Z_AXIS ) { zdimid2 = dimids2[i]; }
+ }
- laddoffset = IS_NOT_EQUAL(addoffset, 0);
- lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+ if ( ncvar2->gridtype == CDI_UNDEFID && gridtype == GRID_UNSTRUCTURED )
+ {
+ if ( xdimid == xdimid2 && ydimid2 != CDI_UNDEFID && zdimid2 == CDI_UNDEFID )
+ {
+ ncvar2->dimtype[ydimidx] = Z_AXIS;
+ ydimid2 = CDI_UNDEFID;
+ }
- if ( laddoffset || lscalefactor )
- {
- for (size_t i = 0; i < size; ++i )
+ if ( xdimid == ydimid2 && xdimid2 != CDI_UNDEFID && zdimid2 == CDI_UNDEFID )
+ {
+ ncvar2->dimtype[xdimidx] = Z_AXIS;
+ xdimid2 = ydimid2;
+ ydimid2 = CDI_UNDEFID;
+ }
+ }
+
+ if ( xdimid == xdimid2 && (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == CDI_UNDEFID)) )
{
- if ( lscalefactor ) data[i] *= scalefactor;
- if ( laddoffset ) data[i] += addoffset;
+ bool same_grid = ncvar1->xvarid == ncvar2->xvarid
+ && ncvar1->yvarid == ncvar2->yvarid
+ && ncvar1->position == ncvar2->position;
+ /*
+ if ( xvarid != -1 && ncvar2->xvarid != CDI_UNDEFID &&
+ xvarid != ncvar2->xvarid ) same_grid = false;
+
+ if ( yvarid != -1 && ncvar2->yvarid != CDI_UNDEFID &&
+ yvarid != ncvar2->yvarid ) same_grid = false;
+ */
+
+ if ( same_grid )
+ {
+ if ( CDI_Debug ) Message("Same gridID %d %s", ncvar1->gridID, ncvar2->name);
+ ncvar2->gridID = ncvar1->gridID;
+ ncvar2->chunktype = ncvar1->chunktype;
+ }
}
}
}
static
-void cdfCreateRecords(stream_t *streamptr, int tsID)
+int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
+ int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
{
- if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
+ for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid )
+ {
+ ncvar_t *ncvar = &ncvars[ncvarid];
+ if ( ncvar->isvar && ncvar->gridID == CDI_UNDEFID )
+ {
+ int ndims = ncvar->ndims;
+ int *dimtype = ncvar->dimtype;
+ int vdimid = CDI_UNDEFID;
+ struct addIfNewRes projAdded = { .Id = CDI_UNDEFID, .isNew = 0 },
+ gridAdded = { .Id = CDI_UNDEFID, .isNew = 0 };
+ int xdimid = CDI_UNDEFID, ydimid = CDI_UNDEFID;
+ int nydims = cdf_get_xydimid(ndims, ncvar->dimids, dimtype, &xdimid, &ydimid);
+
+ int xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID;
+ int yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID;
+ int xvarid = (ncvar->xvarid != CDI_UNDEFID) ? ncvar->xvarid : xaxisid;
+ int yvarid = (ncvar->yvarid != CDI_UNDEFID) ? ncvar->yvarid : yaxisid;
+
+ size_t xsize = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].len : 0;
+ size_t ysize = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].len : 0;
+
+ if ( ydimid == CDI_UNDEFID && yvarid != CDI_UNDEFID )
+ {
+ if ( ncvars[yvarid].ndims == 1 )
+ {
+ ydimid = ncvars[yvarid].dimids[0];
+ ysize = ncdims[ydimid].len;
+ }
+ }
- if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
+ int gmapvarid = ncvar->gmapid;
+ bool lproj = gmapvarid != CDI_UNDEFID;
- int vlistID = streamptr->vlistID;
+ if ( !lproj && xaxisid != CDI_UNDEFID && xaxisid != xvarid && yaxisid != CDI_UNDEFID && yaxisid != yvarid )
+ {
+ lproj = true;
+ }
- tsteps_t* sourceTstep = streamptr->tsteps;
- tsteps_t* destTstep = sourceTstep + tsID;
+ bool lgrid = !(lproj && ncvar->xvarid == CDI_UNDEFID);
- int nvars = vlistNvars(vlistID);
- int nrecs = vlistNrecs(vlistID);
+ bool lunstructured = xdimid != CDI_UNDEFID && xdimid == ydimid && nydims == 0;
+ if ( (ncvar->gridtype == CDI_UNDEFID || ncvar->gridtype == GRID_GENERIC) && lunstructured )
+ ncvar->gridtype = GRID_UNSTRUCTURED;
- if ( nrecs <= 0 ) return;
+ struct cdfLazyGrid *restrict lazyGrid = NULL, *restrict lazyProj = NULL;
- if ( tsID == 0 )
- {
- int nvrecs = nrecs; /* use all records at first timestep */
+ {
+ int gridtype = !lgrid ? GRID_PROJECTION : ncvar->gridtype;
+ if ( CDI_netcdf_lazy_grid_load )
+ {
+ cdfLazyGridRenew(&lazyGrid, gridtype);
+ if ( lgrid && lproj ) cdfLazyGridRenew(&lazyProj, GRID_PROJECTION);
+ }
+ else
+ {
+ cdfBaseGridRenew(&lazyGrid, gridtype);
+ if ( lgrid && lproj ) cdfBaseGridRenew(&lazyProj, GRID_PROJECTION);
+ }
+ }
+ grid_t *grid = &lazyGrid->base;
+ grid_t *proj = ( lgrid && lproj ) ? &lazyProj->base : NULL;
- streamptr->nrecs += nrecs;
+ xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID;
+ yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID;
- destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
- destTstep->nrecs = nrecs;
- destTstep->nallrecs = nrecs;
- destTstep->recordSize = nrecs;
- destTstep->curRecID = UNDEFID;
- destTstep->recIDs = (int *) Malloc((size_t)nvrecs*sizeof (int));;
- for ( int recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
- record_t *records = destTstep->records;
+ if ( cdf_read_coordinates(lazyGrid, ncvar, ncvars, ncdims,
+ timedimid, xvarid, yvarid, xsize, ysize, &vdimid) )
+ continue;
- for ( int varID = 0, recID = 0; varID < nvars; varID++ )
- {
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int nlev = zaxisInqSize(zaxisID);
- for ( int levelID = 0; levelID < nlev; levelID++ )
+ if ( number_of_grid_used != CDI_UNDEFID &&
+ (grid->type == CDI_UNDEFID || grid->type == GRID_GENERIC) &&
+ xdimid != CDI_UNDEFID && xsize > 9999 )
+ grid->type = GRID_UNSTRUCTURED;
+
+ if ( grid->type == GRID_UNSTRUCTURED )
+ if ( cdf_set_unstructured_par(ncvar, grid, &xdimid, &ydimid, number_of_grid_used, uuidOfHGrid) )
+ continue;
+
+ if ( lproj && lgrid )
{
- recordInitEntry(&records[recID]);
- records[recID].varID = (short)varID;
- records[recID].levelID = (short)levelID;
- recID++;
- }
- }
- }
- else if ( tsID == 1 )
- {
- int nvrecs = 0;
- for ( int varID = 0; varID < nvars; varID++ )
- {
- if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+ int dumid;
+ cdf_read_coordinates(lazyProj, ncvar, ncvars, ncdims, timedimid,
+ xaxisid, yaxisid, xsize, ysize, &dumid);
+ }
+
+ if ( CDI_Debug )
+ {
+ Message("grid: type = %d, size = %zu, nx = %zu, ny = %zu",
+ grid->type, grid->size, grid->x.size, grid->y.size);
+ if ( proj )
+ Message("proj: type = %d, size = %zu, nx = %zu, ny = %zu",
+ proj->type, proj->size, proj->x.size, proj->y.size);
+ }
+
+
+ if ( lgrid && lproj )
{
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- nvrecs += zaxisInqSize(zaxisID);
+ projAdded = cdiVlistAddGridIfNew(vlistID, proj, 2);
+ grid->proj = projAdded.Id;
}
- }
- streamptr->nrecs += nvrecs;
+ gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 1);
+ ncvar->gridID = gridAdded.Id;
- destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
- destTstep->nrecs = nvrecs;
- destTstep->nallrecs = nrecs;
- destTstep->recordSize = nrecs;
- destTstep->curRecID = UNDEFID;
+ int gridID = ncvar->gridID;
- memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
+ if ( lproj && gmapvarid != CDI_UNDEFID )
+ {
+ int projID = lgrid ? grid->proj : gridID;
+ int ncid = ncvars[gmapvarid].ncid;
+ const char *gmapname = ncvars[gmapvarid].name;
+ cdf_read_mapping_atts(ncid, gmapvarid, projID, gmapname);
+ cdiGridDefKeyStr(projID, CDI_KEY_MAPPING, (int)(strlen(gmapname)+1), gmapname);
+ gridVerifyProj(projID);
+ }
- if ( nvrecs )
- {
- destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof (int));
- for ( int recID = 0, vrecID = 0; recID < nrecs; recID++ )
+ if ( grid->type == GRID_UNSTRUCTURED && gridfile[0] != 0 )
+ gridDefReference(gridID, gridfile);
+
+ if ( ncvar->chunked ) grid_set_chunktype(grid, ncvar);
+
+ int gridindex = vlistGridIndex(vlistID, gridID);
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimid;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimid;
+ if ( grid->type == GRID_TRAJECTORY )
{
- int varID = destTstep->records[recID].varID;
- if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
- {
- destTstep->recIDs[vrecID++] = recID;
- }
+ ncgrid[gridindex].ncIDs[CDF_VARID_X] = xvarid;
+ ncgrid[gridindex].ncIDs[CDF_VARID_Y] = yvarid;
}
- }
- }
- else
- {
- if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
- int nvrecs = streamptr->tsteps[1].nrecs;
+ if ( xdimid == CDI_UNDEFID && ydimid == CDI_UNDEFID && grid->size == 1 )
+ gridDefHasDims(gridID, FALSE);
- streamptr->nrecs += nvrecs;
+ if ( xdimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_XDIMNAME, (int)(strlen(ncdims[xdimid].name)+1), ncdims[xdimid].name);
+ if ( ydimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_YDIMNAME, (int)(strlen(ncdims[ydimid].name)+1), ncdims[ydimid].name);
+ if ( vdimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_VDIMNAME, (int)(strlen(ncdims[vdimid].name)+1), ncdims[vdimid].name);
- destTstep->records = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
- destTstep->nrecs = nvrecs;
- destTstep->nallrecs = nrecs;
- destTstep->recordSize = nrecs;
- destTstep->curRecID = UNDEFID;
+ if ( CDI_Debug ) Message("gridID %d %d %s", gridID, ncvarid, ncvar->name);
- memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
+ for ( int ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
+ cdf_set_grid_to_similar_vars(ncvar, &ncvars[ncvarid2], grid->type, xdimid, ydimid);
- destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof(int));
+ if ( gridAdded.isNew ) lazyGrid = NULL;
+ if ( projAdded.isNew ) lazyProj = NULL;
- memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
+ if ( lazyGrid )
+ {
+ if ( CDI_netcdf_lazy_grid_load ) cdfLazyGridDestroy(lazyGrid);
+ if ( grid ) { grid_free(grid); Free(grid); }
+ }
+
+ if ( lazyProj )
+ {
+ if ( CDI_netcdf_lazy_grid_load ) cdfLazyGridDestroy(lazyProj);
+ if ( proj ) { grid_free(proj); Free(proj); }
+ }
+ }
}
-}
+ return 0;
+}
+/* define all input zaxes */
static
-int cdfTimeDimID(int fileID, int ndims, int nvars)
+int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
+ size_t vctsize_echam, double *vct_echam, unsigned char *uuidOfVGrid)
{
- for ( int dimid = 0; dimid < ndims; dimid++ )
+ char *pname, *plongname, *punits;
+ size_t vctsize = vctsize_echam;
+ double *vct = vct_echam;
+
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- char dimname[80];
- cdf_inq_dimname(fileID, dimid, dimname);
- if ( memcmp(dimname, "time", 4) == 0 )
- return dimid;
- }
+ ncvar_t *ncvar = &ncvars[ncvarid];
+ if ( ncvar->isvar == TRUE && ncvar->zaxisID == CDI_UNDEFID )
+ {
+ bool is_scalar = false;
+ bool with_bounds = false;
+ int zdimid = CDI_UNDEFID;
+ int zvarid = CDI_UNDEFID;
+ size_t zsize = 1;
+ int psvarid = -1;
+ int p0varid = -1;
+ int positive = 0;
+ int ndims = ncvar->ndims;
- for ( int varid = 0; varid < nvars; varid++ )
- {
- int nvdims, nvatts, dimids[9];
- cdf_inq_var(fileID, varid, NULL, NULL, &nvdims, dimids, &nvatts);
- if ( nvdims == 1 )
- {
- for ( int iatt = 0; iatt < nvatts; iatt++ )
+ if ( ncvar->zvarid != -1 && ncvars[ncvar->zvarid].ndims == 0 )
{
- char sbuf[CDI_MAX_NAME];
- cdf_inq_attname(fileID, varid, iatt, sbuf);
- if ( strncmp(sbuf, "units", 5) == 0 )
+ zvarid = ncvar->zvarid;
+ is_scalar = true;
+ }
+ else
+ {
+ for ( int i = 0; i < ndims; i++ )
{
- cdfGetAttText(fileID, varid, "units", sizeof(sbuf), sbuf);
- strtolower(sbuf);
+ if ( ncvar->dimtype[i] == Z_AXIS )
+ zdimid = ncvar->dimids[i];
+ }
- if ( isTimeUnits(sbuf) )
- return dimids[0];
+ if ( zdimid != CDI_UNDEFID )
+ {
+ // zvarid = ncdims[zdimid].ncvarid;
+ zvarid = (ncvar->zvarid != CDI_UNDEFID) ? ncvar->zvarid : ncdims[zdimid].ncvarid;
+ zsize = ncdims[zdimid].len;
}
}
- }
- }
- return UNDEFID;
-}
+ if ( CDI_Debug ) Message("nlevs = %zu", zsize);
-static
-void init_ncdims(long ndims, ncdim_t *ncdims)
-{
- for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ )
- {
- ncdims[ncdimid].ncvarid = UNDEFID;
- ncdims[ncdimid].dimtype = UNDEFID;
- ncdims[ncdimid].len = 0;
- ncdims[ncdimid].name[0] = 0;
- }
-}
+ double *zvar = NULL;
+ char **zcvals = NULL;
+ size_t zclength = 0;
-static
-void init_ncvars(long nvars, ncvar_t *ncvars)
-{
- for ( long ncvarid = 0; ncvarid < nvars; ++ncvarid )
- {
- ncvars[ncvarid].ncid = UNDEFID;
- ncvars[ncvarid].ignore = FALSE;
- ncvars[ncvarid].isvar = UNDEFID;
- ncvars[ncvarid].islon = FALSE;
- ncvars[ncvarid].islat = FALSE;
- ncvars[ncvarid].islev = FALSE;
- ncvars[ncvarid].istime = FALSE;
- ncvars[ncvarid].warn = FALSE;
- ncvars[ncvarid].tsteptype = TSTEP_CONSTANT;
- ncvars[ncvarid].param = UNDEFID;
- ncvars[ncvarid].code = UNDEFID;
- ncvars[ncvarid].tabnum = 0;
- ncvars[ncvarid].calendar = FALSE;
- ncvars[ncvarid].climatology = FALSE;
- ncvars[ncvarid].bounds = UNDEFID;
- ncvars[ncvarid].lformula = FALSE;
- ncvars[ncvarid].lformulaterms = FALSE;
- ncvars[ncvarid].gridID = UNDEFID;
- ncvars[ncvarid].zaxisID = UNDEFID;
- ncvars[ncvarid].gridtype = UNDEFID;
- ncvars[ncvarid].zaxistype = UNDEFID;
- ncvars[ncvarid].xdim = UNDEFID;
- ncvars[ncvarid].ydim = UNDEFID;
- ncvars[ncvarid].zdim = UNDEFID;
- ncvars[ncvarid].xvarid = UNDEFID;
- ncvars[ncvarid].yvarid = UNDEFID;
- ncvars[ncvarid].zvarid = UNDEFID;
- ncvars[ncvarid].tvarid = UNDEFID;
- ncvars[ncvarid].psvarid = UNDEFID;
- ncvars[ncvarid].p0varid = UNDEFID;
- ncvars[ncvarid].ncoordvars = 0;
- for ( int i = 0; i < MAX_COORDVARS; ++i )
- ncvars[ncvarid].coordvarids[i] = UNDEFID;
- ncvars[ncvarid].nauxvars = 0;
- for ( int i = 0; i < MAX_AUXVARS; ++i )
- ncvars[ncvarid].auxvarids[i] = UNDEFID;
- ncvars[ncvarid].cellarea = UNDEFID;
- ncvars[ncvarid].tableID = UNDEFID;
- ncvars[ncvarid].xtype = 0;
- ncvars[ncvarid].ndims = 0;
- ncvars[ncvarid].gmapid = UNDEFID;
- ncvars[ncvarid].vctsize = 0;
- ncvars[ncvarid].vct = NULL;
- ncvars[ncvarid].truncation = 0;
- ncvars[ncvarid].position = 0;
- ncvars[ncvarid].positive = 0;
- ncvars[ncvarid].chunked = 0;
- ncvars[ncvarid].chunktype = UNDEFID;
- ncvars[ncvarid].defmissval = 0;
- ncvars[ncvarid].deffillval = 0;
- ncvars[ncvarid].missval = 0;
- ncvars[ncvarid].fillval = 0;
- ncvars[ncvarid].addoffset = 0;
- ncvars[ncvarid].scalefactor = 1;
- ncvars[ncvarid].name[0] = 0;
- ncvars[ncvarid].longname[0] = 0;
- ncvars[ncvarid].stdname[0] = 0;
- ncvars[ncvarid].units[0] = 0;
- ncvars[ncvarid].extra[0] = 0;
- ncvars[ncvarid].natts = 0;
- ncvars[ncvarid].atts = NULL;
- ncvars[ncvarid].deflate = 0;
- ncvars[ncvarid].lunsigned = 0;
- ncvars[ncvarid].lvalidrange = 0;
- ncvars[ncvarid].validrange[0] = VALIDMISS;
- ncvars[ncvarid].validrange[1] = VALIDMISS;
- ncvars[ncvarid].ensdata = NULL;
- }
-}
+ int zaxisType = CDI_UNDEFID;
+ if ( zvarid != CDI_UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
+ if ( zaxisType == CDI_UNDEFID ) zaxisType = ZAXIS_GENERIC;
-static
-void cdfSetVar(ncvar_t *ncvars, int ncvarid, short isvar)
-{
- if ( ncvars[ncvarid].isvar != UNDEFID &&
- ncvars[ncvarid].isvar != isvar &&
- ncvars[ncvarid].warn == FALSE )
- {
- if ( ! ncvars[ncvarid].ignore )
- Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
+ int zdatatype = CDI_DATATYPE_FLT64;
+ double *restrict lbounds = NULL;
+ double *restrict ubounds = NULL;
- ncvars[ncvarid].warn = TRUE;
- isvar = FALSE;
- }
+ if ( zvarid != CDI_UNDEFID )
+ {
+ positive = ncvars[zvarid].positive;
+ pname = ncvars[zvarid].name;
+ plongname = ncvars[zvarid].longname;
+ punits = ncvars[zvarid].units;
+ if ( ncvars[zvarid].xtype == NC_FLOAT ) zdatatype = CDI_DATATYPE_FLT32;
+ /* don't change the name !!! */
+ /*
+ if ( (len = strlen(pname)) > 2 )
+ if ( pname[len-2] == '_' && isdigit((int) pname[len-1]) )
+ pname[len-2] = 0;
+ */
+ if ( zaxisType == ZAXIS_CHAR )
+ {
+ if ( ncvars[zvarid].ndims == 2 )
+ {
+ zdatatype = CDI_DATATYPE_UINT8;
+ zclength = ncdims[ncvars[zvarid].dimids[1]].len;
+ cdf_load_cvals(zsize*zclength, zvarid, ncvar, &zcvals, zsize);
+ }
+ }
- ncvars[ncvarid].isvar = isvar;
-}
+ if ( zaxisType == ZAXIS_HYBRID && ncvars[zvarid].vct )
+ {
+ vct = ncvars[zvarid].vct;
+ vctsize = ncvars[zvarid].vctsize;
-static
-void cdfSetDim(ncvar_t *ncvars, int ncvarid, int dimid, int dimtype)
-{
- if ( ncvars[ncvarid].dimtype[dimid] != UNDEFID &&
- ncvars[ncvarid].dimtype[dimid] != dimtype )
- {
- Warning("Inconsistent dimension definition for %s! dimid = %d; type = %d; newtype = %d",
- ncvars[ncvarid].name, dimid, ncvars[ncvarid].dimtype[dimid], dimtype);
+ if ( ncvars[zvarid].psvarid != -1 ) psvarid = ncvars[zvarid].psvarid;
+ if ( ncvars[zvarid].p0varid != -1 ) p0varid = ncvars[zvarid].p0varid;
+ }
+
+ if ( zaxisType != ZAXIS_CHAR )
+ {
+ zvar = (double*) Malloc(zsize*sizeof(double));
+ cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
+ }
+
+ if ( ncvars[zvarid].bounds != CDI_UNDEFID )
+ {
+ int nbdims = ncvars[ncvars[zvarid].bounds].ndims;
+ if ( nbdims == 2 || is_scalar )
+ {
+ size_t nlevel = is_scalar ? 1 : ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
+ int nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1-is_scalar]].len;
+ if ( nlevel == zsize && nvertex == 2 )
+ {
+ with_bounds = true;
+ lbounds = (double *) Malloc(4 * nlevel*sizeof(double));
+ ubounds = lbounds + nlevel;
+ double *restrict zbounds = lbounds + 2 * nlevel;
+ cdf_get_var_double(ncvars[zvarid].ncid, ncvars[zvarid].bounds, zbounds);
+ for ( size_t i = 0; i < nlevel; ++i )
+ {
+ lbounds[i] = zbounds[i*2];
+ ubounds[i] = zbounds[i*2+1];
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ pname = (zdimid != CDI_UNDEFID) ? ncdims[zdimid].name : NULL;
+ plongname = NULL;
+ punits = NULL;
+
+ if ( zsize == 1 && zdimid == CDI_UNDEFID )
+ {
+ zaxisType = (ncvar->zaxistype != CDI_UNDEFID) ? ncvar->zaxistype : ZAXIS_SURFACE;
+ // if ( pname )
+ {
+ zvar = (double*) Malloc(sizeof(double));
+ zvar[0] = 0;
+ }
+ }
+ }
+
+ if ( zsize > INT_MAX )
+ {
+ Warning("Size limit exceeded for z-axis dimension (limit=%d)!", INT_MAX);
+ return CDI_EDIMSIZE;
+ }
+
+ ncvar->zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, (const char **)zcvals, zclength, with_bounds, lbounds, ubounds,
+ (int)vctsize, vct, pname, plongname, punits, zdatatype, 1, 0);
+
+ int zaxisID = ncvar->zaxisID;
+
+ if ( CDI_cmor_mode && zsize == 1 && zaxisType != ZAXIS_HYBRID ) zaxisDefScalar(zaxisID);
+
+ if ( uuidOfVGrid[0] != 0 )
+ zaxisDefUUID(zaxisID, uuidOfVGrid);
+
+ if ( zaxisType == ZAXIS_HYBRID )
+ {
+ if ( psvarid != -1 )
+ cdiZaxisDefKeyStr(zaxisID, CDI_KEY_PSNAME, (int)(strlen(ncvars[psvarid].name)+1), ncvars[psvarid].name);
+ if ( p0varid != -1 )
+ {
+ double px = 1;
+ cdf_get_var_double(ncvars[p0varid].ncid, p0varid, &px);
+ cdiZaxisDefKeyFlt(zaxisID, CDI_KEY_P0VALUE, px);
+ cdiZaxisDefKeyStr(zaxisID, CDI_KEY_P0NAME, (int)(strlen(ncvars[p0varid].name)+1), ncvars[p0varid].name);
+ }
+ }
+
+ if ( positive > 0 ) zaxisDefPositive(zaxisID, positive);
+ if ( is_scalar ) zaxisDefScalar(zaxisID);
+
+ if ( zdimid != CDI_UNDEFID )
+ cdiZaxisDefKeyStr(zaxisID, CDI_KEY_DIMNAME, (int)(strlen(ncdims[zdimid].name)+1), ncdims[zdimid].name);
+ /*
+ if ( vdimid != -1 )
+ cdiZaxisDefKeyStr(zaxisID, CDI_KEY_VDIMNAME, strlen(ncdims[vdimid].name)+1, ncdims[vdimid].name);
+ */
+ if ( zvar ) Free(zvar);
+ if ( zcvals )
+ {
+ for ( size_t i = 0; i < zsize; i++ )
+ Free(zcvals[i]);
+ Free(zcvals);
+ }
+ if ( lbounds ) Free(lbounds);
+
+ if ( zvarid != CDI_UNDEFID )
+ {
+ int ncid = ncvars[zvarid].ncid;
+ int nvatts = ncvars[zvarid].natts;
+ for ( int iatt = 0; iatt < nvatts; ++iatt )
+ {
+ int attnum = ncvars[zvarid].atts[iatt];
+ cdf_set_cdi_attr(ncid, zvarid, attnum, zaxisID, CDI_GLOBAL);
+ }
+ }
+
+ int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+ streamptr->zaxisID[zaxisindex] = zdimid;
+
+ if ( CDI_Debug )
+ Message("zaxisID %d %d %s", zaxisID, ncvarid, ncvar->name);
+
+ for ( int ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
+ if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == CDI_UNDEFID /*&& ncvars[ncvarid2].zaxistype == CDI_UNDEFID*/ )
+ {
+ int zvarid2 = CDI_UNDEFID;
+ if ( ncvars[ncvarid2].zvarid != CDI_UNDEFID && ncvars[ncvars[ncvarid2].zvarid].ndims == 0 )
+ zvarid2 = ncvars[ncvarid2].zvarid;
+
+ int zdimid2 = CDI_UNDEFID;
+ ndims = ncvars[ncvarid2].ndims;
+ for ( int i = 0; i < ndims; i++ )
+ {
+ if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+ zdimid2 = ncvars[ncvarid2].dimids[i];
+ }
+
+ if ( zdimid == zdimid2 /* && zvarid == zvarid2 */)
+ {
+ if ( (zdimid != CDI_UNDEFID && ncvars[ncvarid2].zaxistype == CDI_UNDEFID) ||
+ (zdimid == CDI_UNDEFID && zvarid != CDI_UNDEFID && zvarid == zvarid2) ||
+ (zdimid == CDI_UNDEFID && zaxisType == ncvars[ncvarid2].zaxistype) ||
+ (zdimid == CDI_UNDEFID && zvarid2 == CDI_UNDEFID && ncvars[ncvarid2].zaxistype == CDI_UNDEFID) )
+ {
+ if ( CDI_Debug )
+ Message("zaxisID %d %d %s", zaxisID, ncvarid2, ncvars[ncvarid2].name);
+ ncvars[ncvarid2].zaxisID = zaxisID;
+ }
+ }
+ }
+ }
}
- ncvars[ncvarid].dimtype[dimid] = dimtype;
+ return 0;
}
-static
-bool isLonAxis(const char *units, const char *stdname)
-{
- bool status = false;
- char lc_units[16];
-
- memcpy(lc_units, units, 15);
- lc_units[15] = 0;
- strtolower(lc_units);
-
- if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
- (memcmp(stdname, "grid_longitude", 14) == 0 || memcmp(stdname, "longitude", 9) == 0)) )
- {
- status = true;
- }
- if ( status == false &&
- memcmp(stdname, "grid_latitude", 13) && memcmp(stdname, "latitude", 8) &&
- memcmp(lc_units, "degree", 6) == 0 )
- {
- int ioff = 6;
- if ( lc_units[ioff] == 's' ) ioff++;
- if ( lc_units[ioff] == '_' ) ioff++;
- if ( lc_units[ioff] == 'e' ) status = true;
- }
+struct cdf_varinfo
+{
+ int varid;
+ const char *name;
+};
- return status;
+static
+int cdf_cmp_varname(const void *s1, const void *s2)
+{
+ const struct cdf_varinfo *x = (const struct cdf_varinfo *)s1,
+ *y = (const struct cdf_varinfo *)s2;
+ return strcmp(x->name, y->name);
}
+/* define all input data variables */
static
-bool isLatAxis(const char *units, const char *stdname)
+void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, int num_ncvars, ncvar_t *ncvars)
{
- bool status = false;
- char lc_units[16];
-
- memcpy(lc_units, units, 15);
- lc_units[15] = 0;
- strtolower(lc_units);
+ if ( CDI_Debug )
+ for ( int i = 0; i < nvars; i++ ) Message("varids[%d] = %d", i, varids[i]);
- if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
- (memcmp(stdname, "grid_latitude", 13) == 0 || memcmp(stdname, "latitude", 8) == 0)) )
+ if ( streamptr->sortname )
{
- status = true;
+ struct cdf_varinfo *varInfo
+ = (struct cdf_varinfo *) Malloc((size_t)nvars * sizeof(struct cdf_varinfo));
+
+ for ( int varID = 0; varID < nvars; varID++ )
+ {
+ int ncvarid = varids[varID];
+ varInfo[varID].varid = ncvarid;
+ varInfo[varID].name = ncvars[ncvarid].name;
+ }
+ qsort(varInfo, (size_t)nvars, sizeof(varInfo[0]), cdf_cmp_varname);
+ for ( int varID = 0; varID < nvars; varID++ )
+ {
+ varids[varID] = varInfo[varID].varid;
+ }
+ Free(varInfo);
+ if ( CDI_Debug )
+ for ( int i = 0; i < nvars; i++ ) Message("sorted varids[%d] = %d", i, varids[i]);
}
- if ( status == false &&
- memcmp(stdname, "grid_longitude", 14) && memcmp(stdname, "longitude", 9) &&
- memcmp(lc_units, "degree", 6) == 0 )
+ for ( int varID1 = 0; varID1 < nvars; varID1++ )
{
- int ioff = 6;
- if ( lc_units[ioff] == 's' ) ioff++;
- if ( lc_units[ioff] == '_' ) ioff++;
- if ( lc_units[ioff] == 'n' || lc_units[ioff] == 's' ) status = true;
- }
+ int ncvarid = varids[varID1];
+ int gridID = ncvars[ncvarid].gridID;
+ int zaxisID = ncvars[ncvarid].zaxisID;
- return status;
-}
+ stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
+ int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].timetype);
-static
-bool isDBLAxis(/*const char *units,*/ const char *longname)
-{
- bool status = false;
+#if defined (HAVE_NETCDF4)
+ if ( ncvars[ncvarid].deflate )
+ vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_ZIP);
- if ( strcmp(longname, "depth below land") == 0 ||
- strcmp(longname, "depth_below_land") == 0 ||
- strcmp(longname, "levels below the surface") == 0 )
- {
- /*
- if ( strcmp(ncvars[ncvarid].units, "cm") == 0 ||
- strcmp(ncvars[ncvarid].units, "dm") == 0 ||
- strcmp(ncvars[ncvarid].units, "m") == 0 )
- */
- status = true;
- }
+ if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != CDI_UNDEFID )
+ vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
+#endif
- return status;
-}
+ streamptr->vars[varID1].defmiss = false;
+ streamptr->vars[varID1].ncvarid = ncvarid;
-static
-bool unitsIsHeight(const char *units)
-{
- bool status = false;
- int u0 = units[0];
+ vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
+ if ( ncvars[ncvarid].param != CDI_UNDEFID ) vlistDefVarParam(vlistID, varID, ncvars[ncvarid].param);
+ if ( ncvars[ncvarid].code != CDI_UNDEFID ) vlistDefVarCode(vlistID, varID, ncvars[ncvarid].code);
+ if ( ncvars[ncvarid].code != CDI_UNDEFID )
+ {
+ int param = cdiEncodeParam(ncvars[ncvarid].code, ncvars[ncvarid].tabnum, 255);
+ vlistDefVarParam(vlistID, varID, param);
+ }
+ if ( ncvars[ncvarid].longname[0] ) vlistDefVarLongname(vlistID, varID, ncvars[ncvarid].longname);
+ if ( ncvars[ncvarid].stdname[0] ) vlistDefVarStdname(vlistID, varID, ncvars[ncvarid].stdname);
+ if ( ncvars[ncvarid].units[0] ) vlistDefVarUnits(vlistID, varID, ncvars[ncvarid].units);
- if ( (u0=='m' && (!units[1] || strncmp(units, "meter", 5) == 0)) ||
- (!units[2] && units[1]=='m' && (u0=='c' || u0=='d' || u0=='k')) )
- {
- status = true;
- }
+ if ( ncvars[ncvarid].lvalidrange )
+ vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
- return status;
-}
+ if ( IS_NOT_EQUAL(ncvars[ncvarid].addoffset, 0) )
+ vlistDefVarAddoffset(vlistID, varID, ncvars[ncvarid].addoffset);
+ if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
+ vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
-static
-bool isDepthAxis(const char *stdname, const char *longname)
-{
- bool status = false;
+ vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
- if ( strcmp(stdname, "depth") == 0 )
- status = true;
- else
- if ( strcmp(longname, "depth_below_sea") == 0 ||
- strcmp(longname, "depth below sea") == 0 )
- {
- status = true;
- }
+ vlistDefVarInstitut(vlistID, varID, instID);
+ vlistDefVarModel(vlistID, varID, modelID);
+ if ( ncvars[ncvarid].tableID != CDI_UNDEFID )
+ vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
- return status;
-}
+ if ( ncvars[ncvarid].deffillval == false && ncvars[ncvarid].defmissval )
+ {
+ ncvars[ncvarid].deffillval = true;
+ ncvars[ncvarid].fillval = ncvars[ncvarid].missval;
+ }
-static
-bool isHeightAxis(const char *stdname, const char *longname)
-{
- bool status = false;
+ if ( ncvars[ncvarid].deffillval )
+ vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
- if ( strcmp(stdname, "height") == 0 )
- status = true;
- else
- if ( strcmp(longname, "height") == 0 ||
- strcmp(longname, "height above the surface") == 0 )
- {
- status = true;
- }
+ if ( CDI_Debug )
+ Message("varID = %d gridID = %d zaxisID = %d", varID,
+ vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
- return status;
-}
+ int gridindex = vlistGridIndex(vlistID, gridID);
+ int xdimid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ int ydimid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
-static
-bool unitsIsPressure(const char *units)
-{
- bool status = false;
+ int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+ int zdimid = streamptr->zaxisID[zaxisindex];
- if ( strncmp(units, "millibar", 8) == 0 ||
- strncmp(units, "mb", 2) == 0 ||
- strncmp(units, "hectopas", 8) == 0 ||
- strncmp(units, "hPa", 3) == 0 ||
- strncmp(units, "Pa", 2) == 0 )
- {
- status = true;
- }
+ int ndims = ncvars[ncvarid].ndims;
+ int iodim = 0;
+ int ixyz = 0;
+ static const int ipow10[4] = {1, 10, 100, 1000};
- return status;
-}
+ if ( ncvars[ncvarid].timetype != TIME_CONSTANT ) iodim++;
-static
-int scan_hybrid_formula(int ncid, int ncfvarid, int *apvarid, int *bvarid, int *psvarid, int *avarid, int *p0varid)
-{
- int status = 0;
- *apvarid = -1;
- *bvarid = -1;
- *psvarid = -1;
- *avarid = -1;
- *p0varid = -1;
- enum { attstringlen = 8192 }; char attstring[attstringlen];
- cdfGetAttText(ncid, ncfvarid, "formula", attstringlen, attstring);
- if ( strcmp(attstring, "p = ap + b*ps") == 0 )
- {
- status = 1;
- int lstop = FALSE;
- int dimvarid;
- cdfGetAttText(ncid, ncfvarid, "formula_terms", attstringlen, attstring);
- char *pstring = attstring;
+ const int *dimids = ncvars[ncvarid].dimids;
- for ( int i = 0; i < 3; i++ )
+ if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
{
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *tagname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
-
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *varname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
-
- int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
- if ( status_nc == NC_NOERR )
- {
- if ( strcmp(tagname, "ap:") == 0 ) *apvarid = dimvarid;
- else if ( strcmp(tagname, "b:") == 0 ) *bvarid = dimvarid;
- else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
- }
- else if ( strcmp(tagname, "ps:") != 0 )
+ ixyz = (xdimid == dimids[ndims-1]) ? 321 : 213;
+ }
+ else
+ {
+ for ( int idim = iodim; idim < ndims; idim++ )
{
- Warning("%s - %s", nc_strerror(status_nc), varname);
+ if ( xdimid == dimids[idim] ) ixyz += 1*ipow10[ndims-idim-1];
+ else if ( ydimid == dimids[idim] ) ixyz += 2*ipow10[ndims-idim-1];
+ else if ( zdimid == dimids[idim] ) ixyz += 3*ipow10[ndims-idim-1];
}
-
- if ( lstop ) break;
}
- }
- else if ( strcmp(attstring, "xxxp = a*p0 + b*ps") == 0 )
- {
- status = 2;
- int lstop = FALSE;
- int dimvarid;
- cdfGetAttText(ncid, ncfvarid, "formula_terms", attstringlen, attstring);
- char *pstring = attstring;
- for ( int i = 0; i < 4; i++ )
+ vlistDefVarXYZ(vlistID, varID, ixyz);
+ /*
+ printf("ixyz %d\n", ixyz);
+ printf("ndims %d\n", ncvars[ncvarid].ndims);
+ for ( int i = 0; i < ncvars[ncvarid].ndims; ++i )
+ printf("dimids: %d %d\n", i, dimids[i]);
+ printf("xdimid, ydimid %d %d\n", xdimid, ydimid);
+ */
+ if ( ncvars[ncvarid].ensdata != NULL )
{
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *tagname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
-
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *varname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
-
- int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
- if ( status_nc == NC_NOERR )
- {
- if ( strcmp(tagname, "a:") == 0 ) *avarid = dimvarid;
- else if ( strcmp(tagname, "b:") == 0 ) *bvarid = dimvarid;
- else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
- else if ( strcmp(tagname, "p0:") == 0 ) *p0varid = dimvarid;
- }
- else if ( strcmp(tagname, "ps:") != 0 )
- {
- Warning("%s - %s", nc_strerror(status_nc), varname);
- }
+ vlistDefVarEnsemble( vlistID, varID, ncvars[ncvarid].ensdata->ens_index,
+ ncvars[ncvarid].ensdata->ens_count,
+ ncvars[ncvarid].ensdata->forecast_init_type );
+ Free(ncvars[ncvarid].ensdata);
+ ncvars[ncvarid].ensdata = NULL;
+ }
- if ( lstop ) break;
+ if ( ncvars[ncvarid].extra[0] != 0 )
+ {
+ vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
}
}
- return status;
-}
-
-static
-bool isHybridSigmaPressureCoordinate(int ncid, int ncvarid, ncvar_t *ncvars, const ncdim_t *ncdims)
-{
- bool status = false;
- int ncfvarid = ncvarid;
- ncvar_t *ncvar = &ncvars[ncvarid];
-
- if ( strcmp(ncvar->stdname, "atmosphere_hybrid_sigma_pressure_coordinate") == 0 )
+ for ( int varID = 0; varID < nvars; varID++ )
{
- cdiConvention = CDI_CONVENTION_CF;
-
- status = true;
- ncvar->zaxistype = ZAXIS_HYBRID;
- int dimid = ncvar->dimids[0];
- size_t dimlen = ncdims[dimid].len;
+ int ncvarid = varids[varID];
+ int ncid = ncvars[ncvarid].ncid;
- int ret;
- int apvarid1 = -1, bvarid1 = -1, psvarid1 = -1, avarid1 = -1, p0varid1 = -1;
- if ( ncvars[ncfvarid].lformula && ncvars[ncfvarid].lformulaterms )
- ret = scan_hybrid_formula(ncid, ncfvarid, &apvarid1, &bvarid1, &psvarid1, &avarid1, &p0varid1);
- if ( apvarid1 != -1 ) ncvars[apvarid1].isvar = FALSE;
- if ( bvarid1 != -1 ) ncvars[bvarid1].isvar = FALSE;
- if ( psvarid1 != -1 ) ncvar->psvarid = psvarid1;
- if ( avarid1 != -1 ) ncvars[avarid1].isvar = FALSE;
- if ( p0varid1 != -1 ) ncvar->p0varid = p0varid1;
+ int nvatts = ncvars[ncvarid].natts;
+ for ( int iatt = 0; iatt < nvatts; ++iatt )
+ {
+ int attnum = ncvars[ncvarid].atts[iatt];
+ cdf_set_cdi_attr(ncid, ncvarid, attnum, vlistID, varID);
+ }
- if ( ncvar->bounds != UNDEFID && ncvars[ncvar->bounds].lformula && ncvars[ncvar->bounds].lformulaterms )
+ if ( ncvars[ncvarid].atts )
{
- ncfvarid = ncvar->bounds;
- int apvarid2 = -1, bvarid2 = -1, psvarid2 = -1, avarid2 = -1, p0varid2 = -1;
- ret = 0;
- if ( ncvars[ncfvarid].lformula && ncvars[ncfvarid].lformulaterms )
- ret = scan_hybrid_formula(ncid, ncfvarid, &apvarid2, &bvarid2, &psvarid2, &avarid2, &p0varid2);
- if ( ret == 1 ) avarid2 = apvarid2;
- if ( avarid2 != -1 && bvarid2 != -1 )
- {
- ncvars[avarid2].isvar = FALSE;
- ncvars[bvarid2].isvar = FALSE;
+ Free(ncvars[ncvarid].atts);
+ ncvars[ncvarid].atts = NULL;
+ }
- if ( dimid == ncvars[avarid2].dimids[0] && ncdims[ncvars[avarid2].dimids[1]].len == 2 )
- {
- double px = 1;
- if ( ret == 2 && p0varid1 == p0varid2 )
- cdf_get_var_double(ncid, p0varid2, &px);
+ if ( ncvars[ncvarid].vct )
+ {
+ Free(ncvars[ncvarid].vct);
+ ncvars[ncvarid].vct = NULL;
+ }
+ }
- double abuf[dimlen*2], bbuf[dimlen*2];
- cdf_get_var_double(ncid, avarid2, abuf);
- cdf_get_var_double(ncid, bvarid2, bbuf);
- /*
- for ( int i = 0; i < dimlen; ++i )
- printf("%d %g %g %g %g\n", i, abuf[i*2], abuf[i*2+1], bbuf[i*2], bbuf[i*2+1]);
- */
- size_t vctsize = (dimlen+1)*2;
- double *vct = (double *) Malloc(vctsize * sizeof(double));
- for ( size_t i = 0; i < dimlen; ++i )
- {
- vct[i] = abuf[i*2];
- vct[i+dimlen+1] = bbuf[i*2];
- }
- vct[dimlen] = abuf[dimlen*2-1];
- vct[dimlen*2+1] = bbuf[dimlen*2-1];
+ /* release mem of not freed attributes */
+ for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
+ if ( ncvars[ncvarid].atts ) Free(ncvars[ncvarid].atts);
- if ( ret == 2 && IS_NOT_EQUAL(px, 1) )
- for ( size_t i = 0; i < dimlen+1; ++i ) vct[i] *= px;
+ if ( varids ) Free(varids);
- ncvar->vct = vct;
- ncvar->vctsize = vctsize;
- }
- }
- }
+ for ( int varID = 0; varID < nvars; varID++ )
+ {
+ if ( vlistInqVarCode(vlistID, varID) == -varID-1 )
+ {
+ char name[CDI_MAX_NAME]; name[0] = 0;
+ vlistInqVarName(vlistID, varID, name);
+ size_t len = strlen(name);
+ if ( len > 3 && isdigit((int) name[3]) )
+ {
+ if ( str_is_equal(name, "var") )
+ {
+ vlistDefVarCode(vlistID, varID, atoi(name+3));
+ // vlistDestroyVarName(vlistID, varID);
+ }
+ }
+ else if ( len > 4 && isdigit((int) name[4]) )
+ {
+ if ( str_is_equal(name, "code") )
+ {
+ vlistDefVarCode(vlistID, varID, atoi(name+4));
+ // vlistDestroyVarName(vlistID, varID);
+ }
+ }
+ else if ( len > 5 && isdigit((int) name[5]) )
+ {
+ if ( str_is_equal(name, "param") )
+ {
+ int pnum = -1, pcat = 255, pdis = 255;
+ sscanf(name+5, "%d.%d.%d", &pnum, &pcat, &pdis);
+ vlistDefVarParam(vlistID, varID, cdiEncodeParam(pnum, pcat, pdis));
+ // vlistDestroyVarName(vlistID, varID);
+ }
+ }
+ }
}
- return status;
-}
+ for ( int varID = 0; varID < nvars; varID++ )
+ {
+ int varInstID = vlistInqVarInstitut(vlistID, varID);
+ int varModelID = vlistInqVarModel(vlistID, varID);
+ int varTableID = vlistInqVarTable(vlistID, varID);
+ int code = vlistInqVarCode(vlistID, varID);
+ if ( cdiDefaultTableID != CDI_UNDEFID )
+ {
+ char name[CDI_MAX_NAME]; name[0] = 0;
+ char longname[CDI_MAX_NAME]; longname[0] = 0;
+ char units[CDI_MAX_NAME]; units[0] = 0;
+ tableInqEntry(cdiDefaultTableID, code, -1, name, longname, units);
+ if ( name[0] )
+ {
+ vlistDestroyVarName(vlistID, varID);
+ vlistDestroyVarLongname(vlistID, varID);
+ vlistDestroyVarUnits(vlistID, varID);
+
+ if ( varTableID != CDI_UNDEFID )
+ {
+ vlistDefVarName(vlistID, varID, name);
+ if ( longname[0] ) vlistDefVarLongname(vlistID, varID, longname);
+ if ( units[0] ) vlistDefVarUnits(vlistID, varID, units);
+ }
+ else
+ {
+ varTableID = cdiDefaultTableID;
+ }
+ }
+ if ( cdiDefaultModelID != CDI_UNDEFID ) varModelID = cdiDefaultModelID;
+ if ( cdiDefaultInstID != CDI_UNDEFID ) varInstID = cdiDefaultInstID;
+ }
+ if ( varInstID != CDI_UNDEFID ) vlistDefVarInstitut(vlistID, varID, varInstID);
+ if ( varModelID != CDI_UNDEFID ) vlistDefVarModel(vlistID, varID, varModelID);
+ if ( varTableID != CDI_UNDEFID ) vlistDefVarTable(vlistID, varID, varTableID);
+ }
+}
static
-int isGaussGrid(size_t ysize, double yinc, const double *yvals)
+void cdf_scan_global_attr(int fileID, int vlistID, stream_t *streamptr, int ngatts, int *instID, int *modelID, bool *ucla_les, unsigned char *uuidOfHGrid, unsigned char *uuidOfVGrid, char *gridfile, int *number_of_grid_used)
{
- int lgauss = FALSE;
- double *yv, *yw;
+ nc_type xtype;
+ size_t attlen;
+ char attname[CDI_MAX_NAME];
+ char attstring[65636];
- if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
+ for ( int iatt = 0; iatt < ngatts; iatt++ )
{
- size_t i;
- yv = (double *) Malloc(ysize*sizeof(double));
- yw = (double *) Malloc(ysize*sizeof(double));
- gaussaw(yv, yw, ysize);
- Free(yw);
- for ( i = 0; i < ysize; i++ )
- yv[i] = asin(yv[i])/M_PI*180.0;
+ cdf_inq_attname(fileID, NC_GLOBAL, iatt, attname);
+ cdf_inq_atttype(fileID, NC_GLOBAL, attname, &xtype);
+ cdf_inq_attlen(fileID, NC_GLOBAL, attname, &attlen);
- for ( i = 0; i < ysize; i++ )
- if ( fabs(yv[i] - yvals[i]) >
- ((yv[0] - yv[1])/500) ) break;
+ if ( xtypeIsText(xtype) )
+ {
+ cdfGetAttText(fileID, NC_GLOBAL, attname, sizeof(attstring), attstring);
- if ( i == ysize ) lgauss = TRUE;
+ size_t attstrlen = strlen(attstring);
- /* check S->N */
- if ( lgauss == FALSE )
- {
- for ( i = 0; i < ysize; i++ )
- if ( fabs(yv[i] - yvals[ysize-i-1]) >
- ((yv[0] - yv[1])/500) ) break;
+ if ( attlen > 0 && attstring[0] != 0 )
+ {
+ if ( strcmp(attname, "history") == 0 )
+ {
+ streamptr->historyID = iatt;
+ }
+ else if ( strcmp(attname, "institution") == 0 )
+ {
+ *instID = institutInq(0, 0, NULL, attstring);
+ if ( *instID == CDI_UNDEFID )
+ *instID = institutDef(0, 0, NULL, attstring);
+ }
+ else if ( strcmp(attname, "source") == 0 )
+ {
+ *modelID = modelInq(-1, 0, attstring);
+ if ( *modelID == CDI_UNDEFID )
+ *modelID = modelDef(-1, 0, attstring);
+ }
+ else if ( strcmp(attname, "Source") == 0 )
+ {
+ if ( strncmp(attstring, "UCLA-LES", 8) == 0 )
+ *ucla_les = true;
+ }
+ /*
+ else if ( strcmp(attname, "Conventions") == 0 )
+ {
+ }
+ */
+ else if ( strcmp(attname, "CDI") == 0 )
+ {
+ }
+ else if ( strcmp(attname, "CDO") == 0 )
+ {
+ }
+ /*
+ else if ( strcmp(attname, "forecast_reference_time") == 0 )
+ {
+ memcpy(fcreftime, attstring, attstrlen+1);
+ }
+ */
+ else if ( strcmp(attname, "grid_file_uri") == 0 )
+ {
+ memcpy(gridfile, attstring, attstrlen+1);
+ }
+ else if ( strcmp(attname, "uuidOfHGrid") == 0 && attstrlen == 36 )
+ {
+ attstring[36] = 0;
+ cdiStr2UUID(attstring, uuidOfHGrid);
+ // printf("uuid: %d %s\n", attlen, attstring);
+ }
+ else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
+ {
+ attstring[36] = 0;
+ cdiStr2UUID(attstring, uuidOfVGrid);
+ }
+ else
+ {
+ if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
+ memcpy(gridfile, attstring, attstrlen+1);
- if ( i == ysize ) lgauss = TRUE;
+ cdiDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attstrlen, attstring);
+ }
+ }
+ }
+ else if ( xtype == NC_SHORT || xtype == NC_INT )
+ {
+ if ( strcmp(attname, "number_of_grid_used") == 0 )
+ {
+ (*number_of_grid_used) = CDI_UNDEFID;
+ cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
+ }
+ else
+ {
+ int attint[attlen];
+ cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
+ int datatype = (xtype == NC_SHORT) ? CDI_DATATYPE_INT16 : CDI_DATATYPE_INT32;
+ cdiDefAttInt(vlistID, CDI_GLOBAL, attname, datatype, (int)attlen, attint);
+ }
}
-
- Free(yv);
+ else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
+ {
+ double attflt[attlen];
+ cdfGetAttDouble(fileID, NC_GLOBAL, attname, attlen, attflt);
+ int datatype = (xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
+ cdiDefAttFlt(vlistID, CDI_GLOBAL, attname, datatype, (int)attlen, attflt);
+ }
}
-
- return (lgauss);
}
static
-void printNCvars(const ncvar_t *ncvars, int nvars, const char *oname)
+int find_leadtime(int nvars, ncvar_t *ncvars)
{
- char axis[7];
- int ncvarid, i;
- int ndim;
- static const char iaxis[] = {'t', 'z', 'y', 'x'};
-
- fprintf(stderr, "%s:\n", oname);
+ int leadtime_id = CDI_UNDEFID;
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- ndim = 0;
- if ( ncvars[ncvarid].isvar )
- {
- axis[ndim++] = 'v';
- axis[ndim++] = ':';
- for ( i = 0; i < ncvars[ncvarid].ndims; i++ )
- {/*
- if ( ncvars[ncvarid].tvarid != -1 ) axis[ndim++] = iaxis[0];
- else if ( ncvars[ncvarid].zvarid != -1 ) axis[ndim++] = iaxis[1];
- else if ( ncvars[ncvarid].yvarid != -1 ) axis[ndim++] = iaxis[2];
- else if ( ncvars[ncvarid].xvarid != -1 ) axis[ndim++] = iaxis[3];
- else
- */
- if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) axis[ndim++] = iaxis[0];
- else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) axis[ndim++] = iaxis[1];
- else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) axis[ndim++] = iaxis[2];
- else if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) axis[ndim++] = iaxis[3];
- else axis[ndim++] = '?';
- }
- }
- else
- {
- axis[ndim++] = 'c';
- axis[ndim++] = ':';
- if ( ncvars[ncvarid].istime ) axis[ndim++] = iaxis[0];
- else if ( ncvars[ncvarid].islev ) axis[ndim++] = iaxis[1];
- else if ( ncvars[ncvarid].islat ) axis[ndim++] = iaxis[2];
- else if ( ncvars[ncvarid].islon ) axis[ndim++] = iaxis[3];
- else axis[ndim++] = '?';
- }
-
- axis[ndim++] = 0;
-
- fprintf(stderr, "%3d %3d %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
+ if ( ncvars[ncvarid].ndims == 1 )
+ if ( ncvars[ncvarid].stdname[0] && strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
+ {
+ leadtime_id = ncvarid;
+ break;
+ }
}
+
+ return leadtime_id;
}
static
-void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
- int timedimid, int modelID, int format)
+void find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, stream_t *streamptr,
+ bool *time_has_units, bool *time_has_bounds, bool *time_climatology)
{
- int ncid;
- int ncdimid;
- int nvdims, nvatts;
- int *dimidsp;
- int iatt;
- nc_type xtype, atttype;
- size_t attlen;
- char name[CDI_MAX_NAME];
- char attname[CDI_MAX_NAME];
- const int attstringlen = 8192; char attstring[8192];
-
- int nchecked_vars = 0;
- enum { max_check_vars = 9 };
- char *checked_vars[max_check_vars];
- for ( int i = 0; i < max_check_vars; ++i ) checked_vars[i] = NULL;
+ int ncvarid;
- for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ if ( timedimid == CDI_UNDEFID )
{
- ncid = ncvars[ncvarid].ncid;
- dimidsp = ncvars[ncvarid].dimids;
-
- cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
- strcpy(ncvars[ncvarid].name, name);
-
- for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
- ncvars[ncvarid].dimtype[ncdimid] = -1;
-
- ncvars[ncvarid].xtype = xtype;
- ncvars[ncvarid].ndims = nvdims;
-
-#if defined (HAVE_NETCDF4)
- if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
- {
- int shuffle, deflate, deflate_level;
- size_t chunks[nvdims];
- int storage_in;
- nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflate_level);
- if ( deflate > 0 ) ncvars[ncvarid].deflate = 1;
-
- if ( nc_inq_var_chunking(ncid, ncvarid, &storage_in, chunks) == NC_NOERR )
- {
- if ( storage_in == NC_CHUNKED )
- {
- ncvars[ncvarid].chunked = 1;
- for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = (int)chunks[i];
- if ( CDI_Debug )
- {
- fprintf(stderr, "%s: chunking %d %d %d chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED);
- for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
- fprintf(stderr, "\n");
- }
- {
- char *buf = ncvars[ncvarid].extra;
- size_t pos = strlen(buf);
- static const char prefix[] = "chunks=";
- memcpy(buf + pos, prefix, sizeof (prefix));
- pos += sizeof (prefix) - 1;
- for ( int i = nvdims-1; i >= 0; --i )
- {
- pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i],
- i > 0 ? "x" : ""));
- }
- buf[pos] = ' '; buf[pos + 1] = 0;
- }
- }
- }
- }
-#endif
+ char timeunits[CDI_MAX_NAME];
- if ( nvdims > 0 )
+ for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- if ( timedimid == dimidsp[0] )
- {
- ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
- cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
- }
- else
+ if ( ncvars[ncvarid].ndims == 0 && strcmp(ncvars[ncvarid].name, "time") == 0 )
{
- for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
+ if ( ncvars[ncvarid].units[0] )
{
- if ( timedimid == dimidsp[ncdimid] )
+ strcpy(timeunits, ncvars[ncvarid].units);
+ str_tolower(timeunits);
+
+ if ( is_time_units(timeunits) )
{
- Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
- ncvars[ncvarid].isvar = FALSE;
+ streamptr->basetime.ncvarid = ncvarid;
+ break;
}
}
}
}
+ }
+ else
+ {
+ bool ltimevar = false;
- for ( iatt = 0; iatt < nvatts; iatt++ )
+ if ( ncdims[timedimid].ncvarid != CDI_UNDEFID )
{
- cdf_inq_attname(ncid, ncvarid, iatt, attname);
- cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
- cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+ streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
+ ltimevar = true;
+ }
- if ( strcmp(attname, "long_name") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].longname);
- }
- else if ( strcmp(attname, "standard_name") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].stdname);
- }
- else if ( strcmp(attname, "units") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].units);
- }
- else if ( strcmp(attname, "calendar") == 0 )
- {
- ncvars[ncvarid].calendar = TRUE;
- }
- else if ( strcmp(attname, "param") == 0 && xtypeIsText(atttype) )
- {
- char paramstr[32];
- int pnum = 0, pcat = 255, pdis = 255;
- cdfGetAttText(ncid, ncvarid, attname, sizeof(paramstr), paramstr);
- sscanf(paramstr, "%d.%d.%d", &pnum, &pcat, &pdis);
- ncvars[ncvarid].param = cdiEncodeParam(pnum, pcat, pdis);
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "code") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].code);
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "table") == 0 && !xtypeIsText(atttype) )
+ for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ if ( ncvarid != streamptr->basetime.ncvarid &&
+ ncvars[ncvarid].ndims == 1 &&
+ timedimid == ncvars[ncvarid].dimids[0] &&
+ !xtypeIsText(ncvars[ncvarid].xtype) &&
+ is_timeaxis_units(ncvars[ncvarid].units) )
+ {
+ ncvars[ncvarid].isvar = FALSE;
+
+ if ( !ltimevar )
+ {
+ streamptr->basetime.ncvarid = ncvarid;
+ ltimevar = true;
+ if ( CDI_Debug )
+ fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
+ }
+ else
+ {
+ Warning("Found more than one time variable, skipped variable %s!", ncvars[ncvarid].name);
+ }
+ }
+
+ if ( ltimevar == false ) /* search for WRF time description */
+ {
+ for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ if ( ncvarid != streamptr->basetime.ncvarid &&
+ ncvars[ncvarid].ndims == 2 &&
+ timedimid == ncvars[ncvarid].dimids[0] &&
+ xtypeIsText(ncvars[ncvarid].xtype) &&
+ ncdims[ncvars[ncvarid].dimids[1]].len == 19 )
+ {
+ streamptr->basetime.ncvarid = ncvarid;
+ streamptr->basetime.lwrf = true;
+ break;
+ }
+ }
+
+ /* time varID */
+ ncvarid = streamptr->basetime.ncvarid;
+
+ if ( ncvarid == CDI_UNDEFID )
+ {
+ Warning("Time variable >%s< not found!", ncdims[timedimid].name);
+ }
+ }
+
+ /* time varID */
+ ncvarid = streamptr->basetime.ncvarid;
+
+ if ( ncvarid != CDI_UNDEFID && streamptr->basetime.lwrf == false )
+ {
+ if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = true;
+
+ if ( ncvars[ncvarid].bounds != CDI_UNDEFID )
+ {
+ int nbdims = ncvars[ncvars[ncvarid].bounds].ndims;
+ if ( nbdims == 2 )
{
- int tablenum;
- cdfGetAttInt(ncid, ncvarid, attname, 1, &tablenum);
- if ( tablenum > 0 )
+ int len = (int) ncdims[ncvars[ncvars[ncvarid].bounds].dimids[nbdims-1]].len;
+ if ( len == 2 && timedimid == ncvars[ncvars[ncvarid].bounds].dimids[0] )
{
- ncvars[ncvarid].tabnum = tablenum;
- ncvars[ncvarid].tableID = tableInq(modelID, tablenum, NULL);
- if ( ncvars[ncvarid].tableID == CDI_UNDEFID )
- ncvars[ncvarid].tableID = tableDef(modelID, tablenum, NULL);
+ *time_has_bounds = true;
+ streamptr->basetime.ncvarboundsid = ncvars[ncvarid].bounds;
+ if ( ncvars[ncvarid].climatology ) *time_climatology = true;
}
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "trunc_type") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- if ( memcmp(attstring, "Triangular", attlen) == 0 )
- ncvars[ncvarid].gridtype = GRID_SPECTRAL;
}
- else if ( strcmp(attname, "grid_type") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- strtolower(attstring);
-
- if ( strcmp(attstring, "gaussian reduced") == 0 )
- ncvars[ncvarid].gridtype = GRID_GAUSSIAN_REDUCED;
- else if ( strcmp(attstring, "gaussian") == 0 )
- ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
- else if ( strncmp(attstring, "spectral", 8) == 0 )
- ncvars[ncvarid].gridtype = GRID_SPECTRAL;
- else if ( strncmp(attstring, "fourier", 7) == 0 )
- ncvars[ncvarid].gridtype = GRID_FOURIER;
- else if ( strcmp(attstring, "trajectory") == 0 )
- ncvars[ncvarid].gridtype = GRID_TRAJECTORY;
- else if ( strcmp(attstring, "generic") == 0 )
- ncvars[ncvarid].gridtype = GRID_GENERIC;
- else if ( strcmp(attstring, "cell") == 0 )
- ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
- else if ( strcmp(attstring, "unstructured") == 0 )
- ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
- else if ( strcmp(attstring, "curvilinear") == 0 )
- ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
- else if ( strcmp(attstring, "sinusoidal") == 0 )
- ;
- else if ( strcmp(attstring, "laea") == 0 )
- ;
- else if ( strcmp(attstring, "lcc2") == 0 )
- ;
- else if ( strcmp(attstring, "linear") == 0 ) // ignore grid type linear
- ;
- else
- {
- static int warn = TRUE;
- if ( warn )
- {
- warn = FALSE;
- Warning("NetCDF attribute grid_type='%s' unsupported!", attstring);
- }
- }
+ }
+ }
+}
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "level_type") == 0 && xtypeIsText(atttype) )
+static
+void read_vct_echam(int fileID, int nvars, ncvar_t *ncvars, ncdim_t *ncdims, double **vct, size_t *pvctsize)
+{
+ /* find ECHAM VCT */
+ int nvcth_id = CDI_UNDEFID, vcta_id = CDI_UNDEFID, vctb_id = CDI_UNDEFID;
+
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ size_t len = strlen(ncvars[ncvarid].name);
+ if ( len == 4 && ncvars[ncvarid].name[0] == 'h' && ncvars[ncvarid].name[1] == 'y' )
{
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- strtolower(attstring);
-
- if ( strcmp(attstring, "toa") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_TOA;
- else if ( strcmp(attstring, "cloudbase") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_BASE;
- else if ( strcmp(attstring, "cloudtop") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_TOP;
- else if ( strcmp(attstring, "isotherm0") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_ISOTHERM_ZERO;
- else if ( strcmp(attstring, "seabottom") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_SEA_BOTTOM;
- else if ( strcmp(attstring, "lakebottom") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_LAKE_BOTTOM;
- else if ( strcmp(attstring, "sedimentbottom") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM;
- else if ( strcmp(attstring, "sedimentbottomta") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;
- else if ( strcmp(attstring, "sedimentbottomtw") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;
- else if ( strcmp(attstring, "mixlayer") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_MIX_LAYER;
- else if ( strcmp(attstring, "atmosphere") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_ATMOSPHERE;
- else
+ if ( ncvars[ncvarid].name[2] == 'a' && ncvars[ncvarid].name[3] == 'i' ) // hyai
{
- static int warn = TRUE;
- if ( warn )
- {
- warn = FALSE;
- Warning("NetCDF attribute level_type='%s' unsupported!", attstring);
- }
+ vcta_id = ncvarid;
+ nvcth_id = ncvars[ncvarid].dimids[0];
+ ncvars[ncvarid].isvar = FALSE;
}
-
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "trunc_count") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
- }
- else if ( strcmp(attname, "truncation") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
- }
- else if ( strcmp(attname, "number_of_grid_in_reference") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].position);
- }
- else if ( strcmp(attname, "add_offset") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].addoffset);
- /*
- if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
- if ( ncvars[ncvarid].addoffset != 0 )
- Warning("attribute add_offset not supported for atttype %d", atttype);
- */
- /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( strcmp(attname, "scale_factor") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].scalefactor);
- /*
- if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
- if ( ncvars[ncvarid].scalefactor != 1 )
- Warning("attribute scale_factor not supported for atttype %d", atttype);
- */
- /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( strcmp(attname, "climatology") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- int ncboundsid;
- int status = nc_inq_varid(ncid, attstring, &ncboundsid);
- if ( status == NC_NOERR )
+ else if ( ncvars[ncvarid].name[2] == 'b' && ncvars[ncvarid].name[3] == 'i' ) //hybi
{
- ncvars[ncvarid].climatology = TRUE;
- ncvars[ncvarid].bounds = ncboundsid;
- cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
- cdfSetVar(ncvars, ncvarid, FALSE);
+ vctb_id = ncvarid;
+ nvcth_id = ncvars[ncvarid].dimids[0];
+ ncvars[ncvarid].isvar = FALSE;
}
- else
- Warning("%s - %s", nc_strerror(status), attstring);
- }
- else if ( xtypeIsText(atttype) && strcmp(attname, "bounds") == 0 )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- int ncboundsid;
- int status = nc_inq_varid(ncid, attstring, &ncboundsid);
- if ( status == NC_NOERR )
+ else if ( (ncvars[ncvarid].name[2] == 'a' || ncvars[ncvarid].name[2] == 'b') && ncvars[ncvarid].name[3] == 'm' )
{
- ncvars[ncvarid].bounds = ncboundsid;
- cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
- cdfSetVar(ncvars, ncvarid, FALSE);
+ ncvars[ncvarid].isvar = FALSE; // hyam or hybm
}
- else
- Warning("%s - %s", nc_strerror(status), attstring);
- }
- else if ( xtypeIsText(atttype) && strcmp(attname, "formula_terms") == 0 )
- {
- ncvars[ncvarid].lformulaterms = TRUE;
}
- else if ( xtypeIsText(atttype) && strcmp(attname, "formula") == 0 )
+ }
+ }
+
+ /* read VCT */
+ if ( nvcth_id != CDI_UNDEFID && vcta_id != CDI_UNDEFID && vctb_id != CDI_UNDEFID )
+ {
+ size_t vctsize = ncdims[nvcth_id].len;
+ vctsize *= 2;
+ *vct = (double *) Malloc(vctsize*sizeof(double));
+ cdf_get_var_double(fileID, vcta_id, *vct);
+ cdf_get_var_double(fileID, vctb_id, *vct+vctsize/2);
+ *pvctsize = vctsize;
+ }
+}
+
+static
+void cdf_set_ucla_dimtype(int ndims, ncdim_t *ncdims, ncvar_t *ncvars)
+{
+ for ( int ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ {
+ int ncvarid = ncdims[ncdimid].ncvarid;
+ if ( ncvarid != -1 )
+ {
+ if ( ncdims[ncdimid].dimtype == CDI_UNDEFID && ncvars[ncvarid].units[0] == 'm' )
{
- ncvars[ncvarid].lformula = TRUE;
+ if ( ncvars[ncvarid].name[0] == 'x' ) ncdims[ncdimid].dimtype = X_AXIS;
+ else if ( ncvars[ncvarid].name[0] == 'y' ) ncdims[ncdimid].dimtype = Y_AXIS;
+ else if ( ncvars[ncvarid].name[0] == 'z' ) ncdims[ncdimid].dimtype = Z_AXIS;
}
- else if ( strcmp(attname, "cell_measures") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- char *pstring = attstring;
+ }
+ }
+}
- while ( isspace((int) *pstring) ) pstring++;
- char *cell_measures = pstring;
- while ( isalnum((int) *pstring) ) pstring++;
- *pstring++ = 0;
- while ( isspace((int) *pstring) ) pstring++;
- char *cell_var = pstring;
- while ( ! isspace((int) *pstring) && *pstring != 0 ) pstring++;
- *pstring++ = 0;
- /*
- printf("cell_measures >%s<\n", cell_measures);
- printf("cell_var >%s<\n", cell_var);
- */
- if ( memcmp(cell_measures, "area", 4) == 0 )
- {
- int nc_cell_id;
- int status = nc_inq_varid(ncid, cell_var, &nc_cell_id);
- if ( status == NC_NOERR )
- {
- ncvars[ncvarid].cellarea = nc_cell_id;
- /* ncvars[nc_cell_id].isvar = UNDEFID; */
- cdfSetVar(ncvars, nc_cell_id, FALSE);
- }
- else
- Warning("%s - %s", nc_strerror(status), cell_var);
- }
- else
- {
- Warning("%s has an unexpected contents: %s", attname, cell_measures);
- }
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- /*
- else if ( strcmp(attname, "coordinates") == 0 )
- {
- char *pstring, *xvarname = NULL, *yvarname = NULL;
+static
+int cdf_check_vars(int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid)
+{
+ for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ if ( timedimid != CDI_UNDEFID )
+ if ( ncvars[ncvarid].isvar == -1 &&
+ ncvars[ncvarid].ndims > 1 &&
+ timedimid == ncvars[ncvarid].dimids[0] )
+ cdf_set_var(ncvars, ncvarid, TRUE);
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- pstring = attstring;
+ if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
+ cdf_set_var(ncvars, ncvarid, FALSE);
- while ( isspace((int) *pstring) ) pstring++;
- xvarname = pstring;
- while ( isgraph((int) *pstring) ) pstring++;
- *pstring++ = 0;
- while ( isspace((int) *pstring) ) pstring++;
- yvarname = pstring;
- while ( isgraph((int) *pstring) ) pstring++;
- *pstring++ = 0;
+ //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
+ if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
+ cdf_set_var(ncvars, ncvarid, TRUE);
- cdf_inq_varid(ncid, xvarname, &ncvars[ncvarid].xvarid);
- cdf_inq_varid(ncid, yvarname, &ncvars[ncvarid].yvarid);
+ if ( ncvars[ncvarid].isvar == -1 )
+ {
+ ncvars[ncvarid].isvar = 0;
+ Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
+ continue;
+ }
- cdfSetVar(ncvars, ncvars[ncvarid].xvarid, FALSE);
- cdfSetVar(ncvars, ncvars[ncvarid].yvarid, FALSE);
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- */
- else if ( (strcmp(attname, "associate") == 0 || strcmp(attname, "coordinates") == 0) && xtypeIsText(atttype) )
- {
- int lstop = FALSE;
- int dimvarid;
+ if ( ncvars[ncvarid].ndims > 4 )
+ {
+ ncvars[ncvarid].isvar = 0;
+ Warning("%d dimensional variables are not supported, skipped variable %s!",
+ ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+ continue;
+ }
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- char *pstring = attstring;
+ if ( ncvars[ncvarid].ndims == 4 && timedimid == CDI_UNDEFID )
+ {
+ ncvars[ncvarid].isvar = 0;
+ Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
+ ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+ continue;
+ }
- for ( int i = 0; i < MAX_COORDVARS; i++ )
- {
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *varname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
+ if ( xtypeIsText(ncvars[ncvarid].xtype) )
+ {
+ ncvars[ncvarid].isvar = 0;
+ continue;
+ }
- int status = nc_inq_varid(ncid, varname, &dimvarid);
- if ( status == NC_NOERR )
- {
- cdfSetVar(ncvars, dimvarid, FALSE);
- if ( cdiIgnoreAttCoordinates == FALSE )
- {
- ncvars[ncvarid].coordvarids[i] = dimvarid;
- ncvars[ncvarid].ncoordvars++;
- }
- }
- else
- {
- int k;
- for ( k = 0; k < nchecked_vars; ++k )
- if ( strcmp(checked_vars[k], varname) == 0 ) break;
+ if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
+ {
+ ncvars[ncvarid].isvar = 0;
+ Warning("Unsupported data type, skipped variable %s!", ncvars[ncvarid].name);
+ continue;
+ }
- if ( k == nchecked_vars )
- {
- if ( nchecked_vars < max_check_vars ) checked_vars[nchecked_vars++] = strdup(varname);
- Warning("%s - %s", nc_strerror(status), varname);
- }
- }
+ if ( timedimid != CDI_UNDEFID && ntsteps == 0 && ncvars[ncvarid].ndims > 0 )
+ {
+ if ( timedimid == ncvars[ncvarid].dimids[0] )
+ {
+ ncvars[ncvarid].isvar = 0;
+ Warning("Number of time steps undefined, skipped variable %s!", ncvars[ncvarid].name);
+ continue;
+ }
+ }
+ }
- if ( lstop ) break;
- }
+ return timedimid;
+}
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( (strcmp(attname, "auxiliary_variable") == 0) && xtypeIsText(atttype) )
- {
- int lstop = FALSE;
- int dimvarid;
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- char *pstring = attstring;
+int cdfInqContents(stream_t *streamptr)
+{
+ int ndims, nvars, ngatts, unlimdimid;
+ int ncvarid;
+ int ncdimid;
+ int *varids;
+ int nvarids;
+ bool time_has_units = false;
+ bool time_has_bounds = false;
+ bool time_climatology = false;
+ int leadtime_id = CDI_UNDEFID;
+ int nvars_data;
+ int instID = CDI_UNDEFID;
+ int modelID = CDI_UNDEFID;
+ int calendar = CDI_UNDEFID;
+ int format = 0;
+ bool ucla_les = false;
+ char gridfile[8912];
+ char fcreftime[CDI_MAX_NAME];
+ int number_of_grid_used = CDI_UNDEFID;
- for ( int i = 0; i < MAX_AUXVARS; i++ )
- {
- while ( isspace((int) *pstring) ) pstring++;
- if ( *pstring == 0 ) break;
- char *varname = pstring;
- while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
- if ( *pstring == 0 ) lstop = TRUE;
- *pstring++ = 0;
+ unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+ unsigned char uuidOfVGrid[CDI_UUID_SIZE];
+ memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
+ memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
+ gridfile[0] = 0;
+ fcreftime[0] = 0;
- int status = nc_inq_varid(ncid, varname, &dimvarid);
- if ( status == NC_NOERR )
- {
- cdfSetVar(ncvars, dimvarid, FALSE);
- // if ( cdiIgnoreAttCoordinates == FALSE )
- {
- ncvars[ncvarid].auxvarids[i] = dimvarid;
- ncvars[ncvarid].nauxvars++;
- }
- }
- else
- Warning("%s - %s", nc_strerror(status), varname);
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
- if ( lstop ) break;
- }
+ if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "grid_mapping") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- int nc_gmap_id;
- int status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
- if ( status == NC_NOERR )
- {
- ncvars[ncvarid].gmapid = nc_gmap_id;
- cdfSetVar(ncvars, ncvars[ncvarid].gmapid, FALSE);
- }
- else
- Warning("%s - %s", nc_strerror(status), attstring);
+#if defined (HAVE_NETCDF4)
+ nc_inq_format(fileID, &format);
+#endif
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else if ( strcmp(attname, "positive") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- strtolower(attstring);
+ cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
- if ( memcmp(attstring, "down", 4) == 0 ) ncvars[ncvarid].positive = POSITIVE_DOWN;
- else if ( memcmp(attstring, "up", 2) == 0 ) ncvars[ncvarid].positive = POSITIVE_UP;
+ if ( CDI_Debug )
+ Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
+ /*
+ if ( ndims == 0 )
+ {
+ Warning("No dimensions found!");
+ return CDI_EUFSTRUCT;
+ }
+ */
+ // alloc ncdims
+ ncdim_t *ncdims = ndims ? (ncdim_t *) Malloc((size_t)ndims * sizeof(ncdim_t)) : NULL;
+ init_ncdims(ndims, ncdims);
- if ( ncvars[ncvarid].ndims == 1 )
- {
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
- ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
- }
- }
- else if ( strcmp(attname, "_FillValue") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
- ncvars[ncvarid].deffillval = TRUE;
- /* cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( strcmp(attname, "missing_value") == 0 && !xtypeIsText(atttype) )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
- ncvars[ncvarid].defmissval = TRUE;
- /* cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
- {
- if ( ncvars[ncvarid].lvalidrange == FALSE )
- {
- extern int cdiIgnoreValidRange;
- int lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
- if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
- ncvars[ncvarid].lvalidrange = TRUE;
- if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
- ncvars[ncvarid].lunsigned = TRUE;
- /* cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( lignore )
- {
- Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
- }
- }
- }
- else if ( strcmp(attname, "valid_min") == 0 && attlen == 1 )
- {
- if ( ncvars[ncvarid].lvalidrange == FALSE )
- {
- extern int cdiIgnoreValidRange;
- int lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
- if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
- ncvars[ncvarid].lvalidrange = TRUE;
- }
- else if ( lignore )
- {
- Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
- }
- }
- }
- else if ( strcmp(attname, "valid_max") == 0 && attlen == 1 )
+#if defined (TEST_GROUPS)
+#if defined (HAVE_NETCDF4)
+ if ( format == NC_FORMAT_NETCDF4 )
+ {
+ int ncid;
+ int numgrps;
+ int ncids[NC_MAX_VARS];
+ char name1[CDI_MAX_NAME];
+ int gndims, gnvars, gngatts, gunlimdimid;
+ nc_inq_grps(fileID, &numgrps, ncids);
+ for ( int i = 0; i < numgrps; ++i )
+ {
+ ncid = ncids[i];
+ nc_inq_grpname(ncid, name1);
+ cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
+
+ if ( CDI_Debug )
+ Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
+
+ if ( gndims == 0 )
{
- if ( ncvars[ncvarid].lvalidrange == FALSE )
- {
- extern int cdiIgnoreValidRange;
- int lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
- if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
- {
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
- ncvars[ncvarid].lvalidrange = TRUE;
- }
- else if ( lignore )
- {
- Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
- }
- }
}
- else if ( strcmp(attname, "_Unsigned") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- strtolower(attstring);
+ }
+ }
+#endif
+#endif
- if ( memcmp(attstring, "true", 4) == 0 )
- {
- ncvars[ncvarid].lunsigned = TRUE;
- /*
- ncvars[ncvarid].lvalidrange = TRUE;
- ncvars[ncvarid].validrange[0] = 0;
- ncvars[ncvarid].validrange[1] = 255;
- */
- }
- /* cdfSetVar(ncvars, ncvarid, TRUE); */
- }
- else if ( strcmp(attname, "cdi") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- strtolower(attstring);
+ if ( nvars == 0 )
+ {
+ Warning("No arrays found!");
+ return CDI_EUFSTRUCT;
+ }
- if ( memcmp(attstring, "ignore", 6) == 0 )
- {
- ncvars[ncvarid].ignore = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- }
- }
- else if ( strcmp(attname, "axis") == 0 && xtypeIsText(atttype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- attlen = strlen(attstring);
+ // alloc ncvars
+ ncvar_t *ncvars = nvars ? (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t)) : NULL;
+ init_ncvars(nvars, ncvars);
- if ( (int) attlen > nvdims && nvdims > 0 && attlen > 1 )
- {
- Warning("Unexpected axis attribute length for %s, ignored!", name);
- }
- else if ( nvdims == 0 && attlen == 1 )
- {
- if ( attstring[0] == 'z' || attstring[0] == 'Z' )
- {
- cdfSetVar(ncvars, ncvarid, FALSE);
- ncvars[ncvarid].islev = TRUE;
- }
- }
- else
- {
- strtolower(attstring);
- int i;
- for ( i = 0; i < (int)attlen; ++i )
- {
- if ( attstring[i] != '-' && attstring[i] != 't' && attstring[i] != 'z' &&
- attstring[i] != 'y' && attstring[i] != 'x' )
- {
- Warning("Unexpected character in axis attribute for %s, ignored!", name);
- break;
- }
- }
+ for ( ncvarid = 0; ncvarid < nvars; ++ncvarid ) ncvars[ncvarid].ncid = fileID;
- if ( i == (int) attlen && (int) attlen == nvdims )
- {
- while ( attlen-- )
- {
- if ( (int) attstring[attlen] == 't' )
- {
- if ( attlen != 0 ) Warning("axis attribute 't' not on first position");
- cdfSetDim(ncvars, ncvarid, (int)attlen, T_AXIS);
- }
- else if ( (int) attstring[attlen] == 'z' )
- {
- ncvars[ncvarid].zdim = dimidsp[attlen];
- cdfSetDim(ncvars, ncvarid, (int)attlen, Z_AXIS);
-
- if ( ncvars[ncvarid].ndims == 1 )
- {
- cdfSetVar(ncvars, ncvarid, FALSE);
- ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
- }
- }
- else if ( (int) attstring[attlen] == 'y' )
- {
- ncvars[ncvarid].ydim = dimidsp[attlen];
- cdfSetDim(ncvars, ncvarid, (int)attlen, Y_AXIS);
-
- if ( ncvars[ncvarid].ndims == 1 )
- {
- cdfSetVar(ncvars, ncvarid, FALSE);
- ncdims[ncvars[ncvarid].dimids[0]].dimtype = Y_AXIS;
- }
- }
- else if ( (int) attstring[attlen] == 'x' )
- {
- ncvars[ncvarid].xdim = dimidsp[attlen];
- cdfSetDim(ncvars, ncvarid, (int)attlen, X_AXIS);
-
- if ( ncvars[ncvarid].ndims == 1 )
- {
- cdfSetVar(ncvars, ncvarid, FALSE);
- ncdims[ncvars[ncvarid].dimids[0]].dimtype = X_AXIS;
- }
- }
- }
- }
- }
- }
- else if ( ( strcmp(attname, "realization") == 0 ) ||
- ( strcmp(attname, "ensemble_members") == 0 ) ||
- ( strcmp(attname, "forecast_init_type") == 0 ) )
- {
- int temp;
- if( ncvars[ncvarid].ensdata == NULL )
- ncvars[ncvarid].ensdata = (ensinfo_t *) Malloc( sizeof( ensinfo_t ) );
+ // scan global attributes
+ cdf_scan_global_attr(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les,
+ uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
+
+ // find time dim
+ int timedimid = (unlimdimid >= 0) ? unlimdimid : cdf_time_dimid(fileID, ndims, nvars);
+
+ streamptr->basetime.ncdimid = timedimid;
+
+ size_t ntsteps = 0;
+ if ( timedimid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, timedimid, &ntsteps);
+ if ( ntsteps > INT_MAX )
+ {
+ Warning("Size limit exceeded for time dimension (limit=%d)!", INT_MAX);
+ return CDI_EDIMSIZE;
+ }
+
+ if ( CDI_Debug ) Message("Number of timesteps = %zu", ntsteps);
+ if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
+
+ // read ncdims
+ for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ {
+ cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
+ cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name);
+ if ( timedimid == ncdimid )
+ ncdims[ncdimid].dimtype = T_AXIS;
+ }
+
+ if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_scan_var_attr");
- cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
+ // scan attributes of all variables
+ cdf_scan_var_attr(nvars, ncvars, ncdims, timedimid, modelID, format);
- if( strcmp(attname, "realization") == 0 )
- ncvars[ncvarid].ensdata->ens_index = temp;
- else if( strcmp(attname, "ensemble_members") == 0 )
- ncvars[ncvarid].ensdata->ens_count = temp;
- else if( strcmp(attname, "forecast_init_type") == 0 )
- ncvars[ncvarid].ensdata->forecast_init_type = temp;
- cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else
- {
- if ( ncvars[ncvarid].natts == 0 )
- ncvars[ncvarid].atts
- = (int *) Malloc((size_t)nvatts * sizeof (int));
+ if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "find coordinate vars");
- ncvars[ncvarid].atts[ncvars[ncvarid].natts++] = iatt;
- /*
- int attrint;
- double attrflt;
- nc_type attrtype;
- cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
- cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
- if ( attlen == 1 && (attrtype == NC_INT || attrtype == NC_SHORT) )
- {
- cdfGetAttInt(ncid, ncvarid, attname, 1, &attrint);
- printf("int: %s.%s = %d\n", ncvars[ncvarid].name, attname, attrint);
- }
- else if ( attlen == 1 && (attrtype == NC_FLOAT || attrtype == NC_DOUBLE) )
+ // find coordinate vars
+ for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ {
+ for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ {
+ if ( ncvars[ncvarid].ndims == 1 )
+ {
+ if ( timedimid != CDI_UNDEFID && timedimid == ncvars[ncvarid].dimids[0] )
{
- cdfGetAttDouble(ncid, ncvarid, attname, 1, &attrflt);
- printf("flt: %s.%s = %g\n", ncvars[ncvarid].name, attname, attrflt);
+ if ( ncvars[ncvarid].isvar != FALSE ) cdf_set_var(ncvars, ncvarid, TRUE);
}
- else if ( attrtype == NC_CHAR )
+ else
{
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- attstring[attlen] = 0;
- printf("txt: %s.%s = %s\n", ncvars[ncvarid].name, attname, attstring);
+ // if ( ncvars[ncvarid].isvar != TRUE ) cdf_set_var(ncvars, ncvarid, FALSE);
}
- else
- printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
- */
+ // if ( ncvars[ncvarid].isvar != TRUE ) cdf_set_var(ncvars, ncvarid, FALSE);
+
+ if ( ncdimid == ncvars[ncvarid].dimids[0] && ncdims[ncdimid].ncvarid == CDI_UNDEFID )
+ if ( strcmp(ncvars[ncvarid].name, ncdims[ncdimid].name) == 0 )
+ {
+ ncdims[ncdimid].ncvarid = ncvarid;
+ ncvars[ncvarid].isvar = FALSE;
+ }
}
}
}
- for ( int i = 0; i < max_check_vars; ++i ) if ( checked_vars[i] ) Free(checked_vars[i]);
-}
-
-static
-void setDimType(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
-{
- int ndims;
- int ncvarid, ncdimid;
- int i;
-
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- {
- if ( ncvars[ncvarid].isvar == TRUE )
- {
- int lxdim = 0, lydim = 0, lzdim = 0/* , ltdim = 0 */;
- ndims = ncvars[ncvarid].ndims;
- for ( i = 0; i < ndims; i++ )
- {
- ncdimid = ncvars[ncvarid].dimids[i];
- if ( ncdims[ncdimid].dimtype == X_AXIS ) cdfSetDim(ncvars, ncvarid, i, X_AXIS);
- else if ( ncdims[ncdimid].dimtype == Y_AXIS ) cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
- else if ( ncdims[ncdimid].dimtype == Z_AXIS ) cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
- else if ( ncdims[ncdimid].dimtype == T_AXIS ) cdfSetDim(ncvars, ncvarid, i, T_AXIS);
- }
+ // find time vars
+ find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
- if ( CDI_Debug )
- {
- Message("var %d %s", ncvarid, ncvars[ncvarid].name);
- for ( i = 0; i < ndims; i++ )
- printf(" dim%d type=%d ", i, ncvars[ncvarid].dimtype[i]);
- printf("\n");
- }
+ leadtime_id = find_leadtime(nvars, ncvars);
+ if ( leadtime_id != CDI_UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
- for ( i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) lxdim = TRUE;
- else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) lydim = TRUE;
- else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) lzdim = TRUE;
- /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = TRUE; */
- }
+ // check ncvars
+ timedimid = cdf_check_vars(nvars, ncvars, ntsteps, timedimid);
- if ( lxdim == FALSE && ncvars[ncvarid].xvarid != UNDEFID )
- {
- if ( ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = TRUE;
- }
+ // verify coordinate vars - first scan (dimname == varname)
+ bool lhybrid_cf = false;
+ verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid, &lhybrid_cf);
- if ( lydim == FALSE && ncvars[ncvarid].yvarid != UNDEFID )
- {
- if ( ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = TRUE;
- }
+ // verify coordinate vars - second scan (all other variables)
+ verify_coordinate_vars_2(nvars, ncvars);
- // if ( ndims > 1 )
- for ( i = ndims-1; i >= 0; i-- )
- {
- if ( ncvars[ncvarid].dimtype[i] == -1 )
- {
- if ( lxdim == FALSE )
- {
- cdfSetDim(ncvars, ncvarid, i, X_AXIS);
- lxdim = TRUE;
- }
- else if ( lydim == FALSE && ncvars[ncvarid].gridtype != GRID_UNSTRUCTURED )
- {
- cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
- lydim = TRUE;
- }
- else if ( lzdim == FALSE )
- {
- cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
- lzdim = TRUE;
- }
- }
- }
- }
- }
-}
+ if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "verify_coordinate_vars");
-/* verify coordinate vars - first scan (dimname == varname) */
-static
-void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid)
-{
- int ncdimid, ncvarid;
+ if ( ucla_les ) cdf_set_ucla_dimtype(ndims, ncdims, ncvars);
+ /*
for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
{
ncvarid = ncdims[ncdimid].ncvarid;
if ( ncvarid != -1 )
{
- if ( ncvars[ncvarid].dimids[0] == timedimid )
- {
- ncvars[ncvarid].istime = TRUE;
- ncdims[ncdimid].dimtype = T_AXIS;
- continue;
- }
-
- if ( isHybridSigmaPressureCoordinate(ncid, ncvarid, ncvars, ncdims) ) continue;
-
- if ( ncvars[ncvarid].units[0] != 0 )
- {
- if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
- {
- ncvars[ncvarid].islon = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
- ncdims[ncdimid].dimtype = X_AXIS;
- }
- else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
- {
- ncvars[ncvarid].islat = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
- ncdims[ncdimid].dimtype = Y_AXIS;
- }
- else if ( unitsIsPressure(ncvars[ncvarid].units) )
- {
- ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
- }
- else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
- {
- if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
- else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
- else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
- else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
- else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
- }
- else if ( isDBLAxis(ncvars[ncvarid].longname) )
- {
- ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
- }
- else if ( unitsIsHeight(ncvars[ncvarid].units) )
- {
- if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
- ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
- else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
- ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
- }
- }
- else
- {
- if ( (strcmp(ncvars[ncvarid].longname, "generalized_height") == 0 ||
- strcmp(ncvars[ncvarid].longname, "generalized height") == 0) &&
- strcmp(ncvars[ncvarid].stdname, "height") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_REFERENCE;
- }
-
- if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
- ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
- {
- if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
- {
- ncvars[ncvarid].islon = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
- ncdims[ncdimid].dimtype = X_AXIS;
- continue;
- }
- else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
- {
- ncvars[ncvarid].islat = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
- ncdims[ncdimid].dimtype = Y_AXIS;
- continue;
- }
- }
+ printf("coord var %d %s %s\n", ncvarid, ncvars[ncvarid].name, ncvars[ncvarid].units);
+ if ( ncdims[ncdimid].dimtype == X_AXIS )
+ printf("coord var %d %s is x dim\n", ncvarid, ncvars[ncvarid].name);
+ if ( ncdims[ncdimid].dimtype == Y_AXIS )
+ printf("coord var %d %s is y dim\n", ncvarid, ncvars[ncvarid].name);
+ if ( ncdims[ncdimid].dimtype == Z_AXIS )
+ printf("coord var %d %s is z dim\n", ncvarid, ncvars[ncvarid].name);
+ if ( ncdims[ncdimid].dimtype == T_AXIS )
+ printf("coord var %d %s is t dim\n", ncvarid, ncvars[ncvarid].name);
- if ( ncvars[ncvarid].zaxistype != UNDEFID )
- {
- ncvars[ncvarid].islev = TRUE;
- cdfSetVar(ncvars, ncvarid, FALSE);
- cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
- ncdims[ncdimid].dimtype = Z_AXIS;
- }
+ if ( ncvars[ncvarid].islon )
+ printf("coord var %d %s is lon\n", ncvarid, ncvars[ncvarid].name);
+ if ( ncvars[ncvarid].islat )
+ printf("coord var %d %s is lat\n", ncvarid, ncvars[ncvarid].name);
+ if ( ncvars[ncvarid].islev )
+ printf("coord var %d %s is lev\n", ncvarid, ncvars[ncvarid].name);
}
}
-}
-
-/* verify coordinate vars - second scan (all other variables) */
-static
-void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
-{
- int ncvarid;
+ */
+ // Set coordinate varids (att: associate)
for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
{
- if ( ncvars[ncvarid].isvar == 0 )
+ ncvar_t *ncvar = &ncvars[ncvarid];
+ if ( ncvar->isvar == TRUE && ncvar->ncoordvars )
{
- if ( ncvars[ncvarid].units[0] != 0 )
- {
- if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
- {
- ncvars[ncvarid].islon = TRUE;
- continue;
- }
- else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
- {
- ncvars[ncvarid].islat = TRUE;
- continue;
- }
- else if ( unitsIsPressure(ncvars[ncvarid].units) )
- {
- ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
- continue;
- }
- else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
- {
- if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
- else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
- else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
- else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
- else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
- ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
- continue;
- }
- else if ( isDBLAxis(ncvars[ncvarid].longname) )
- {
- ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
- continue;
- }
- else if ( unitsIsHeight(ncvars[ncvarid].units) )
- {
- if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
- ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
- else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
- ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
- continue;
- }
- }
-
- /* not needed anymore for rotated grids */
- if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
- ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
+ int ncoordvars = ncvar->ncoordvars;
+ for ( int i = 0; i < ncoordvars; i++ )
{
- if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
- {
- ncvars[ncvarid].islon = TRUE;
- continue;
- }
- else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
- {
- ncvars[ncvarid].islat = TRUE;
- continue;
- }
+ if ( ncvars[ncvar->coordvarids[i]].islon ||
+ ncvars[ncvar->coordvarids[i]].isx ) ncvar->xvarid = ncvar->coordvarids[i];
+ else if ( ncvars[ncvar->coordvarids[i]].islat ||
+ ncvars[ncvar->coordvarids[i]].isy ) ncvar->yvarid = ncvar->coordvarids[i];
+ else if ( ncvars[ncvar->coordvarids[i]].islev ) ncvar->zvarid = ncvar->coordvarids[i];
+ else if ( ncvars[ncvar->coordvarids[i]].isc ) ncvar->cvarids[i] = ncvar->coordvarids[i];
}
}
}
-}
-#if defined (PROJECTION_TEST)
-static
-void copy_numeric_projatts(int gridID, int ncvarID, int ncfileID)
-{
- int iatt, nvatts;
- size_t attlen;
- char attname[CDI_MAX_NAME];
- nc_type xtype;
+ // set dim type
+ cdf_set_dimtype(nvars, ncvars, ncdims);
- cdf_inq_varnatts(ncfileID, ncvarID, &nvatts);
+ // read ECHAM VCT if present
+ size_t vctsize = 0;
+ double *vct = NULL;
+ if ( !lhybrid_cf ) read_vct_echam(fileID, nvars, ncvars, ncdims, &vct, &vctsize);
- for ( iatt = 0; iatt < nvatts; iatt++ )
- {
- cdf_inq_attname(ncfileID, ncvarID, iatt, attname);
- cdf_inq_atttype(ncfileID, ncvarID, attname, &xtype);
- cdf_inq_attlen(ncfileID, ncvarID, attname, &attlen);
- // printf("%s %d\n", attname, (int)attlen);
+ if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_define_all_grids");
+
+ // define all grids
+ int status;
+ status = cdf_define_all_grids(streamptr->ncgrid, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
+ if ( status < 0 ) return status;
+
+ // define all zaxes
+ status = cdf_define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
+ if ( vct ) Free(vct);
+ if ( status < 0 ) return status;
+
+
+ // select vars
+ varids = (int *) Malloc((size_t)nvars * sizeof (int));
+ nvarids = 0;
+ for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
+
+ nvars_data = nvarids;
+
+ if ( CDI_Debug ) Message("time varid = %d", streamptr->basetime.ncvarid);
+ if ( CDI_Debug ) Message("ntsteps = %zu", ntsteps);
+ if ( CDI_Debug ) Message("nvars_data = %d", nvars_data);
+
+
+ if ( nvars_data == 0 )
+ {
+ streamptr->ntsteps = 0;
+ return CDI_EUFSTRUCT;
}
-}
-#endif
+ if ( ntsteps == 0 && streamptr->basetime.ncdimid == CDI_UNDEFID && streamptr->basetime.ncvarid != CDI_UNDEFID )
+ ntsteps = 1;
-static
-void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
-{
- if ( ncvar->chunked )
+ streamptr->ntsteps = (long)ntsteps;
+
+ // define all data variables
+ cdf_define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
+
+
+ cdiCreateTimesteps(streamptr);
+
+ // time varID
+ int nctimevarid = streamptr->basetime.ncvarid;
+
+ if ( time_has_units )
{
- int ndims = ncvar->ndims;
+ taxis_t *taxis = &streamptr->tsteps[0].taxis;
- if ( grid->type == GRID_UNSTRUCTURED )
+ if ( setBaseTime(ncvars[nctimevarid].units, taxis) == 1 )
{
- if ( ncvar->chunks[ndims-1] == grid->size )
- ncvar->chunktype = CHUNK_GRID;
- else
- ncvar->chunktype = CHUNK_AUTO;
+ nctimevarid = CDI_UNDEFID;
+ streamptr->basetime.ncvarid = CDI_UNDEFID;
}
- else
+
+ if ( leadtime_id != CDI_UNDEFID && taxis->type == TAXIS_RELATIVE )
{
- if ( grid->xsize > 1 && grid->ysize > 1 && ndims > 1 &&
- grid->xsize == ncvar->chunks[ndims-1] &&
- grid->ysize == ncvar->chunks[ndims-2] )
- ncvar->chunktype = CHUNK_GRID;
- else if ( grid->xsize > 1 && grid->xsize == ncvar->chunks[ndims-1] )
- ncvar->chunktype = CHUNK_LINES;
- else
- ncvar->chunktype = CHUNK_AUTO;
+ streamptr->basetime.leadtimeid = leadtime_id;
+ taxis->type = TAXIS_FORECAST;
+
+ int timeunit = -1;
+ if ( ncvars[leadtime_id].units[0] != 0 ) timeunit = scanTimeUnit(ncvars[leadtime_id].units);
+ if ( timeunit == -1 ) timeunit = taxis->unit;
+ taxis->fc_unit = timeunit;
+
+ setForecastTime(fcreftime, taxis);
}
}
-}
-static struct gridVirtTable cdfLazyGridVtable;
-static double *cdfPendingLoad;
-#ifdef HAVE_LIBPTHREAD
-static pthread_once_t cdfLazyInitialized = PTHREAD_ONCE_INIT;
-#else
-static bool cdfLazyInitialized;
-#endif
+ if ( time_has_bounds )
+ {
+ streamptr->tsteps[0].taxis.has_bounds = true;
+ if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = true;
+ }
-struct cdfLazyGrid
-{
- grid_t base;
- const struct gridVirtTable *baseVtable;
- struct {
- int datasetNCId, varNCId;
- } cellAreaGet, xBoundsGet, yBoundsGet;
- struct xyValGet {
- double scalefactor, addoffset;
- size_t start[3], count[3], size, dimsize;
- int datasetNCId, varNCId;
- short ndims;
- } xValsGet, yValsGet;
-#ifdef HAVE_LIBPTHREAD
- pthread_mutex_t loadSerialize;
-#endif
-};
+ if ( nctimevarid != CDI_UNDEFID )
+ {
+ taxis_t *taxis = &streamptr->tsteps[0].taxis;
+ ptaxisDefName(taxis, ncvars[nctimevarid].name);
-#ifdef HAVE_LIBPTHREAD
-#define lock_lazy_load(plGrid) pthread_mutex_lock(&((plGrid)->loadSerialize))
-#define unlock_lazy_load(plGrid) pthread_mutex_unlock(&((plGrid)->loadSerialize))
-#define destroy_lazy_load_lock(plGrid) pthread_mutex_destroy(&((plGrid)->loadSerialize))
-#define init_lazy_load_lock(plGrid) pthread_mutex_init(&((plGrid)->loadSerialize), NULL)
-#else
-#define lock_lazy_load(plGrid)
-#define unlock_lazy_load(plGrid)
-#define destroy_lazy_load_lock(plGrid)
-#define init_lazy_load_lock(plGrid)
+ if ( ncvars[nctimevarid].longname[0] )
+ ptaxisDefLongname(taxis, ncvars[nctimevarid].longname);
+
+ if ( ncvars[nctimevarid].units[0] )
+ ptaxisDefUnits(taxis, ncvars[nctimevarid].units);
+
+ int datatype = (ncvars[nctimevarid].xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
+ ptaxisDefDatatype(taxis, datatype);
+ }
+
+ if ( nctimevarid != CDI_UNDEFID )
+ if ( ncvars[nctimevarid].calendar == true )
+ {
+ char attstring[1024];
+ cdfGetAttText(fileID, nctimevarid, "calendar", sizeof(attstring), attstring);
+ str_tolower(attstring);
+ set_calendar(attstring, &calendar);
+ }
+
+ int taxisID;
+ if ( streamptr->tsteps[0].taxis.type == TAXIS_FORECAST )
+ {
+ taxisID = taxisCreate(TAXIS_FORECAST);
+ }
+ else if ( streamptr->tsteps[0].taxis.type == TAXIS_RELATIVE )
+ {
+ taxisID = taxisCreate(TAXIS_RELATIVE);
+ }
+ else
+ {
+ taxisID = taxisCreate(TAXIS_ABSOLUTE);
+ if ( !time_has_units )
+ {
+ taxisDefTunit(taxisID, TUNIT_DAY);
+ streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
+ }
+ }
+
+
+ if ( calendar == CDI_UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
+ {
+ calendar = CALENDAR_STANDARD;
+ }
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstrict-overflow"
+#endif
+ if ( calendar != CDI_UNDEFID )
+ {
+ taxis_t *taxis = &streamptr->tsteps[0].taxis;
+ taxis->calendar = calendar;
+ taxisDefCalendar(taxisID, calendar);
+ }
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic pop
#endif
-static void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid)
-{
- lazyGrid->base.extraData = NULL;
- if (lazyGrid->base.area == cdfPendingLoad)
- lazyGrid->base.area = NULL;
- if (lazyGrid->base.xvals == cdfPendingLoad)
- lazyGrid->base.xvals = NULL;
- if (lazyGrid->base.yvals == cdfPendingLoad)
- lazyGrid->base.yvals = NULL;
- if (lazyGrid->base.xbounds == cdfPendingLoad)
- lazyGrid->base.xbounds = NULL;
- if (lazyGrid->base.ybounds == cdfPendingLoad)
- lazyGrid->base.ybounds = NULL;
- destroy_lazy_load_lock(lazyGrid);
-}
+ vlistDefTaxis(vlistID, taxisID);
-static void cdfLazyGridDelete(grid_t *grid)
-{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- void (*baseDestroy)(grid_t *grid) = cdfGrid->baseVtable->destroy;
- cdfLazyGridDestroy(cdfGrid);
- baseDestroy(grid);
+ streamptr->curTsID = 0;
+ streamptr->rtsteps = 1;
+
+ (void) cdfInqTimestep(streamptr, 0);
+
+ cdfCreateRecords(streamptr, 0);
+
+ // free ncdims
+ if ( ncdims ) Free(ncdims);
+
+ // free ncvars
+ if ( ncvars ) Free(ncvars);
+
+ return 0;
}
-static void cdfLazyGridDestroyOnce(void)
+static
+void wrf_read_timestep(int fileID, int nctimevarid, int tsID, taxis_t *taxis)
{
- /*
-#ifdef HAVE_MMAP
- size_t pgSize = cdiGetPageSize(false);
- munmap(cdfPendingLoad, pgSize);
-#endif
- */
+ size_t start[2], count[2];
+ char stvalue[32];
+ start[0] = (size_t) tsID; start[1] = 0;
+ count[0] = 1; count[1] = 19;
+ stvalue[0] = 0;
+ cdf_get_vara_text(fileID, nctimevarid, start, count, stvalue);
+ stvalue[19] = 0;
+ {
+ int year = 1, month = 1, day = 1 , hour = 0, minute = 0, second = 0;
+ if ( strlen(stvalue) == 19 )
+ sscanf(stvalue, "%d-%d-%d_%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
+ taxis->vdate = cdiEncodeDate(year, month, day);
+ taxis->vtime = cdiEncodeTime(hour, minute, second);
+ taxis->type = TAXIS_ABSOLUTE;
+ }
}
-static void
-cdfLazyGridDefArea(grid_t *grid, const double *area)
+static
+double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(cdfGrid);
- if (grid->area == cdfPendingLoad)
- grid->area = NULL;
- cdfGrid->cellAreaGet.datasetNCId = -1;
- cdfGrid->cellAreaGet.varNCId = -1;
- cdfGrid->baseVtable->defArea(grid, area);
- unlock_lazy_load(cdfGrid);
+ double timevalue = 0;
+
+ if ( tcache )
+ {
+ if ( tcache->size == 0 || (tsID < tcache->startid || tsID > (tcache->startid+tcache->size-1)) )
+ {
+ int maxvals = MAX_TIMECACHE_SIZE;
+ tcache->startid = (tsID/MAX_TIMECACHE_SIZE)*MAX_TIMECACHE_SIZE;
+ if ( (tcache->startid + maxvals) > tcache->maxvals ) maxvals = (tcache->maxvals)%MAX_TIMECACHE_SIZE;
+ tcache->size = maxvals;
+ size_t index = (size_t) tcache->startid;
+ // fprintf(stderr, "fill time cache: %d %d %d %d %d\n", tcache->maxvals, tsID, tcache->startid, tcache->startid+maxvals-1, maxvals);
+ for ( int ival = 0; ival < maxvals; ++ival )
+ {
+ cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
+ if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+ tcache->cache[ival] = timevalue;
+ index++;
+ }
+ }
+
+ timevalue = tcache->cache[tsID%MAX_TIMECACHE_SIZE];
+ }
+ else
+ {
+ size_t index = (size_t) tsID;
+ cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
+ if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+ }
+
+ return timevalue;
}
-static const double *
-cdfLazyGridInqAreaPtr(grid_t *grid)
+int cdfInqTimestep(stream_t * streamptr, int tsID)
{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- if (grid->area == cdfPendingLoad)
+ if ( CDI_Debug ) Message("streamID = %d tsID = %d", streamptr->self, tsID);
+
+ if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
+
+ if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
{
- grid->area = (double *)Malloc((size_t)grid->size * sizeof(double));
- cdf_get_var_double(lazyGrid->cellAreaGet.datasetNCId,
- lazyGrid->cellAreaGet.varNCId, grid->area);
+ cdfCreateRecords(streamptr, tsID);
+
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+ if ( tsID > 0 )
+ ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
+
+ double timevalue = tsID;
+
+ int nctimevarid = streamptr->basetime.ncvarid;
+ if ( nctimevarid != CDI_UNDEFID )
+ {
+ int fileID = streamptr->fileID;
+ size_t index = (size_t)tsID;
+
+ if ( streamptr->basetime.lwrf )
+ {
+ wrf_read_timestep(fileID, nctimevarid, tsID, taxis);
+ }
+ else
+ {
+#if defined (USE_TIMECACHE)
+ if ( streamptr->basetime.timevar_cache == NULL )
+ {
+ streamptr->basetime.timevar_cache = (timecache_t *) Malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t));
+ streamptr->basetime.timevar_cache->size = 0;
+ streamptr->basetime.timevar_cache->maxvals = streamptr->ntsteps;
+ }
+#endif
+ timevalue = get_timevalue(fileID, nctimevarid, tsID, streamptr->basetime.timevar_cache);
+ cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
+ }
+
+ int nctimeboundsid = streamptr->basetime.ncvarboundsid;
+ if ( nctimeboundsid != CDI_UNDEFID )
+ {
+ size_t start[2], count[2];
+ start[0] = index; count[0] = 1; start[1] = 0; count[1] = 1;
+ cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
+ if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+
+ cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
+
+ start[0] = index; count[0] = 1; start[1] = 1; count[1] = 1;
+ cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
+ if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+
+ cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
+ }
+
+ int leadtimeid = streamptr->basetime.leadtimeid;
+ if ( leadtimeid != CDI_UNDEFID )
+ {
+ timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
+ cdiSetForecastPeriod(timevalue, taxis);
+ }
+ }
}
- unlock_lazy_load(lazyGrid);
- return lazyGrid->baseVtable->inqAreaPtr(grid);
-}
-static void
-cdfLazyGridInqArea(grid_t *grid, double *area)
-{
- grid->vtable->inqAreaPtr(grid);
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lazyGrid->baseVtable->inqArea(grid, area);
+ streamptr->curTsID = tsID;
+ long nrecs = streamptr->tsteps[tsID].nrecs;
+
+ return (int) nrecs;
}
-static void
-cdfLazyLoadXYVals(struct xyValGet *valsGet, double **valsp)
+int cdfInqHistorySize(stream_t *streamptr)
{
- double *grid_vals
- = (double *)Malloc(valsGet->size * sizeof (double));
- *valsp = grid_vals;
- if ( valsGet->ndims == 3 )
- cdf_get_vara_double(valsGet->datasetNCId, valsGet->varNCId,
- valsGet->start, valsGet->count, grid_vals);
- else
- cdf_get_var_double(valsGet->datasetNCId, valsGet->varNCId, grid_vals);
- scale_add(valsGet->size, grid_vals, valsGet->addoffset, valsGet->scalefactor);
-}
+ size_t size = 0;
+ int ncid = streamptr->fileID;
+ if ( streamptr->historyID != CDI_UNDEFID )
+ cdf_inq_attlen(ncid, NC_GLOBAL, "history", &size);
-static const double *
-cdfLazyGridInqXValsPtr(grid_t *grid)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- if (grid->xvals == cdfPendingLoad)
- cdfLazyLoadXYVals(&lazyGrid->xValsGet, &grid->xvals);
- unlock_lazy_load(lazyGrid);
- return lazyGrid->baseVtable->inqXValsPtr(grid);
+ return (int) size;
}
-static const double *
-cdfLazyGridInqYValsPtr(grid_t *grid)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- if (grid->yvals == cdfPendingLoad)
- cdfLazyLoadXYVals(&lazyGrid->yValsGet, &grid->yvals);
- unlock_lazy_load(lazyGrid);
- return lazyGrid->baseVtable->inqYValsPtr(grid);
-}
-static double
-cdfLazyGridInqXYVal(grid_t *grid, size_t index,
- const struct xyValGet *valsGet, double *vals,
- const double *(*inqValsPtr)(grid_t *gridptr))
+void cdfInqHistoryString(stream_t *streamptr, char *history)
{
- size_t size = valsGet->size;
- double v;
- if ( vals == cdfPendingLoad )
+ int ncid = streamptr->fileID;
+ if ( streamptr->historyID != CDI_UNDEFID )
{
- /* prevent full load if only first/last values get inspected */
- if ( index == 0 || index == size - 1 )
+ nc_type atttype;
+ cdf_inq_atttype(ncid, NC_GLOBAL, "history", &atttype);
+
+ if ( atttype == NC_CHAR )
{
- size_t indexND[3];
- if ( valsGet->ndims == 3 )
- {
- indexND[0] = 0;
- indexND[1] = index / valsGet->count[2];
- indexND[2] = index % valsGet->count[2];
- }
- else if ( valsGet->ndims == 2)
- {
- indexND[0] = index / (size_t)grid->xsize;
- indexND[1] = index % (size_t)grid->xsize;
- }
- else
- indexND[0] = index;
- cdf_get_var1_double(valsGet->datasetNCId, valsGet->varNCId,
- indexND, &v);
+ cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
}
- else
+#if defined (HAVE_NETCDF4)
+ else if ( atttype == NC_STRING )
{
- const double *grid_vals = inqValsPtr(grid);
- v = grid_vals[index];
+ // ToDo
+ Warning("History attribute with type NC_STRING unsupported!");
}
+#endif
}
- else if ( vals )
- v = vals[index];
- else
- v = 0.0;
- return v;
}
-static void
-cdfLazyGridDefXVals(grid_t *grid, const double *vals)
-{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(cdfGrid);
- if (grid->xvals == cdfPendingLoad)
- grid->xvals = NULL;
- cdfGrid->xValsGet.datasetNCId = -1;
- cdfGrid->xValsGet.varNCId = -1;
- cdfGrid->baseVtable->defXVals(grid, vals);
- unlock_lazy_load(cdfGrid);
-}
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
-static void
-cdfLazyGridDefYVals(grid_t *grid, const double *vals)
-{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(cdfGrid);
- if (grid->yvals == cdfPendingLoad)
- grid->yvals = NULL;
- cdfGrid->yValsGet.datasetNCId = -1;
- cdfGrid->yValsGet.varNCId = -1;
- cdfGrid->baseVtable->defYVals(grid, vals);
- unlock_lazy_load(cdfGrid);
-}
+#ifdef HAVE_LIBNETCDF
-static double
-cdfLazyGridInqXVal(grid_t *grid, int index)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->xValsGet,
- grid->xvals, grid->vtable->inqXValsPtr);
- unlock_lazy_load(lazyGrid);
- return rv;
-}
-static double
-cdfLazyGridInqYVal(grid_t *grid, int index)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->yValsGet,
- grid->yvals, grid->vtable->inqYValsPtr);
- unlock_lazy_load(lazyGrid);
- return rv;
-}
-static bool
-cdfLazyXYValGetCompare(struct cdfLazyGrid *lazyGridRef,
- struct cdfLazyGrid *lazyGridTest)
+#define POSITIVE_UP 1
+#define POSITIVE_DOWN 2
+
+
+static const char bndsName[] = "bnds";
+
+
+void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
{
- struct xyValGet *valsGetXRef = &lazyGridRef->xValsGet,
- *valsGetYRef = &lazyGridRef->yValsGet,
- *valsGetXTest = &lazyGridTest->xValsGet,
- *valsGetYTest = &lazyGridTest->yValsGet;
- if (valsGetXRef->datasetNCId == -1
- || valsGetXTest->datasetNCId == -1
- || valsGetYRef->datasetNCId == -1
- || valsGetYTest->datasetNCId == -1)
- return lazyGridRef->baseVtable->compareXYFull(&lazyGridRef->base,
- &lazyGridTest->base);
- return valsGetXRef->datasetNCId != valsGetXTest->datasetNCId
- || valsGetXRef->varNCId != valsGetXTest->varNCId
- || valsGetYRef->datasetNCId != valsGetYTest->datasetNCId
- || valsGetYRef->varNCId != valsGetYTest->varNCId;
+ int vlistID1 = streamptr1->vlistID;
+ int tsID = streamptr1->curTsID;
+ int vrecID = streamptr1->tsteps[tsID].curRecID;
+ int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
+ int ivarID = streamptr1->tsteps[tsID].records[recID].varID;
+ int gridID = vlistInqVarGrid(vlistID1, ivarID);
+ size_t datasize = gridInqSize(gridID);
+ int datatype = vlistInqVarDatatype(vlistID1, ivarID);
+ int memtype = datatype != CDI_DATATYPE_FLT32 ? MEMTYPE_DOUBLE : MEMTYPE_FLOAT;
+
+ void *data = Malloc(datasize * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
+
+ size_t nmiss;
+ cdf_read_record(streamptr1, memtype, data, &nmiss);
+ cdf_write_record(streamptr2, memtype, data, nmiss);
+
+ Free(data);
}
-static bool
-cdfLazyCompareXYFull(grid_t *gridRef, grid_t *gridTest)
+
+void cdfDefRecord(stream_t *streamptr)
{
- bool diff;
- struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
- if (gridTest->vtable == &cdfLazyGridVtable)
- diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
- else
- diff = lazyGridRef->baseVtable->compareXYFull(gridRef, gridTest);
- return diff;
+ (void)streamptr;
}
-static bool
-cdfLazyCompareXYAO(grid_t *gridRef, grid_t *gridTest)
+static
+void cdfDefTimeValue(stream_t *streamptr, int tsID)
{
- bool diff;
- struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
- if (gridTest->vtable == &cdfLazyGridVtable)
- diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
- else
- diff = lazyGridRef->baseVtable->compareXYAO(gridRef, gridTest);
- return diff;
-}
+ int fileID = streamptr->fileID;
+
+ if ( CDI_Debug )
+ Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
-static const double *
-cdfLazyGridInqXBoundsPtr(grid_t *grid)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- if (grid->xbounds == cdfPendingLoad)
+ if ( streamptr->ncmode == 1 )
{
- grid->xbounds = (double *)Malloc((size_t)grid->nvertex
- * (size_t)grid->size * sizeof(double));
- cdf_get_var_double(lazyGrid->xBoundsGet.datasetNCId,
- lazyGrid->xBoundsGet.varNCId, grid->xbounds);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
}
- unlock_lazy_load(lazyGrid);
- return lazyGrid->baseVtable->inqXBoundsPtr(grid);
-}
-static void
-cdfLazyGridDefXBounds(grid_t *grid, const double *xbounds)
-{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(cdfGrid);
- if (grid->xbounds == cdfPendingLoad)
- grid->xbounds = NULL;
- cdfGrid->xBoundsGet.datasetNCId = -1;
- cdfGrid->xBoundsGet.varNCId = -1;
- cdfGrid->baseVtable->defXBounds(grid, xbounds);
- unlock_lazy_load(cdfGrid);
-}
+ double timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
+ if ( CDI_Debug ) Message("tsID = %d timevalue = %f", tsID, timevalue);
-static void
-cdfLazyGridDefYBounds(grid_t *grid, const double *ybounds)
-{
- struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(cdfGrid);
- if (grid->ybounds == cdfPendingLoad)
- grid->ybounds = NULL;
- cdfGrid->yBoundsGet.datasetNCId = -1;
- cdfGrid->yBoundsGet.varNCId = -1;
- cdfGrid->baseVtable->defYBounds(grid, ybounds);
- unlock_lazy_load(cdfGrid);
-}
+ int ncvarid = streamptr->basetime.ncvarid;
+ size_t index = (size_t)tsID;
+ cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
-static const double *
-cdfLazyGridInqYBoundsPtr(grid_t *grid)
-{
- struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
- lock_lazy_load(lazyGrid);
- if (grid->ybounds == cdfPendingLoad)
+ if ( taxis->has_bounds )
{
- grid->ybounds = (double *)Malloc((size_t)grid->nvertex
- * (size_t)grid->size * sizeof(double));
- cdf_get_var_double(lazyGrid->yBoundsGet.datasetNCId,
- lazyGrid->yBoundsGet.varNCId, grid->ybounds);
+ ncvarid = streamptr->basetime.ncvarboundsid;
+ if ( ncvarid == CDI_UNDEFID ) Error("Call to taxisWithBounds() missing!");
+
+ timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
+ size_t start[2], count[2];
+ start[0] = (size_t)tsID; count[0] = 1; start[1] = 0; count[1] = 1;
+ cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+
+ timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
+ start[0] = (size_t)tsID; count[0] = 1; start[1] = 1; count[1] = 1;
+ cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+ }
+
+ ncvarid = streamptr->basetime.leadtimeid;
+ if ( taxis->type == TAXIS_FORECAST && ncvarid != CDI_UNDEFID )
+ {
+ timevalue = taxis->fc_period;
+ cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
}
- unlock_lazy_load(lazyGrid);
- return lazyGrid->baseVtable->inqYBoundsPtr(grid);
}
-static void
-cdfLazyGridCopyScalarFields(grid_t *gridptrOrig, grid_t *gridptrDup)
+void cdfDefTimestep(stream_t *streamptr, int tsID)
{
- struct cdfLazyGrid *lazyGridDup = (struct cdfLazyGrid *)gridptrDup,
- *lazyGridOrig = (struct cdfLazyGrid *)gridptrOrig;
- lazyGridOrig->baseVtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
- lazyGridDup->baseVtable = lazyGridOrig->baseVtable;
- lazyGridDup->cellAreaGet = lazyGridOrig->cellAreaGet;
- lazyGridDup->xBoundsGet = lazyGridOrig->xBoundsGet;
- lazyGridDup->yBoundsGet = lazyGridOrig->yBoundsGet;
- lazyGridDup->xValsGet = lazyGridOrig->xValsGet;
- lazyGridDup->yValsGet = lazyGridOrig->yValsGet;
- init_lazy_load_lock(lazyGridDup);
+ cdfDefTimeValue(streamptr, tsID);
}
-static void
-cdfLazyGridCopyArrayFields(grid_t *gridptrOrig, grid_t *gridptrDup)
+static
+void cdfDefComplex(stream_t *streamptr, int gridID, int gridindex)
{
- size_t nrowlon = (size_t)gridptrOrig->nrowlon;
- size_t gridsize = (size_t)gridptrOrig->size;
- int gridtype = gridptrOrig->type;
- int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
- if ( nrowlon )
+ int dimID;
+ ncgrid_t *ncgrid = streamptr->ncgrid;
+
+ for ( int index = 0; index < gridindex; ++index )
{
- gridptrDup->rowlon = (int *)Malloc(nrowlon * sizeof (int));
- memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
+ if ( ncgrid[index].ncIDs[CDF_DIMID_X] != CDI_UNDEFID )
+ {
+ int gridID0 = ncgrid[index].gridID;
+ int gridtype0 = gridInqType(gridID0);
+ if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
+ {
+ dimID = ncgrid[index].ncIDs[CDF_DIMID_X];
+ goto dimIDEstablished;
+ }
+ }
}
- if ( gridptrOrig->xvals != NULL && gridptrOrig->xvals != cdfPendingLoad )
- {
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->xsize;
+ {
+ static const char axisname[] = "nc2";
+ size_t dimlen = 2;
+ int fileID = streamptr->fileID;
+
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ cdf_def_dim(fileID, axisname, dimlen, &dimID);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
+ }
+ dimIDEstablished:
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+}
- gridptrDup->xvals = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->xvals, gridptrOrig->xvals, size * sizeof (double));
- }
+struct idSearch
+{
+ int numNonMatching, foundID;
+ size_t foundIdx;
+};
- if ( gridptrOrig->yvals != NULL && gridptrOrig->yvals != cdfPendingLoad )
+static inline struct idSearch
+cdfSearchIDBySize(size_t startIdx, size_t numIDs, const ncgrid_t ncgrid[numIDs],
+ int ncIDType, int searchType, int searchSize,
+ int (*typeInq)(int id), size_t (*sizeInq)(int id))
+{
+ int numNonMatching = 0,
+ foundID = CDI_UNDEFID;
+ size_t foundIdx = SIZE_MAX;
+ for ( size_t index = startIdx; index < numIDs; index++ )
{
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->ysize;
-
- gridptrDup->yvals = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->yvals, gridptrOrig->yvals, size * sizeof (double));
+ if ( ncgrid[index].ncIDs[ncIDType] != CDI_UNDEFID )
+ {
+ int id0 = ncgrid[index].gridID,
+ id0Type = typeInq(id0);
+ if ( id0Type == searchType )
+ {
+ int size0 = sizeInq(id0);
+ if ( searchSize == size0 )
+ {
+ foundID = ncgrid[index].ncIDs[ncIDType];
+ foundIdx = index;
+ break;
+ }
+ numNonMatching++;
+ }
+ }
}
+ return (struct idSearch){ .numNonMatching = numNonMatching,
+ .foundID = foundID, .foundIdx = foundIdx };
+}
- if ( gridptrOrig->xbounds != NULL && gridptrOrig->xbounds != cdfPendingLoad )
- {
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->xsize)
- * (size_t)gridptrOrig->nvertex;
+static size_t
+cdfGridInqHalfSize(int gridID)
+{
+ return gridInqSize(gridID)/2;
+}
- gridptrDup->xbounds = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->xbounds, gridptrOrig->xbounds, size * sizeof (double));
- }
- if ( gridptrOrig->ybounds != NULL && gridptrOrig->ybounds != cdfPendingLoad )
- {
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->ysize)
- * (size_t)gridptrOrig->nvertex;
+static void
+cdfDefSPorFC(stream_t *streamptr, int gridID, int gridindex,
+ char *restrict axisname, int gridRefType)
+{
+ ncgrid_t *ncgrid = streamptr->ncgrid;
- gridptrDup->ybounds = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->ybounds, gridptrOrig->ybounds, size * sizeof (double));
- }
+ size_t dimlen = gridInqSize(gridID)/2;
+ int iz;
+ int dimID;
{
- if ( gridptrOrig->area != NULL && gridptrOrig->area != cdfPendingLoad )
- {
- size_t size = gridsize;
-
- gridptrDup->area = (double *)Malloc(size * sizeof (double));
- memcpy(gridptrDup->area, gridptrOrig->area, size * sizeof (double));
- }
+ struct idSearch search
+ = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_Y,
+ gridRefType, (int)dimlen,
+ gridInqType, cdfGridInqHalfSize);
+ dimID = search.foundID;
+ iz = search.numNonMatching;
}
- if ( gridptrOrig->mask != NULL )
+ if ( dimID == CDI_UNDEFID )
{
- size_t size = gridsize;
+ int fileID = streamptr->fileID;
+ if ( iz == 0 ) axisname[3] = '\0';
+ else sprintf(&axisname[3], "%1d", iz+1);
- gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
- memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
- }
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- if ( gridptrOrig->mask_gme != NULL )
- {
- size_t size = gridsize;
+ cdf_def_dim(fileID, axisname, dimlen, &dimID);
- gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
- memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
}
-}
-static grid_t *
-cdfLazyGridCopy(grid_t *gridptrOrig)
-{
- struct cdfLazyGrid *lazyGridDup
- = (struct cdfLazyGrid *)Malloc(sizeof (*lazyGridDup));
- gridptrOrig->vtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
- gridptrOrig->vtable->copyArrayFields(gridptrOrig, &lazyGridDup->base);
- return &lazyGridDup->base;
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = dimID;
}
-static void
-cdfLazyGridInitOnce(void)
+static
+void cdfDefSP(stream_t *streamptr, int gridID, int gridindex)
{
- cdfLazyGridVtable = cdiGridVtable;
- cdfLazyGridVtable.destroy = cdfLazyGridDelete;
- cdfLazyGridVtable.copy = cdfLazyGridCopy;
- cdfLazyGridVtable.copyScalarFields = cdfLazyGridCopyScalarFields;
- cdfLazyGridVtable.copyArrayFields = cdfLazyGridCopyArrayFields;
- cdfLazyGridVtable.defArea = cdfLazyGridDefArea;
- cdfLazyGridVtable.inqAreaPtr = cdfLazyGridInqAreaPtr;
- cdfLazyGridVtable.inqArea = cdfLazyGridInqArea;
- cdfLazyGridVtable.inqXValsPtr = cdfLazyGridInqXValsPtr;
- cdfLazyGridVtable.inqYValsPtr = cdfLazyGridInqYValsPtr;
- cdfLazyGridVtable.inqXVal = cdfLazyGridInqXVal;
- cdfLazyGridVtable.inqYVal = cdfLazyGridInqYVal;
- cdfLazyGridVtable.defXVals = cdfLazyGridDefXVals;
- cdfLazyGridVtable.defYVals = cdfLazyGridDefYVals;
- cdfLazyGridVtable.compareXYFull = cdfLazyCompareXYFull;
- cdfLazyGridVtable.compareXYAO = cdfLazyCompareXYAO;
- cdfLazyGridVtable.defXBounds = cdfLazyGridDefXBounds;
- cdfLazyGridVtable.defYBounds = cdfLazyGridDefYBounds;
- cdfLazyGridVtable.inqXBoundsPtr = cdfLazyGridInqXBoundsPtr;
- cdfLazyGridVtable.inqYBoundsPtr = cdfLazyGridInqYBoundsPtr;
- /* create inaccessible memory area, if possible, this serves as
- * dummy value for pointers to data not yet loaded */
/*
-#ifdef HAVE_MMAP
- {
- size_t pgSize = cdiGetPageSize(false);
- static const char devZero[] = "/dev/zero";
- int fd = open(devZero, O_RDWR);
- if (fd == -1)
- SysError("Could not open %s to map anonymous memory", devZero);
- void *cdfInvalid = mmap(NULL, pgSize, PROT_NONE, MAP_PRIVATE, fd, 0);
- if (cdfInvalid == MAP_FAILED)
- SysError("Could not mmap anonymous memory");
- cdfPendingLoad = cdfInvalid;
- int rc = close(fd);
- if (rc == -1)
- SysError("Could not close %s file handle %d after mapping anonymous"
- " memory", devZero, fd);
- }
-#else
+ char longname[] = "Spherical harmonic coefficient";
*/
- cdfPendingLoad = (double *)&cdfPendingLoad;
- //#endif
- atexit(cdfLazyGridDestroyOnce);
-#ifndef HAVE_LIBPTHREAD
- cdfLazyInitialized = true;
-#endif
+ char axisname[5] = "nspX";
+ cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_SPECTRAL);
}
-static void
-cdfBaseGridInit(grid_t *grid, int gridtype)
+
+static
+void cdfDefFC(stream_t *streamptr, int gridID, int gridindex)
{
- grid_init(grid);
- cdiGridTypeInit(grid, gridtype, 0);
+ char axisname[5] = "nfcX";
+ cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_FOURIER);
}
-static void
-cdfLazyGridInit(struct cdfLazyGrid *grid, int gridtype)
+static const struct cdfDefGridAxisInqs {
+ size_t (*axisSize)(int gridID);
+ int (*axisDimname)(int cdiID, int key, int size, char *mesg);
+ int (*axisName)(int cdiID, int key, int size, char *mesg);
+ int (*axisLongname)(int cdiID, int key, int size, char *mesg);
+ int (*axisUnits)(int cdiID, int key, int size, char *mesg);
+ void (*axisStdname)(int cdiID, char *dimstdname);
+ double (*axisVal)(int gridID, size_t index);
+ const double *(*axisValsPtr)(int gridID);
+ const double *(*axisBoundsPtr)(int gridID);
+} gridInqsX = {
+ .axisSize = gridInqXsize,
+ .axisDimname = cdiGridInqKeyStr,
+ .axisName = cdiGridInqKeyStr,
+ .axisLongname = cdiGridInqKeyStr,
+ .axisUnits = cdiGridInqKeyStr,
+ .axisStdname = gridInqXstdname,
+ .axisVal = gridInqXval,
+ .axisValsPtr = gridInqXvalsPtr,
+ .axisBoundsPtr = gridInqXboundsPtr,
+}, gridInqsY = {
+ .axisSize = gridInqYsize,
+ .axisDimname = cdiGridInqKeyStr,
+ .axisName = cdiGridInqKeyStr,
+ .axisLongname = cdiGridInqKeyStr,
+ .axisUnits = cdiGridInqKeyStr,
+ .axisStdname = gridInqYstdname,
+ .axisVal = gridInqYval,
+ .axisValsPtr = gridInqYvalsPtr,
+ .axisBoundsPtr = gridInqYboundsPtr,
+}, gridInqsZ = {
+ .axisLongname = cdiZaxisInqKeyStr,
+ .axisUnits = cdiZaxisInqKeyStr,
+ .axisStdname = zaxisInqStdname,
+};
+
+static
+void cdfPutGridStdAtts(int fileID, int ncvarid, int gridID, int dimtype, const struct cdfDefGridAxisInqs *inqs)
{
-#ifdef HAVE_LIBPTHREAD
- pthread_once(&cdfLazyInitialized, cdfLazyGridInitOnce);
-#else
- if (cdfLazyInitialized) ; else cdfLazyGridInitOnce();
-#endif
- cdfBaseGridInit(&grid->base, gridtype);
- grid->baseVtable = grid->base.vtable;
- grid->cellAreaGet.datasetNCId = -1;
- grid->cellAreaGet.varNCId = -1;
- grid->xValsGet.datasetNCId = -1;
- grid->xValsGet.varNCId = -1;
- grid->yValsGet.datasetNCId = -1;
- grid->yValsGet.varNCId = -1;
- grid->xBoundsGet.datasetNCId = -1;
- grid->xBoundsGet.varNCId = -1;
- grid->yBoundsGet.datasetNCId = -1;
- grid->yBoundsGet.varNCId = -1;
- grid->base.vtable = &cdfLazyGridVtable;
- init_lazy_load_lock(grid);
+ size_t len;
+
+ char stdname[CDI_MAX_NAME];
+ inqs->axisStdname(gridID, stdname);
+ if ( (len = strlen(stdname)) )
+ cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+
+ char longname[CDI_MAX_NAME]; longname[0] = 0;
+ int keyname = (dimtype == 'Z') ? CDI_KEY_LONGNAME : (dimtype == 'X') ? CDI_KEY_XLONGNAME : CDI_KEY_YLONGNAME;
+ inqs->axisLongname(gridID, keyname, CDI_MAX_NAME, longname);
+ if ( longname[0] && (len = strlen(longname)) )
+ cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+
+ char units[CDI_MAX_NAME]; units[0] = 0;
+ keyname = (dimtype == 'Z') ? CDI_KEY_UNITS : (dimtype == 'X') ? CDI_KEY_XUNITS : CDI_KEY_YUNITS;
+ inqs->axisUnits(gridID, keyname, CDI_MAX_NAME, units);
+ if ( units[0] && (len = strlen(units)) )
+ cdf_put_att_text(fileID, ncvarid, "units", len, units);
}
static void
-cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
+cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex,
+ const struct cdfDefGridAxisInqs *inqs, int dimtype)
{
- struct cdfLazyGrid *restrict grid = *gridpptr;
- if (!grid)
- *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (*grid));
- cdfLazyGridInit(grid, gridtype);
+ nc_type xtype = (gridInqDatatype(gridID) == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
+ ncgrid_t *ncgrid = streamptr->ncgrid;
+
+ size_t dimlen = inqs->axisSize(gridID);
+ if ( dimlen != 1 )
+ Error("%c size isn't 1 for %s grid!", dimtype, gridNamePtr(gridInqType(gridID)));
+
+ int ncvarid = ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y];
+
+ if ( ncvarid == CDI_UNDEFID )
+ {
+ int dimNcID = streamptr->basetime.ncvarid;
+ int fileID = streamptr->fileID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+ char axisname[CDI_MAX_NAME]; axisname[0] = 0;
+ int keyname = (dimtype == 'X') ? CDI_KEY_XNAME : CDI_KEY_YNAME;
+ inqs->axisName(gridID, keyname, CDI_MAX_NAME, axisname);
+ cdf_def_var(fileID, axisname, xtype, 1, &dimNcID, &ncvarid);
+ cdfPutGridStdAtts(fileID, ncvarid, gridID, dimtype, inqs);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
+ }
+
+ ncgrid[gridindex].gridID = gridID;
+ /* var ID for trajectory !!! */
+ ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y] = ncvarid;
}
-static void
-cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
+static
+void cdfDefTrajLon(stream_t *streamptr, int gridID, int gridindex)
{
- struct cdfLazyGrid *restrict grid = *gridpptr;
- if (!grid)
- *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (grid_t));
- cdfBaseGridInit((grid_t*)grid, gridtype);
+ cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsX, 'X');
+}
+
+
+static
+void cdfDefTrajLat(stream_t *streamptr, int gridID, int gridindex)
+{
+ cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsY, 'Y');
}
+static
+int checkDimName(int fileID, size_t dimlen, char *dimname)
+{
+ /* check whether the dimenion name is already defined with the same length */
+ unsigned iz = 0;
+ int dimid = CDI_UNDEFID;
+ char name[CDI_MAX_NAME];
+
+ size_t len = strlen(dimname);
+ memcpy(name, dimname, len + 1);
+
+ do
+ {
+ if ( iz ) sprintf(name + len, "_%u", iz+1);
+
+ int dimid0, status = nc_inq_dimid(fileID, name, &dimid0);
+ if ( status != NC_NOERR )
+ break;
+ size_t dimlen0;
+ cdf_inq_dimlen(fileID, dimid0, &dimlen0);
+ if ( dimlen0 == dimlen )
+ {
+ dimid = dimid0;
+ break;
+ }
+ iz++;
+ }
+ while ( iz <= 99 );
+
+
+ if ( iz ) sprintf(dimname + len, "_%u", iz+1);
+
+ return dimid;
+}
-/* define all input grids */
static
-void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
+void checkGridName(char *axisname, int fileID)
{
- int ltwarn = TRUE;
- struct cdfLazyGrid *restrict lazyGrid = NULL, *restrict lazyProj = NULL;
-#define grid (&lazyGrid->base)
-#define proj (&lazyProj->base)
+ int ncdimid;
+ char axisname2[CDI_MAX_NAME];
- for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid )
+ /* check that the name is not already defined */
+ unsigned iz = 0;
+
+ size_t axisnameLen = strlen(axisname);
+ memcpy(axisname2, axisname, axisnameLen + 1);
+ do
{
- if ( ncvars[ncvarid].isvar && ncvars[ncvarid].gridID == UNDEFID )
- {
- int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
- int xdimid = -1, ydimid = -1;
- int vdimid = -1;
- int islon = 0, islat = 0;
- int nxdims = 0, nydims = 0;
- size_t size = 0;
- size_t xsize = 0, ysize = 0;
- double yinc = 0;
- struct addIffNewRes projAdded = { .Id = CDI_UNDEFID, .isNew = 0 },
- gridAdded = { .Id = CDI_UNDEFID, .isNew = 0 };
+ if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
- int ndims = ncvars[ncvarid].ndims;
- for ( int i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvarid].dimtype[i] == X_AXIS && nxdims < 2 )
- {
- xdimids[nxdims] = ncvars[ncvarid].dimids[i];
- nxdims++;
- }
- else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS && nydims < 2 )
- {
- ydimids[nydims] = ncvars[ncvarid].dimids[i];
- nydims++;
- }
- }
+ int status = nc_inq_varid(fileID, axisname2, &ncdimid);
+ if ( status != NC_NOERR ) break;
- if ( nxdims == 2 )
- {
- xdimid = xdimids[1];
- ydimid = xdimids[0];
- }
- else if ( nydims == 2 )
- {
- xdimid = ydimids[1];
- ydimid = ydimids[0];
- }
- else
- {
- xdimid = xdimids[0];
- ydimid = ydimids[0];
- }
+ ++iz;
+ }
+ while ( iz <= 99 );
- int xvarid = ncvars[ncvarid].xvarid != UNDEFID
- ? ncvars[ncvarid].xvarid
- : (xdimid != UNDEFID ? ncdims[xdimid].ncvarid : -1);
- int yvarid = ncvars[ncvarid].yvarid != UNDEFID
- ? ncvars[ncvarid].yvarid
- : (ydimid != UNDEFID ? ncdims[ydimid].ncvarid : -1);
+ if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
+}
- /*
- if ( xdimid != UNDEFID )
- xvarid = ncdims[xdimid].ncvarid;
- if ( xvarid == UNDEFID && ncvars[ncvarid].xvarid != UNDEFID )
- xvarid = ncvars[ncvarid].xvarid;
-
- if ( ydimid != UNDEFID )
- yvarid = ncdims[ydimid].ncvarid;
- if ( yvarid == UNDEFID && ncvars[ncvarid].yvarid != UNDEFID )
- yvarid = ncvars[ncvarid].yvarid;
- */
+static
+int checkZaxisName(char *axisname, int fileID, int vlistID, int zaxisID, int nzaxis)
+{
+ char axisname2[CDI_MAX_NAME];
- if ( xdimid != UNDEFID ) xsize = ncdims[xdimid].len;
- if ( ydimid != UNDEFID ) ysize = ncdims[ydimid].len;
+ /* check that the name is not already defined */
+ unsigned iz = 0;
- if ( ydimid == UNDEFID && yvarid != UNDEFID )
- {
- if ( ncvars[yvarid].ndims == 1 )
- {
- ydimid = ncvars[yvarid].dimids[0];
- ysize = ncdims[ydimid].len;
- }
- }
+ size_t axisnameLen = strlen(axisname);
+ memcpy(axisname2, axisname, axisnameLen + 1);
+ do
+ {
+ if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
- if ( ncvars[ncvarid].gridtype == UNDEFID || ncvars[ncvarid].gridtype == GRID_GENERIC )
- if ( xdimid != UNDEFID && xdimid == ydimid && nydims == 0 ) ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
+ int ncdimid, status = nc_inq_varid(fileID, axisname2, &ncdimid);
- if (CDI_netcdf_lazy_grid_load)
- {
- cdfLazyGridRenew(&lazyGrid, ncvars[ncvarid].gridtype);
- cdfLazyGridRenew(&lazyProj, GRID_PROJECTION);
- }
- else
+ if ( status != NC_NOERR )
+ {
+ if ( iz )
{
- cdfBaseGridRenew(&lazyGrid, ncvars[ncvarid].gridtype);
- cdfBaseGridRenew(&lazyProj, GRID_PROJECTION);
+ /* check that the name does not exist for other zaxes */
+ for ( int index = 0; index < nzaxis; index++ )
+ {
+ int zaxisID0 = vlistZaxis(vlistID, index);
+ if ( zaxisID != zaxisID0 )
+ {
+ const char *axisname0 = zaxisInqNamePtr(zaxisID0);
+ if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
+ }
+ }
}
+ break;
+ }
+ nextSuffix:
+ ++iz;
+ }
+ while (iz <= 99);
- grid->prec = DATATYPE_FLT64;
- grid->trunc = ncvars[ncvarid].truncation;
- if ( ncvars[ncvarid].gridtype == GRID_TRAJECTORY )
- {
- if ( ncvars[ncvarid].xvarid == UNDEFID )
- Error("Longitude coordinate undefined for %s!", ncvars[ncvarid].name);
- if ( ncvars[ncvarid].yvarid == UNDEFID )
- Error("Latitude coordinate undefined for %s!", ncvars[ncvarid].name);
- }
- else
- {
- size_t start[3], count[3];
- int ltgrid = FALSE;
+ if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
- if ( xvarid != UNDEFID && yvarid != UNDEFID )
- {
- if ( ncvars[xvarid].ndims != ncvars[yvarid].ndims )
- {
- Warning("Inconsistent grid structure for variable %s!", ncvars[ncvarid].name);
- ncvars[ncvarid].xvarid = UNDEFID;
- ncvars[ncvarid].yvarid = UNDEFID;
- xvarid = UNDEFID;
- yvarid = UNDEFID;
- }
+ return (int)iz;
+}
- if ( ncvars[xvarid].ndims > 2 || ncvars[yvarid].ndims > 2 )
- {
- if ( ncvars[xvarid].ndims == 3 && ncvars[xvarid].dimids[0] == timedimid &&
- ncvars[yvarid].ndims == 3 && ncvars[yvarid].dimids[0] == timedimid )
- {
- if ( ltwarn )
- Warning("Time varying grids unsupported, using grid at time step 1!");
- ltgrid = TRUE;
- ltwarn = FALSE;
- start[0] = start[1] = start[2] = 0;
- count[0] = 1; count[1] = ysize; count[2] = xsize;
- }
- else
- {
- Warning("Unsupported grid structure for variable %s (grid dims > 2)!", ncvars[ncvarid].name);
- ncvars[ncvarid].xvarid = UNDEFID;
- ncvars[ncvarid].yvarid = UNDEFID;
- xvarid = UNDEFID;
- yvarid = UNDEFID;
- }
- }
- }
+static void
+cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
+ const struct cdfDefGridAxisInqs *gridAxisInq, int dimKey, char axisLetter,
+ void (*finishCyclicBounds)(double *pbounds, size_t dimlen, const double *pvals))
+{
+ int dimID = CDI_UNDEFID;
+ int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
+ int nvdimID = CDI_UNDEFID;
+ int fileID = streamptr->fileID;
+ size_t dimlen = gridAxisInq->axisSize(gridID);
+ nc_type xtype = (nc_type)cdfDefDatatype(gridInqDatatype(gridID), streamptr->filetype);
- if ( xvarid != UNDEFID )
- {
- if ( ncvars[xvarid].ndims > 3 || (ncvars[xvarid].ndims == 3 && ltgrid == FALSE) )
- {
- Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[xvarid].name, ncvars[xvarid].ndims);
- //ncvars[ncvarid].xvarid = UNDEFID;
- xvarid = UNDEFID;
- }
- }
+ ncgrid_t *ncgrid = streamptr->ncgrid;
+
+ const double *pvals = gridAxisInq->axisValsPtr(gridID);
+ char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
+ if ( ndims && pvals == NULL ) cdiGridInqKeyStr(gridID, dimKey, CDI_MAX_NAME, dimname);
- if ( yvarid != UNDEFID )
+ for ( int index = 0; index < gridindex; ++index )
+ {
+ int gridID0 = ncgrid[index].gridID;
+ assert(gridID0 != CDI_UNDEFID);
+ int gridtype0 = gridInqType(gridID0);
+ if ( gridtype0 == GRID_GAUSSIAN ||
+ gridtype0 == GRID_LONLAT ||
+ gridtype0 == GRID_PROJECTION ||
+ gridtype0 == GRID_CURVILINEAR ||
+ gridtype0 == GRID_GENERIC )
+ {
+ size_t dimlen0 = gridAxisInq->axisSize(gridID0);
+ char dimname0[CDI_MAX_NAME]; dimname0[0] = 0;
+ if ( dimname[0] ) cdiGridInqKeyStr(gridID0, dimKey, CDI_MAX_NAME, dimname0);
+ bool lname = dimname0[0] ? strcmp(dimname, dimname0) == 0 : true;
+ if ( dimlen == dimlen0 && lname )
+ {
+ double (*inqVal)(int gridID, size_t index) = gridAxisInq->axisVal;
+ if ( IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) &&
+ IS_EQUAL(inqVal(gridID0, dimlen-1), inqVal(gridID, dimlen-1)) )
{
- if ( ncvars[yvarid].ndims > 3 || (ncvars[yvarid].ndims == 3 && ltgrid == FALSE) )
- {
- Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
- //ncvars[ncvarid].yvarid = UNDEFID;
- yvarid = UNDEFID;
- }
+ dimID = ncgrid[index].ncIDs[dimKey == CDI_KEY_XDIMNAME
+ ? CDF_DIMID_X : CDF_DIMID_Y];
+ break;
}
+ }
+ }
+ }
- if ( xvarid != UNDEFID )
- {
- bool skipvar = true;
- islon = ncvars[xvarid].islon;
- ndims = ncvars[xvarid].ndims;
- if ( ndims == 2 || ndims == 3 )
- {
- ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
- size = xsize*ysize;
- /* Check size of 2 dimensional coordinate variables */
- int dimid = ncvars[xvarid].dimids[ndims-2];
- size_t dimsize1 = ncdims[dimid].len;
- dimid = ncvars[xvarid].dimids[ndims-1];
- size_t dimsize2 = ncdims[dimid].len;
- skipvar = dimsize1*dimsize2 != size;
- }
- else if ( ndims == 1 )
- {
- size = xsize;
- /* Check size of 1 dimensional coordinate variables */
- int dimid = ncvars[xvarid].dimids[0];
- size_t dimsize = ncdims[dimid].len;
- skipvar = dimsize != size;
- }
- else if ( ndims == 0 && xsize == 0 )
- {
- size = xsize = 1;
- skipvar = false;
- }
+ if ( dimID == CDI_UNDEFID )
+ {
+ char axisname[CDI_MAX_NAME]; axisname[0] = 0;
+ int keyname = (axisLetter == 'X') ? CDI_KEY_XNAME : CDI_KEY_YNAME;
+ gridAxisInq->axisName(gridID, keyname, CDI_MAX_NAME, axisname);
+ if ( axisname[0] == 0 ) Error("axis name undefined!");
+ size_t axisnameLen = strlen(axisname);
- if ( skipvar )
- {
- Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
- ncvars[ncvarid].isvar = -1;
- continue;
- }
+ /* enough to append _ plus up to 100 decimal and trailing \0 */
+ char extendedAxisname[axisnameLen + 4 + 1];
+ memcpy(extendedAxisname, axisname, axisnameLen + 1);
+ checkGridName(extendedAxisname, fileID);
+ size_t extendedAxisnameLen = axisnameLen + strlen(extendedAxisname + axisnameLen);
- if ( ncvars[xvarid].xtype == NC_FLOAT ) grid->prec = DATATYPE_FLT32;
- if (CDI_netcdf_lazy_grid_load)
- {
- lazyGrid->xValsGet = (struct xyValGet){
- .scalefactor = ncvars[xvarid].scalefactor,
- .addoffset = ncvars[xvarid].addoffset,
- .start = { start[0], start[1], start[2] },
- .count = { count[0], count[1], count[2] },
- .size = size,
- .datasetNCId = ncvars[xvarid].ncid,
- .varNCId = xvarid,
- .ndims = (short)ndims,
- };
- grid->xvals = cdfPendingLoad;
- }
- else
- {
- grid->xvals = (double *) Malloc(size*sizeof(double));
- if ( ltgrid )
- cdf_get_vara_double(ncvars[xvarid].ncid, xvarid,
- start, count, grid->xvals);
- else
- cdf_get_var_double(ncvars[xvarid].ncid, xvarid,
- grid->xvals);
- scale_add(size, grid->xvals,
- ncvars[xvarid].addoffset,
- ncvars[xvarid].scalefactor);
- }
- strcpy(grid->xname, ncvars[xvarid].name);
- strcpy(grid->xlongname, ncvars[xvarid].longname);
- strcpy(grid->xunits, ncvars[xvarid].units);
- /* don't change the name !!! */
- /*
- if ( (len = strlen(grid->xname)) > 2 )
- if ( grid->xname[len-2] == '_' && isdigit((int) grid->xname[len-1]) )
- grid->xname[len-2] = 0;
- */
- }
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- if ( yvarid != UNDEFID )
- {
- bool skipvar = true;
- islat = ncvars[yvarid].islat;
- ndims = ncvars[yvarid].ndims;
- if ( ndims == 2 || ndims == 3 )
- {
- ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
- size = xsize*ysize;
- /* Check size of 2 dimensional coordinate variables */
- {
- int dimid;
- size_t dimsize1, dimsize2;
- dimid = ncvars[yvarid].dimids[ndims-2];
- dimsize1 = ncdims[dimid].len;
- dimid = ncvars[yvarid].dimids[ndims-1];
- dimsize2 = ncdims[dimid].len;
- skipvar = dimsize1*dimsize2 != size;
- }
- }
- else if ( ndims == 1 )
- {
- if ( (int) ysize == 0 ) size = xsize;
- else size = ysize;
-
- /* Check size of 1 dimensional coordinate variables */
- {
- int dimid;
- size_t dimsize;
- dimid = ncvars[yvarid].dimids[0];
- dimsize = ncdims[dimid].len;
- skipvar = dimsize != size;
- }
- }
- else if ( ndims == 0 && ysize == 0 )
- {
- size = ysize = 1;
- skipvar = false;
- }
+ if ( ndims )
+ {
+ if ( dimname[0] == 0 ) strcpy(dimname, extendedAxisname);
+ dimID = checkDimName(fileID, dimlen, dimname);
- if ( skipvar )
- {
- Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
- ncvars[ncvarid].isvar = -1;
- continue;
- }
+ if ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+ }
- if ( ncvars[yvarid].xtype == NC_FLOAT ) grid->prec = DATATYPE_FLT32;
- /* see below for when it's impossible to operate
- * without y values */
- if ( !CDI_netcdf_lazy_grid_load
- || ((ncvars[ncvarid].gridtype == UNDEFID ||
- ncvars[ncvarid].gridtype == GRID_GENERIC)
- && islat && (islon || xsize == 0)) )
- {
- grid->yvals = (double *) Malloc(size*sizeof(double));
-
- if ( ltgrid )
- cdf_get_vara_double(ncvars[yvarid].ncid, yvarid, start, count, grid->yvals);
- else
- cdf_get_var_double(ncvars[yvarid].ncid, yvarid, grid->yvals);
-
- scale_add(size, grid->yvals, ncvars[yvarid].addoffset, ncvars[yvarid].scalefactor);
-
- /* don't change the name !!! */
- /*
- if ( (len = strlen(grid->yname)) > 2 )
- if ( grid->yname[len-2] == '_' && isdigit((int) grid->yname[len-1]) )
- grid->yname[len-2] = 0;
- */
- if ( islon && (int) ysize > 1 )
- {
- yinc = fabs(grid->yvals[0] - grid->yvals[1]);
- for ( size_t i = 2; i < ysize; i++ )
- if ( (fabs(grid->yvals[i-1] - grid->yvals[i]) - yinc) > (yinc/1000) )
- {
- yinc = 0;
- break;
- }
- }
- }
- else
- {
- lazyGrid->yValsGet = (struct xyValGet){
- .scalefactor = ncvars[yvarid].scalefactor,
- .addoffset = ncvars[yvarid].addoffset,
- .start = { start[0], start[1], start[2] },
- .count = { count[0], count[1], count[2] },
- .size = size,
- .datasetNCId = ncvars[yvarid].ncid,
- .varNCId = yvarid,
- .ndims = (short)ndims,
- };
- grid->yvals = cdfPendingLoad;
- }
- strcpy(grid->yname, ncvars[yvarid].name);
- strcpy(grid->ylongname, ncvars[yvarid].longname);
- strcpy(grid->yunits, ncvars[yvarid].units);
- }
+ bool gen_bounds = false;
+ bool grid_is_cyclic = gridIsCircular(gridID) > 0;
+ double *pbounds = NULL;
+ if ( pvals )
+ {
+ cdf_def_var(fileID, extendedAxisname, xtype, ndims, &dimID, &ncvarid);
- if ( (int) ysize == 0 ) size = xsize;
- else if ( (int) xsize == 0 ) size = ysize;
- else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize;
- else size = xsize*ysize;
- }
+ cdfPutGridStdAtts(fileID, ncvarid, gridID, axisLetter, gridAxisInq);
+ {
+ char axisStr[2] = { axisLetter, '\0' };
+ cdf_put_att_text(fileID, ncvarid, "axis", 1, axisStr);
+ }
- if ( ncvars[ncvarid].gridtype == UNDEFID ||
- ncvars[ncvarid].gridtype == GRID_GENERIC )
- {
- if ( islat && (islon || xsize == 0) )
- {
- if ( isGaussGrid(ysize, yinc, grid->yvals) )
- {
- ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
- grid->np = (int)(ysize/2);
- }
- else
- ncvars[ncvarid].gridtype = GRID_LONLAT;
- }
- else if ( islon && !islat && ysize == 0 )
- {
- ncvars[ncvarid].gridtype = GRID_LONLAT;
- }
- else
- ncvars[ncvarid].gridtype = GRID_GENERIC;
- }
+ size_t nvertex = gridInqNvertex(gridID);
+ pbounds = (double *)gridAxisInq->axisBoundsPtr(gridID);
- switch (ncvars[ncvarid].gridtype)
- {
- case GRID_GENERIC:
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- case GRID_UNSTRUCTURED:
- case GRID_CURVILINEAR:
- {
- grid->size = (int)size;
- grid->xsize = (int)xsize;
- grid->ysize = (int)ysize;
- if ( xvarid != UNDEFID )
- {
- grid->xdef = 1;
- if ( ncvars[xvarid].bounds != UNDEFID )
- {
- int nbdims = ncvars[ncvars[xvarid].bounds].ndims;
- if ( nbdims == 2 || nbdims == 3 )
- {
- vdimid = ncvars[ncvars[xvarid].bounds].dimids[nbdims-1];
- size_t nvertex = ncdims[vdimid].len;
- grid->nvertex = (int)nvertex;
- if (CDI_netcdf_lazy_grid_load)
- {
- lazyGrid->xBoundsGet.datasetNCId
- = ncvars[xvarid].ncid;
- lazyGrid->xBoundsGet.varNCId
- = ncvars[xvarid].bounds;
- grid->xbounds = cdfPendingLoad;
- }
- else
- {
- grid->xbounds
- = (double *)Malloc(nvertex * size
- * sizeof(double));
- cdf_get_var_double(ncvars[xvarid].ncid,
- ncvars[xvarid].bounds,
- grid->xbounds);
- }
- }
- }
- }
- if ( yvarid != UNDEFID )
- {
- grid->ydef = 1;
- if ( ncvars[yvarid].bounds != UNDEFID )
- {
- int nbdims = ncvars[ncvars[yvarid].bounds].ndims;
- if ( nbdims == 2 || nbdims == 3 )
- {
- /* size_t nvertex = ncdims[ncvars[ncvars[yvarid].bounds].dimids[nbdims-1]].len;
- if ( nvertex != grid->nvertex )
- Warning("nvertex problem! nvertex x %d, nvertex y %d",
- grid->nvertex, (int) nvertex);
- */
- if (CDI_netcdf_lazy_grid_load)
- {
- lazyGrid->yBoundsGet.datasetNCId
- = ncvars[yvarid].ncid;
- lazyGrid->yBoundsGet.varNCId
- = ncvars[yvarid].bounds;
- grid->ybounds = cdfPendingLoad;
- }
- else
- {
- vdimid = ncvars[ncvars[yvarid].bounds].dimids[nbdims-1];
- size_t nvertex = ncdims[vdimid].len;
- /*
- if ( nvertex != grid->nvertex )
- Warning("nvertex problem! nvertex x %d, nvertex y %d",
- grid->nvertex, (int) nvertex);
- */
- grid->ybounds
- = (double *)Malloc(nvertex * size
- * sizeof(double));
- cdf_get_var_double(ncvars[yvarid].ncid,
- ncvars[yvarid].bounds,
- grid->ybounds);
- }
- }
- }
- }
+ if ( CDI_cmor_mode && grid_is_cyclic && !pbounds )
+ {
+ gen_bounds = true;
+ nvertex = 2;
+ pbounds = (double*) Malloc(2*dimlen*sizeof(double));
+ for ( size_t i = 0; i < dimlen-1; ++i )
+ {
+ pbounds[i*2+1] = (pvals[i] + pvals[i+1])/2;
+ pbounds[(i+1)*2] = (pvals[i] + pvals[i+1])/2;
+ }
+ finishCyclicBounds(pbounds, dimlen, pvals);
+ }
+ if ( pbounds )
+ {
+ if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
+ cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+ }
+ if ( pbounds && nvdimID != CDI_UNDEFID )
+ {
+ char boundsname[extendedAxisnameLen + 1 + sizeof(bndsName)];
+ memcpy(boundsname, axisname, extendedAxisnameLen);
+ boundsname[extendedAxisnameLen] = '_';
+ memcpy(boundsname + extendedAxisnameLen + 1, bndsName, sizeof bndsName);
+ int dimIDs[2] = { dimID, nvdimID };
+ cdf_def_var(fileID, boundsname, xtype, 2, dimIDs, &ncbvarid);
+ cdf_put_att_text(fileID, ncvarid, "bounds", extendedAxisnameLen + sizeof (bndsName), boundsname);
+ }
+ }
- if ( ncvars[ncvarid].cellarea != UNDEFID )
- {
- if (CDI_netcdf_lazy_grid_load)
- {
- grid->area = cdfPendingLoad;
- lazyGrid->cellAreaGet.datasetNCId
- = ncvars[ncvarid].ncid;
- lazyGrid->cellAreaGet.varNCId
- = ncvars[ncvarid].cellarea;
- }
- else
- {
- grid->area = (double *) Malloc(size*sizeof(double));
- cdf_get_var_double(ncvars[ncvarid].ncid,
- ncvars[ncvarid].cellarea,
- grid->area);
- }
- }
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
- break;
- }
- case GRID_SPECTRAL:
- {
- grid->size = (int)size;
- grid->lcomplex = 1;
- break;
- }
- case GRID_FOURIER:
- {
- grid->size = (int)size;
- break;
- }
- case GRID_TRAJECTORY:
- {
- grid->size = 1;
- break;
- }
- }
+ if ( ncvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncvarid, pvals);
+ if ( ncbvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbvarid, pbounds);
+ if ( gen_bounds ) Free(pbounds);
- if ( grid->type != ncvars[ncvarid].gridtype )
- {
- int gridtype = ncvars[ncvarid].gridtype;
- grid->type = gridtype;
- cdiGridTypeInit(grid, gridtype, grid->size);
- }
+ if ( ndims == 0 )
+ ncgrid[gridindex].ncIDs[dimKey == CDI_KEY_XDIMNAME
+ ? CDF_VARID_X : CDF_VARID_Y] = ncvarid;
+ }
- if ( grid->size == 0 )
- {
- if ( (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == T_AXIS) ||
- (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == Z_AXIS) ||
- (ncvars[ncvarid].ndims == 2 && ncvars[ncvarid].dimtype[0] == T_AXIS && ncvars[ncvarid].dimtype[1] == Z_AXIS) )
- {
- grid->type = GRID_GENERIC;
- grid->size = 1;
- grid->xsize = 0;
- grid->ysize = 0;
- }
- else
- {
- Warning("Variable %s has an unsupported grid, skipped!", ncvars[ncvarid].name);
- ncvars[ncvarid].isvar = -1;
- continue;
- }
- }
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[dimKey == CDI_KEY_XDIMNAME
+ ? CDF_DIMID_X : CDF_DIMID_Y] = dimID;
+}
- if ( number_of_grid_used != UNDEFID && (grid->type == UNDEFID || grid->type == GRID_GENERIC) )
- grid->type = GRID_UNSTRUCTURED;
+static
+void finishCyclicXBounds(double *pbounds, size_t dimlen, const double *pvals)
+{
+ pbounds[0] = (pvals[0] + pvals[dimlen-1]-360)*0.5;
+ pbounds[2*dimlen-1] = (pvals[dimlen-1] + pvals[0]+360)*0.5;
+}
- if ( number_of_grid_used != UNDEFID && grid->type == GRID_UNSTRUCTURED )
- grid->number = number_of_grid_used;
+static
+void cdfDefXaxis(stream_t *streamptr, int gridID, int gridindex, int ndims)
+{
+ cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, &gridInqsX,
+ CDI_KEY_XDIMNAME, 'X', finishCyclicXBounds);
+}
- if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
- {
- int nvatts;
- cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
+static
+void finishCyclicYBounds(double *pbounds, size_t dimlen, const double *pvals)
+{
+ pbounds[0] = copysign(90.0, pvals[0]);
+ pbounds[2*dimlen-1] = copysign(90.0, pvals[dimlen-1]);
+}
- for ( int iatt = 0; iatt < nvatts; iatt++ )
- {
- size_t attlen;
- char attname[CDI_MAX_NAME];
- cdf_inq_attname(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, iatt, attname);
- cdf_inq_attlen(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, &attlen);
+static
+void cdfDefYaxis(stream_t *streamptr, int gridID, int gridindex, int ndims)
+{
+ cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, &gridInqsY,
+ CDI_KEY_YDIMNAME, 'Y', finishCyclicYBounds);
+}
- if ( strcmp(attname, "grid_mapping_name") == 0 )
- {
- enum {
- attstringlen = 8192,
- };
- char attstring[attstringlen];
-
- cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen, attstring);
- strtolower(attstring);
-
- if ( strcmp(attstring, "rotated_latitude_longitude") == 0 )
- grid->isRotated = TRUE;
- else if ( strcmp(attstring, "sinusoidal") == 0 )
- grid->type = GRID_SINUSOIDAL;
- else if ( strcmp(attstring, "lambert_azimuthal_equal_area") == 0 )
- grid->type = GRID_LAEA;
- else if ( strcmp(attstring, "lambert_conformal_conic") == 0 )
- grid->type = GRID_LCC2;
- else if ( strcmp(attstring, "lambert_cylindrical_equal_area") == 0 )
- {
- proj->type = GRID_PROJECTION;
- proj->name = strdup(attstring);
- }
- }
- else if ( strcmp(attname, "earth_radius") == 0 )
- {
- double datt;
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
- grid->laea_a = datt;
- grid->lcc2_a = datt;
- }
- else if ( strcmp(attname, "longitude_of_projection_origin") == 0 )
- {
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid->laea_lon_0);
- }
- else if ( strcmp(attname, "longitude_of_central_meridian") == 0 )
- {
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid->lcc2_lon_0);
- }
- else if ( strcmp(attname, "latitude_of_projection_origin") == 0 )
- {
- double datt;
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
- grid->laea_lat_0 = datt;
- grid->lcc2_lat_0 = datt;
- }
- else if ( strcmp(attname, "standard_parallel") == 0 )
- {
- if ( attlen == 1 )
- {
- double datt;
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
- grid->lcc2_lat_1 = datt;
- grid->lcc2_lat_2 = datt;
- }
- else
- {
- double datt2[2];
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 2, datt2);
- grid->lcc2_lat_1 = datt2[0];
- grid->lcc2_lat_2 = datt2[1];
- }
- }
- else if ( strcmp(attname, "grid_north_pole_latitude") == 0 )
- {
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid->ypole);
- }
- else if ( strcmp(attname, "grid_north_pole_longitude") == 0 )
- {
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid->xpole);
- }
- else if ( strcmp(attname, "north_pole_grid_longitude") == 0 )
- {
- cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid->angle);
- }
- }
- }
+static
+void cdfGridCompress(int fileID, int ncvarid, size_t gridsize, int filetype, int comptype)
+{
+#if defined (HAVE_NETCDF4)
+ if ( gridsize > 1 && comptype == CDI_COMPRESS_ZIP && (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C) )
+ {
+ cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
+ cdfDefVarDeflate(fileID, ncvarid, 1);
+ }
+#endif
+}
- if ( grid->type == GRID_UNSTRUCTURED )
- {
- int zdimid = UNDEFID;
- int xdimidx = -1, ydimidx = -1;
+static
+void cdfDefGridReference(stream_t *streamptr, int gridID)
+{
+ int fileID = streamptr->fileID;
+ int number = gridInqNumber(gridID);
- for ( int i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) xdimidx = i;
- else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) ydimidx = i;
- else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) zdimid = ncvars[ncvarid].dimids[i];
- }
+ if ( number > 0 )
+ {
+ cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
+ }
- if ( xdimid != UNDEFID && ydimid != UNDEFID && zdimid == UNDEFID )
- {
- if ( grid->xsize > grid->ysize && grid->ysize < 1000 )
- {
- ncvars[ncvarid].dimtype[ydimidx] = Z_AXIS;
- ydimid = UNDEFID;
- grid->size = grid->xsize;
- grid->ysize = 0;
- }
- else if ( grid->ysize > grid->xsize && grid->xsize < 1000 )
- {
- ncvars[ncvarid].dimtype[xdimidx] = Z_AXIS;
- xdimid = ydimid;
- ydimid = UNDEFID;
- grid->size = grid->ysize;
- grid->xsize = grid->ysize;
- grid->ysize = 0;
- }
- }
+ const char *gridfile = gridInqReferencePtr(gridID);
+ if ( gridfile && gridfile[0] != 0 )
+ cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
+}
- if ( grid->size != grid->xsize )
- {
- Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
- ncvars[ncvarid].isvar = -1;
- continue;
- }
+static
+void cdfDefGridUUID(stream_t *streamptr, int gridID)
+{
+ unsigned char uuidOfHGrid[CDI_UUID_SIZE];
- if ( ncvars[ncvarid].position > 0 ) grid->position = ncvars[ncvarid].position;
- if ( uuidOfHGrid[0] != 0 ) memcpy(grid->uuid, uuidOfHGrid, 16);
- }
+ gridInqUUID(gridID, uuidOfHGrid);
+ if ( !cdiUUIDIsNull(uuidOfHGrid) )
+ {
+ char uuidOfHGridStr[37];
+ cdiUUID2Str(uuidOfHGrid, uuidOfHGridStr);
+ if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+ {
+ int fileID = streamptr->fileID;
+ //if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
+ //if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+ }
+ }
+}
-#if defined (PROJECTION_TEST)
- if ( proj->type == GRID_PROJECTION )
- {
- if ( grid->type == GRID_GENERIC )
- {
- grid->type = GRID_CURVILINEAR;
- }
+struct cdfDefIrregularGridCommonIDs
+{
+ int xdimID, ydimID, ncxvarid, ncyvarid, ncavarid;
+};
- if ( grid->type == GRID_CURVILINEAR )
- {
- proj->size = grid->size;
- proj->xsize = grid->xsize;
- proj->ysize = grid->ysize;
- }
+static struct cdfDefIrregularGridCommonIDs
+cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
+ size_t xdimlen, size_t ydimlen,
+ int ndims, const char *xdimname_default,
+ size_t nvertex, const char *vdimname_default,
+ bool setVdimname)
+{
+ nc_type xtype = (nc_type)cdfDefDatatype(gridInqDatatype(gridID), streamptr->filetype);
+ int xdimID = CDI_UNDEFID;
+ int ydimID = CDI_UNDEFID;
+ int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
+ int ncbxvarid = CDI_UNDEFID, ncbyvarid = CDI_UNDEFID;
+ int fileID = streamptr->fileID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- // grid->proj = gridGenerate(proj);
- }
-#endif
+ {
+ char xdimname[CDI_MAX_NAME+3];
+ xdimname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, xdimname);
+ if ( xdimname[0] == 0 ) strcpy(xdimname, xdimname_default);
+ xdimID = checkDimName(fileID, xdimlen, xdimname);
+ if ( xdimID == CDI_UNDEFID ) cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
+ }
- if ( CDI_Debug )
- {
- Message("grid: type = %d, size = %d, nx = %d, ny %d",
- grid->type, grid->size, grid->xsize, grid->ysize);
- Message("proj: type = %d, size = %d, nx = %d, ny %d",
- proj->type, proj->size, proj->xsize, proj->ysize);
- }
+ if ( ndims == 3 )
+ {
+ char ydimname[CDI_MAX_NAME+3];
+ ydimname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, ydimname);
+ if ( ydimname[0] == 0 ) { ydimname[0] = 'y'; ydimname[1] = 0; }
+ ydimID = checkDimName(fileID, ydimlen, ydimname);
+ if ( ydimID == CDI_UNDEFID ) cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
+ }
-#if defined (PROJECTION_TEST)
- if ( proj->type == GRID_PROJECTION )
- {
- projAdded = cdiVlistAddGridIfNew(vlistID, proj, 1);
- ncvars[ncvarid].gridID = projAdded.Id;
- copy_numeric_projatts(ncvars[ncvarid].gridID, ncvars[ncvarid].gmapid, ncvars[ncvarid].ncid);
- }
- else
-#endif
- {
- gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 1);
- ncvars[ncvarid].gridID = gridAdded.Id;
- }
+ int nvdimID = CDI_UNDEFID;
+ int dimIDs[3];
+ dimIDs[ndims-1] = CDI_UNDEFID;
+ if ( setVdimname )
+ {
+ char vdimname[CDI_MAX_NAME+3]; vdimname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_VDIMNAME, CDI_MAX_NAME, vdimname);
+ if ( vdimname[0] == 0 ) strcpy(vdimname, vdimname_default);
+ nvdimID = dimIDs[ndims-1] = checkDimName(fileID, nvertex, vdimname);
+ if ( nvdimID == CDI_UNDEFID )
+ {
+ cdf_def_dim(fileID, vdimname, nvertex, dimIDs+ndims-1);
+ nvdimID = dimIDs[ndims-1];
+ }
+ }
- if ( grid->type == GRID_UNSTRUCTURED )
- {
- if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
- }
+ if ( ndims == 3 )
+ {
+ dimIDs[0] = ydimID;
+ dimIDs[1] = xdimID;
+ }
+ else /* ndims == 2 */
+ {
+ dimIDs[0] = xdimID;
+ cdfDefGridReference(streamptr, gridID);
+ cdfDefGridUUID(streamptr, gridID);
+ }
- if ( ncvars[ncvarid].chunked ) grid_set_chunktype(grid, &ncvars[ncvarid]);
+ const double *xvalsPtr = gridInqXvalsPtr(gridID),
+ *xboundsPtr = NULL;
+ if ( xvalsPtr )
+ {
+ char xaxisname[CDI_MAX_NAME]; xaxisname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xaxisname);
+ checkGridName(xaxisname, fileID);
+ cdf_def_var(fileID, xaxisname, xtype, ndims-1, dimIDs, &ncxvarid);
+ cdfGridCompress(fileID, ncxvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
- int gridindex = vlistGridIndex(vlistID, ncvars[ncvarid].gridID);
- streamptr->xdimID[gridindex] = xdimid;
- streamptr->ydimID[gridindex] = ydimid;
- if ( xdimid == -1 && ydimid == -1 && grid->size == 1 )
- gridDefHasDims(ncvars[ncvarid].gridID, FALSE);
+ cdfPutGridStdAtts(fileID, ncxvarid, gridID, 'X', &gridInqsX);
- if ( xdimid != -1 )
- cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_XDIMNAME, (int)(strlen(ncdims[xdimid].name)+1), ncdims[xdimid].name);
- if ( ydimid != -1 )
- cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_YDIMNAME, (int)(strlen(ncdims[ydimid].name)+1), ncdims[ydimid].name);
- if ( vdimid != -1 )
- cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_VDIMNAME, (int)(strlen(ncdims[vdimid].name)+1), ncdims[vdimid].name);
+ /* attribute for Panoply */
+ if ( ndims == 3 )
+ cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
- if ( CDI_Debug )
- Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
+ if ( (xboundsPtr = gridInqXboundsPtr(gridID)) && nvdimID != CDI_UNDEFID )
+ {
+ size_t xaxisnameLen = strlen(xaxisname);
+ xaxisname[xaxisnameLen] = '_';
+ memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
+ cdf_def_var(fileID, xaxisname, xtype, ndims, dimIDs, &ncbxvarid);
+ cdfGridCompress(fileID, ncbxvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
- for ( int ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
- if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].gridID == UNDEFID )
- {
- int xdimid2 = UNDEFID, ydimid2 = UNDEFID, zdimid2 = UNDEFID;
- int xdimidx = -1, ydimidx = -1;
- int ndims2 = ncvars[ncvarid2].ndims;
+ cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
+ }
+ }
- for ( int i = 0; i < ndims2; i++ )
- {
- if ( ncvars[ncvarid2].dimtype[i] == X_AXIS )
- { xdimid2 = ncvars[ncvarid2].dimids[i]; xdimidx = i; }
- else if ( ncvars[ncvarid2].dimtype[i] == Y_AXIS )
- { ydimid2 = ncvars[ncvarid2].dimids[i]; ydimidx = i; }
- else if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
- { zdimid2 = ncvars[ncvarid2].dimids[i]; }
- }
+ const double *yvalsPtr = gridInqYvalsPtr(gridID),
+ *yboundsPtr = NULL;
+ if ( yvalsPtr )
+ {
+ char yaxisname[CDI_MAX_NAME];
+ gridInqYname(gridID, yaxisname);
+ checkGridName(yaxisname, fileID);
- if ( ncvars[ncvarid2].gridtype == UNDEFID && grid->type == GRID_UNSTRUCTURED )
- {
- if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
- {
- ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
- ydimid2 = UNDEFID;
- }
+ cdf_def_var(fileID, yaxisname, xtype, ndims - 1, dimIDs, &ncyvarid);
+ cdfGridCompress(fileID, ncyvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
- if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
- {
- ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
- xdimid2 = ydimid2;
- ydimid2 = UNDEFID;
- }
- }
+ cdfPutGridStdAtts(fileID, ncyvarid, gridID, 'Y', &gridInqsY);
- if ( xdimid == xdimid2 &&
- (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
- {
- int same_grid = ncvars[ncvarid].xvarid == ncvars[ncvarid2].xvarid
- && ncvars[ncvarid].yvarid == ncvars[ncvarid2].yvarid
- && ncvars[ncvarid].position == ncvars[ncvarid2].position;
- /*
- if ( xvarid != -1 && ncvars[ncvarid2].xvarid != UNDEFID &&
- xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
-
- if ( yvarid != -1 && ncvars[ncvarid2].yvarid != UNDEFID &&
- yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
- */
-
- if ( same_grid )
- {
- if ( CDI_Debug )
- Message("Same gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
- ncvars[ncvarid2].gridID = ncvars[ncvarid].gridID;
- ncvars[ncvarid2].chunktype = ncvars[ncvarid].chunktype;
- }
- }
- }
+ /* attribute for Panoply */
+ if ( ndims == 3 )
+ cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
- if (gridAdded.isNew)
- lazyGrid = NULL;
- if (projAdded.isNew)
- lazyProj = NULL;
- }
- }
- if (lazyGrid)
- {
- if (CDI_netcdf_lazy_grid_load) cdfLazyGridDestroy(lazyGrid);
- grid_free(grid);
- Free(grid);
+ if ( (yboundsPtr = gridInqYboundsPtr(gridID)) && nvdimID != CDI_UNDEFID )
+ {
+ size_t yaxisnameLen = strlen(yaxisname);
+ yaxisname[yaxisnameLen] = '_';
+ memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
+ cdf_def_var(fileID, yaxisname, xtype, ndims, dimIDs, &ncbyvarid);
+ cdfGridCompress(fileID, ncbyvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
+
+ cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
+ }
}
- if (lazyProj)
+
+ const double *areaPtr = gridInqAreaPtr(gridID);
+ if ( areaPtr )
{
- if (CDI_netcdf_lazy_grid_load) cdfLazyGridDestroy(lazyProj);
- grid_free(proj);
- Free(proj);
+ static const char yaxisname_[] = "cell_area";
+ static const char units[] = "m2";
+ static const char longname[] = "area of grid cell";
+ static const char stdname[] = "cell_area";
+
+ cdf_def_var(fileID, yaxisname_, xtype, ndims-1, dimIDs, &ncavarid);
+
+ cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
+ cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
+ cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
}
-#undef proj
-#undef grid
+
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
+
+ if ( ncxvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncxvarid, xvalsPtr);
+ if ( ncbxvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, xboundsPtr);
+ if ( ncyvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncyvarid, yvalsPtr);
+ if ( ncbyvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, yboundsPtr);
+ if ( ncavarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncavarid, areaPtr);
+
+ return (struct cdfDefIrregularGridCommonIDs) {
+ .xdimID=xdimID, .ydimID = ydimID,
+ .ncxvarid=ncxvarid, .ncyvarid=ncyvarid, .ncavarid=ncavarid
+ };
}
-/* define all input zaxes */
static
-void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
- size_t vctsize_echam, double *vct_echam, unsigned char *uuidOfVGrid)
-{
- int ncvarid, ncvarid2;
- int i, ilev;
- int zaxisindex;
- int nbdims, nvertex, nlevel;
- int psvarid = -1;
- char *pname, *plongname, *punits;
- size_t vctsize = vctsize_echam;
- double *vct = vct_echam;
-
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- {
- if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].zaxisID == UNDEFID )
- {
- int is_scalar = FALSE;
- int with_bounds = FALSE;
- int zdimid = UNDEFID;
- int zvarid = UNDEFID;
- int zsize = 1;
- double *lbounds = NULL;
- double *ubounds = NULL;
+void cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex)
+{
+ ncgrid_t *ncgrid = streamptr->ncgrid;
- int positive = 0;
- int ndims = ncvars[ncvarid].ndims;
+ size_t dimlen = gridInqSize(gridID);
+ size_t xdimlen = gridInqXsize(gridID);
+ size_t ydimlen = gridInqYsize(gridID);
- if ( ncvars[ncvarid].zvarid != -1 && ncvars[ncvars[ncvarid].zvarid].ndims == 0 )
+ int xdimID = CDI_UNDEFID, ydimID = CDI_UNDEFID;
+ int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
+ {
+ size_t ofs = 0;
+ do {
+ struct idSearch search
+ = cdfSearchIDBySize(ofs, (size_t)gridindex, ncgrid, CDF_DIMID_X,
+ GRID_CURVILINEAR, (int)dimlen,
+ gridInqType, gridInqSize);
+ size_t index = search.foundIdx;
+ if ( index != SIZE_MAX )
+ {
+ int gridID0 = ncgrid[index].gridID;
+ if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0))
+ && IS_EQUAL(gridInqXval(gridID0, dimlen-1),
+ gridInqXval(gridID, dimlen-1))
+ && IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0))
+ && IS_EQUAL(gridInqYval(gridID0, dimlen-1),
+ gridInqYval(gridID, dimlen-1)) )
{
- zvarid = ncvars[ncvarid].zvarid;
- is_scalar = TRUE;
+ xdimID = ncgrid[index].ncIDs[CDF_DIMID_X];
+ ydimID = ncgrid[index].ncIDs[CDF_DIMID_Y];
+ ncxvarid = ncgrid[index].ncIDs[CDF_VARID_X];
+ ncyvarid = ncgrid[index].ncIDs[CDF_VARID_Y];
+ break;
}
- else
- {
- for ( i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvarid].dimtype[i] == Z_AXIS )
- zdimid = ncvars[ncvarid].dimids[i];
- }
+ ofs = search.foundIdx;
+ if ( ofs < (size_t)gridindex )
+ continue;
+ }
+ } while (false);
+ }
- if ( zdimid != UNDEFID )
- {
- zvarid = ncdims[zdimid].ncvarid;
- zsize = (int)ncdims[zdimid].len;
- }
- }
+ if ( xdimID == CDI_UNDEFID || ydimID == CDI_UNDEFID )
+ {
+ struct cdfDefIrregularGridCommonIDs createdIDs
+ = cdfDefIrregularGridCommon(streamptr, gridID,
+ xdimlen, ydimlen, 3, "x", 4, "nv4",
+ gridInqXboundsPtr(gridID)
+ || gridInqYboundsPtr(gridID));
+ xdimID = createdIDs.xdimID;
+ ydimID = createdIDs.ydimID;
+ ncxvarid = createdIDs.ncxvarid;
+ ncyvarid = createdIDs.ncyvarid;
+ ncavarid = createdIDs.ncavarid;
+ }
- if ( CDI_Debug ) Message("nlevs = %d", zsize);
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimID;
+ ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid;
+ ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid;
+ ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid;
+}
- double *zvar = (double *) Malloc((size_t)zsize * sizeof (double));
- int zaxisType = UNDEFID;
- if ( zvarid != UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
- if ( zaxisType == UNDEFID ) zaxisType = ZAXIS_GENERIC;
+static
+void cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex)
+{
+ ncgrid_t *ncgrid = streamptr->ncgrid;
- int zprec = DATATYPE_FLT64;
+ size_t dimlen = gridInqSize(gridID);
- if ( zvarid != UNDEFID )
- {
- positive = ncvars[zvarid].positive;
- pname = ncvars[zvarid].name;
- plongname = ncvars[zvarid].longname;
- punits = ncvars[zvarid].units;
- if ( ncvars[zvarid].xtype == NC_FLOAT ) zprec = DATATYPE_FLT32;
- /* don't change the name !!! */
- /*
- if ( (len = strlen(pname)) > 2 )
- if ( pname[len-2] == '_' && isdigit((int) pname[len-1]) )
- pname[len-2] = 0;
- */
- psvarid = -1;
- if ( zaxisType == ZAXIS_HYBRID && ncvars[zvarid].vct )
- {
- vct = ncvars[zvarid].vct;
- vctsize = ncvars[zvarid].vctsize;
+ int dimID = CDI_UNDEFID;
+ int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
+ {
+ size_t ofs = 0;
+ do {
+ struct idSearch search
+ = cdfSearchIDBySize(ofs, (size_t)gridindex, ncgrid, CDF_DIMID_X,
+ GRID_UNSTRUCTURED, (int)dimlen,
+ gridInqType, gridInqSize);
+ size_t index = search.foundIdx;
+ if ( index != SIZE_MAX )
+ {
+ int gridID0 = ncgrid[index].gridID;
+ if ( gridInqNvertex(gridID0) == gridInqNvertex(gridID) &&
+ IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
+ IS_EQUAL(gridInqXval(gridID0, dimlen-1),
+ gridInqXval(gridID, dimlen-1)) &&
+ IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
+ IS_EQUAL(gridInqYval(gridID0, dimlen-1),
+ gridInqYval(gridID, dimlen-1)) )
+ {
+ dimID = ncgrid[index].ncIDs[CDF_DIMID_X];
+ ncxvarid = ncgrid[index].ncIDs[CDF_VARID_X];
+ ncyvarid = ncgrid[index].ncIDs[CDF_VARID_Y];
+ ncavarid = ncgrid[index].ncIDs[CDF_VARID_A];
+ break;
+ }
+ ofs = search.foundIdx;
+ if ( ofs < (size_t)gridindex )
+ continue;
+ }
+ } while (false);
+ }
- if ( ncvars[zvarid].psvarid != -1 ) psvarid = ncvars[zvarid].psvarid;
- }
+ if ( dimID == CDI_UNDEFID )
+ {
+ size_t nvertex = (size_t)gridInqNvertex(gridID);
+ struct cdfDefIrregularGridCommonIDs createdIDs
+ = cdfDefIrregularGridCommon(streamptr, gridID,
+ dimlen, 1, 2, "ncells",
+ nvertex, "vertices", nvertex > 0);
+ dimID = createdIDs.xdimID;
+ ncxvarid = createdIDs.ncxvarid;
+ ncyvarid = createdIDs.ncyvarid;
+ ncavarid = createdIDs.ncavarid;
+ }
- cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+ ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid;
+ ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid;
+ ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid;
+}
- if ( ncvars[zvarid].bounds != UNDEFID )
- {
- nbdims = ncvars[ncvars[zvarid].bounds].ndims;
- if ( nbdims == 2 )
- {
- nlevel = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
- nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1]].len;
- if ( nlevel == zsize && nvertex == 2 )
- {
- with_bounds = TRUE;
- lbounds = (double *) Malloc((size_t)nlevel*sizeof(double));
- ubounds = (double *) Malloc((size_t)nlevel*sizeof(double));
- double zbounds[2*nlevel];
- cdf_get_var_double(ncvars[zvarid].ncid, ncvars[zvarid].bounds, zbounds);
- for ( i = 0; i < nlevel; ++i )
- {
- lbounds[i] = zbounds[i*2];
- ubounds[i] = zbounds[i*2+1];
- }
- }
- }
- }
- }
- else
- {
- pname = NULL;
- plongname = NULL;
- punits = NULL;
+struct attTxtTab2
+{
+ const char *attName, *attVal;
+ size_t valLen;
+};
- if ( zsize == 1 )
- {
- if ( ncvars[ncvarid].zaxistype != UNDEFID )
- zaxisType = ncvars[ncvarid].zaxistype;
- else
- zaxisType = ZAXIS_SURFACE;
+static
+void cdf_def_vct_echam(stream_t *streamptr, int zaxisID)
+{
+ int type = zaxisInqType(zaxisID);
+
+ if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+ {
+ int ilev = zaxisInqVctSize(zaxisID)/2;
+ if ( ilev == 0 ) return;
+
+ int mlev = ilev - 1;
+
+ if ( streamptr->vct.ilev > 0 )
+ {
+ if ( streamptr->vct.ilev != ilev )
+ Error("More than one VCT for each file unsupported!");
+ return;
+ }
- zvar[0] = 0;
- /*
- if ( zdimid == UNDEFID )
- zvar[0] = 9999;
- else
- zvar[0] = 0;
- */
- }
- else
- {
- for ( ilev = 0; ilev < zsize; ilev++ ) zvar[ilev] = ilev + 1;
- }
- }
+ int fileID = streamptr->fileID;
- ncvars[ncvarid].zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, with_bounds, lbounds, ubounds,
- (int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- if ( uuidOfVGrid[0] != 0 )
- {
- // printf("uuidOfVGrid: defined\n");
- zaxisDefUUID(ncvars[ncvarid].zaxisID, uuidOfVGrid);
- }
+ int ncdimid = -1, ncdimid2 = -1;
+ int hyaiid, hybiid, hyamid = -1, hybmid = -1;
- if ( zaxisType == ZAXIS_HYBRID && psvarid != -1 ) zaxisDefPsName(ncvars[ncvarid].zaxisID, ncvars[psvarid].name);
+ cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
+ cdf_def_var(fileID, "hyai", NC_DOUBLE, 1, &ncdimid2, &hyaiid);
+ cdf_def_var(fileID, "hybi", NC_DOUBLE, 1, &ncdimid2, &hybiid);
+ if ( mlev > 0 )
+ {
+ cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
+ cdf_def_var(fileID, "hyam", NC_DOUBLE, 1, &ncdimid, &hyamid);
+ cdf_def_var(fileID, "hybm", NC_DOUBLE, 1, &ncdimid, &hybmid);
+ }
- if ( positive > 0 ) zaxisDefPositive(ncvars[ncvarid].zaxisID, positive);
- if ( is_scalar ) zaxisDefScalar(ncvars[ncvarid].zaxisID);
+ streamptr->vct.ilev = ilev;
+ streamptr->vct.mlev = mlev;
+ streamptr->vct.mlevID = ncdimid;
+ streamptr->vct.ilevID = ncdimid2;
- if ( zdimid != -1 )
- cdiZaxisDefString(ncvars[ncvarid].zaxisID, CDI_ZAXIS_DIMNAME, (int)(strlen(ncdims[zdimid].name)+1), ncdims[zdimid].name);
- /*
- if ( vdimid != -1 )
- cdiZaxisDefString(ncvars[ncvarid].zaxisID, CDI_ZAXIS_VDIMNAME, strlen(ncdims[vdimid].name)+1, ncdims[vdimid].name);
- */
- Free(zvar);
- Free(lbounds);
- Free(ubounds);
+ {
+ static const char lname_n[] = "long_name",
+ units_n[] = "units",
+ lname_v_ai[] = "hybrid A coefficient at layer interfaces",
+ units_v_ai[] = "Pa",
+ lname_v_bi[] = "hybrid B coefficient at layer interfaces",
+ units_v_bi[] = "1";
+ static const struct attTxtTab2 tab[]
+ = {
+ { lname_n, lname_v_ai, sizeof (lname_v_ai) - 1 },
+ { units_n, units_v_ai, sizeof (units_v_ai) - 1 },
+ { lname_n, lname_v_bi, sizeof (lname_v_bi) - 1 },
+ { units_n, units_v_bi, sizeof (units_v_bi) - 1 },
+ };
+ enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
+ int ids[tabLen] = { hyaiid, hyaiid, hybiid, hybiid };
+ for ( size_t i = 0; i < tabLen; ++i )
+ cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
+ }
- zaxisindex = vlistZaxisIndex(vlistID, ncvars[ncvarid].zaxisID);
- streamptr->zaxisID[zaxisindex] = zdimid;
+ {
+ static const char lname_n[] = "long_name",
+ units_n[] = "units",
+ lname_v_am[] = "hybrid A coefficient at layer midpoints",
+ units_v_am[] = "Pa",
+ lname_v_bm[] = "hybrid B coefficient at layer midpoints",
+ units_v_bm[] = "1";
+ static const struct attTxtTab2 tab[]
+ = {
+ { lname_n, lname_v_am, sizeof (lname_v_am) - 1 },
+ { units_n, units_v_am, sizeof (units_v_am) - 1 },
+ { lname_n, lname_v_bm, sizeof (lname_v_bm) - 1 },
+ { units_n, units_v_bm, sizeof (units_v_bm) - 1 },
+ };
+ enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
+ int ids[tabLen] = { hyamid, hyamid, hybmid, hybmid };
+ for ( size_t i = 0; i < tabLen; ++i )
+ cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
+ }
- if ( CDI_Debug )
- Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
- for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
- if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID /*&& ncvars[ncvarid2].zaxistype == UNDEFID*/ )
- {
- int zvarid2 = UNDEFID;
- if ( ncvars[ncvarid2].zvarid != UNDEFID && ncvars[ncvars[ncvarid2].zvarid].ndims == 0 )
- zvarid2 = ncvars[ncvarid2].zvarid;
+ const double *vctptr = zaxisInqVctPtr(zaxisID);
- int zdimid2 = UNDEFID;
- ndims = ncvars[ncvarid2].ndims;
- for ( i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
- zdimid2 = ncvars[ncvarid2].dimids[i];
- }
+ cdf_put_var_double(fileID, hyaiid, vctptr);
+ cdf_put_var_double(fileID, hybiid, vctptr+ilev);
- if ( zdimid == zdimid2 /* && zvarid == zvarid2 */)
- {
- if ( (zdimid != UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID) ||
- (zdimid == UNDEFID && zvarid != UNDEFID && zvarid == zvarid2) ||
- (zdimid == UNDEFID && zaxisType == ncvars[ncvarid2].zaxistype) ||
- (zdimid == UNDEFID && zvarid2 == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID) )
- {
- if ( CDI_Debug )
- Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid2, ncvars[ncvarid2].name);
- ncvars[ncvarid2].zaxisID = ncvars[ncvarid].zaxisID;
- }
- }
- }
- }
+ size_t start;
+ size_t count = 1;
+ double mval;
+ for ( int i = 0; i < mlev; i++ )
+ {
+ start = (size_t)i;
+ mval = (vctptr[i] + vctptr[i+1]) * 0.5;
+ cdf_put_vara_double(fileID, hyamid, &start, &count, &mval);
+ mval = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
+ cdf_put_vara_double(fileID, hybmid, &start, &count, &mval);
+ }
}
}
-struct varinfo
-{
- int ncvarid;
- const char *name;
-};
-
static
-int cmpvarname(const void *s1, const void *s2)
+void cdf_def_vct_cf(stream_t *streamptr, int zaxisID, int nclevID, int ncbndsID, int p0status, double p0value)
{
- const struct varinfo *x = (const struct varinfo *)s1,
- *y = (const struct varinfo *)s2;
- return (strcmp(x->name, y->name));
-}
+ int type = zaxisInqType(zaxisID);
-/* define all input data variables */
-static
-void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, int num_ncvars, ncvar_t *ncvars)
-{
- if ( CDI_Debug )
- {
- for(int i = 0; i < nvars; i++) Message("varids[%d] = %d", i, varids[i]);
- }
- if ( streamptr->sortname )
+ if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
{
- struct varinfo *varInfo
- = (struct varinfo *) Malloc((size_t)nvars * sizeof (struct varinfo));
+ int ilev = zaxisInqVctSize(zaxisID)/2;
+ if ( ilev == 0 ) return;
- for ( int varID = 0; varID < nvars; varID++ )
- {
- int ncvarid = varids[varID];
- varInfo[varID].ncvarid = ncvarid;
- varInfo[varID].name = ncvars[ncvarid].name;
- }
- qsort(varInfo, (size_t)nvars, sizeof(varInfo[0]), cmpvarname);
- for ( int varID = 0; varID < nvars; varID++ )
- {
- varids[varID] = varInfo[varID].ncvarid;
- }
- Free(varInfo);
- if ( CDI_Debug )
+ int mlev = ilev - 1;
+ int hyaiid = 0, hybiid = 0, hyamid, hybmid;
+
+ if ( streamptr->vct.ilev > 0 )
{
- for(int i = 0; i < nvars; i++) Message("sorted varids[%d] = %d", i, varids[i]);
+ if ( streamptr->vct.ilev != ilev )
+ Error("more than one VCT for each file unsupported!");
+ return;
}
- }
-
- for ( int varID1 = 0; varID1 < nvars; varID1++ )
- {
- int ncvarid = varids[varID1];
- int gridID = ncvars[ncvarid].gridID;
- int zaxisID = ncvars[ncvarid].zaxisID;
-
- stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
- int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
-
-#if defined (HAVE_NETCDF4)
- if ( ncvars[ncvarid].deflate )
- vlistDefVarCompType(vlistID, varID, COMPRESS_ZIP);
- if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != UNDEFID )
- vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
-#endif
-
- streamptr->vars[varID1].defmiss = 0;
- streamptr->vars[varID1].ncvarid = ncvarid;
+ int fileID = streamptr->fileID;
- vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
- if ( ncvars[ncvarid].param != UNDEFID ) vlistDefVarParam(vlistID, varID, ncvars[ncvarid].param);
- if ( ncvars[ncvarid].code != UNDEFID ) vlistDefVarCode(vlistID, varID, ncvars[ncvarid].code);
- if ( ncvars[ncvarid].code != UNDEFID )
- {
- int param = cdiEncodeParam(ncvars[ncvarid].code, ncvars[ncvarid].tabnum, 255);
- vlistDefVarParam(vlistID, varID, param);
- }
- if ( ncvars[ncvarid].longname[0] ) vlistDefVarLongname(vlistID, varID, ncvars[ncvarid].longname);
- if ( ncvars[ncvarid].stdname[0] ) vlistDefVarStdname(vlistID, varID, ncvars[ncvarid].stdname);
- if ( ncvars[ncvarid].units[0] ) vlistDefVarUnits(vlistID, varID, ncvars[ncvarid].units);
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- if ( ncvars[ncvarid].lvalidrange )
- vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
+ int dimIDs[2];
+ dimIDs[0] = nclevID;
+ dimIDs[1] = ncbndsID;
- if ( IS_NOT_EQUAL(ncvars[ncvarid].addoffset, 0) )
- vlistDefVarAddoffset(vlistID, varID, ncvars[ncvarid].addoffset);
- if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
- vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
+ streamptr->vct.mlev = mlev;
+ streamptr->vct.ilev = ilev;
+ streamptr->vct.mlevID = nclevID;
+ streamptr->vct.ilevID = nclevID;
- vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
+ if ( p0status == 0 )
+ cdf_def_var(fileID, "a", NC_DOUBLE, 1, dimIDs, &hyamid);
+ else
+ cdf_def_var(fileID, "ap", NC_DOUBLE, 1, dimIDs, &hyamid);
+ cdf_def_var(fileID, "b", NC_DOUBLE, 1, dimIDs, &hybmid);
- vlistDefVarInstitut(vlistID, varID, instID);
- vlistDefVarModel(vlistID, varID, modelID);
- if ( ncvars[ncvarid].tableID != UNDEFID )
- vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
+ {
+ static const char lname[] = "vertical coordinate formula term: ap(k)";
+ cdf_put_att_text(fileID, hyamid, "long_name", sizeof (lname) - 1, lname);
+ }
+ {
+ static const char units[] = "Pa";
+ cdf_put_att_text(fileID, hyamid, "units", sizeof (units) - 1, units);
+ }
+ {
+ static const char lname[] = "vertical coordinate formula term: b(k)";
+ cdf_put_att_text(fileID, hybmid, "long_name", sizeof (lname) - 1, lname);
+ }
+ {
+ static const char units[] = "1";
+ cdf_put_att_text(fileID, hybmid, "units", sizeof (units) - 1, units);
+ }
- if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
+ if ( ncbndsID != -1 )
{
- ncvars[ncvarid].deffillval = TRUE;
- ncvars[ncvarid].fillval = ncvars[ncvarid].missval;
+ if ( p0status == 0 )
+ cdf_def_var(fileID, "a_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
+ else
+ cdf_def_var(fileID, "ap_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
+ cdf_def_var(fileID, "b_bnds", NC_DOUBLE, 2, dimIDs, &hybiid);
+ {
+ static const char lname[] = "vertical coordinate formula term: ap(k+1/2)";
+ cdf_put_att_text(fileID, hyaiid, "long_name", sizeof (lname) - 1, lname);
+ }
+ {
+ static const char units[] = "Pa";
+ cdf_put_att_text(fileID, hyaiid, "units", sizeof (units) - 1, units);
+ }
+ {
+ static const char lname[] = "vertical coordinate formula term: b(k+1/2)";
+ cdf_put_att_text(fileID, hybiid, "long_name", sizeof (lname) - 1, lname);
+ }
+ {
+ static const char units[] = "1";
+ cdf_put_att_text(fileID, hybiid, "units", sizeof (units) - 1, units);
+ }
}
- if ( ncvars[ncvarid].deffillval == TRUE )
- vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
-
- if ( CDI_Debug )
- Message("varID = %d gridID = %d zaxisID = %d", varID,
- vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
-
- int gridindex = vlistGridIndex(vlistID, gridID);
- int xdimid = streamptr->xdimID[gridindex];
- int ydimid = streamptr->ydimID[gridindex];
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
- int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
- int zdimid = streamptr->zaxisID[zaxisindex];
+ int vctsize = zaxisInqVctSize(zaxisID);
+ double vct[vctsize];
+ zaxisInqVct(zaxisID, vct);
- int ndims = ncvars[ncvarid].ndims;
- int iodim = 0;
- int ixyz = 0;
- int ipow10[4] = {1, 10, 100, 1000};
+ if ( p0status == 0 && IS_NOT_EQUAL(p0value,0) )
+ for ( int i = 0; i < vctsize/2; ++i ) vct[i] /= p0value;
- if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
+ double tarray[ilev*2];
- if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
+ if ( ncbndsID != -1 )
{
- if ( xdimid == ncvars[ncvarid].dimids[ndims-1] )
- {
- ixyz = 321;
- }
- else
+ for ( int i = 0; i < mlev; ++i )
{
- ixyz = 213;
+ tarray[2*i ] = vct[i];
+ tarray[2*i+1] = vct[i+1];
}
- }
- else
- {
- for ( int idim = iodim; idim < ndims; idim++ )
+ cdf_put_var_double(fileID, hyaiid, tarray);
+
+ for ( int i = 0; i < mlev; ++i )
{
- if ( xdimid == ncvars[ncvarid].dimids[idim] )
- ixyz += 1*ipow10[ndims-idim-1];
- else if ( ydimid == ncvars[ncvarid].dimids[idim] )
- ixyz += 2*ipow10[ndims-idim-1];
- else if ( zdimid == ncvars[ncvarid].dimids[idim] )
- ixyz += 3*ipow10[ndims-idim-1];
+ tarray[2*i ] = vct[ilev+i];
+ tarray[2*i+1] = vct[ilev+i+1];
}
+ cdf_put_var_double(fileID, hybiid, tarray);
}
- vlistDefVarXYZ(vlistID, varID, ixyz);
- /*
- printf("ixyz %d\n", ixyz);
- printf("ndims %d\n", ncvars[ncvarid].ndims);
- for ( int i = 0; i < ncvars[ncvarid].ndims; ++i )
- printf("dimids: %d %d\n", i, ncvars[ncvarid].dimids[i]);
- printf("xdimid, ydimid %d %d\n", xdimid, ydimid);
- */
- if ( ncvars[ncvarid].ensdata != NULL )
- {
- vlistDefVarEnsemble( vlistID, varID, ncvars[ncvarid].ensdata->ens_index,
- ncvars[ncvarid].ensdata->ens_count,
- ncvars[ncvarid].ensdata->forecast_init_type );
- Free(ncvars[ncvarid].ensdata);
- ncvars[ncvarid].ensdata = NULL;
- }
+ for ( int i = 0; i < mlev; ++i )
+ tarray[i] = (vct[i] + vct[i+1]) * 0.5;
+ cdf_put_var_double(fileID, hyamid, tarray);
- if ( ncvars[ncvarid].extra[0] != 0 )
- {
- vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
- }
+ for ( int i = 0; i < mlev; ++i )
+ tarray[i] = (vct[ilev+i] + vct[ilev+i+1]) * 0.5;
+ cdf_put_var_double(fileID, hybmid, tarray);
}
+}
- for ( int varID = 0; varID < nvars; varID++ )
- {
- int ncvarid = varids[varID];
- int ncid = ncvars[ncvarid].ncid;
+struct attTxtTab { const char *txt; size_t txtLen; };
- if ( ncvars[ncvarid].natts )
- {
- int attnum;
- int iatt;
- nc_type attrtype;
- size_t attlen;
- char attname[CDI_MAX_NAME];
- const int attstringlen = 8192; char attstring[8192];
- int nvatts = ncvars[ncvarid].natts;
-
- for ( iatt = 0; iatt < nvatts; iatt++ )
- {
- attnum = ncvars[ncvarid].atts[iatt];
- cdf_inq_attname(ncid, ncvarid, attnum, attname);
- cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
- cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
+static
+void cdf_def_zaxis_hybrid_echam(stream_t *streamptr, int type, int *ncvaridp, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+{
+ int fileID = streamptr->fileID;
- if ( attrtype == NC_SHORT || attrtype == NC_INT )
- {
- int attint[attlen];
- cdfGetAttInt(ncid, ncvarid, attname, (int)attlen, attint);
- if ( attrtype == NC_SHORT )
- vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT16, (int)attlen, attint);
- else
- vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT32, (int)attlen, attint);
- }
- else if ( attrtype == NC_FLOAT || attrtype == NC_DOUBLE )
- {
- double attflt[attlen];
- cdfGetAttDouble(ncid, ncvarid, attname, (int)attlen, attflt);
- if ( attrtype == NC_FLOAT )
- vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT32, (int)attlen, attflt);
- else
- vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT64, (int)attlen, attflt);
- }
- else if ( xtypeIsText(attrtype) )
- {
- cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
- vlistDefAttTxt(vlistID, varID, attname, (int)attlen, attstring);
- }
- else
- {
- if ( CDI_Debug ) printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
- }
- }
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- if (ncvars[ncvarid].vct) Free(ncvars[ncvarid].vct);
- if (ncvars[ncvarid].atts) Free(ncvars[ncvarid].atts);
- ncvars[ncvarid].vct = NULL;
- ncvars[ncvarid].atts = NULL;
- }
- }
+ cdf_def_dim(fileID, axisname, dimlen, dimID);
+ cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID, ncvaridp);
+ int ncvarid = *ncvaridp;
- /* release mem of not freed attributes */
- for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
- if ( ncvars[ncvarid].atts ) Free(ncvars[ncvarid].atts);
+ {
+ static const char sname[] = "hybrid_sigma_pressure";
+ cdf_put_att_text(fileID, ncvarid, "standard_name", sizeof (sname) - 1, sname);
+ }
+ {
+ static const char *attName[] = {
+ "long_name",
+ "formula",
+ "formula_terms"
+ };
+ enum { nAtt = sizeof (attName) / sizeof (attName[0]) };
+ static const char lname_m[] = "hybrid level at layer midpoints",
+ formula_m[] = "hyam hybm (mlev=hyam+hybm*aps)",
+ fterms_m[] = "ap: hyam b: hybm ps: aps",
+ lname_i[] = "hybrid level at layer interfaces",
+ formula_i[] = "hyai hybi (ilev=hyai+hybi*aps)",
+ fterms_i[] = "ap: hyai b: hybi ps: aps";
+ static const struct attTxtTab tab[2][nAtt] = {
+ {
+ { lname_i, sizeof (lname_i) - 1 },
+ { formula_i, sizeof (formula_i) - 1 },
+ { fterms_i, sizeof (fterms_i) - 1 }
+ },
+ {
+ { lname_m, sizeof (lname_m) - 1 },
+ { formula_m, sizeof (formula_m) - 1 },
+ { fterms_m, sizeof (fterms_m) - 1 }
+ }
+ };
- if ( varids ) Free(varids);
+ size_t tabSelect = type == ZAXIS_HYBRID;
+ for (size_t i = 0; i < nAtt; ++i)
+ cdf_put_att_text(fileID, ncvarid, attName[i],
+ tab[tabSelect][i].txtLen, tab[tabSelect][i].txt);
+ }
- for ( int varID = 0; varID < nvars; varID++ )
- {
- if ( vlistInqVarCode(vlistID, varID) == -varID-1 )
- {
- const char *pname = vlistInqVarNamePtr(vlistID, varID);
- size_t len = strlen(pname);
- if ( len > 3 && isdigit((int) pname[3]) )
- {
- if ( memcmp("var", pname, 3) == 0 )
- {
- vlistDefVarCode(vlistID, varID, atoi(pname+3));
- // vlistDestroyVarName(vlistID, varID);
- }
- }
- else if ( len > 4 && isdigit((int) pname[4]) )
- {
- if ( memcmp("code", pname, 4) == 0 )
- {
- vlistDefVarCode(vlistID, varID, atoi(pname+4));
- // vlistDestroyVarName(vlistID, varID);
- }
- }
- else if ( len > 5 && isdigit((int) pname[5]) )
- {
- if ( memcmp("param", pname, 5) == 0 )
- {
- int pnum = -1, pcat = 255, pdis = 255;
- sscanf(pname+5, "%d.%d.%d", &pnum, &pcat, &pdis);
- vlistDefVarParam(vlistID, varID, cdiEncodeParam(pnum, pcat, pdis));
- // vlistDestroyVarName(vlistID, varID);
- }
- }
- }
- }
+ {
+ static const char units[] = "level";
+ cdf_put_att_text(fileID, ncvarid, "units", sizeof (units) - 1, units);
+ }
+ {
+ static const char direction[] = "down";
+ cdf_put_att_text(fileID, ncvarid, "positive", sizeof (direction) - 1, direction);
+ }
- for ( int varID = 0; varID < nvars; varID++ )
- {
- int varInstID = vlistInqVarInstitut(vlistID, varID);
- int varModelID = vlistInqVarModel(vlistID, varID);
- int varTableID = vlistInqVarTable(vlistID, varID);
- int code = vlistInqVarCode(vlistID, varID);
- if ( cdiDefaultTableID != UNDEFID )
- {
- if ( tableInqParNamePtr(cdiDefaultTableID, code) )
- {
- vlistDestroyVarName(vlistID, varID);
- vlistDestroyVarLongname(vlistID, varID);
- vlistDestroyVarUnits(vlistID, varID);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
- if ( varTableID != UNDEFID )
- {
- vlistDefVarName(vlistID, varID, tableInqParNamePtr(cdiDefaultTableID, code));
- if ( tableInqParLongnamePtr(cdiDefaultTableID, code) )
- vlistDefVarLongname(vlistID, varID, tableInqParLongnamePtr(cdiDefaultTableID, code));
- if ( tableInqParUnitsPtr(cdiDefaultTableID, code) )
- vlistDefVarUnits(vlistID, varID, tableInqParUnitsPtr(cdiDefaultTableID, code));
- }
- else
- {
- varTableID = cdiDefaultTableID;
- }
- }
+ cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
- if ( cdiDefaultModelID != UNDEFID ) varModelID = cdiDefaultModelID;
- if ( cdiDefaultInstID != UNDEFID ) varInstID = cdiDefaultInstID;
- }
- if ( varInstID != UNDEFID ) vlistDefVarInstitut(vlistID, varID, varInstID);
- if ( varModelID != UNDEFID ) vlistDefVarModel(vlistID, varID, varModelID);
- if ( varTableID != UNDEFID ) vlistDefVarTable(vlistID, varID, varTableID);
- }
+ cdf_def_vct_echam(streamptr, zaxisID);
+
+ if ( *dimID == CDI_UNDEFID )
+ streamptr->zaxisID[zaxisindex] = type == ZAXIS_HYBRID
+ ? streamptr->vct.mlevID : streamptr->vct.ilevID;
}
static
-void scan_global_attributes(int fileID, int vlistID, stream_t *streamptr, int ngatts, int *instID, int *modelID, int *ucla_les, unsigned char *uuidOfHGrid, unsigned char *uuidOfVGrid, char *gridfile, int *number_of_grid_used)
+void cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int *ncvaridp, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
{
- nc_type xtype;
- size_t attlen;
- char attname[CDI_MAX_NAME];
- enum { attstringlen = 65636 };
- char attstring[attstringlen];
- int iatt;
+ int fileID = streamptr->fileID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- for ( iatt = 0; iatt < ngatts; iatt++ )
- {
- cdf_inq_attname(fileID, NC_GLOBAL, iatt, attname);
- cdf_inq_atttype(fileID, NC_GLOBAL, attname, &xtype);
- cdf_inq_attlen(fileID, NC_GLOBAL, attname, &attlen);
+ char psname[CDI_MAX_NAME]; psname[0] = 0;
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_PSNAME, CDI_MAX_NAME, psname);
+ if ( psname[0] == 0 ) strcpy(psname, "ps");
- if ( xtypeIsText(xtype) )
- {
- cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen, attstring);
+ char p0name[CDI_MAX_NAME]; p0name[0] = 0;
+ double p0value = 1;
+ int p0varid = CDI_UNDEFID;
+ int p0status = cdiZaxisInqKeyFlt(zaxisID, CDI_KEY_P0VALUE, &p0value);
+ if ( p0status == 0 )
+ {
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_P0NAME, CDI_MAX_NAME, p0name);
+ if ( p0name[0] == 0 ) strcpy(p0name, "p0");
+ cdf_def_var(fileID, p0name, NC_DOUBLE, 0, 0, &p0varid);
+ static const char longname[] = "reference pressure";
+ cdf_put_att_text(fileID, p0varid, "long_name", strlen(longname), longname);
+ static const char units[] = "Pa";
+ cdf_put_att_text(fileID, p0varid, "units", strlen(units), units);
+ }
+
+ char zname[CDI_MAX_NAME]; zname[0] = 0;
+ char zlongname[CDI_MAX_NAME]; zlongname[0] = 0;
+ char zunits[CDI_MAX_NAME]; zunits[0] = 0;
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, zname);
+ //cdiZaxisInqKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, zlongname);
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, zunits);
+ if ( zname[0] ) strcpy(axisname, zname);
+ if ( zlongname[0] == 0 ) strcpy(zlongname, "hybrid sigma pressure coordinate");
+ if ( zunits[0] == 0 ) strcpy(zunits, "1");
- size_t attstrlen = strlen(attstring);
+ cdf_def_dim(fileID, axisname, dimlen, dimID);
+ cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID, ncvaridp);
+ int ncvarid = *ncvaridp;
- if ( attlen > 0 && attstring[0] != 0 )
- {
- if ( strcmp(attname, "history") == 0 )
- {
- streamptr->historyID = iatt;
- }
- else if ( strcmp(attname, "institution") == 0 )
- {
- *instID = institutInq(0, 0, NULL, attstring);
- if ( *instID == UNDEFID )
- *instID = institutDef(0, 0, NULL, attstring);
- }
- else if ( strcmp(attname, "source") == 0 )
- {
- *modelID = modelInq(-1, 0, attstring);
- if ( *modelID == UNDEFID )
- *modelID = modelDef(-1, 0, attstring);
- }
- else if ( strcmp(attname, "Source") == 0 )
- {
- if ( strncmp(attstring, "UCLA-LES", 8) == 0 )
- *ucla_les = TRUE;
- }
- /*
- else if ( strcmp(attname, "Conventions") == 0 )
- {
- }
- */
- else if ( strcmp(attname, "CDI") == 0 )
- {
- }
- else if ( strcmp(attname, "CDO") == 0 )
- {
- }
- /*
- else if ( strcmp(attname, "forecast_reference_time") == 0 )
- {
- memcpy(fcreftime, attstring, attstrlen+1);
- }
- */
- else if ( strcmp(attname, "grid_file_uri") == 0 )
- {
- memcpy(gridfile, attstring, attstrlen+1);
- }
- else if ( strcmp(attname, "uuidOfHGrid") == 0 && attstrlen == 36 )
- {
- attstring[36] = 0;
- cdiStr2UUID(attstring, uuidOfHGrid);
- // printf("uuid: %d %s\n", attlen, attstring);
- }
- else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
- {
- attstring[36] = 0;
- cdiStr2UUID(attstring, uuidOfVGrid);
- }
- else
- {
- if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
- {
- memcpy(gridfile, attstring, attstrlen+1);
- }
+ {
+ static const char sname[] = "standard_name",
+ sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
+ axis[] = "axis",
+ axis_v[] = "Z",
+ direction[] = "positive",
+ direction_v[] = "down";
+ struct attTxtTab2 tab[] = {
+ { sname, sname_v, sizeof (sname_v) - 1 },
+ { axis, axis_v, sizeof (axis_v) - 1 },
+ { direction, direction_v, sizeof (direction_v) - 1 },
+ };
+ enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
+ for ( size_t i = 0; i < nAtt; ++i )
+ cdf_put_att_text(fileID, ncvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
- vlistDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attstrlen, attstring);
- }
- }
- }
- else if ( xtype == NC_SHORT || xtype == NC_INT )
- {
- if ( strcmp(attname, "number_of_grid_used") == 0 )
- {
- (*number_of_grid_used) = UNDEFID;
- cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
- }
- else
- {
- int attint[attlen];
- cdfGetAttInt(fileID, NC_GLOBAL, attname, (int)attlen, attint);
- if ( xtype == NC_SHORT )
- vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
- else
- vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
- }
+ cdf_put_att_text(fileID, ncvarid, "long_name", strlen(zlongname), zlongname);
+ cdf_put_att_text(fileID, ncvarid, "units", strlen(zunits), zunits);
+ }
+
+ size_t len = 0;
+ char txt[CDI_MAX_NAME];
+ if ( p0status == 0 )
+ len = (size_t)(sprintf(txt, "%s%s %s%s", "a: a b: b p0: ", p0name, "ps: ", psname));
+ else
+ len = (size_t)(sprintf(txt, "%s%s", "ap: ap b: b ps: ", psname));
+ cdf_put_att_text(fileID, ncvarid, "formula_terms", len, txt);
+
+ int ncbvarid = CDI_UNDEFID;
+ int nvdimID = CDI_UNDEFID;
+
+ double lbounds[dimlen], ubounds[dimlen], levels[dimlen];
+
+ if ( zaxisInqLevels(zaxisID, NULL) )
+ zaxisInqLevels(zaxisID, levels);
+ else
+ for ( size_t i = 0; i < dimlen; ++i ) levels[i] = i+1;
+
+ if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+ {
+ zaxisInqLbounds(zaxisID, lbounds);
+ zaxisInqUbounds(zaxisID, ubounds);
+ }
+ else
+ {
+ for ( size_t i = 0; i < dimlen; ++i ) lbounds[i] = levels[i];
+ for ( size_t i = 0; i < dimlen-1; ++i ) ubounds[i] = levels[i+1];
+ ubounds[dimlen-1] = levels[dimlen-1] + 1;
+ }
+
+ //if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+ {
+ size_t nvertex = 2;
+ if ( dimlen > 1 && nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
+ cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+
+ if ( nvdimID != CDI_UNDEFID )
+ {
+ size_t axisnameLen = strlen(axisname);
+ axisname[axisnameLen] = '_';
+ memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
+ axisnameLen += sizeof (bndsName);
+ int dimIDs[2] = { *dimID, nvdimID };
+ cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
+ cdf_put_att_text(fileID, ncvarid, "bounds", axisnameLen, axisname);
+ {
+ static const char sname[] = "standard_name",
+ sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate";
+ struct attTxtTab2 tab[] = {
+ { sname, sname_v, sizeof (sname_v) - 1 },
+ };
+ enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
+ for ( size_t i = 0; i < nAtt; ++i )
+ cdf_put_att_text(fileID, ncbvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
+ cdf_put_att_text(fileID, ncbvarid, "units", strlen(zunits), zunits);
+ }
+
+ if ( p0status == 0 )
+ len = (size_t)(sprintf(txt, "%s%s %s%s", "a: a_bnds b: b_bnds p0: ", p0name, "ps: ", psname));
+ else
+ len = (size_t)(sprintf(txt, "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname));
+ cdf_put_att_text(fileID, ncbvarid, "formula_terms", len, txt);
}
- else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
- {
- double attflt[attlen];
- cdfGetAttDouble(fileID, NC_GLOBAL, attname, (int)attlen, attflt);
- if ( xtype == NC_FLOAT )
- vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT32, (int)attlen, attflt);
- else
- vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT64, (int)attlen, attflt);
- }
}
-}
-static
-int find_leadtime(int nvars, ncvar_t *ncvars)
-{
- int leadtime_id = UNDEFID;
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
- for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ cdf_put_var_double(fileID, ncvarid, levels);
+
+ if ( p0varid != CDI_UNDEFID ) cdf_put_var_double(fileID, p0varid, &p0value);
+
+ if ( ncbvarid != CDI_UNDEFID )
{
- if ( ncvars[ncvarid].stdname[0] )
+ double zbounds[2*dimlen];
+ for ( size_t i = 0; i < dimlen; ++i )
{
- if ( strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
- {
- leadtime_id = ncvarid;
- break;
- }
+ zbounds[2*i ] = lbounds[i];
+ zbounds[2*i+1] = ubounds[i];
}
+ cdf_put_var_double(fileID, ncbvarid, zbounds);
}
- return (leadtime_id);
+ cdf_def_vct_cf(streamptr, zaxisID, *dimID, nvdimID, p0status, p0value);
+
+ if ( *dimID == CDI_UNDEFID )
+ streamptr->zaxisID[zaxisindex] = type == ZAXIS_HYBRID
+ ? streamptr->vct.mlevID : streamptr->vct.ilevID;
}
static
-void find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, stream_t *streamptr,
- int *time_has_units, int *time_has_bounds, int *time_climatology)
+void cdf_def_zaxis_hybrid(stream_t *streamptr, int type, int *ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
{
- int ncvarid;
+ void (*def_zaxis_hybrid_delegate)(stream_t *streamptr, int type, int *ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+ = ( (!CDI_cmor_mode && cdiConvention == CDI_CONVENTION_ECHAM)
+ || type == ZAXIS_HYBRID_HALF )
+ ? cdf_def_zaxis_hybrid_echam : cdf_def_zaxis_hybrid_cf;
+ def_zaxis_hybrid_delegate(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
+}
- if ( timedimid == UNDEFID )
- {
- char timeunits[CDI_MAX_NAME];
+static
+void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
+{
+ unsigned char uuidOfVGrid[CDI_UUID_SIZE];
+ zaxisInqUUID(zaxisID, uuidOfVGrid);
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ if ( uuidOfVGrid[0] != 0 )
+ {
+ char uuidOfVGridStr[37];
+ cdiUUID2Str(uuidOfVGrid, uuidOfVGridStr);
+ if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
{
- if ( ncvars[ncvarid].ndims == 0 && strcmp(ncvars[ncvarid].name, "time") == 0 )
- {
- if ( ncvars[ncvarid].units[0] )
- {
- strcpy(timeunits, ncvars[ncvarid].units);
- strtolower(timeunits);
-
- if ( isTimeUnits(timeunits) )
- {
- streamptr->basetime.ncvarid = ncvarid;
- break;
- }
- }
- }
+ int fileID = streamptr->fileID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
+ if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
}
}
- else
- {
- int ltimevar = FALSE;
+}
- if ( ncdims[timedimid].ncvarid != UNDEFID )
- {
- streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
- ltimevar = TRUE;
- }
+static
+void cdfDefZaxisChar(stream_t *streamptr, int zaxisID, char *axisname, int *dimID, size_t dimlen, int zaxisindex)
+{
+ int fileID = streamptr->fileID;
+ int ncvarID = CDI_UNDEFID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- if ( ncvarid != streamptr->basetime.ncvarid &&
- ncvars[ncvarid].ndims == 1 &&
- timedimid == ncvars[ncvarid].dimids[0] &&
- !xtypeIsText(ncvars[ncvarid].xtype) &&
- isTimeAxisUnits(ncvars[ncvarid].units) )
- {
- ncvars[ncvarid].isvar = FALSE;
+ /* Check StrlenID */
+ char strlen[7] = "strlen\0";
+ size_t clen = (size_t) zaxisInqCLen(zaxisID);
+ if ( clen == 0 )
+ Error("Maximal string length value is 0.\nA given character axis requires a dimension to save the maximal string length.");
+ int strlenID = CDI_UNDEFID;
+ strlenID = checkDimName(fileID, clen, strlen);
- if ( !ltimevar )
- {
- streamptr->basetime.ncvarid = ncvarid;
- ltimevar = TRUE;
- if ( CDI_Debug )
- fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
- }
- else
- {
- Warning("Found more than one time variable, skipped variable %s!", ncvars[ncvarid].name);
- }
- }
+ if ( strlenID == CDI_UNDEFID ) cdf_def_dim(fileID, strlen, clen, &strlenID);
- if ( ltimevar == FALSE ) /* search for WRF time description */
- {
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- if ( ncvarid != streamptr->basetime.ncvarid &&
- ncvars[ncvarid].ndims == 2 &&
- timedimid == ncvars[ncvarid].dimids[0] &&
- xtypeIsText(ncvars[ncvarid].xtype) &&
- ncdims[ncvars[ncvarid].dimids[1]].len == 19 )
- {
- streamptr->basetime.ncvarid = ncvarid;
- streamptr->basetime.lwrf = TRUE;
- break;
- }
- }
+ /* Check 'areatype'dimID */
+ char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
+ *dimID = checkDimName(fileID, dimlen, dimname);
+ if ( !(dimlen > 0) )
+ Error("No strings delivered for a character axis.");
+ if ( dimname[0] == 0 ) { memcpy(dimname, "area_type", 10); dimname[10] = 0; }
- /* time varID */
- ncvarid = streamptr->basetime.ncvarid;
+ if ( *dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, dimID);
- if ( ncvarid == UNDEFID )
- {
- Warning("Time variable >%s< not found!", ncdims[timedimid].name);
- }
- }
+ int dimIDs[2];
+ dimIDs[0] = *dimID;
+ dimIDs[1] = strlenID;
- /* time varID */
- ncvarid = streamptr->basetime.ncvarid;
+ /* Get Stringvalues */
+ char **cvals = zaxisInqCValsPtr(zaxisID);
- if ( ncvarid != UNDEFID && streamptr->basetime.lwrf == FALSE )
+ if ( cvals )
{
- if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = TRUE;
+ /* Define variable and its attributes */
+ cdf_def_var(fileID, axisname, NC_CHAR, 2, dimIDs, &ncvarID);
- if ( ncvars[ncvarid].bounds != UNDEFID )
- {
- int nbdims = ncvars[ncvars[ncvarid].bounds].ndims;
- if ( nbdims == 2 )
- {
- int len = (int) ncdims[ncvars[ncvars[ncvarid].bounds].dimids[nbdims-1]].len;
- if ( len == 2 && timedimid == ncvars[ncvars[ncvarid].bounds].dimids[0] )
- {
- *time_has_bounds = TRUE;
- streamptr->basetime.ncvarboundsid = ncvars[ncvarid].bounds;
- if ( ncvars[ncvarid].climatology ) *time_climatology = TRUE;
- }
- }
- }
- }
-}
+ cdfPutGridStdAtts(fileID, ncvarID, zaxisID, 'Z', &gridInqsZ);
+ cdf_put_att_text(fileID, ncvarID, "axis", 1, "Z");
+ cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarID);
-static
-void read_vct_echam(int fileID, int nvars, ncvar_t *ncvars, ncdim_t *ncdims, double **vct, size_t *pvctsize)
-{
- /* find ECHAM VCT */
- int nvcth_id = UNDEFID, vcta_id = UNDEFID, vctb_id = UNDEFID;
+ streamptr->nczvarID[zaxisindex] = ncvarID;
+ cdf_enddef(fileID);
- for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
- {
- if ( ncvars[ncvarid].ndims == 1 )
+ /* Write Stringvalues */
+ size_t start[2], count[2];
+ start[1] = 0;
+ count[0] = 1;
+ count[1] = clen;
+ for ( size_t i = 0; i < dimlen; i++ )
{
- size_t len = strlen(ncvars[ncvarid].name);
- if ( len == 4 && ncvars[ncvarid].name[0] == 'h' && ncvars[ncvarid].name[1] == 'y' )
- {
- if ( ncvars[ncvarid].name[2] == 'a' && ncvars[ncvarid].name[3] == 'i' ) // hyai
- {
- vcta_id = ncvarid;
- nvcth_id = ncvars[ncvarid].dimids[0];
- ncvars[ncvarid].isvar = FALSE;
- }
- else if ( ncvars[ncvarid].name[2] == 'b' && ncvars[ncvarid].name[3] == 'i' ) //hybi
- {
- vctb_id = ncvarid;
- nvcth_id = ncvars[ncvarid].dimids[0];
- ncvars[ncvarid].isvar = FALSE;
- }
- else if ( (ncvars[ncvarid].name[2] == 'a' || ncvars[ncvarid].name[2] == 'b') && ncvars[ncvarid].name[3] == 'm' )
- {
- ncvars[ncvarid].isvar = FALSE; // hyam or hybm
- }
- }
- }
+ start[0] = i;
+ nc_put_vara_text(fileID, ncvarID, start, count, cvals[i]);
+ }
}
- /* read VCT */
- if ( nvcth_id != UNDEFID && vcta_id != UNDEFID && vctb_id != UNDEFID )
- {
- size_t vctsize = ncdims[nvcth_id].len;
- vctsize *= 2;
- *vct = (double *) Malloc(vctsize*sizeof(double));
- cdf_get_var_double(fileID, vcta_id, *vct);
- cdf_get_var_double(fileID, vctb_id, *vct+vctsize/2);
- *pvctsize = vctsize;
- }
+ streamptr->ncmode = 2;
}
-
-int cdfInqContents(stream_t *streamptr)
+static
+void cdfDefZaxis(stream_t *streamptr, int zaxisID)
{
- int ndims, nvars, ngatts, unlimdimid;
- int ncvarid;
- int ncdimid;
- size_t ntsteps;
- int timedimid = -1;
- int *varids;
- int nvarids;
- int time_has_units = FALSE;
- int time_has_bounds = FALSE;
- int time_climatology = FALSE;
- int leadtime_id = UNDEFID;
- int nvars_data;
- int instID = UNDEFID;
- int modelID = UNDEFID;
- int taxisID;
- int i;
- int calendar = UNDEFID;
- ncdim_t *ncdims;
- ncvar_t *ncvars = NULL;
- int format = 0;
- int ucla_les = FALSE;
- unsigned char uuidOfHGrid[CDI_UUID_SIZE];
- unsigned char uuidOfVGrid[CDI_UUID_SIZE];
- char gridfile[8912];
- char fcreftime[CDI_MAX_NAME];
- int number_of_grid_used = UNDEFID;
-
- memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
- memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
- gridfile[0] = 0;
- fcreftime[0] = 0;
+ /* char zaxisname0[CDI_MAX_NAME]; */
+ char axisname[CDI_MAX_NAME];
+ int dimID = CDI_UNDEFID;
+ int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
+ int xtype = zaxisInqDatatype(zaxisID) == CDI_DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
- if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+ int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-#if defined (HAVE_NETCDF4)
- nc_inq_format(fileID, &format);
-#endif
+ int nzaxis = vlistNzaxis(vlistID);
- cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
+ size_t dimlen = (size_t)zaxisInqSize(zaxisID);
+ int type = zaxisInqType(zaxisID);
- if ( CDI_Debug )
- Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
+ int ndims = 1;
- if ( ndims == 0 )
+ if ( dimlen == 1 )
{
- Warning("ndims = %d", ndims);
- return (CDI_EUFSTRUCT);
+ bool is_scalar = zaxisInqScalar(zaxisID) > 0;
+ if ( !is_scalar && CDI_cmor_mode )
+ {
+ is_scalar = true;
+ zaxisDefScalar(zaxisID);
+ }
+
+ if ( is_scalar ) ndims = 0;
+ if ( CDI_reduce_dim ) return;
+
+ switch (type)
+ {
+ case ZAXIS_SURFACE:
+ case ZAXIS_CLOUD_BASE:
+ case ZAXIS_CLOUD_TOP:
+ case ZAXIS_ISOTHERM_ZERO:
+ case ZAXIS_TOA:
+ case ZAXIS_SEA_BOTTOM:
+ case ZAXIS_ATMOSPHERE:
+ case ZAXIS_MEANSEA:
+ case ZAXIS_LAKE_BOTTOM:
+ case ZAXIS_SEDIMENT_BOTTOM:
+ case ZAXIS_SEDIMENT_BOTTOM_TA:
+ case ZAXIS_SEDIMENT_BOTTOM_TW:
+ case ZAXIS_MIX_LAYER:
+ return;
+ }
}
- /* alloc ncdims */
- ncdims = (ncdim_t *) Malloc((size_t)ndims * sizeof (ncdim_t));
- init_ncdims(ndims, ncdims);
+ zaxisInqName(zaxisID, axisname);
- if ( nvars > 0 )
+ if ( dimID == CDI_UNDEFID )
{
- /* alloc ncvars */
- ncvars = (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t));
- init_ncvars(nvars, ncvars);
+ checkZaxisName(axisname, fileID, vlistID, zaxisID, nzaxis);
- for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
- ncvars[ncvarid].ncid = fileID;
- }
+ char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
+ //cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
+ if ( dimname[0] == 0 ) strcpy(dimname, axisname);
-#if defined (TEST_GROUPS)
-#if defined (HAVE_NETCDF4)
- if ( format == NC_FORMAT_NETCDF4 )
- {
- int ncid;
- int numgrps;
- int ncids[NC_MAX_VARS];
- char name1[CDI_MAX_NAME];
- int gndims, gnvars, gngatts, gunlimdimid;
- nc_inq_grps(fileID, &numgrps, ncids);
- for ( int i = 0; i < numgrps; ++i )
- {
- ncid = ncids[i];
- nc_inq_grpname (ncid, name1);
- cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
+ if ( type == ZAXIS_REFERENCE ) cdfDefZaxisUUID(streamptr, zaxisID);
- if ( CDI_Debug )
- Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
+ if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+ {
+ cdf_def_zaxis_hybrid(streamptr, type, &ncvarid, zaxisID, zaxisindex, xtype, dimlen, &dimID, axisname);
- if ( gndims == 0 )
- {
- }
+ int natts;
+ cdiInqNatts(zaxisID, CDI_GLOBAL, &natts);
+ if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
+ cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
+ if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
}
- }
-#endif
-#endif
+ else if ( type == ZAXIS_CHAR )
+ cdfDefZaxisChar(streamptr, zaxisID, axisname, &dimID, dimlen, zaxisindex);
+ else
+ {
+ dimID = checkDimName(fileID, dimlen, dimname);
- if ( nvars == 0 )
- {
- Warning("nvars = %d", nvars);
- return (CDI_EUFSTRUCT);
- }
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- /* scan global attributes */
- scan_global_attributes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les,
- uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
+ if ( ndims && dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
- /* find time dim */
- if ( unlimdimid >= 0 )
- timedimid = unlimdimid;
- else
- timedimid = cdfTimeDimID(fileID, ndims, nvars);
+ if ( zaxisInqLevels(zaxisID, NULL) )
+ {
+ cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
- streamptr->basetime.ncdimid = timedimid;
+ cdfPutGridStdAtts(fileID, ncvarid, zaxisID, 'Z', &gridInqsZ);
- if ( timedimid != UNDEFID )
- cdf_inq_dimlen(fileID, timedimid, &ntsteps);
- else
- ntsteps = 0;
+ {
+ int positive = zaxisInqPositive(zaxisID);
+ static const char positive_up[] = "up",
+ positive_down[] = "down";
+ static const struct attTxtTab tab[2] = {
+ { positive_up, sizeof (positive_up) - 1 },
+ { positive_down, sizeof (positive_down) - 1 },
+ };
+ if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
+ {
+ size_t select = positive == POSITIVE_DOWN;
+ cdf_put_att_text(fileID, ncvarid, "positive", tab[select].txtLen, tab[select].txt);
+ }
+ }
+ cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
- if ( CDI_Debug ) Message("Number of timesteps = %d", ntsteps);
- if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
+ if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+ {
+ int nvdimID = CDI_UNDEFID;
+ size_t nvertex = 2;
+ if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
+ cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
- /* read ncdims */
- for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
- {
- cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
- cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name);
- if ( timedimid == ncdimid )
- ncdims[ncdimid].dimtype = T_AXIS;
- }
+ if ( nvdimID != CDI_UNDEFID )
+ {
+ size_t axisnameLen = strlen(axisname);
+ axisname[axisnameLen] = '_';
+ memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
+ int dimIDs[2];
+ dimIDs[0] = dimID;
+ dimIDs[ndims] = nvdimID;
+ cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
+ cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
+ }
+ }
- if ( CDI_Debug ) printNCvars(ncvars, nvars, "cdfScanVarAttributes");
+ cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
+ }
- /* scan attributes of all variables */
- cdfScanVarAttributes(nvars, ncvars, ncdims, timedimid, modelID, format);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
+ if ( zaxisInqLevels(zaxisID, NULL) )
+ {
+ cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
- if ( CDI_Debug ) printNCvars(ncvars, nvars, "find coordinate vars");
+ if ( ncbvarid != CDI_UNDEFID )
+ {
+ double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
+ zaxisInqLbounds(zaxisID, lbounds);
+ zaxisInqUbounds(zaxisID, ubounds);
+ for ( size_t i = 0; i < dimlen; ++i )
+ {
+ zbounds[2*i ] = lbounds[i];
+ zbounds[2*i+1] = ubounds[i];
+ }
- /* find coordinate vars */
- for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
- {
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- {
- if ( ncvars[ncvarid].ndims == 1 )
- {
- if ( timedimid != UNDEFID && timedimid == ncvars[ncvarid].dimids[0] )
- {
- if ( ncvars[ncvarid].isvar != FALSE ) cdfSetVar(ncvars, ncvarid, TRUE);
- }
- else
- {
- // if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
- }
- // if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
+ cdf_put_var_double(fileID, ncbvarid, zbounds);
+ }
- if ( ncdimid == ncvars[ncvarid].dimids[0] && ncdims[ncdimid].ncvarid == UNDEFID )
- if ( strcmp(ncvars[ncvarid].name, ncdims[ncdimid].name) == 0 )
- {
- ncdims[ncdimid].ncvarid = ncvarid;
- ncvars[ncvarid].isvar = FALSE;
- }
- }
- }
+ if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
+ }
+ }
}
- /* find time vars */
- find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
-
- leadtime_id = find_leadtime(nvars, ncvars);
- if ( leadtime_id != UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
+ if ( dimID != CDI_UNDEFID )
+ streamptr->zaxisID[zaxisindex] = dimID;
+}
- /* check ncvars */
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+static
+void cdf_def_mapping(stream_t *streamptr, int gridID)
+{
+ char mapping[CDI_MAX_NAME]; mapping[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+ if ( mapping[0] )
{
- if ( timedimid != UNDEFID )
- if ( ncvars[ncvarid].isvar == -1 &&
- ncvars[ncvarid].ndims > 1 &&
- timedimid == ncvars[ncvarid].dimids[0] )
- cdfSetVar(ncvars, ncvarid, TRUE);
+ char gmapvarname[CDI_MAX_NAME]; gmapvarname[0] = 0;
+ cdiGridInqKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, gmapvarname);
- if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
- cdfSetVar(ncvars, ncvarid, FALSE);
+ int fileID = streamptr->fileID;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
- if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
- cdfSetVar(ncvars, ncvarid, TRUE);
+ int ncvarid;
+ int ncerrcode = nc_def_var(fileID, gmapvarname, (nc_type) NC_INT, 0, NULL, &ncvarid);
+ if ( ncerrcode == NC_NOERR )
+ cdfDefineAttributes(gridID, CDI_GLOBAL, fileID, ncvarid);
- if ( ncvars[ncvarid].isvar == -1 )
- {
- ncvars[ncvarid].isvar = 0;
- Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
- continue;
- }
+ cdf_enddef(fileID);
- if ( ncvars[ncvarid].ndims > 4 )
- {
- ncvars[ncvarid].isvar = 0;
- Warning("%d dimensional variables are not supported, skipped variable %s!",
- ncvars[ncvarid].ndims, ncvars[ncvarid].name);
- continue;
- }
+ if ( ncerrcode == NC_NOERR )
+ {
+ int dummy = 1;
+ cdf_put_var_int(fileID, ncvarid, &dummy);
+ }
+ }
+}
- if ( ncvars[ncvarid].ndims == 4 && timedimid == UNDEFID )
- {
- ncvars[ncvarid].isvar = 0;
- Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
- ncvars[ncvarid].ndims, ncvars[ncvarid].name);
- continue;
- }
+static
+void cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int xory, int strlen)
+{
+ if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
- if ( xtypeIsText(ncvars[ncvarid].xtype) )
- {
- ncvars[ncvarid].isvar = 0;
- continue;
- }
+ size_t dimlen = ( xory == 0 ) ? gridInqXsize(gridID) : gridInqYsize(gridID);
+ int dimID, strlenID;
+ ncgrid_t *ncgrid = streamptr->ncgrid;
- if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
- {
- ncvars[ncvarid].isvar = 0;
- Warning("Variable %s has an unsupported data type, skipped!", ncvars[ncvarid].name);
- continue;
- }
+ /* Check for all grids up to gridindex whether it already is defined */
- if ( timedimid != UNDEFID && ntsteps == 0 && ncvars[ncvarid].ndims > 0 )
- {
- if ( timedimid == ncvars[ncvarid].dimids[0] )
- {
- ncvars[ncvarid].isvar = 0;
- Warning("Number of time steps undefined, skipped variable %s!", ncvars[ncvarid].name);
- continue;
- }
- }
+ for ( int index = 0; index < gridindex; index++ )
+ {
+ int gridID0 = ncgrid[index].gridID;
+ int gridtype0 = gridInqType(gridID0);
+ if ( gridtype0 == GRID_CHARXY )
+ {
+ if ( gridInqXIsc(gridID0) == strlen &&
+ gridInqXsize(gridID0) == dimlen )
+ return;
+ else if ( gridInqYIsc(gridID0) == strlen &&
+ gridInqYsize(gridID0) == dimlen )
+ return;
+ }
}
- /* verify coordinate vars - first scan (dimname == varname) */
- verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid);
+ int fileID = streamptr->fileID;
+
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+/* Define Dims */
- /* verify coordinate vars - second scan (all other variables) */
- verify_coordinate_vars_2(nvars, ncvars);
+ char dimname[CDI_MAX_NAME+3];
+ dimname[0] = 0;
+ if ( xory == 0 )
+ cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, dimname);
+ else
+ cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, dimname);
+ if ( dimname[0] == 0 ) { memcpy(dimname, "region", 7); dimname[6] = 0; }
+ dimID = checkDimName(fileID, dimlen, dimname);
+ if ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+
+/* Define strlength dim */
+
+ strcpy(dimname, "strlen");
+ strlenID = checkDimName(fileID, strlen, dimname);
+ if ( strlenID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, strlen, &strlenID);
+
+/* Define Variable */
- if ( CDI_Debug ) printNCvars(ncvars, nvars, "verify_coordinate_vars");
+ int dimIDs[2];
+ dimIDs[0] = dimID;
+ dimIDs[1] = strlenID;
- if ( ucla_les == TRUE )
+ char axisname[CDI_MAX_NAME]; axisname[0] = 0;
+ char **cvals = (char **) Malloc(dimlen * sizeof(char *));
+ for ( size_t i = 0; i < dimlen; i++ )
+ cvals[i] = Malloc(strlen * sizeof(char) );
+ int ncaxisid;
+ if ( xory == 0 )
{
- for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
- {
- ncvarid = ncdims[ncdimid].ncvarid;
- if ( ncvarid != -1 )
- {
- if ( ncdims[ncdimid].dimtype == UNDEFID && ncvars[ncvarid].units[0] == 'm' )
- {
- if ( ncvars[ncvarid].name[0] == 'x' ) ncdims[ncdimid].dimtype = X_AXIS;
- else if ( ncvars[ncvarid].name[0] == 'y' ) ncdims[ncdimid].dimtype = Y_AXIS;
- else if ( ncvars[ncvarid].name[0] == 'z' ) ncdims[ncdimid].dimtype = Z_AXIS;
- }
- }
- }
+ cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, axisname);
+ gridInqXCvals(gridID, cvals);
}
- /*
- for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+ else
{
- ncvarid = ncdims[ncdimid].ncvarid;
- if ( ncvarid != -1 )
- {
- printf("coord var %d %s %s\n", ncvarid, ncvars[ncvarid].name, ncvars[ncvarid].units);
- if ( ncdims[ncdimid].dimtype == X_AXIS )
- printf("coord var %d %s is x dim\n", ncvarid, ncvars[ncvarid].name);
- if ( ncdims[ncdimid].dimtype == Y_AXIS )
- printf("coord var %d %s is y dim\n", ncvarid, ncvars[ncvarid].name);
- if ( ncdims[ncdimid].dimtype == Z_AXIS )
- printf("coord var %d %s is z dim\n", ncvarid, ncvars[ncvarid].name);
- if ( ncdims[ncdimid].dimtype == T_AXIS )
- printf("coord var %d %s is t dim\n", ncvarid, ncvars[ncvarid].name);
+ cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, axisname);
+ gridInqXCvals(gridID, cvals);
+ }
+ int status = nc_inq_varid(fileID, axisname, &ncaxisid);
+ if ( status != NC_NOERR )
+ {
+ cdf_def_var(fileID, axisname, NC_CHAR, 2, dimIDs, &ncaxisid);
+ if ( xory == 0 )
+ cdfPutGridStdAtts(fileID, ncaxisid, gridID, 'X', &gridInqsX);
+ else
+ cdfPutGridStdAtts(fileID, ncaxisid, gridID, 'Y', &gridInqsY);
+ }
+ else
+ return;
+ cdf_enddef(fileID);
- if ( ncvars[ncvarid].islon )
- printf("coord var %d %s is lon\n", ncvarid, ncvars[ncvarid].name);
- if ( ncvars[ncvarid].islat )
- printf("coord var %d %s is lat\n", ncvarid, ncvars[ncvarid].name);
- if ( ncvars[ncvarid].islev )
- printf("coord var %d %s is lev\n", ncvarid, ncvars[ncvarid].name);
- }
+/* Write Var */
+
+ size_t start[2], count[2];
+ start[1] = 0;
+ count[0] = 1;
+ count[1] = strlen;
+ for (size_t i = 0; i < dimlen; i++)
+ {
+ start[0] = i;
+ status = nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]);
}
- */
- /* Set coordinate varids (att: associate) */
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+ ncgrid[gridindex].gridID = gridID;
+ if ( xory == 0 )
{
- if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].ncoordvars )
- {
- /* ndims = ncvars[ncvarid].ndims; */
- ndims = ncvars[ncvarid].ncoordvars;
- for ( i = 0; i < ndims; i++ )
- {
- if ( ncvars[ncvars[ncvarid].coordvarids[i]].islon )
- ncvars[ncvarid].xvarid = ncvars[ncvarid].coordvarids[i];
- else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islat )
- ncvars[ncvarid].yvarid = ncvars[ncvarid].coordvarids[i];
- else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islev )
- ncvars[ncvarid].zvarid = ncvars[ncvarid].coordvarids[i];
- }
- }
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+ ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncaxisid;
+ }
+ else
+ {
+ ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = dimID;
+ ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncaxisid;
}
+ streamptr->ncmode = 2;
+}
+
+static
+void cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex)
+{
+ ncgrid_t *ncgrid = streamptr->ncgrid;
- /* set dim type */
- setDimType(nvars, ncvars, ncdims);
+ size_t dimlen = gridInqSize(gridID);
- /* read ECHAM VCT if present */
- size_t vctsize = 0;
- double *vct = NULL;
- read_vct_echam(fileID, nvars, ncvars, ncdims, &vct, &vctsize);
+ int iz;
+ int dimID;
+ {
+ struct idSearch search
+ = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_X,
+ GRID_GAUSSIAN_REDUCED, (int)dimlen,
+ gridInqType, gridInqSize);
+ iz = search.numNonMatching;
+ dimID = search.foundID;
+ }
+ if ( dimID == CDI_UNDEFID )
+ {
+ int fileID = streamptr->fileID;
+ static bool lwarn = true;
+ if ( lwarn )
+ {
+ Warning("Creating a NetCDF file with data on a gaussian reduced grid.");
+ Warning("The further processing of the resulting file is unsupported!");
+ lwarn = false;
+ }
- if ( CDI_Debug ) printNCvars(ncvars, nvars, "define_all_grids");
+ char axisname[16] = "rgridX";
+ if ( iz == 0 ) axisname[5] = '\0';
+ else sprintf(&axisname[5], "%1d", iz+1);
- /* define all grids */
- define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+ cdf_def_dim(fileID, axisname, dimlen, &dimID);
- /* define all zaxes */
- define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
- if ( vct ) Free(vct);
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
+ }
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+}
- /* select vars */
- varids = (int *) Malloc((size_t)nvars * sizeof (int));
- nvarids = 0;
- for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
- if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
+static
+void cdfDefGdim(stream_t *streamptr, int gridID, int gridindex)
+{
+ ncgrid_t *ncgrid = streamptr->ncgrid;
+ int iz = 0;
+ int dimID = CDI_UNDEFID;
- nvars_data = nvarids;
+ size_t dimlen = gridInqSize(gridID);
- if ( CDI_Debug ) Message("time varid = %d", streamptr->basetime.ncvarid);
- if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
- if ( CDI_Debug ) Message("nvars_data = %d", nvars_data);
+ if ( gridInqYsize(gridID) == 0 )
+ {
+ struct idSearch search
+ = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_X,
+ GRID_GENERIC, (int)dimlen,
+ gridInqType, gridInqSize);
+ iz = search.numNonMatching;
+ dimID = search.foundID;
+ }
+ if ( gridInqXsize(gridID) == 0 )
+ {
+ struct idSearch search
+ = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_Y,
+ GRID_GENERIC, (int)dimlen,
+ gridInqType, gridInqSize);
+ iz += search.numNonMatching;
+ dimID = search.foundID;
+ }
- if ( nvars_data == 0 )
+ if ( dimID == CDI_UNDEFID )
{
- streamptr->ntsteps = 0;
- return (CDI_EUFSTRUCT);
+ int fileID = streamptr->fileID;
+ char dimname[CDI_MAX_NAME];
+ strcpy(dimname, "gsize");
+
+ dimID = checkDimName(fileID, dimlen, dimname);
+
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+ if ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+
+ cdf_enddef(fileID);
+ streamptr->ncmode = 2;
}
- if ( ntsteps == 0 && streamptr->basetime.ncdimid == UNDEFID && streamptr->basetime.ncvarid != UNDEFID )
- ntsteps = 1;
+ ncgrid[gridindex].gridID = gridID;
+ ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+}
- streamptr->ntsteps = (long)ntsteps;
+static
+void cdfDefGrid(stream_t *streamptr, int gridID, int gridindex)
+{
+ if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
- /* define all data variables */
- define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
+ int gridtype = gridInqType(gridID);
+ size_t size = gridInqSize(gridID);
+ if ( CDI_Debug )
+ Message("gridtype = %d size = %zu", gridtype, size);
- cdiCreateTimesteps(streamptr);
+ if ( CDI_reduce_dim && size == 1 )
+ {
+ // no grid information
+ streamptr->ncgrid[gridindex].gridID = gridID;
+ return;
+ }
- /* time varID */
- int nctimevarid = streamptr->basetime.ncvarid;
+ if ( gridtype == GRID_GAUSSIAN ||
+ gridtype == GRID_LONLAT ||
+ gridtype == GRID_PROJECTION ||
+ gridtype == GRID_GENERIC )
+ {
+ if ( gridtype == GRID_GENERIC )
+ {
+ if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+ {
+ // no grid information
+ streamptr->ncgrid[gridindex].gridID = gridID;
+ }
+ else
+ {
+ bool lx = false, ly = false;
+ if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+ {
+ cdfDefXaxis(streamptr, gridID, gridindex, 1);
+ lx = true;
+ }
- if ( time_has_units )
- {
- taxis_t *taxis = &streamptr->tsteps[0].taxis;
+ if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+ {
+ cdfDefYaxis(streamptr, gridID, gridindex, 1);
+ ly = true;
+ }
- if ( setBaseTime(ncvars[nctimevarid].units, taxis) == 1 )
- {
- nctimevarid = UNDEFID;
- streamptr->basetime.ncvarid = UNDEFID;
+ if ( !lx && !ly ) cdfDefGdim(streamptr, gridID, gridindex);
+ }
}
-
- if ( leadtime_id != UNDEFID && taxis->type == TAXIS_RELATIVE )
+ else
{
- streamptr->basetime.leadtimeid = leadtime_id;
- taxis->type = TAXIS_FORECAST;
+ int ndims = !(gridtype == GRID_LONLAT && size == 1 && !gridInqHasDims(gridID));
- int timeunit = -1;
- if ( ncvars[leadtime_id].units[0] != 0 ) timeunit = scanTimeUnit(ncvars[leadtime_id].units);
- if ( timeunit == -1 ) timeunit = taxis->unit;
- taxis->fc_unit = timeunit;
+ if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, gridindex, ndims);
+ if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, gridindex, ndims);
- setForecastTime(fcreftime, taxis);
+ cdf_def_mapping(streamptr, gridID);
}
}
-
- if ( time_has_bounds )
+ else if ( gridtype == GRID_CURVILINEAR )
{
- streamptr->tsteps[0].taxis.has_bounds = TRUE;
- if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = TRUE;
+ cdfDefCurvilinear(streamptr, gridID, gridindex);
}
-
- if ( nctimevarid != UNDEFID )
+ else if ( gridtype == GRID_UNSTRUCTURED )
{
- taxis_t *taxis = &streamptr->tsteps[0].taxis;
- ptaxisDefName(taxis, ncvars[nctimevarid].name);
- if ( ncvars[nctimevarid].longname[0] )
- ptaxisDefLongname(taxis, ncvars[nctimevarid].longname);
+ cdfDefUnstructured(streamptr, gridID, gridindex);
}
-
- if ( nctimevarid != UNDEFID )
- if ( ncvars[nctimevarid].calendar == TRUE )
- {
- enum {attstringlen = 8192};
- char attstring[attstringlen];
-
- cdfGetAttText(fileID, nctimevarid, "calendar", attstringlen, attstring);
- strtolower(attstring);
-
- if ( memcmp(attstring, "standard", 8) == 0 ||
- memcmp(attstring, "gregorian", 9) == 0 )
- calendar = CALENDAR_STANDARD;
- else if ( memcmp(attstring, "none", 4) == 0 )
- calendar = CALENDAR_NONE;
- else if ( memcmp(attstring, "proleptic", 9) == 0 )
- calendar = CALENDAR_PROLEPTIC;
- else if ( memcmp(attstring, "360", 3) == 0 )
- calendar = CALENDAR_360DAYS;
- else if ( memcmp(attstring, "365", 3) == 0 ||
- memcmp(attstring, "noleap", 6) == 0 )
- calendar = CALENDAR_365DAYS;
- else if ( memcmp(attstring, "366", 3) == 0 ||
- memcmp(attstring, "all_leap", 8) == 0 )
- calendar = CALENDAR_366DAYS;
- else
- Warning("calendar >%s< unsupported!", attstring);
- }
-
- if ( streamptr->tsteps[0].taxis.type == TAXIS_FORECAST )
+ else if ( gridtype == GRID_GAUSSIAN_REDUCED )
{
- taxisID = taxisCreate(TAXIS_FORECAST);
+ cdfDefRgrid(streamptr, gridID, gridindex);
}
- else if ( streamptr->tsteps[0].taxis.type == TAXIS_RELATIVE )
+ else if ( gridtype == GRID_SPECTRAL )
{
- taxisID = taxisCreate(TAXIS_RELATIVE);
+ cdfDefComplex(streamptr, gridID, gridindex);
+ cdfDefSP(streamptr, gridID, gridindex);
+ }
+ else if ( gridtype == GRID_FOURIER )
+ {
+ cdfDefComplex(streamptr, gridID, gridindex);
+ cdfDefFC(streamptr, gridID, gridindex);
+ }
+ else if ( gridtype == GRID_TRAJECTORY )
+ {
+ cdfDefTrajLon(streamptr, gridID, gridindex);
+ cdfDefTrajLat(streamptr, gridID, gridindex);
+ }
+ else if ( gridtype == GRID_CHARXY )
+ {
+ int strlen = 0;
+ if ( (strlen = gridInqXIsc(gridID)) )
+ cdfDefCharacter(streamptr, gridID, gridindex, 0, strlen);
+ else
+ if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, gridindex, 1);
+ if ( (strlen = gridInqYIsc(gridID)) )
+ cdfDefCharacter(streamptr, gridID, gridindex, 1, strlen);
+ else
+ if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, gridindex, 1);
}
else
{
- taxisID = taxisCreate(TAXIS_ABSOLUTE);
- if ( !time_has_units )
- {
- taxisDefTunit(taxisID, TUNIT_DAY);
- streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
- }
+ Error("Unsupported grid type: %s", gridNamePtr(gridtype));
}
+}
+
+
+void cdfDefHistory(stream_t *streamptr, int size, const char *history)
+{
+ int ncid = streamptr->fileID;
+ cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
+}
+
+
+void cdfDefVars(stream_t *streamptr)
+{
+ int vlistID = streamptr->vlistID;
+ if ( vlistID == CDI_UNDEFID )
+ Error("Internal problem! vlist undefined for streamptr %p", streamptr);
+ if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
- if ( calendar == UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
+ int ngrids = vlistNgrids(vlistID);
+ if ( 2*ngrids > MAX_GRIDS_PS ) Error("Internal problem! Too many grids per stream (max=%d)\n", MAX_GRIDS_PS);
+ for ( int index = 0; index < 2*ngrids; ++index )
{
- calendar = CALENDAR_STANDARD;
+ streamptr->ncgrid[index].gridID = CDI_UNDEFID;
+ for (size_t i = 0; i < CDF_SIZE_ncIDs; ++i)
+ streamptr->ncgrid[index].ncIDs[i] = CDI_UNDEFID;
}
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic warning "-Wstrict-overflow"
-#endif
- if ( calendar != UNDEFID )
+ for ( int index = 0; index < ngrids; ++index )
{
- taxis_t *taxis = &streamptr->tsteps[0].taxis;
- taxis->calendar = calendar;
- taxisDefCalendar(taxisID, calendar);
+ int gridID = vlistGrid(vlistID, index);
+ cdfDefGrid(streamptr, gridID, index);
+ }
+ {
+ int index = ngrids-1;
+ for ( int i = 0; i < ngrids; ++i )
+ {
+ int gridID = vlistGrid(vlistID, i);
+ int projID = gridInqProj(gridID);
+ if ( projID != CDI_UNDEFID ) cdfDefGrid(streamptr, projID, ++index);
+ }
+ }
+ int nzaxis = vlistNzaxis(vlistID);
+ for ( int index = 0; index < nzaxis; ++index )
+ {
+ int zaxisID = vlistZaxis(vlistID, index);
+ if ( streamptr->zaxisID[index] == CDI_UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
}
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic pop
-#endif
-
- vlistDefTaxis(vlistID, taxisID);
- streamptr->curTsID = 0;
- streamptr->rtsteps = 1;
+ if ( streamptr->ncmode != 2 )
+ {
+ cdf_enddef(streamptr->fileID);
+ streamptr->ncmode = 2;
+ }
+}
- (void) cdfInqTimestep(streamptr, 0);
+#endif
- cdfCreateRecords(streamptr, 0);
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
- /* free ncdims */
- Free(ncdims);
+#ifdef HAVE_LIBNETCDF
- /* free ncvars */
- Free(ncvars);
+#include <stdio.h>
+#include <string.h>
- return (0);
-}
static
-void wrf_read_timestep(int fileID, int nctimevarid, int tsID, taxis_t *taxis)
+int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *taxis_name, taxis_t* taxis)
{
- size_t start[2], count[2];
- char stvalue[32];
- start[0] = (size_t) tsID; start[1] = 0;
- count[0] = 1; count[1] = 19;
- stvalue[0] = 0;
- cdf_get_vara_text(fileID, nctimevarid, start, count, stvalue);
- stvalue[19] = 0;
- {
- int year = 1, month = 1, day = 1 , hour = 0, minute = 0, second = 0;
- if ( strlen(stvalue) == 19 )
- sscanf(stvalue, "%d-%d-%d_%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
- taxis->vdate = cdiEncodeDate(year, month, day);
- taxis->vtime = cdiEncodeTime(hour, minute, second);
- taxis->type = TAXIS_ABSOLUTE;
- }
-}
+ int time_bndsid = -1;
+ int dims[2];
-static
-double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
-{
- double timevalue = 0;
- size_t index = (size_t) tsID;
+ dims[0] = nctimedimid;
- if ( tcache )
- {
- if ( tcache->size == 0 || (tsID < tcache->startid || tsID > (tcache->startid+tcache->size-1)) )
- {
- int maxvals = MAX_TIMECACHE_SIZE;
- tcache->startid = (tsID/MAX_TIMECACHE_SIZE)*MAX_TIMECACHE_SIZE;
- if ( (tcache->startid + maxvals) > tcache->maxvals ) maxvals = (tcache->maxvals)%MAX_TIMECACHE_SIZE;
- tcache->size = maxvals;
- index = (size_t) tcache->startid;
- // fprintf(stderr, "fill time cache: %d %d %d %d %d\n", tcache->maxvals, tsID, tcache->startid, tcache->startid+maxvals-1, maxvals);
- for ( int ival = 0; ival < maxvals; ++ival )
- {
- cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
- if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
- tcache->cache[ival] = timevalue;
- index++;
- }
- }
+ /* fprintf(stderr, "time has bounds\n"); */
+ static const char bndsName[] = "bnds";
+ if ( nc_inq_dimid(fileID, bndsName, &dims[1]) != NC_NOERR )
+ cdf_def_dim(fileID, bndsName, 2, &dims[1]);
- timevalue = tcache->cache[tsID%MAX_TIMECACHE_SIZE];
+ const char *bndsAttName, *bndsAttVal;
+ size_t bndsAttValLen;
+ char tmpstr[CDI_MAX_NAME];
+ if ( taxis->climatology )
+ {
+ static const char climatology_bndsName[] = "climatology_bnds",
+ climatology_bndsAttName[] = "climatology";
+ bndsAttName = climatology_bndsAttName;
+ bndsAttValLen = sizeof (climatology_bndsName) - 1;
+ bndsAttVal = climatology_bndsName;
}
else
{
- cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
- if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+ size_t taxisnameLen = strlen(taxis_name);
+ memcpy(tmpstr, taxis_name, taxisnameLen);
+ tmpstr[taxisnameLen] = '_';
+ memcpy(tmpstr + taxisnameLen + 1, bndsName, sizeof (bndsName));
+ size_t tmpstrLen = taxisnameLen + sizeof (bndsName);
+ static const char generic_bndsAttName[] = "bounds";
+ bndsAttName = generic_bndsAttName;
+ bndsAttValLen = tmpstrLen;
+ bndsAttVal = tmpstr;
}
+ cdf_def_var(fileID, bndsAttVal, NC_DOUBLE, 2, dims, &time_bndsid);
+ cdf_put_att_text(fileID, nctimevarid, bndsAttName, bndsAttValLen, bndsAttVal);
- return timevalue;
+ return time_bndsid;
}
-
-int cdfInqTimestep(stream_t * streamptr, int tsID)
+static
+void cdfDefTimeUnits(char *unitstr, taxis_t *taxis0, taxis_t *taxis)
{
- long nrecs = 0;
- double timevalue;
- int fileID;
- taxis_t *taxis;
+ if ( taxis->units && taxis->units[0] )
+ {
+ strcpy(unitstr, taxis->units);
+ }
+ else
+ {
+ unitstr[0] = 0;
- if ( CDI_Debug ) Message("streamID = %d tsID = %d", streamptr->self, tsID);
+ if ( taxis0->type == TAXIS_ABSOLUTE )
+ {
+ static const char *const unitstrfmt[3]
+ = { "year as %Y.%f",
+ "month as %Y%m.%f",
+ "day as %Y%m%d.%f" };
+ size_t fmtidx = (taxis0->unit == TUNIT_YEAR ? 0
+ : (taxis0->unit == TUNIT_MONTH ? 1
+ : 2));
+ strcpy(unitstr, unitstrfmt[fmtidx]);
+ }
+ else
+ {
+ int year, month, day, hour, minute, second;
+ cdiDecodeDate(taxis->rdate, &year, &month, &day);
+ cdiDecodeTime(taxis->rtime, &hour, &minute, &second);
+
+ int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
+ if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
+ else if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
+ else if ( timeunit == TUNIT_3HOURS
+ || timeunit == TUNIT_6HOURS
+ || timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
+
+ sprintf(unitstr, "%s since %d-%d-%d %02d:%02d:%02d",
+ tunitNamePtr(timeunit), year, month, day, hour, minute, second);
+ }
+ }
+}
- if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
+static
+void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
+{
+ unitstr[0] = 0;
- if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
- {
- cdfCreateRecords(streamptr, tsID);
+ if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
+ else if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
+ else if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
+ else if ( timeunit == TUNIT_3HOURS
+ || timeunit == TUNIT_6HOURS
+ || timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
- taxis = &streamptr->tsteps[tsID].taxis;
- if ( tsID > 0 )
- ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
+ strcpy(unitstr, tunitNamePtr(timeunit));
+}
- timevalue = tsID;
+static
+void cdfDefCalendar(int fileID, int ncvarid, int calendar)
+{
+ static const struct { int calCode; const char *calStr; } calTab[] = {
+ { CALENDAR_STANDARD, "standard" },
+ { CALENDAR_GREGORIAN, "gregorian" },
+ { CALENDAR_PROLEPTIC, "proleptic_gregorian" },
+ { CALENDAR_NONE, "none" },
+ { CALENDAR_360DAYS, "360_day" },
+ { CALENDAR_365DAYS, "365_day" },
+ { CALENDAR_366DAYS, "366_day" },
+ };
+ enum { calTabSize = sizeof calTab / sizeof calTab[0] };
- int nctimevarid = streamptr->basetime.ncvarid;
- if ( nctimevarid != UNDEFID )
- {
- fileID = streamptr->fileID;
- size_t index = (size_t)tsID;
+ for ( size_t i = 0; i < calTabSize; ++i )
+ if ( calTab[i].calCode == calendar )
+ {
+ const char *calstr = calTab[i].calStr;
+ size_t len = strlen(calstr);
+ cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
+ break;
+ }
+}
- if ( streamptr->basetime.lwrf )
- {
- wrf_read_timestep(fileID, nctimevarid, tsID, taxis);
- }
- else
- {
-#if defined (USE_TIMECACHE)
- if ( streamptr->basetime.timevar_cache == NULL )
- {
- streamptr->basetime.timevar_cache = (timecache_t *) Malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t));
- streamptr->basetime.timevar_cache->size = 0;
- streamptr->basetime.timevar_cache->maxvals = streamptr->ntsteps;
- }
-#endif
- timevalue = get_timevalue(fileID, nctimevarid, tsID, streamptr->basetime.timevar_cache);
- cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
- }
- int nctimeboundsid = streamptr->basetime.ncvarboundsid;
- if ( nctimeboundsid != UNDEFID )
- {
- size_t start[2], count[2];
- start[0] = index; count[0] = 1; start[1] = 0; count[1] = 1;
- cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
- if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+void cdfDefTime(stream_t* streamptr)
+{
+ int time_varid;
+ int time_dimid;
+ int time_bndsid = -1;
+ static const char default_name[] = "time";
- cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
+ if ( streamptr->basetime.ncvarid != CDI_UNDEFID ) return;
- start[0] = index; count[0] = 1; start[1] = 1; count[1] = 1;
- cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
- if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+ int fileID = streamptr->fileID;
- cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
- }
+ if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
+ if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
- int leadtimeid = streamptr->basetime.leadtimeid;
- if ( leadtimeid != UNDEFID )
- {
- timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
- cdiSetForecastPeriod(timevalue, taxis);
- }
- }
- }
+ taxis_t *taxis = &streamptr->tsteps[0].taxis;
- streamptr->curTsID = tsID;
- nrecs = streamptr->tsteps[tsID].nrecs;
+ const char *taxis_name = (taxis->name && taxis->name[0]) ? taxis->name : default_name ;
- return ((int) nrecs);
-}
+ cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
+ streamptr->basetime.ncdimid = time_dimid;
+ nc_type xtype = (taxis->datatype == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
-void cdfDefHistory(stream_t *streamptr, int size, const char *history)
-{
- int ncid = streamptr->fileID;
- cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
-}
+ cdf_def_var(fileID, taxis_name, xtype, 1, &time_dimid, &time_varid);
+ streamptr->basetime.ncvarid = time_varid;
-int cdfInqHistorySize(stream_t *streamptr)
-{
- size_t size = 0;
- int ncid = streamptr->fileID;
- if ( streamptr->historyID != UNDEFID )
- cdf_inq_attlen(ncid, NC_GLOBAL, "history", &size);
+#if defined (HAVE_NETCDF4)
+ if ( streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C )
+ {
+ size_t chunk = 512;
+ cdf_def_var_chunking(fileID, time_varid, NC_CHUNKED, &chunk);
+ }
+#endif
- return ((int) size);
-}
+ {
+ static const char timeStr[] = "time";
+ cdf_put_att_text(fileID, time_varid, "standard_name", sizeof(timeStr) - 1, timeStr);
+ }
+ if ( taxis->longname && taxis->longname[0] )
+ cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
-void cdfInqHistoryString(stream_t *streamptr, char *history)
-{
- int ncid = streamptr->fileID;
- if ( streamptr->historyID != UNDEFID )
+ if ( taxis->has_bounds )
{
- nc_type atttype;
- cdf_inq_atttype(ncid, NC_GLOBAL, "history", &atttype);
-
- if ( atttype == NC_CHAR )
- {
- cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
- }
-#if defined (HAVE_NETCDF4)
- else if ( atttype == NC_STRING )
- {
- // ToDo
- Warning("History attribute with type NC_STRING unsupported!");
- }
-#endif
+ time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
+ streamptr->basetime.ncvarboundsid = time_bndsid;
}
-}
+ {
+ char unitstr[CDI_MAX_NAME];
+ cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
+ size_t len = strlen(unitstr);
+ if ( len )
+ {
+ cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
+ /*
+ if ( taxis->has_bounds )
+ cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
+ */
+ }
+ }
-void cdfDefVars(stream_t *streamptr)
-{
- int vlistID = streamptr->vlistID;
- if ( vlistID == UNDEFID )
- Error("Internal problem! vlist undefined for streamptr %p", streamptr);
+ if ( taxis->calendar != -1 )
+ {
+ cdfDefCalendar(fileID, time_varid, taxis->calendar);
+ /*
+ if ( taxis->has_bounds )
+ cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
+ */
+ }
+
+ if ( taxis->type == TAXIS_FORECAST )
+ {
+ int leadtimeid;
+ cdf_def_var(fileID, "leadtime", xtype, 1, &time_dimid, &leadtimeid);
+ streamptr->basetime.leadtimeid = leadtimeid;
- int ngrids = vlistNgrids(vlistID);
- int nzaxis = vlistNzaxis(vlistID);
- /*
- if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
- */
- if ( ngrids > 0 )
- for ( int index = 0; index < ngrids; index++ )
{
- int gridID = vlistGrid(vlistID, index);
- cdfDefGrid(streamptr, gridID);
+ static const char stdname[] = "forecast_period";
+ cdf_put_att_text(fileID, leadtimeid, "standard_name", sizeof(stdname) - 1, stdname);
}
- if ( nzaxis > 0 )
- for ( int index = 0; index < nzaxis; index++ )
{
- int zaxisID = vlistZaxis(vlistID, index);
- if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
+ static const char lname[] = "Time elapsed since the start of the forecast";
+ cdf_put_att_text(fileID, leadtimeid, "long_name", sizeof(lname) - 1, lname);
}
- /* define time first!!!
- int nvars = vlistNvars(vlistID);
- for ( int varID = 0; varID < nvars; varID++ )
- {
- int ncvarid = cdfDefVar(streamptr, varID);
+ {
+ char unitstr[CDI_MAX_NAME];
+ cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
+ size_t len = strlen(unitstr);
+ if ( len )
+ cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
+ }
}
- */
+
+ cdf_put_att_text(fileID, time_varid, "axis", 1, "T");
+
+ if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
}
+
+
#endif
/*
* Local Variables:
@@ -45078,21 +45094,26 @@ datetimeCmp(DateTime dt1, DateTime dt2)
* require-trailing-newline: t
* End:
*/
-#ifndef _STREAM_CGRIBEX_H
-#define _STREAM_CGRIBEX_H
+#ifndef STREAM_CGRIBEX_H
+#define STREAM_CGRIBEX_H
int cgribexScanTimestep1(stream_t * streamptr);
int cgribexScanTimestep2(stream_t * streamptr);
int cgribexScanTimestep(stream_t * streamptr);
-int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long datasize,
- int unreduced, int *nmiss, double missval);
+int cgribexDecode(int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval);
size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const void *data, int nmiss, void *gribbuffer, size_t gribbuffersize);
+ size_t datasize, const void *data, size_t nmiss, void *gribbuffer, size_t gribbuffersize);
+
+void *cgribex_handle_new_from_meassage(void *gribbuffer, size_t recsize);
+void cgribex_handle_delete(void *gh);
-#endif /* _STREAM_CGRIBEX_H */
+void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev);
+
+#endif /* STREAM_CGRIBEX_H */
/*
* Local Variables:
* c-file-style: "Java"
@@ -45129,17 +45150,12 @@ int cgribexGetGridType(int *isec2)
switch (ISEC2_GridType)
{
- case GRIB1_GTYPE_LATLON: { if ( ISEC2_Reduced ) break; }
- case GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT; break; }
- case GRIB1_GTYPE_LCC: { gridtype = GRID_LCC; break; }
- case GRIB1_GTYPE_GAUSSIAN: { if ( ISEC2_Reduced )
- gridtype = GRID_GAUSSIAN_REDUCED;
- else
- gridtype = GRID_GAUSSIAN;
- break;
- }
- case GRIB1_GTYPE_SPECTRAL: { gridtype = GRID_SPECTRAL; break; }
- case GRIB1_GTYPE_GME: { gridtype = GRID_GME; break; }
+ case GRIB1_GTYPE_LATLON: { gridtype = GRID_LONLAT; break; }
+ case GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_PROJECTION; break; }
+ case GRIB1_GTYPE_LCC: { gridtype = GRID_LCC; break; }
+ case GRIB1_GTYPE_GAUSSIAN: { gridtype = ISEC2_Reduced ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN; break; }
+ case GRIB1_GTYPE_SPECTRAL: { gridtype = GRID_SPECTRAL; break; }
+ case GRIB1_GTYPE_GME: { gridtype = GRID_GME; break; }
}
return gridtype;
@@ -45148,9 +45164,7 @@ int cgribexGetGridType(int *isec2)
static
bool cgribexGetIsRotated(int *isec2)
{
- bool isRotated = (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT) ? true : false;
-
- return isRotated;
+ return (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT);
}
static
@@ -45211,9 +45225,9 @@ bool cgribexTimeIsFC(int *isec1)
static
int cgribexGetTsteptype(int timerange)
{
- int tsteptype = TSTEP_INSTANT;
static bool lprint = true;
+ int tsteptype = TSTEP_INSTANT;
switch ( timerange )
{
case 0: tsteptype = TSTEP_INSTANT; break;
@@ -45236,15 +45250,21 @@ int cgribexGetTsteptype(int timerange)
}
static
-void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
+void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
{
bool compyinc = true;
int gridtype = cgribexGetGridType(isec2);
+ int projtype = (gridtype == GRID_PROJECTION && cgribexGetIsRotated(isec2)) ? CDI_PROJ_RLL : CDI_UNDEFID;
+ if ( gridtype == GRID_LCC )
+ {
+ gridtype = GRID_PROJECTION;
+ projtype = CDI_PROJ_LCC;
+ }
if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
{
- int ilat, nlon = 0;
- for ( ilat = 0; ilat < ISEC2_NumLat; ++ilat )
+ int nlon = 0;
+ for ( int ilat = 0; ilat < ISEC2_NumLat; ++ilat )
if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
gridtype = GRID_GAUSSIAN;
ISEC2_NumLon = nlon;
@@ -45254,197 +45274,194 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4,
grid_init(grid);
cdiGridTypeInit(grid, gridtype, 0);
- switch (gridtype)
+
+ if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
{
- case GRID_LONLAT:
- case GRID_GAUSSIAN:
- {
- if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
- grid->size = ISEC4_NumValues;
- grid->xsize = ISEC2_NumLon;
- grid->ysize = ISEC2_NumLat;
- if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
- grid->xinc = 0;
- grid->yinc = 0;
- grid->xdef = 0;
- /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
- {
- if ( grid->xsize > 1 )
- {
- bool recompinc = true;
+ bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
+ bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
+ if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
- if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+ size_t nvalues = (size_t) ISEC4_NumValues;
+ size_t nlon = (size_t) ISEC2_NumLon;
+ size_t nlat = (size_t) ISEC2_NumLat;
+ if ( nvalues != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon*nlat);
- if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
- {
- if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
- {
- recompinc = false;
- grid->xinc = ISEC2_LonIncr * 0.001;
- }
- }
+ grid->size = nvalues;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
- /* recompute xinc if necessary */
- if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize-1);
+ if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
+ grid->x.inc = 0;
+ grid->y.inc = 0;
+ grid->x.flag = 0;
+ /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
+ {
+ if ( grid->x.size > 1 )
+ {
+ bool recompinc = true;
- /* correct xinc if necessary */
- if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
- {
- double xinc = 360. / grid->xsize;
+ if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
- if ( fabs(grid->xinc-xinc) > 0.0 )
- {
- grid->xinc = xinc;
- if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
- }
- }
- }
- grid->xfirst = ISEC2_FirstLon * 0.001;
- grid->xlast = ISEC2_LastLon * 0.001;
- grid->xdef = 2;
- }
- grid->ydef = 0;
- /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
- {
- if ( grid->ysize > 1 && compyinc )
- {
- bool recompinc = true;
- if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
+ if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
+ {
+ if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->x.size-1))) <= 2 )
{
- if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
- {
- recompinc = false;
- grid->yinc = ISEC2_LatIncr * 0.001;
- }
+ recompinc = false;
+ grid->x.inc = ISEC2_LonIncr * 0.001;
}
+ }
- /* recompute yinc if necessary */
- if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
- }
- grid->yfirst = ISEC2_FirstLat * 0.001;
- grid->ylast = ISEC2_LastLat * 0.001;
- grid->ydef = 2;
- }
- break;
- }
- case GRID_GAUSSIAN_REDUCED:
- {
- grid->np = ISEC2_NumPar;
- grid->size = ISEC4_NumValues;
- grid->rowlon = ISEC2_RowLonPtr;
- grid->nrowlon = ISEC2_NumLat;
- grid->ysize = ISEC2_NumLat;
- grid->xinc = 0;
- grid->yinc = 0;
- grid->xdef = 0;
- /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
- {
- if ( grid->xsize > 1 )
- {
- if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+ /* recompute xinc if necessary */
+ if ( recompinc ) grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
- if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
- grid->xinc = ISEC2_LonIncr * 0.001;
- else
- grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
- }
- grid->xfirst = ISEC2_FirstLon * 0.001;
- grid->xlast = ISEC2_LastLon * 0.001;
- grid->xdef = 2;
- }
- grid->ydef = 0;
- /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
- {
- if ( grid->ysize > 1 )
- {
- if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
- grid->yinc = ISEC2_LatIncr * 0.001;
- else
- grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
- }
- grid->yfirst = ISEC2_FirstLat * 0.001;
- grid->ylast = ISEC2_LastLat * 0.001;
- grid->ydef = 2;
- }
- break;
+ /* correct xinc if necessary */
+ if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
+ {
+ double xinc = 360. / grid->x.size;
+ if ( fabs(grid->x.inc-xinc) > 0.0 )
+ {
+ grid->x.inc = xinc;
+ if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+ }
+ }
+ }
+ grid->x.first = ISEC2_FirstLon * 0.001;
+ grid->x.last = ISEC2_LastLon * 0.001;
+ grid->x.flag = 2;
}
- case GRID_LCC:
+ grid->y.flag = 0;
+ /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
{
- if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!",
- ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
-
- grid->size = ISEC4_NumValues;
- grid->xsize = ISEC2_NumLon;
- grid->ysize = ISEC2_NumLat;
-
- grid->lcc_xinc = ISEC2_Lambert_dx;
- grid->lcc_yinc = ISEC2_Lambert_dy;
- grid->lcc_originLon = ISEC2_FirstLon * 0.001;
- grid->lcc_originLat = ISEC2_FirstLat * 0.001;
- grid->lcc_lonParY = ISEC2_Lambert_Lov * 0.001;
- grid->lcc_lat1 = ISEC2_Lambert_LatS1 * 0.001;
- grid->lcc_lat2 = ISEC2_Lambert_LatS2 * 0.001;
- grid->lcc_projflag = ISEC2_Lambert_ProjFlag;
- grid->lcc_scanflag = ISEC2_ScanFlag;
-
- grid->xdef = 0;
- grid->ydef = 0;
+ if ( grid->y.size > 1 && compyinc )
+ {
+ bool recompinc = true;
+ if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
+ {
+ if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->y.size-1))) <= 2 )
+ {
+ recompinc = false;
+ grid->y.inc = ISEC2_LatIncr * 0.001;
+ }
+ }
- break;
+ /* recompute yinc if necessary */
+ if ( recompinc ) grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
+ }
+ grid->y.first = ISEC2_FirstLat * 0.001;
+ grid->y.last = ISEC2_LastLat * 0.001;
+ grid->y.flag = 2;
}
- case GRID_SPECTRAL:
+ }
+ else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+ {
+ bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
+ bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
+ if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
+ grid->np = ISEC2_NumPar;
+ grid->size = (size_t)ISEC4_NumValues;
+ grid->rowlon = ISEC2_RowLonPtr;
+ grid->nrowlon = (size_t)ISEC2_NumLat;
+ grid->y.size = (size_t)ISEC2_NumLat;
+ grid->x.inc = 0;
+ grid->y.inc = 0;
+ grid->x.flag = 0;
+ /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
{
- grid->size = ISEC4_NumValues;
- grid->trunc = ISEC2_PentaJ;
- if ( ISEC2_RepMode == 2 )
- grid->lcomplex = 1;
- else
- grid->lcomplex = 0;
+ if ( grid->x.size > 1 )
+ {
+ if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
- break;
- }
- case GRID_GME:
- {
- grid->size = ISEC4_NumValues;
- grid->nd = ISEC2_GME_ND;
- grid->ni = ISEC2_GME_NI;
- grid->ni2 = ISEC2_GME_NI2;
- grid->ni3 = ISEC2_GME_NI3;
- break;
- }
- case GRID_GENERIC:
- {
- grid->size = ISEC4_NumValues;
- grid->xsize = 0;
- grid->ysize = 0;
- break;
+ if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
+ grid->x.inc = ISEC2_LonIncr * 0.001;
+ else
+ grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size - 1);
+ }
+ grid->x.first = ISEC2_FirstLon * 0.001;
+ grid->x.last = ISEC2_LastLon * 0.001;
+ grid->x.flag = 2;
}
- default:
+ grid->y.flag = 0;
+ /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
{
- Error("Unsupported grid type: %s", gridNamePtr(gridtype));
- break;
+ if ( grid->y.size > 1 )
+ {
+ if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
+ grid->y.inc = ISEC2_LatIncr * 0.001;
+ else
+ grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
+ }
+ grid->y.first = ISEC2_FirstLat * 0.001;
+ grid->y.last = ISEC2_LastLat * 0.001;
+ grid->y.flag = 2;
}
}
+ else if ( projtype == CDI_PROJ_LCC )
+ {
+ bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
+ if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
+
+ size_t nvalues = (size_t) ISEC4_NumValues;
+ size_t nlon = (size_t) ISEC2_NumLon;
+ size_t nlat = (size_t) ISEC2_NumLat;
+ if ( nvalues != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon*nlat);
- grid->isRotated = FALSE;
- if ( cgribexGetIsRotated(isec2) )
+ grid->size = nvalues;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
+
+ grid->x.first = 0;
+ grid->x.last = 0;
+ grid->x.inc = ISEC2_Lambert_dx;
+ grid->y.first = 0;
+ grid->y.last = 0;
+ grid->y.inc = ISEC2_Lambert_dy;
+ grid->x.flag = 2;
+ grid->y.flag = 2;
+ }
+ else if ( gridtype == GRID_SPECTRAL )
+ {
+ grid->size = (size_t) ISEC4_NumValues;
+ grid->trunc = ISEC2_PentaJ;
+ grid->lcomplex = (ISEC2_RepMode == 2) ? 1 : 0;
+ }
+ else if ( gridtype == GRID_GME )
+ {
+ grid->size = (size_t) ISEC4_NumValues;
+ grid->gme.nd = ISEC2_GME_ND;
+ grid->gme.ni = ISEC2_GME_NI;
+ grid->gme.ni2 = ISEC2_GME_NI2;
+ grid->gme.ni3 = ISEC2_GME_NI3;
+ }
+ else if ( gridtype == GRID_GENERIC )
+ {
+ grid->size = (size_t) ISEC4_NumValues;
+ grid->x.size = 0;
+ grid->y.size = 0;
+ }
+ else
{
- grid->isRotated = TRUE;
- grid->ypole = - ISEC2_LatSP*0.001;
- grid->xpole = ISEC2_LonSP*0.001 - 180;
- grid->angle = - FSEC2_RotAngle;
+ Error("Unsupported grid type: %s", gridNamePtr(gridtype));
}
- grid->xvals = NULL;
- grid->yvals = NULL;
- grid->type = gridtype;
+ grid->type = gridtype;
+ grid->projtype = projtype;
+}
+
+static
+void cgribexGetLevel(int *isec1, int *leveltype, int *level1, int *level2)
+{
+ *leveltype = ISEC1_LevelType;
+ *level1 = ISEC1_Level1;
+ *level2 = ISEC1_Level2;
+ if ( *leveltype == GRIB1_LTYPE_ISOBARIC ) *level1 *= 100;
+ else if ( *leveltype == GRIB1_LTYPE_99 || *leveltype == GRIB1_LTYPE_ISOBARIC_PA ) *leveltype = GRIB1_LTYPE_ISOBARIC;
}
static
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
- int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
+ int *isec4, size_t recsize, off_t position, int datatype, int comptype, int lmv, int iret)
{
int varID;
int levelID = 0;
@@ -45457,23 +45474,23 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
int numavg = ISEC1_AvgNum;
- int level1 = ISEC1_Level1;
- int level2 = ISEC1_Level2;
+ int leveltype, level1, level2;
+ cgribexGetLevel(isec1, &leveltype, &level1, &level2);
- /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
+ /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype); */
- record->size = (size_t)recsize;
+ record->size = recsize;
record->position = position;
record->param = param;
record->ilevel = level1;
record->ilevel2 = level2;
- record->ltype = ISEC1_LevelType;
+ record->ltype = leveltype;
record->tsteptype = (short)tsteptype;
grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
- cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
+ cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret);
- struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
+ struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
int gridID = gridAdded.Id;
if ( gridAdded.isNew )
{
@@ -45484,11 +45501,44 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
gridptr->rowlon = (int*) Malloc(nrowlon * sizeof(int));
memcpy(gridptr->rowlon, rowlon, nrowlon * sizeof(int));
}
+ else if ( gridptr->projtype == CDI_PROJ_RLL )
+ {
+ double xpole = ISEC2_LonSP*0.001 - 180;
+ double ypole = - ISEC2_LatSP*0.001;
+ double angle = - FSEC2_RotAngle;
+ gridDefParamRLL(gridID, xpole, ypole, angle);
+ }
+ else if ( gridptr->projtype == CDI_PROJ_LCC )
+ {
+ double a = 6367470., rf = 0;
+ bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2);
+ if ( earthIsOblate ) { a = 6378160.; rf = 297.0; }
+ double xval_0 = ISEC2_FirstLon * 0.001;
+ double yval_0 = ISEC2_FirstLat * 0.001;
+ double lon_0 = ISEC2_Lambert_Lov * 0.001;
+ double lat_1 = ISEC2_Lambert_LatS1 * 0.001;
+ double lat_2 = ISEC2_Lambert_LatS2 * 0.001;
+ bool lsouth = gribbyte_get_bit(ISEC2_Lambert_ProjFlag, 1);
+ if ( lsouth ) { lat_1 = -lat_1; lat_2 = -lat_2; }
+
+ double lat_0 = lat_2;
+ double x_0 = grid_missval;
+ double y_0 = grid_missval;
+
+ if ( proj_lonlat_to_lcc_func )
+ {
+ x_0 = xval_0; y_0 = yval_0;
+ proj_lonlat_to_lcc_func(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, (size_t)1, &x_0, &y_0);
+ if ( IS_NOT_EQUAL(x_0, grid_missval) && IS_NOT_EQUAL(y_0, grid_missval) )
+ { x_0 = -x_0; y_0 = -y_0; }
+ }
+ gridDefParamLCC(gridID, grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0);
+ }
}
else
Free(gridptr);
- int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
+ int zaxistype = grib1ltypeToZaxisType(leveltype);
if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
{
@@ -45498,13 +45548,13 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
varDefVCT(vctsize, vctptr);
}
- int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
+ int lbounds = cgribexGetZaxisHasBounds(leveltype);
- if ( datatype > 32 ) datatype = DATATYPE_PACK32;
- if ( datatype < 0 ) datatype = DATATYPE_PACK;
+ if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
+ if ( datatype < 0 ) datatype = CDI_DATATYPE_PACK;
varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
- datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
+ datatype, &varID, &levelID, tsteptype, numavg, leveltype, -1,
NULL, NULL, NULL, NULL, NULL, NULL);
record->varID = (short)varID;
@@ -45524,10 +45574,9 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
if ( varInqInst(varID) == CDI_UNDEFID )
{
- int center, subcenter, instID;
- center = ISEC1_CenterID;
- subcenter = ISEC1_SubCenterID;
- instID = institutInq(center, subcenter, NULL, NULL);
+ int center = ISEC1_CenterID;
+ int subcenter = ISEC1_SubCenterID;
+ int instID = institutInq(center, subcenter, NULL, NULL);
if ( instID == CDI_UNDEFID )
instID = institutDef(center, subcenter, NULL, NULL);
varDefInst(varID, instID);
@@ -45535,8 +45584,7 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
if ( varInqModel(varID) == CDI_UNDEFID )
{
- int modelID;
- modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
+ int modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
if ( modelID == CDI_UNDEFID )
modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
varDefModel(varID, modelID);
@@ -45544,10 +45592,7 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
if ( varInqTable(varID) == CDI_UNDEFID )
{
- int tableID;
-
- tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
-
+ int tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
if ( tableID == CDI_UNDEFID )
tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
varDefTable(varID, tableID);
@@ -45590,16 +45635,18 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
int ipunp = 0, iword = 0;
memset(isec1, 0, 256*sizeof(int));
+ memset(isec2, 0, 32*sizeof(int));
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
+ if ( !(ISEC1_Sec2Or3Flag & 128) ) isec2[0] = -1; // default generic grid
+
*lmv = 0;
if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
{
double undef_pds, undef_eps;
-
MCH_get_undef(isec1, &undef_pds, &undef_eps);
FSEC3_MissVal = undef_pds;
*lmv = 1;
@@ -45609,9 +45656,9 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
static
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
{
- compvar_t compVar;
int tsteptype = cgribexGetTsteptype(trange);
+ compvar_t compVar;
compVar.param = param;
compVar.level1 = level1;
compVar.level2 = level2;
@@ -45624,11 +45671,10 @@ compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int tr
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
{
- int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
- & (record.tsteptype == TSTEP_INSTANT3))
- |((compVar.tsteptype == TSTEP_INSTANT3)
- & (record.tsteptype == TSTEP_INSTANT)))))
- & (compVar.tsteptype != record.tsteptype);
+ bool vinst = compVar.tsteptype == TSTEP_INSTANT || compVar.tsteptype == TSTEP_INSTANT2 || compVar.tsteptype == TSTEP_INSTANT3;
+ bool rinst = record.tsteptype == TSTEP_INSTANT || record.tsteptype == TSTEP_INSTANT2 || record.tsteptype == TSTEP_INSTANT3;
+ int tstepDiff = (!((flag == 0) & (vinst && rinst)))
+ & (compVar.tsteptype != record.tsteptype);
int rstatus = (compVar.param != record.param)
| (compVar.level1 != record.ilevel)
| (compVar.level2 != record.ilevel2)
@@ -45652,7 +45698,7 @@ cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
}
@@ -45666,16 +45712,14 @@ cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
if ( taxis->vdate == 0 && taxis->vtime == 0 )
{
streamptr->ntsteps = 0;
- for (int varID = 0; varID < streamptr->nvars; varID++ )
- {
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
- }
+ for ( int varID = 0; varID < streamptr->nvars; varID++ )
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
}
}
-int cgribexScanTimestep1(stream_t * streamptr)
+int cgribexScanTimestep1(stream_t *streamptr)
{
double fsec2[512], fsec3[2], *fsec4 = NULL;
int lmv = 0, iret = 0;
@@ -45684,13 +45728,13 @@ int cgribexScanTimestep1(stream_t * streamptr)
size_t buffersize = 0;
int rstatus;
int param = 0;
- int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+ int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
size_t readsize;
unsigned nrecords, recID;
int nrecs_scanned = 0;
int datatype;
- long recsize = 0;
+ size_t recsize = 0;
bool warn_time = true;
bool warn_numavg = true;
int taxisID = -1;
@@ -45698,7 +45742,7 @@ int cgribexScanTimestep1(stream_t * streamptr)
bool fcast = false;
int vlistID;
int comptype;
- long unzipsize;
+ size_t unzipsize;
char paramstr[32];
int nskip = cdiSkipRecords;
@@ -45729,7 +45773,7 @@ int cgribexScanTimestep1(stream_t * streamptr)
}
unsigned nrecs = 0;
- while ( TRUE )
+ while ( true )
{
recsize = gribGetSize(fileID);
recpos = fileGetPos(fileID);
@@ -45742,24 +45786,24 @@ int cgribexScanTimestep1(stream_t * streamptr)
streamptr->ntsteps = 1;
break;
}
- if ( (size_t)recsize > buffersize )
+ if ( recsize > buffersize )
{
- buffersize = (size_t)recsize;
+ buffersize = recsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
- readsize = (size_t)recsize;
+ readsize = recsize;
rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
if ( rstatus ) break;
- comptype = COMPRESS_NONE;
+ comptype = CDI_COMPRESS_NONE;
if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
{
- comptype = COMPRESS_SZIP;
+ comptype = CDI_COMPRESS_SZIP;
unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
- if ( buffersize < (size_t)unzipsize )
+ if ( buffersize < unzipsize )
{
- buffersize = (size_t)unzipsize;
+ buffersize = unzipsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
}
@@ -45771,17 +45815,11 @@ int cgribexScanTimestep1(stream_t * streamptr)
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
cdiParamToString(param, paramstr, sizeof(paramstr));
- if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
- if ( ISEC1_LevelType == 99 ) ISEC1_LevelType = 100;
- level1 = ISEC1_Level1;
- level2 = ISEC1_Level2;
+ cgribexGetLevel(isec1, &leveltype, &level1, &level2);
gribDateTime(isec1, &vdate, &vtime);
- if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
- datatype = ISEC4_NumBits;
- else
- datatype = DATATYPE_PACK;
+ datatype = (ISEC4_NumBits > 0 && ISEC4_NumBits <= 32) ? ISEC4_NumBits : CDI_DATATYPE_PACK;
if ( nrecs == 0 )
{
@@ -45794,9 +45832,9 @@ int cgribexScanTimestep1(stream_t * streamptr)
}
else
{
- datetime.date = vdate;
- datetime.time = vtime;
- compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+ datetime.date = vdate;
+ datetime.time = vtime;
+ compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
for ( recID = 0; recID < nrecs; recID++ )
{
if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
@@ -45887,7 +45925,7 @@ int cgribexScanTimestep1(stream_t * streamptr)
streamptr->tsteps[0].recIDs[recID] = (int)recID;
streamptr->record->buffer = gribbuffer;
- streamptr->record->buffersize = (size_t)buffersize;
+ streamptr->record->buffersize = buffersize;
cgribexScanTsFixNtsteps(streamptr, recpos);
cgribexScanTsConstAdjust(streamptr, taxis);
@@ -45903,15 +45941,15 @@ int cgribexScanTimestep2(stream_t * streamptr)
int lmv = 0, iret = 0;
off_t recpos = 0;
int param = 0;
- int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+ int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
int varID, gridID;
size_t readsize;
int nrecs, recID;
- long recsize = 0;
+ size_t recsize = 0;
bool warn_numavg = true;
int tsteptype;
- long unzipsize;
+ size_t unzipsize;
char paramstr[32];
streamptr->curTsID = 1;
@@ -45954,7 +45992,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
int nrecs_scanned = nrecords;
int rindex = 0;
- while ( TRUE )
+ while ( true )
{
if ( rindex > nrecords ) break;
@@ -45965,22 +46003,22 @@ int cgribexScanTimestep2(stream_t * streamptr)
streamptr->ntsteps = 2;
break;
}
- if ( (size_t)recsize > buffersize )
+ if ( recsize > buffersize )
{
- buffersize = (size_t)recsize;
+ buffersize = recsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
- readsize = (size_t)recsize;
+ readsize = recsize;
rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
if ( rstatus ) break;
if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
{
unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
- if ( buffersize < (size_t)unzipsize )
+ if ( buffersize < unzipsize )
{
- buffersize = (size_t)unzipsize;
+ buffersize = unzipsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
}
@@ -45993,10 +46031,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
cdiParamToString(param, paramstr, sizeof(paramstr));
- if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
- if ( ISEC1_LevelType == 99 ) ISEC1_LevelType = 100;
- level1 = ISEC1_Level1;
- level2 = ISEC1_Level2;
+ cgribexGetLevel(isec1, &leveltype, &level1, &level2);
gribDateTime(isec1, &vdate, &vtime);
@@ -46041,7 +46076,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
datetime.date = vdate;
datetime.time = vtime;
- compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+ compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
for ( recID = 0; recID < nrecords; recID++ )
{
@@ -46062,7 +46097,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
}
@@ -46077,7 +46112,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
}
@@ -46085,7 +46120,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
if ( CDI_Debug )
Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
- streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+ streamptr->tsteps[tsID].records[recID].size = recsize;
if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
{
@@ -46118,7 +46153,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
if ( ! streamptr->tsteps[tsID].records[recID].used )
{
varID = streamptr->tsteps[tsID].records[recID].varID;
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
else
{
@@ -46145,13 +46180,13 @@ int cgribexScanTimestep(stream_t * streamptr)
int rstatus = 0;
double fsec2[512], fsec3[2], *fsec4 = NULL;
int lmv = 0, iret = 0;
- long recsize = 0;
+ size_t recsize = 0;
off_t recpos = 0;
void *gribbuffer;
size_t buffersize = 0;
int fileID;
int param = 0;
- int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+ int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
int vrecID, recID;
bool warn_numavg = true;
@@ -46159,7 +46194,7 @@ int cgribexScanTimestep(stream_t * streamptr)
int taxisID = -1;
int rindex, nrecs = 0;
int nrecs_scanned;
- long unzipsize;
+ size_t unzipsize;
char paramstr[32];
/*
@@ -46200,7 +46235,7 @@ int cgribexScanTimestep(stream_t * streamptr)
nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
rindex = 0;
- while ( TRUE )
+ while ( true )
{
if ( rindex > nrecs ) break;
@@ -46211,15 +46246,15 @@ int cgribexScanTimestep(stream_t * streamptr)
streamptr->ntsteps = streamptr->rtsteps + 1;
break;
}
- if ( recsize > 0 && (size_t)recsize > buffersize )
+ if ( recsize > 0 && recsize > buffersize )
{
- buffersize = (size_t)recsize;
+ buffersize = recsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
if ( rindex >= nrecs ) break;
- readsize = (size_t)recsize;
+ readsize = recsize;
rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
if ( rstatus )
{
@@ -46231,9 +46266,9 @@ int cgribexScanTimestep(stream_t * streamptr)
if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
{
unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
- if ( buffersize < (size_t)unzipsize )
+ if ( buffersize < unzipsize )
{
- buffersize = (size_t)unzipsize;
+ buffersize = unzipsize;
gribbuffer = Realloc(gribbuffer, buffersize);
}
}
@@ -46246,10 +46281,7 @@ int cgribexScanTimestep(stream_t * streamptr)
param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
cdiParamToString(param, paramstr, sizeof(paramstr));
- if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
- if ( ISEC1_LevelType == 99 ) ISEC1_LevelType = 100;
- level1 = ISEC1_Level1;
- level2 = ISEC1_Level2;
+ cgribexGetLevel(isec1, &leveltype, &level1, &level2);
gribDateTime(isec1, &vdate, &vtime);
@@ -46296,7 +46328,7 @@ int cgribexScanTimestep(stream_t * streamptr)
datetime.date = vdate;
datetime.time = vtime;
- compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+ compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
for ( vrecID = 0; vrecID < nrecs; vrecID++ )
{
@@ -46316,7 +46348,7 @@ int cgribexScanTimestep(stream_t * streamptr)
if ( cdiInventoryMode == 1 )
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
else
@@ -46335,7 +46367,7 @@ int cgribexScanTimestep(stream_t * streamptr)
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
}
@@ -46353,7 +46385,7 @@ int cgribexScanTimestep(stream_t * streamptr)
}
streamptr->tsteps[tsID].records[recID].position = recpos;
- streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+ streamptr->tsteps[tsID].records[recID].size = recsize;
rindex++;
}
@@ -46380,7 +46412,7 @@ int cgribexScanTimestep(stream_t * streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = 1;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -46408,8 +46440,8 @@ int cgribexScanTimestep(stream_t * streamptr)
#endif
#if defined (HAVE_LIBCGRIBEX)
-int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long datasize,
- int unreduced, int *nmiss, double missval)
+int cgribexDecode(int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval)
{
int status = 0;
int iret = 0, iword = 0;
@@ -46425,15 +46457,12 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
if ( memtype == MEMTYPE_FLOAT )
gribExSP(isec0, isec1, isec2, fsec2f, isec3, fsec3f, isec4, (float*) data,
- (int) datasize, (int*) gribbuffer, gribsize, &iword, hoper, &iret);
+ (int) datasize, (int*) gribbuffer, (int)gribsize, &iword, hoper, &iret);
else
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, (double*) data,
- (int) datasize, (int*) gribbuffer, gribsize, &iword, hoper, &iret);
+ (int) datasize, (int*) gribbuffer, (int)gribsize, &iword, hoper, &iret);
- if ( ISEC1_Sec2Or3Flag & 64 )
- *nmiss = ISEC4_NumValues - ISEC4_NumNonMissValues;
- else
- *nmiss = 0;
+ *nmiss = (ISEC1_Sec2Or3Flag & 64) ? ISEC4_NumValues - ISEC4_NumNonMissValues : 0;
if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
{
@@ -46444,7 +46473,7 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
if ( memtype == MEMTYPE_FLOAT )
{
float *restrict dataf = (float*) data;
- for ( long i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
if ( (fabs(dataf[i]-undef_pds) < undef_eps) || IS_EQUAL(dataf[i],FSEC3_MissVal) ) {
dataf[i] = (float)missval;
(*nmiss)++;
@@ -46453,7 +46482,7 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
else
{
double *restrict datad = (double*) data;
- for ( long i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
if ( (fabs(datad[i]-undef_pds) < undef_eps) || IS_EQUAL(datad[i],FSEC3_MissVal) ) {
datad[i] = missval;
(*nmiss)++;
@@ -46470,33 +46499,18 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
static
void cgribexDefInstitut(int *isec1, int vlistID, int varID)
{
- int instID;
-
- if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
- instID = vlistInqInstitut(vlistID);
- else
- instID = vlistInqVarInstitut(vlistID, varID);
-
+ int instID = (vlistInqInstitut(vlistID) != CDI_UNDEFID) ? vlistInqInstitut(vlistID) : vlistInqVarInstitut(vlistID, varID);
if ( instID != CDI_UNDEFID )
{
- int center, subcenter;
- center = institutInqCenter(instID);
- subcenter = institutInqSubcenter(instID);
- ISEC1_CenterID = center;
- ISEC1_SubCenterID = subcenter;
+ ISEC1_CenterID = institutInqCenter(instID);
+ ISEC1_SubCenterID = institutInqSubcenter(instID);
}
}
static
void cgribexDefModel(int *isec1, int vlistID, int varID)
{
- int modelID;
-
- if ( vlistInqModel(vlistID) != CDI_UNDEFID )
- modelID = vlistInqModel(vlistID);
- else
- modelID = vlistInqVarModel(vlistID, varID);
-
+ int modelID = (vlistInqModel(vlistID) != CDI_UNDEFID) ? vlistInqModel(vlistID) : vlistInqVarModel(vlistID, varID);
if ( modelID != CDI_UNDEFID )
ISEC1_ModelID = modelInqGribID(modelID);
}
@@ -46505,9 +46519,7 @@ static
void cgribexDefParam(int *isec1, int param)
{
int pdis, pcat, pnum;
-
cdiDecodeParam(param, &pnum, &pcat, &pdis);
-
if ( pnum < 0 ) pnum = -pnum;
static bool lwarn_pdis = true;
@@ -46535,10 +46547,8 @@ static
int cgribexDefTimerange(int tsteptype, int factor, int calendar,
int rdate, int rtime, int vdate, int vtime, int *pip1, int *pip2)
{
- int timerange = -1;
int year, month, day, hour, minute, second;
int julday1, secofday1, julday2, secofday2, days, secs;
- int ip1 = 0, ip2 = 0;
cdiDecodeDate(rdate, &year, &month, &day);
cdiDecodeTime(rtime, &hour, &minute, &second);
@@ -46550,6 +46560,8 @@ int cgribexDefTimerange(int tsteptype, int factor, int calendar,
(void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+ int timerange = -1;
+ int ip1 = 0, ip2 = 0;
if ( !(int)(fmod(days*86400.0 + secs, factor)) )
{
int ip = (int) ((days*86400.0 + secs)/factor);
@@ -46579,13 +46591,10 @@ static
int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
{
int year, month, day, hour, minute, second;
- int century = 0;
- int factor = 1;
-
cdiDecodeDate(date, &year, &month, &day);
cdiDecodeTime(time, &hour, &minute, &second);
- century = year / 100;
+ int century = year / 100;
ISEC1_Year = year - century*100;
@@ -46611,6 +46620,7 @@ int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
ISEC1_Century = century;
+ int factor = 1;
switch (timeunit)
{
case TUNIT_MINUTE: factor = 60; ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE; break;
@@ -46642,16 +46652,12 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
if ( timetype == TAXIS_RELATIVE )
{
- int factor = 1;
- int rdate, rtime;
- int ip1 = 0, ip2 = 0;
- int calendar;
-
- calendar = taxisInqCalendar(taxisID);
- rdate = taxisInqRdate(taxisID);
- rtime = taxisInqRtime(taxisID);
+ int calendar = taxisInqCalendar(taxisID);
+ int rdate = taxisInqRdate(taxisID);
+ int rtime = taxisInqRtime(taxisID);
- factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
+ int factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
+ int ip1 = 0, ip2 = 0;
timerange = cgribexDefTimerange(tsteptype, factor, calendar,
rdate, rtime, vdate, vtime, &ip1, &ip2);
@@ -46709,8 +46715,8 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
static
void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID)
{
+ bool lrotated = false;
bool lcurvi = false;
- static bool lwarning = true;
memset(isec2, 0, 16*sizeof(int));
@@ -46722,9 +46728,9 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
if ( gridtype == GRID_GENERIC )
{
- int gridsize = gridInqSize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int gridsize = (int)gridInqSize(gridID);
+ int xsize = (int)gridInqXsize(gridID);
+ int ysize = (int)gridInqYsize(gridID);
if ( (ysize == 32 || ysize == 48 || ysize == 64 ||
ysize == 96 || ysize == 160 || ysize == 192 ||
@@ -46748,16 +46754,39 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
}
else if ( gridtype == GRID_CURVILINEAR )
{
- if ( lwarning && gridInqSize(gridID) > 1 )
- {
- lwarning = false;
- Warning("Curvilinear grids are unsupported in GRIB1! Created wrong Grid Description Section!");
- }
- gridtype = GRID_LONLAT;
- lcurvi = true;
+ int projID = gridInqProj(gridID);
+ if ( projID != CDI_UNDEFID && gridInqType(projID) == GRID_PROJECTION )
+ {
+ gridID = projID;
+ gridtype = GRID_PROJECTION;
+ }
+ else
+ {
+ static bool lwarning = true;
+ if ( lwarning && gridInqSize(gridID) > 1 )
+ {
+ lwarning = false;
+ Warning("Curvilinear grid is unsupported in GRIB1! Created wrong Grid Description Section!");
+ }
+ lcurvi = true;
+ gridtype = GRID_LONLAT;
+ }
+ }
+
+ if ( gridtype == GRID_PROJECTION )
+ {
+ if ( gridInqProjType(gridID) == CDI_PROJ_RLL )
+ {
+ gridtype = GRID_LONLAT;
+ lrotated = true;
+ }
+ else if ( gridInqProjType(gridID) == CDI_PROJ_LCC )
+ {
+ gridtype = GRID_LCC;
+ }
}
- ISEC2_Reduced = FALSE;
+ ISEC2_Reduced = false;
ISEC2_ScanFlag = 0;
switch (gridtype)
@@ -46769,45 +46798,38 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
{
double xfirst = 0, xlast = 0, xinc = 0;
double yfirst = 0, ylast = 0, yinc = 0;
- bool isRotated = gridIsRotated(gridID);
if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN;
- else if ( gridtype == GRID_LONLAT && isRotated )
+ else if ( gridtype == GRID_LONLAT && lrotated )
ISEC2_GridType = GRIB1_GTYPE_LATLON_ROT;
else
ISEC2_GridType = GRIB1_GTYPE_LATLON;
- int nlon = gridInqXsize(gridID);
- int nlat = gridInqYsize(gridID);
+ int nlon = (int)gridInqXsize(gridID);
+ int nlat = (int)gridInqYsize(gridID);
if ( gridtype == GRID_GAUSSIAN_REDUCED )
{
- ISEC2_Reduced = TRUE;
+ ISEC2_Reduced = true;
nlon = 0;
gridInqRowlon(gridID, ISEC2_RowLonPtr);
}
else
{
- if ( nlon == 0 )
- {
- nlon = 1;
- }
+ if ( nlon == 0 ) nlon = 1;
else
{
- xfirst = gridInqXval(gridID, 0);
+ xfirst = gridInqXval(gridID, 0);
xlast = gridInqXval(gridID, (lcurvi ? nlon*nlat : nlon) - 1);
- xinc = gridInqXinc(gridID);
+ xinc = fabs(gridInqXinc(gridID));
}
}
- if ( nlat == 0 )
- {
- nlat = 1;
- }
+ if ( nlat == 0 ) nlat = 1;
else
{
- yfirst = gridInqYval(gridID, 0);
+ yfirst = gridInqYval(gridID, 0);
ylast = gridInqYval(gridID, (lcurvi ? nlon*nlat : nlat) - 1);
yinc = fabs(gridInqYinc(gridID));
}
@@ -46838,7 +46860,6 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
else
{
ISEC2_LatIncr = (int)lround(yinc*1000);
- if ( ISEC2_LatIncr < 0 ) ISEC2_LatIncr = -ISEC2_LatIncr;
}
if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
@@ -46847,51 +46868,64 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
- ISEC2_ResFlag = ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 ) ? 0 : 128;
+ ISEC2_ResFlag = 0;
+ if ( ISEC2_LatIncr && ISEC2_LonIncr ) gribbyte_set_bit(&ISEC2_ResFlag, 1);
+ if ( gridInqUvRelativeToGrid(gridID) ) gribbyte_set_bit(&ISEC2_ResFlag, 5);
- if ( isRotated )
- {
- ISEC2_LatSP = - (int)lround(gridInqYpole(gridID) * 1000);
- ISEC2_LonSP = (int)lround((gridInqXpole(gridID) + 180) * 1000);
- double angle = gridInqAngle(gridID);
+ if ( lrotated )
+ {
+ double xpole = 0, ypole = 0, angle = 0;
+ gridInqParamRLL(gridID, &xpole, &ypole, &angle);
+
+ ISEC2_LatSP = - (int)lround(ypole * 1000);
+ ISEC2_LonSP = (int)lround((xpole + 180) * 1000);
if ( fabs(angle) > 0 ) angle = -angle;
FSEC2_RotAngle = angle;
- }
-
- /* East -> West */
- if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
+ }
- /* South -> North */
- if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
+ ISEC2_ScanFlag = 0;
+ if ( ISEC2_LastLon < ISEC2_FirstLon ) gribbyte_set_bit(&ISEC2_ScanFlag, 1); // East -> West
+ if ( ISEC2_LastLat > ISEC2_FirstLat ) gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North
break;
}
case GRID_LCC:
{
- double originLon = 0.0, originLat = 0.0, lonParY = 0.0,
- lat1 = 0.0, lat2 = 0.0, xincm = 0.0, yincm = 0.0;
- int projflag = 0, scanflag = 0;
+ int xsize = (int)gridInqXsize(gridID);
+ int ysize = (int)gridInqYsize(gridID);
- int xsize = gridInqXsize(gridID),
- ysize = gridInqYsize(gridID);
+ double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
+ gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
+ gridVerifyGribParamLCC(grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
+ bool lsouth = (lat_1 < 0);
+ if ( lsouth ) { lat_1 = -lat_2; lat_2 = -lat_2; }
- gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
- &projflag, &scanflag);
+ double xinc = gridInqXinc(gridID);
+ double yinc = gridInqYinc(gridID);
ISEC2_GridType = GRIB1_GTYPE_LCC;
ISEC2_NumLon = xsize;
ISEC2_NumLat = ysize;
- ISEC2_FirstLon = (int)lround(originLon * 1000);
- ISEC2_FirstLat = (int)lround(originLat * 1000);
- ISEC2_Lambert_Lov = (int)lround(lonParY * 1000);
- ISEC2_Lambert_LatS1 = (int)lround(lat1 * 1000);
- ISEC2_Lambert_LatS2 = (int)lround(lat2 * 1000);
- ISEC2_Lambert_dx = (int)lround(xincm);
- ISEC2_Lambert_dy = (int)lround(yincm);
+ ISEC2_FirstLon = (int)lround(xval_0 * 1000);
+ ISEC2_FirstLat = (int)lround(yval_0 * 1000);
+ ISEC2_Lambert_Lov = (int)lround(lon_0 * 1000);
+ ISEC2_Lambert_LatS1 = (int)lround(lat_1 * 1000);
+ ISEC2_Lambert_LatS2 = (int)lround(lat_2 * 1000);
+ ISEC2_Lambert_dx = (int)lround(xinc);
+ ISEC2_Lambert_dy = (int)lround(yinc);
ISEC2_Lambert_LatSP = 0;
ISEC2_Lambert_LonSP = 0;
- ISEC2_Lambert_ProjFlag = projflag;
- ISEC2_ScanFlag = scanflag;
+ ISEC2_Lambert_ProjFlag = 0;
+ if ( lsouth ) gribbyte_set_bit(&ISEC2_Lambert_ProjFlag, 1);
+
+ bool earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
+ ISEC2_ResFlag = 0;
+ if ( ISEC2_Lambert_dx && ISEC2_Lambert_dy ) gribbyte_set_bit(&ISEC2_ResFlag, 1);
+ if ( earthIsOblate ) gribbyte_set_bit(&ISEC2_ResFlag, 2);
+ if ( gridInqUvRelativeToGrid(gridID) ) gribbyte_set_bit(&ISEC2_ResFlag, 5);
+
+ ISEC2_ScanFlag = 0;
+ gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North
break;
}
@@ -46922,10 +46956,12 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
case GRID_GME:
{
ISEC2_GridType = GRIB1_GTYPE_GME;
- ISEC2_GME_ND = gridInqGMEnd(gridID);
- ISEC2_GME_NI = gridInqGMEni(gridID);
- ISEC2_GME_NI2 = gridInqGMEni2(gridID);
- ISEC2_GME_NI3 = gridInqGMEni3(gridID);
+ int nd = 0, ni = 0, ni2 = 0, ni3 = 0;
+ gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
+ ISEC2_GME_ND = nd;
+ ISEC2_GME_NI = ni;
+ ISEC2_GME_NI2 = ni2;
+ ISEC2_GME_NI3 = ni3;
ISEC2_GME_AFlag = 0;
ISEC2_GME_LatPP = 90000;
ISEC2_GME_LonPP = 0;
@@ -46933,20 +46969,45 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
ISEC2_GME_BFlag = 0;
break;
}
+ case GRID_GENERIC:
+ {
+ ISEC1_Sec2Or3Flag = 0;
+ break;
+ }
default:
{
- Warning("The CGRIBEX library can not store fields on the used grid!");
- Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+ ISEC1_Sec2Or3Flag = 0;
+ Warning("CGRIBEX library doesn't support %s grids, grid information will be lost!", gridNamePtr(gridtype));
break;
}
}
+
+
+ if ( cdiGribChangeModeUvRelativeToGrid.active )
+ {
+ // this will overrule/change the UvRelativeToGrid flag;
+ // typically when the wind is rotated with respect to north pole
+ bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
+ if ( uvRelativeToGrid && !cdiGribChangeModeUvRelativeToGrid.mode )
+ gribbyte_clear_bit(&ISEC2_ResFlag, 5);
+ else if ( !uvRelativeToGrid && cdiGribChangeModeUvRelativeToGrid.mode )
+ gribbyte_set_bit(&ISEC2_ResFlag, 5);
+ }
+}
+
+static
+void isec1DefLevel(int *isec1, int leveltype, int level1, int level2)
+{
+ ISEC1_LevelType = leveltype;
+ ISEC1_Level1 = level1;
+ ISEC1_Level2 = level2;
}
static
void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int levelID)
{
+ char units[CDI_MAX_NAME];
static bool lwarning_vct = true;
- double level;
int zaxistype = zaxisInqType(zaxisID);
int ltype = zaxisInqLtype(zaxisID);
@@ -46954,8 +47015,7 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
{
Message("Changed zaxis type from %s to %s",
- zaxisNamePtr(zaxistype),
- zaxisNamePtr(ZAXIS_PRESSURE));
+ zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
zaxistype = ZAXIS_PRESSURE;
zaxisChangeType(zaxisID, zaxistype);
zaxisDefUnits(zaxisID, "Pa");
@@ -46973,9 +47033,7 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
case ZAXIS_DEPTH_BELOW_SEA:
case ZAXIS_ISENTROPIC:
{
- ISEC1_LevelType = grib_ltype;
- ISEC1_Level1 = (int) (zaxisInqLevel(zaxisID, levelID));
- ISEC1_Level2 = 0;
+ isec1DefLevel(isec1, grib_ltype, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
break;
}
case ZAXIS_CLOUD_BASE:
@@ -46985,26 +47043,17 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
case ZAXIS_SEA_BOTTOM:
case ZAXIS_ATMOSPHERE:
{
- ISEC1_LevelType = grib_ltype;
- ISEC1_Level1 = 0;
- ISEC1_Level2 = 0;
+ isec1DefLevel(isec1, grib_ltype, 0, 0);
break;
}
case ZAXIS_HYBRID:
case ZAXIS_HYBRID_HALF:
{
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- ISEC1_LevelType = GRIB1_LTYPE_HYBRID_LAYER;
- ISEC1_Level1 = (int) (zaxisInqLbound(zaxisID, levelID));
- ISEC1_Level2 = (int) (zaxisInqUbound(zaxisID, levelID));
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
+ (int)(zaxisInqUbound(zaxisID, levelID)));
else
- {
- ISEC1_LevelType = GRIB1_LTYPE_HYBRID;
- ISEC1_Level1 = (int) (zaxisInqLevel(zaxisID, levelID));
- ISEC1_Level2 = 0;
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_HYBRID, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
int vctsize = zaxisInqVctSize(zaxisID);
if ( vctsize > 255 )
@@ -47025,33 +47074,25 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
}
case ZAXIS_PRESSURE:
{
- level = zaxisInqLevel(zaxisID, levelID);
- if ( level < 0 )
- Warning("Pressure level of %f Pa is below zero!", level);
+ double level = zaxisInqLevel(zaxisID, levelID);
+ if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
- char units[128];
zaxisInqUnits(zaxisID, units);
if ( (units[0] != 'P') | (units[1] != 'a') ) level *= 100;
double dum;
if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
- {
- grib_ltype = GRIB1_LTYPE_99;
- }
+ grib_ltype = GRIB1_LTYPE_ISOBARIC_PA;
else
- {
- level = level/100;
- }
- ISEC1_LevelType = grib_ltype;
- ISEC1_Level1 = (int) level;
- ISEC1_Level2 = 0;
+ level = level/100;
+
+ isec1DefLevel(isec1, grib_ltype, (int) level, 0);
break;
}
case ZAXIS_HEIGHT:
{
- level = zaxisInqLevel(zaxisID, levelID);
+ double level = zaxisInqLevel(zaxisID, levelID);
- char units[128];
zaxisInqUnits(zaxisID, units);
if ( units[1] == 'm' && !units[2] )
{
@@ -47060,61 +47101,39 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
else if ( units[0] == 'k' ) level *= 1000;
}
- ISEC1_LevelType = grib_ltype;
- ISEC1_Level1 = (int) level;
- ISEC1_Level2 = 0;
-
+ isec1DefLevel(isec1, grib_ltype, (int) level, 0);
break;
}
case ZAXIS_SIGMA:
{
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- ISEC1_LevelType = GRIB1_LTYPE_SIGMA_LAYER;
- ISEC1_Level1 = (int) zaxisInqLbound(zaxisID, levelID);
- ISEC1_Level2 = (int) zaxisInqUbound(zaxisID, levelID);
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_SIGMA_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
+ (int)(zaxisInqUbound(zaxisID, levelID)));
else
- {
- ISEC1_LevelType = GRIB1_LTYPE_SIGMA;
- ISEC1_Level1 = (int) zaxisInqLevel(zaxisID, levelID);
- ISEC1_Level2 = 0;
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_SIGMA, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
break;
}
case ZAXIS_DEPTH_BELOW_LAND:
{
- char units[128];
zaxisInqUnits(zaxisID, units);
- double factor;
+ double factor = 100; // default: meter
if ( units[0] == 'm' && units[1] == 'm' ) factor = 0.1;
else if ( units[0] == 'c' && units[1] == 'm' ) factor = 1;
else if ( units[0] == 'd' && units[1] == 'm' ) factor = 10;
- else factor = 100; // meter
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH_LAYER;
- ISEC1_Level1 = (int) (factor*zaxisInqLbound(zaxisID, levelID));
- ISEC1_Level2 = (int) (factor*zaxisInqUbound(zaxisID, levelID));
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_LANDDEPTH_LAYER, (int) (factor*zaxisInqLbound(zaxisID, levelID)),
+ (int) (factor*zaxisInqUbound(zaxisID, levelID)));
else
- {
- ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH;
- ISEC1_Level1 = (int) (factor*zaxisInqLevel(zaxisID, levelID));
- ISEC1_Level2 = 0;
- }
+ isec1DefLevel(isec1, GRIB1_LTYPE_LANDDEPTH, (int) (factor*zaxisInqLevel(zaxisID, levelID)), 0);
break;
}
case ZAXIS_GENERIC:
{
- ISEC1_LevelType = ltype;
- ISEC1_Level1 = (int) zaxisInqLevel(zaxisID, levelID);
- ISEC1_Level2 = 0;
-
+ isec1DefLevel(isec1, ltype, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
break;
}
default:
@@ -47178,23 +47197,19 @@ void cgribexDefEnsembleVar(int *isec1, int vlistID, int varID)
#if defined (HAVE_LIBCGRIBEX)
size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const void *data, int nmiss, void *gribbuffer, size_t gribbuffersize)
+ size_t datasize, const void *data, size_t nmiss, void *gribbuffer, size_t gribbuffersize)
{
- size_t nbytes = 0;
- int gribsize;
int iret = 0, iword = 0;
int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
float fsec2f[512], fsec3f[2];
double fsec2[512], fsec3[2];
- int datatype;
- int param;
memset(isec1, 0, 256*sizeof(int));
fsec2[0] = 0; fsec2[1] = 0;
fsec2f[0] = 0; fsec2f[1] = 0;
- gribsize = (int)(gribbuffersize / sizeof(int));
- param = vlistInqVarParam(vlistID, varID);
+ int gribsize = (int)(gribbuffersize / sizeof(int));
+ int param = vlistInqVarParam(vlistID, varID);
cgribexDefaultSec0(isec0);
cgribexDefaultSec1(isec1);
@@ -47203,7 +47218,7 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
cgribexDefInstitut(isec1, vlistID, varID);
cgribexDefModel(isec1, vlistID, varID);
- datatype = vlistInqVarDatatype(vlistID, varID);
+ int datatype = vlistInqVarDatatype(vlistID, varID);
cgribexDefParam(isec1, param);
cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
@@ -47212,7 +47227,9 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
cgribexDefEnsembleVar(isec1, vlistID, varID);
- ISEC4_NumValues = gridInqSize(gridID);
+ cdi_check_gridsize_int_limit("GRIB1", datasize);
+
+ ISEC4_NumValues = (int) datasize;
ISEC4_NumBits = grbBitsPerValue(datatype);
if ( nmiss > 0 )
@@ -47248,27 +47265,69 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
if ( iret ) Error("Problem during GRIB encode (errno = %d)!", iret);
- nbytes = (size_t)iword * sizeof (int);
+ size_t nbytes = (size_t)iword * sizeof(int);
return nbytes;
}
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef STREAM_FCOMMON_H
-#define STREAM_FCOMMON_H
-#ifndef _CDI_INT_H
-#endif
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
- const char *container_name);
+typedef struct
+{
+ void *gribbuffer;
+ size_t gribbuffersize;
+ unsigned char *pds;
+ unsigned char *gds;
+ unsigned char *bms;
+ unsigned char *bds;
+} cgribex_handle;
+
+
+int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
+ unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
+
+void *cgribex_handle_new_from_meassage(void *gribbuffer, size_t gribbuffersize)
+{
+ cgribex_handle *gh = (cgribex_handle*) Malloc(sizeof(cgribex_handle));
+ gh->gribbuffer = NULL;
+ gh->gribbuffersize = 0;
+ gh->pds = NULL;
+
+ if ( gribbuffersize && gribbuffer )
+ {
+ unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ long gribrecsize;
+ int status = grib1Sections((unsigned char *)gribbuffer, (long)gribbuffersize, &pds, &gds, &bms, &bds, &gribrecsize);
+ if ( status >= 0 )
+ {
+ gh->gribbuffer = gribbuffer;
+ gh->gribbuffersize = gribbuffersize;
+ gh->pds = pds;
+ gh->gds = gds;
+ gh->bms = bms;
+ gh->bds = bds;
+ }
+ }
+
+ return (void*)gh;
+}
+
+
+void cgribex_handle_delete(void *gh)
+{
+ if ( gh ) Free(gh);
+}
+
+
+void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev)
+{
+ if ( !gh ) return;
+
+ unsigned char *pds = ((cgribex_handle*)gh)->pds;
+ if ( !pds ) return;
+
+ pds[8] = (unsigned char) code;
+ pds[9] = (unsigned char) ltype;
+ pds[10] = (unsigned char) lev;
+}
#endif
/*
@@ -47283,22 +47342,11 @@ void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
#if defined (HAVE_CONFIG_H)
#endif
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
-
-#define SINGLE_PRECISION 4
-#define DOUBLE_PRECISION 8
#if defined (HAVE_LIBEXTRA)
-
typedef struct {
int param;
int level;
@@ -47310,36 +47358,24 @@ int extInqDatatype(int prec, int number)
int datatype;
if ( number == 2 )
- {
- if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_CPX64;
- else datatype = DATATYPE_CPX32;
- }
+ datatype = (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_CPX64 : CDI_DATATYPE_CPX32;
else
- {
- if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
- else datatype = DATATYPE_FLT32;
- }
+ datatype = (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
- return (datatype);
+ return datatype;
}
static
void extDefDatatype(int datatype, int *prec, int *number)
{
- if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 &&
- datatype != DATATYPE_CPX32 && datatype != DATATYPE_CPX64 )
- datatype = DATATYPE_FLT32;
+ if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 &&
+ datatype != CDI_DATATYPE_CPX32 && datatype != CDI_DATATYPE_CPX64 )
+ datatype = CDI_DATATYPE_FLT32;
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
- *number = 2;
- else
- *number = 1;
+ *number = (datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64) ? 2 : 1;
- if ( datatype == DATATYPE_FLT64 || datatype == DATATYPE_CPX64 )
- *prec = DOUBLE_PRECISION;
- else
- *prec = SINGLE_PRECISION;
+ *prec = (datatype == CDI_DATATYPE_FLT64 || datatype == CDI_DATATYPE_CPX64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
}
/* not used
@@ -47360,7 +47396,7 @@ int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
*levelID = -1;
status = extRead(fileID, extp);
- if ( status != 0 ) return (0);
+ if ( status != 0 ) return 0;
extInqHeader(extp, header);
@@ -47369,55 +47405,46 @@ int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
*varID = vlistInqVarID(vlistID, icode);
- if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+ if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
zaxisID = vlistInqVarZaxis(vlistID, *varID);
*levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
- return (1);
+ return 1;
}
*/
-void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void extReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
- int vlistID, fileID;
- int status;
- int recID, vrecID, tsID;
- off_t recpos;
- int header[4];
- int varID, gridID;
- int i, size;
- double missval;
- void *extp = streamptr->record->exsep;
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- vrecID = streamptr->tsteps[tsID].curRecID;
- recID = streamptr->tsteps[tsID].recIDs[vrecID];
- recpos = streamptr->tsteps[tsID].records[recID].position;
- varID = streamptr->tsteps[tsID].records[recID].varID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int tsID = streamptr->curTsID;
+ int vrecID = streamptr->tsteps[tsID].curRecID;
+ int recID = streamptr->tsteps[tsID].recIDs[vrecID];
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ off_t recpos = streamptr->tsteps[tsID].records[recID].position;
fileSetPos(fileID, recpos, SEEK_SET);
- status = extRead(fileID, extp);
- if ( status != 0 )
- Error("Failed to read EXTRA record");
+ void *extp = streamptr->record->exsep;
+ int status = extRead(fileID, extp);
+ if ( status != 0 ) Error("Failed to read EXTRA record");
+ int header[4];
extInqHeader(extp, header);
extInqDataDP(extp, data);
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- size = gridInqSize(gridID);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
{
- for ( i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -47426,7 +47453,7 @@ void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
}
else
{
- for ( i = 0; i < 2*size; i+=2 )
+ for ( size_t i = 0; i < 2*size; i+=2 )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -47444,21 +47471,19 @@ void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
void extDefRecord(stream_t *streamptr)
{
- int gridID;
- int header[4];
int pdis, pcat, pnum;
- extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
- gridID = streamptr->record->gridID;
-
cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
+
+ int header[4];
header[0] = streamptr->record->date;
header[1] = pnum;
header[2] = streamptr->record->level;
- header[3] = gridInqSize(gridID);
+ int gridID = streamptr->record->gridID;
+ cdi_check_gridsize_int_limit("EXTRA", gridInqSize(gridID));
+ header[3] = (int) gridInqSize(gridID);
+ extrec_t *extp = (extrec_t*) streamptr->record->exsep;
extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
-
extDefHeader(extp, header);
}
@@ -47473,13 +47498,13 @@ void extWriteRecord(stream_t *streamptr, const double *data)
}
static
-void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
+void extAddRecord(stream_t *streamptr, int param, int level, size_t xysize,
size_t recsize, off_t position, int prec, int number)
{
int vlistID = streamptr->vlistID;
int tsID = streamptr->curTsID;
int recID = recordNewEntry(streamptr, tsID);
- record_t *record = &streamptr->tsteps[tsID].records[recID];
+ record_t *record = &streamptr->tsteps[tsID].records[recID];
record->size = recsize;
record->position = position;
@@ -47489,11 +47514,9 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
grid_init(grid);
cdiGridTypeInit(grid, GRID_GENERIC, xysize);
- grid->xsize = xysize;
- grid->ysize = 0;
- grid->xvals = NULL;
- grid->yvals = NULL;
- struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+ grid->x.size = xysize;
+ grid->y.size = 0;
+ struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
int gridID = gridAdded.Id;
if (!gridAdded.isNew) Free(grid);
/*
@@ -47513,46 +47536,36 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
streamptr->nrecs++;
if ( CDI_Debug )
- Message("varID = %d gridID = %d levelID = %d",
- varID, gridID, levelID);
+ Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
}
static
void extScanTimestep1(stream_t *streamptr)
{
int header[4];
- int status;
- int fileID;
- int rxysize = 0;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
DateTime datetime0 = { LONG_MIN, LONG_MIN };
- int tsID;
int varID;
+ off_t recpos = 0;
long recsize;
- off_t recpos;
- int nrecords, nrecs, recID;
- int taxisID = -1;
- taxis_t *taxis;
- int vlistID;
+ int recID;
extcompvar_t compVar, compVar0;
extrec_t *extp = (extrec_t*) streamptr->record->exsep;
streamptr->curTsID = 0;
- tsID = tstepsNewEntry(streamptr);
- taxis = &streamptr->tsteps[tsID].taxis;
+ int tsID = tstepsNewEntry(streamptr);
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
if ( tsID != 0 )
Error("Internal problem! tstepsNewEntry returns %d", tsID);
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
- nrecs = 0;
- while ( TRUE )
+ int nrecs = 0;
+ while ( true )
{
recpos = fileGetPos(fileID);
- status = extRead(fileID, extp);
+ int status = extRead(fileID, extp);
if ( status != 0 )
{
streamptr->ntsteps = 1;
@@ -47562,13 +47575,13 @@ void extScanTimestep1(stream_t *streamptr)
extInqHeader(extp, header);
- vdate = header[0];
- vtime = 0;
- rcode = header[1];
- rlevel = header[2];
- rxysize = header[3];
+ int vdate = header[0];
+ int vtime = 0;
+ int rcode = header[1];
+ int rlevel = header[2];
+ int rxysize = header[3];
- param = cdiEncodeParam(rcode, 255, 255);
+ int param = cdiEncodeParam(rcode, 255, 255);
if ( nrecs == 0 )
{
@@ -47604,17 +47617,17 @@ void extScanTimestep1(stream_t *streamptr)
cdi_generate_vars(streamptr);
- taxisID = taxisCreate(TAXIS_ABSOLUTE);
+ int taxisID = taxisCreate(TAXIS_ABSOLUTE);
taxis->type = TAXIS_ABSOLUTE;
taxis->vdate = (int)datetime0.date;
taxis->vtime = (int)datetime0.time;
- vlistID = streamptr->vlistID;
+ int vlistID = streamptr->vlistID;
vlistDefTaxis(vlistID, taxisID);
vlist_check_contents(vlistID);
- nrecords = streamptr->tsteps[0].nallrecs;
+ int nrecords = streamptr->tsteps[0].nallrecs;
if ( nrecords < streamptr->tsteps[0].recordSize )
{
streamptr->tsteps[0].recordSize = nrecords;
@@ -47633,7 +47646,7 @@ void extScanTimestep1(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -47643,9 +47656,7 @@ void extScanTimestep1(stream_t *streamptr)
{
streamptr->ntsteps = 0;
for ( varID = 0; varID < streamptr->nvars; varID++ )
- {
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
- }
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
}
}
@@ -47654,43 +47665,33 @@ static
int extScanTimestep2(stream_t *streamptr)
{
int header[4];
- int status;
- int fileID;
- // int rxysize = 0;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
- int tsID;
int varID;
off_t recpos = 0;
- int nrecords, nrecs, recID, rindex;
- int nextstep;
- taxis_t *taxis;
- int vlistID;
extcompvar_t compVar, compVar0;
void *extp = streamptr->record->exsep;
streamptr->curTsID = 1;
- fileID = streamptr->fileID;
- vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
- tsID = streamptr->rtsteps;
+ int tsID = streamptr->rtsteps;
if ( tsID != 1 )
Error("Internal problem! unexpected timestep %d", tsID+1);
- taxis = &streamptr->tsteps[tsID].taxis;
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
cdi_create_records(streamptr, tsID);
- nrecords = streamptr->tsteps[0].nallrecs;
+ int nrecords = streamptr->tsteps[0].nallrecs;
streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
streamptr->tsteps[1].nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
streamptr->tsteps[1].recIDs[recID] = -1;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
{
varID = streamptr->tsteps[0].records[recID].varID;
streamptr->tsteps[tsID].records[recID].position =
@@ -47699,10 +47700,10 @@ int extScanTimestep2(stream_t *streamptr)
streamptr->tsteps[0].records[recID].size;
}
- for ( rindex = 0; rindex <= nrecords; rindex++ )
+ for ( int rindex = 0; rindex <= nrecords; rindex++ )
{
recpos = fileGetPos(fileID);
- status = extRead(fileID, extp);
+ int status = extRead(fileID, extp);
if ( status != 0 )
{
streamptr->ntsteps = 2;
@@ -47712,13 +47713,13 @@ int extScanTimestep2(stream_t *streamptr)
extInqHeader(extp, header);
- vdate = header[0];
- vtime = 0;
- rcode = header[1];
- rlevel = header[2];
+ int vdate = header[0];
+ int vtime = 0;
+ int rcode = header[1];
+ int rlevel = header[2];
// rxysize = header[3];
- param = cdiEncodeParam(rcode, 255, 255);
+ int param = cdiEncodeParam(rcode, 255, 255);
if ( rindex == 0 )
{
@@ -47729,7 +47730,8 @@ int extScanTimestep2(stream_t *streamptr)
compVar.param = param;
compVar.level = rlevel;
- nextstep = FALSE;
+ bool nextstep = false;
+ int recID;
for ( recID = 0; recID < nrecords; recID++ )
{
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
@@ -47739,11 +47741,11 @@ int extScanTimestep2(stream_t *streamptr)
{
if ( streamptr->tsteps[tsID].records[recID].used )
{
- nextstep = TRUE;
+ nextstep = true;
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
break;
@@ -47752,7 +47754,7 @@ int extScanTimestep2(stream_t *streamptr)
if ( recID == nrecords )
{
Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
if ( nextstep ) break;
@@ -47771,19 +47773,19 @@ int extScanTimestep2(stream_t *streamptr)
tsID, recID,
streamptr->tsteps[tsID].records[recID].param, param,
streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
streamptr->tsteps[1].records[recID].position = recpos;
}
- nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ int nrecs = 0;
+ for ( int recID = 0; recID < nrecords; recID++ )
{
if ( ! streamptr->tsteps[tsID].records[recID].used )
{
varID = streamptr->tsteps[tsID].records[recID].varID;
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
else
{
@@ -47800,44 +47802,36 @@ int extScanTimestep2(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
- return (0);
+ return 0;
}
int extInqContents(stream_t *streamptr)
{
- int fileID;
- int status = 0;
-
- fileID = streamptr->fileID;
-
streamptr->curTsID = 0;
extScanTimestep1(streamptr);
+ int status = 0;
if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
+ int fileID = streamptr->fileID;
fileSetPos(fileID, 0, SEEK_SET);
- return (status);
+ return status;
}
static
long extScanTimestep(stream_t *streamptr)
{
int header[4];
- int status;
- int fileID;
- // int rxysize = 0;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
off_t recpos = 0;
int recID;
- int rindex, nrecs = 0;
+ int nrecs = 0;
extcompvar_t compVar, compVar0;
void *extp = streamptr->record->exsep;
/*
@@ -47864,14 +47858,14 @@ long extScanTimestep(stream_t *streamptr)
for ( recID = 0; recID < nrecs; recID++ )
streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
- for ( rindex = 0; rindex <= nrecs; rindex++ )
+ for ( int rindex = 0; rindex <= nrecs; rindex++ )
{
recpos = fileGetPos(fileID);
- status = extRead(fileID, extp);
+ int status = extRead(fileID, extp);
if ( status != 0 )
{
streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -47881,13 +47875,13 @@ long extScanTimestep(stream_t *streamptr)
extInqHeader(extp, header);
- vdate = header[0];
- vtime = 0;
- rcode = header[1];
- rlevel = header[2];
+ int vdate = header[0];
+ int vtime = 0;
+ int rcode = header[1];
+ int rlevel = header[2];
// rxysize = header[3];
- param = cdiEncodeParam(rcode, 255, 255);
+ int param = cdiEncodeParam(rcode, 255, 255);
// if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
if ( rindex == nrecs ) continue;
@@ -47929,7 +47923,7 @@ long extScanTimestep(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = 1;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -47943,131 +47937,54 @@ long extScanTimestep(stream_t *streamptr)
streamptr->ntsteps = tsID;
}
- return (streamptr->ntsteps);
+ return streamptr->ntsteps;
}
int extInqTimestep(stream_t *streamptr, int tsID)
{
- int nrecs;
- long ntsteps;
-
if ( tsID == 0 && streamptr->rtsteps == 0 )
Error("Call to cdiInqContents missing!");
if ( CDI_Debug )
Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
- ntsteps = UNDEFID;
- while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+ long ntsteps = CDI_UNDEFID;
+ while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
ntsteps = extScanTimestep(streamptr);
- if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
- {
- nrecs = 0;
- }
- else
+ int nrecs = 0;
+ if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
{
streamptr->curTsID = tsID;
nrecs = streamptr->tsteps[tsID].nrecs;
}
- return (nrecs);
+ return nrecs;
}
-void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
- int vlistID, fileID;
- int levID, nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int header[4];
- int tsid;
- int recID;
- int i;
- double missval;
- void *extp = streamptr->record->exsep;
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- /* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
- currentfilepos = fileGetPos(fileID);
-
- for (levID = 0; levID < nlevs; levID++)
- {
- /* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
- fileSetPos(fileID, recpos, SEEK_SET);
- extRead(fileID, extp);
- extInqHeader(extp, header);
- extInqDataDP(extp, &data[levID*gridsize]);
- }
- fileSetPos(fileID, currentfilepos, SEEK_SET);
-
- *nmiss = 0;
- if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
- {
- for ( i = 0; i < nlevs*gridsize; i++ )
- if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
- {
- data[i] = missval;
- (*nmiss)++;
- }
- }
- else
- {
- for ( i = 0; i < 2*nlevs*gridsize; i+=2 )
- if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
- {
- data[i] = missval;
- (*nmiss)++;
- }
- }
-}
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
-
-void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
-{
- int vlistID, fileID;
- int nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int header[4];
- int tsid;
- int recID;
- int i;
- double missval;
void *extp = streamptr->record->exsep;
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d",
- nlevs, gridID, gridsize);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ int tsid = streamptr->curTsID;
- currentfilepos = fileGetPos(fileID);
+ off_t currentfilepos = fileGetPos(fileID);
/* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
+ int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+ off_t recpos = streamptr->tsteps[tsid].records[recID].position;
fileSetPos(fileID, recpos, SEEK_SET);
extRead(fileID, extp);
+ int header[4];
extInqHeader(extp, header);
extInqDataDP(extp, data);
@@ -48076,7 +47993,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
*nmiss = 0;
if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
{
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -48085,7 +48002,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
else
{
- for ( i = 0; i < 2*gridsize; i+=2 )
+ for ( size_t i = 0; i < 2*gridsize; i+=2 )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -48095,126 +48012,61 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
- int fileID;
- int levID, nlevs, gridID, gridsize;
- int zaxisID;
- double level;
- int header[4];
- int tsID;
- int vlistID;
- int pdis, pcat, pnum;
- extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- nlevs = zaxisInqSize(zaxisID);
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
- cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
-
- header[0] = streamptr->tsteps[tsID].taxis.vdate;
- header[1] = pnum;
- header[3] = gridInqSize(gridID);
-
- extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
-
- for ( levID = 0; levID < nlevs; levID++ )
- {
- level = zaxisInqLevel(zaxisID, levID);
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
- header[2] = (int) level;
- extDefHeader(extp, header);
- extDefDataDP(extp, &data[levID*gridsize]);
- extWrite(fileID, extp);
- }
+ for ( size_t levID = 0; levID < nlevs; levID++)
+ extReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
}
void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
{
- int fileID;
- int gridID;
- int zaxisID;
- double level;
- int header[4];
- int tsID;
- int vlistID;
- int pdis, pcat, pnum;
- extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- level = zaxisInqLevel(zaxisID, levID);
-
- if ( CDI_Debug )
- Message("gridID = %d zaxisID = %d", gridID, zaxisID);
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int tsID = streamptr->curTsID;
+ int pdis, pcat, pnum;
cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+ int header[4];
header[0] = streamptr->tsteps[tsID].taxis.vdate;
header[1] = pnum;
- header[2] = (int) level;
- header[3] = gridInqSize(gridID);
+ header[2] = (int)(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID));
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ cdi_check_gridsize_int_limit("EXTRA", gridInqSize(gridID));
+ header[3] = (int) gridInqSize(gridID);
+ extrec_t *extp = (extrec_t*) streamptr->record->exsep;
extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
-
extDefHeader(extp, header);
+
extDefDataDP(extp, data);
extWrite(fileID, extp);
}
-#endif /* HAVE_LIBEXTRA */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <stdlib.h>
-
-
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name)
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
{
- int fileID1 = streamptr1->fileID;
- int fileID2 = streamptr2->fileID;
-
- int tsID = streamptr1->curTsID;
- int vrecID = streamptr1->tsteps[tsID].curRecID;
- int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
- off_t recpos = streamptr1->tsteps[tsID].records[recID].position;
- size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
-
- if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
- Error("Cannot seek input file for %s record copy!", container_name);
-
- char *buffer = (char *) Malloc(recsize);
-
- if (fileRead(fileID1, buffer, recsize) != recsize)
- Error("Failed to read record from %s file for copying!", container_name);
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
- if (fileWrite(fileID2, buffer, recsize) != recsize)
- Error("Failed to write record to %s file when copying!", container_name);
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
- Free(buffer);
+ for ( size_t levID = 0; levID < nlevs; levID++ )
+ extWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
}
+#endif /* HAVE_LIBEXTRA */
+
/*
* Local Variables:
* c-file-style: "Java"
@@ -48224,21 +48076,31 @@ void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *c
* require-trailing-newline: t
* End:
*/
-#ifndef _STREAM_GRIBAPI_H
-#define _STREAM_GRIBAPI_H
+#ifndef STREAM_GRIBAPI_H
+#define STREAM_GRIBAPI_H
+
+#ifdef HAVE_LIBGRIB_API
+
int gribapiScanTimestep1(stream_t * streamptr);
int gribapiScanTimestep2(stream_t * streamptr);
int gribapiScanTimestep(stream_t * streamptr);
-int gribapiDecode(void *gribbuffer, int gribsize, double *data, long datasize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID);
+int gribapiDecode(void *gribbuffer, size_t gribsize, double *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID);
size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const double *data, int nmiss, void **gribbuffer, size_t *gribbuffersize,
+ size_t datasize, const double *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize,
int ljpeg, void *gribContainer);
+int gribapiGetScanningMode(grib_handle *gh);
+void gribapiSetScanningMode(grib_handle *gh, int scanningMode);
+
+void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype, int lev);
+
+#endif
+
#endif /* _STREAM_GRIBAPI_H */
/*
* Local Variables:
@@ -48253,6 +48115,55 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
#endif
+int cdiDebugExt = 0; // Debug level for the KNMI extensions
+#ifdef HIRLAM_EXTENSIONS
+// *** RELATED to GRIB only ***
+int cdiGribUseTimeRangeIndicator = 0; // normaly cdo looks in grib for attribute called "stepType"
+ // but NWP models such as Harmonie 37h1.2, use "timeRangeIndicator"
+ // where: 0: for instanteneous fields; 4: for accumulated fields
+#endif // HIRLAM_EXTENSIONS
+
+
+// Regarding operation to change parameter identification:
+// change if cdiGribChangeParameterID.active
+struct cdiGribParamChange cdiGribChangeParameterID;
+
+// Used only for CDO module Selmulti
+void streamGrbChangeParameterIdentification(int code, int ltype, int lev)
+{
+ // NOTE this is a "PROXY" function for gribapiChangeParameterIdentification();
+ // This just sets the globals. There are probably better solutions to this.
+ // The parameter change is done by function gribapiChangeParameterIdentification() in stream_gribapi.c
+ // Setting this control variable to true will cause calling fnc. gribapiChangeParameterIdentification later.
+ // After grib attributes have been changed this variable goes to false.
+ cdiGribChangeParameterID.active = true;
+ cdiGribChangeParameterID.code = code;
+ cdiGribChangeParameterID.ltype = ltype;
+ cdiGribChangeParameterID.lev = lev;
+}
+
+struct cdiGribModeChange cdiGribChangeModeUvRelativeToGrid;
+
+// Used only for CDO module WindTrans
+void streamGrbChangeModeUvRelativeToGrid(int mode)
+{
+ cdiGribChangeModeUvRelativeToGrid.active = true;
+ cdiGribChangeModeUvRelativeToGrid.mode = (mode > 0);
+}
+
+struct cdiGribScanModeChange cdiGribDataScanningMode;
+
+void streamGrbDefDataScanningMode(int scanmode)
+{
+ cdiGribDataScanningMode.active = true;
+ cdiGribDataScanningMode.value = scanmode;
+}
+
+int streamGrbInqDataScanningMode(void)
+{
+ return cdiGribDataScanningMode.value;
+}
+
int grib1ltypeToZaxisType(int grib_ltype)
{
@@ -48269,6 +48180,7 @@ int grib1ltypeToZaxisType(int grib_ltype)
case GRIB1_LTYPE_ATMOSPHERE: zaxistype = ZAXIS_ATMOSPHERE; break;
case GRIB1_LTYPE_MEANSEA: zaxistype = ZAXIS_MEANSEA; break;
case GRIB1_LTYPE_99:
+ case GRIB1_LTYPE_ISOBARIC_PA:
case GRIB1_LTYPE_ISOBARIC: zaxistype = ZAXIS_PRESSURE; break;
case GRIB1_LTYPE_HEIGHT: zaxistype = ZAXIS_HEIGHT; break;
case GRIB1_LTYPE_ALTITUDE: zaxistype = ZAXIS_ALTITUDE; break;
@@ -48408,14 +48320,14 @@ int grbBitsPerValue(int datatype)
{
int bitsPerValue = 16;
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
Error("CDI/GRIB library does not support complex numbers!");
if ( datatype != CDI_UNDEFID )
{
if ( datatype > 0 && datatype <= 32 )
bitsPerValue = datatype;
- else if ( datatype == DATATYPE_FLT64 )
+ else if ( datatype == CDI_DATATYPE_FLT64 )
bitsPerValue = 24;
else
bitsPerValue = 16;
@@ -48449,7 +48361,7 @@ int grbScanTimestep1(stream_t * streamptr)
#if defined (HAVE_LIBCGRIBEX)
int filetype = streamptr->filetype;
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
status = cgribexScanTimestep1(streamptr);
#endif
#if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
@@ -48470,10 +48382,8 @@ int grbScanTimestep2(stream_t * streamptr)
#if defined (HAVE_LIBCGRIBEX)
int filetype = streamptr->filetype;
- if ( filetype == FILETYPE_GRB )
- {
- status = cgribexScanTimestep2(streamptr);
- }
+ if ( filetype == CDI_FILETYPE_GRB )
+ status = cgribexScanTimestep2(streamptr);
#endif
#if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
else
@@ -48489,15 +48399,12 @@ static
int grbScanTimestep(stream_t * streamptr)
{
int status = CDI_EUFTYPE;
- int filetype;
-
- filetype = streamptr->filetype;
#if defined (HAVE_LIBCGRIBEX)
- if ( filetype == FILETYPE_GRB )
- {
- status = cgribexScanTimestep(streamptr);
- }
+ int filetype = streamptr->filetype;
+
+ if ( filetype == CDI_FILETYPE_GRB )
+ status = cgribexScanTimestep(streamptr);
else
#endif
#ifdef HAVE_LIBGRIB_API
@@ -48513,17 +48420,12 @@ int grbScanTimestep(stream_t * streamptr)
#if defined (HAVE_LIBGRIB)
int grbInqContents(stream_t * streamptr)
{
- int fileID;
- int status = 0;
-
- fileID = streamptr->fileID;
-
streamptr->curTsID = 0;
- status = grbScanTimestep1(streamptr);
-
+ int status = grbScanTimestep1(streamptr);
if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
+ int fileID = streamptr->fileID;
fileSetPos(fileID, 0, SEEK_SET);
return status;
@@ -48532,15 +48434,13 @@ int grbInqContents(stream_t * streamptr)
int grbInqTimestep(stream_t * streamptr, int tsID)
{
- int ntsteps, nrecs;
-
if ( tsID == 0 && streamptr->rtsteps == 0 )
Error("Call to cdiInqContents missing!");
if ( CDI_Debug )
Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
- ntsteps = CDI_UNDEFID;
+ int ntsteps = CDI_UNDEFID;
while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
{
ntsteps = grbScanTimestep(streamptr);
@@ -48551,6 +48451,8 @@ int grbInqTimestep(stream_t * streamptr, int tsID)
}
}
+ int nrecs;
+
if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
{
nrecs = 0;
@@ -48571,7 +48473,7 @@ void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
int filetype = streamptr->filetype;
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
int tsID = streamptr->curTsID;
int vrecID = streamptr->tsteps[tsID].curRecID;
@@ -48705,14 +48607,11 @@ int vlistInsertTrivialTileSubtype(int vlistID);
#if defined (HAVE_CONFIG_H)
#endif
-#if defined (HAVE_LIBGRIB_API)
-#include <limits.h>
-#include <stdio.h>
-
+#ifdef HAVE_LIBGRIB_API
-# include <grib_api.h>
+#include <grib_api.h>
extern int cdiInventoryMode;
@@ -48724,6 +48623,14 @@ typedef struct {
int level2;
int ltype;
int tsteptype;
+#ifdef HIRLAM_EXTENSIONS
+ // NOTE: tsteptype MUST be part of attributes used to compare variables!
+ // Modern NWP models (HARMONIE, HIRLAM) use timeRangeIndicator to specify
+ // if the field is instantanous or accumulated.
+ // Both types are typically in the same GRIB-file.
+ // (181; 105, 0, timeRangeIndicator=0) .. instantanous rain
+ // (181; 105, 0, timeRangeIndicator=4) .. accumulated rain .. both can be in the same grib file
+#endif // HIRLAM_EXTENSIONS
char name[32];
var_tile_t tiles;
@@ -48887,7 +48794,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
}
{
- static int lprint = TRUE;
+ static bool lprint = true;
extern int grib_calendar;
int ryear, rmonth, rday, rhour, rminute, rsecond;
int julday, secofday;
@@ -48915,7 +48822,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
if ( lprint )
{
Warning("Time unit %d unsupported", timeUnits);
- lprint = FALSE;
+ lprint = false;
}
break;
}
@@ -48965,9 +48872,9 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
{
double dlevel;
GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0); //2 byte
- if ( *leveltype == 100 ) dlevel *= 100;
+ if ( *leveltype == GRIB1_LTYPE_ISOBARIC ) dlevel *= 100;
if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
- if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
+ if ( *leveltype == GRIB1_LTYPE_99 || *leveltype == GRIB1_LTYPE_ISOBARIC_PA ) *leveltype = GRIB1_LTYPE_ISOBARIC;
*level1 = (int) dlevel;
*level2 = 0;
@@ -49119,11 +49026,11 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
int vlistID = streamptr->vlistID;
int tsID = streamptr->curTsID;
int recID = recordNewEntry(streamptr, tsID);
- record_t *record = &streamptr->tsteps[tsID].records[recID];
+ record_t *record = &streamptr->tsteps[tsID].records[recID];
int tsteptype = gribapiGetTsteptype(gh);
// numavg = ISEC1_AvgNum;
- int numavg = 0;
+ int numavg = 0;
// fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
@@ -49148,12 +49055,54 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
// I. e. kick the fixed size array and allocate enough space, whatever that may be.
strncpy(record->varname, varname, sizeof(record->varname));
- grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
+ grid_t *grid = (grid_t *)Malloc(sizeof(*grid));
gribapiGetGrid(gh, grid);
- struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+ struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
int gridID = gridAdded.Id;
- if (!gridAdded.isNew) Free(grid);
+ if ( !gridAdded.isNew ) Free(grid);
+ else if ( grid->projtype == CDI_PROJ_RLL )
+ {
+ double xpole = 0, ypole = 0, angle = 0;
+ grib_get_double(gh, "latitudeOfSouthernPoleInDegrees", &ypole);
+ grib_get_double(gh, "longitudeOfSouthernPoleInDegrees", &xpole);
+ grib_get_double(gh, "angleOfRotation", &angle);
+ xpole -= 180;
+ if ( fabs(ypole) > 0 ) ypole = -ypole; // change from south to north pole
+ if ( fabs(angle) > 0 ) angle = -angle;
+
+ gridDefParamRLL(gridID, xpole, ypole, angle);
+ }
+ else if ( grid->projtype == CDI_PROJ_LCC )
+ {
+ double a = 6367470., rf = 0;
+ long earthIsOblate;
+ grib_get_long(gh, "earthIsOblate", &earthIsOblate);
+ if ( earthIsOblate ) { a = 6378160.; rf = 297.0; }
+ double lon_0, lat_1, lat_2, xval_0, yval_0;
+ long projflag = 0;
+ grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &xval_0);
+ grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &yval_0);
+ grib_get_double(gh, "LoVInDegrees", &lon_0);
+ grib_get_double(gh, "Latin1InDegrees", &lat_1);
+ grib_get_double(gh, "Latin2InDegrees", &lat_2);
+ grib_get_long(gh, "projectionCentreFlag", &projflag);
+ bool lsouth = gribbyte_get_bit((int)projflag, 1);
+ if ( lsouth ) { lat_1 = -lat_1; lat_2 = -lat_2; }
+
+ double lat_0 = lat_2;
+ double x_0 = grid_missval;
+ double y_0 = grid_missval;
+
+ if ( proj_lonlat_to_lcc_func )
+ {
+ x_0 = xval_0; y_0 = yval_0;
+ proj_lonlat_to_lcc_func(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, (size_t)1, &x_0, &y_0);
+ if ( IS_NOT_EQUAL(x_0, grid_missval) && IS_NOT_EQUAL(y_0, grid_missval) )
+ { x_0 = -x_0; y_0 = -y_0; }
+ }
+ gridDefParamLCC(gridID, grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0);
+ }
int zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
@@ -49181,10 +49130,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
unsigned char uuid[CDI_UUID_SIZE];
long lpar;
GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
- if ( lpar != 6 )
- {
- fprintf(stderr, "Warning ...\n");
- }
+ if ( lpar != 6 ) fprintf(stderr, "Warning ...\n");
GRIB_CHECK(grib_get_long(gh, "nlev", &lpar), 0);
int nhlev = (int)lpar;
GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &lpar), 0);
@@ -49197,8 +49143,8 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
}
}
- // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
- if ( datatype < 0 ) datatype = DATATYPE_PACK;
+ // if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
+ if ( datatype < 0 ) datatype = CDI_DATATYPE_PACK;
stdname[0] = 0;
longname[0] = 0;
@@ -49249,12 +49195,11 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
if ( grib_get_long(gh, "productDefinitionTemplateNumber", &productDefinitionTemplate) == 0 )
varDefProductDefinitionTemplate(varID, (int) productDefinitionTemplate);
- int i;
long lval;
double dval;
if (lread_additional_keys)
- for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
+ for ( int i = 0; i < cdiNAdditionalGRIBKeys; i++ )
{
/* note: if the key is not defined, we do not throw an error! */
if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
@@ -49266,10 +49211,9 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
if ( varInqInst(varID) == CDI_UNDEFID )
{
long center, subcenter;
- int instID;
GRIB_CHECK(grib_get_long(gh, "centre", ¢er), 0);
GRIB_CHECK(grib_get_long(gh, "subCentre", &subcenter), 0);
- instID = institutInq((int)center, (int)subcenter, NULL, NULL);
+ int instID = institutInq((int)center, (int)subcenter, NULL, NULL);
if ( instID == CDI_UNDEFID )
instID = institutDef((int)center, (int)subcenter, NULL, NULL);
varDefInst(varID, instID);
@@ -49277,12 +49221,11 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
if ( varInqModel(varID) == CDI_UNDEFID )
{
- int modelID;
long processID;
if ( grib_get_long(gh, "generatingProcessIdentifier", &processID) == 0 )
{
/* FIXME: assert(processID >= INT_MIN && processID <= INT_MAX) */
- modelID = modelInq(varInqInst(varID), (int)processID, NULL);
+ int modelID = modelInq(varInqInst(varID), (int)processID, NULL);
if ( modelID == CDI_UNDEFID )
modelID = modelDef(varInqInst(varID), (int)processID, NULL);
varDefModel(varID, modelID);
@@ -49292,16 +49235,12 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
if ( varInqTable(varID) == CDI_UNDEFID )
{
int pdis, pcat, pnum;
-
cdiDecodeParam(param, &pnum, &pcat, &pdis);
if ( pdis == 255 )
{
- int tableID;
int tabnum = pcat;
-
- tableID = tableInq(varInqModel(varID), tabnum, NULL);
-
+ int tableID = tableInq(varInqModel(varID), tabnum, NULL);
if ( tableID == CDI_UNDEFID )
tableID = tableDef(varInqModel(varID), tabnum, NULL);
varDefTable(varID, tableID);
@@ -49316,7 +49255,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
varID, param, zaxistype, gridID, levelID);
}
-static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype,
+static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype,
int tsteptype, char *name, var_tile_t tiles_data)
{
compvar2_t compVar;
@@ -49369,12 +49308,28 @@ void ensureBufferSize(size_t requiredSize, size_t *curSize, void **buffer)
}
static
-grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, void **gribbuffer, int *outDatatype, int *outCompressionType, long *outUnzipsize)
+grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, void **gribbuffer, int *outDatatype, int *outCompressionType, size_t *outUnzipsize)
{
- bool lieee = false;
+ int gribversion = (int)((char*)*gribbuffer)[7];
+
+ if ( gribversion <= 1 )
+ {
+ if ( gribGetZip(recsize, *gribbuffer, outUnzipsize) > 0 )
+ {
+ *outCompressionType = CDI_COMPRESS_SZIP;
+ ensureBufferSize(*outUnzipsize + 100, buffersize, gribbuffer);
+ }
+ else
+ {
+ *outCompressionType = CDI_COMPRESS_NONE;
+ }
+ }
grib_handle *gh = grib_handle_new_from_message(NULL, *gribbuffer, recsize);
- if(gribEditionNumber(gh) > 1)
+
+ bool lieee = false;
+
+ if ( gribversion > 1 )
{
size_t len = 256;
char typeOfPacking[256];
@@ -49382,40 +49337,29 @@ grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, vo
if ( grib_get_string(gh, "packingType", typeOfPacking, &len) == 0 )
{
// fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
- if ( strncmp(typeOfPacking, "grid_jpeg", len) == 0 ) *outCompressionType = COMPRESS_JPEG;
- else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = COMPRESS_SZIP;
+ if ( strncmp(typeOfPacking, "grid_jpeg", len) == 0 ) *outCompressionType = CDI_COMPRESS_JPEG;
+ else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = CDI_COMPRESS_SZIP;
else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = true;
}
}
- else
- {
- if( gribGetZip((long)recsize, *gribbuffer, outUnzipsize) > 0 )
- {
- *outCompressionType = COMPRESS_SZIP;
- ensureBufferSize((size_t)*outUnzipsize + 100, buffersize, gribbuffer);
- }
- else
- {
- *outCompressionType = COMPRESS_NONE;
- }
- }
if ( lieee )
{
- *outDatatype = DATATYPE_FLT64;
+ *outDatatype = CDI_DATATYPE_FLT64;
long precision;
int status = grib_get_long(gh, "precision", &precision);
- if ( status == 0 && precision == 1 ) *outDatatype = DATATYPE_FLT32;
+ if ( status == 0 && precision == 1 ) *outDatatype = CDI_DATATYPE_FLT32;
}
else
{
- *outDatatype = DATATYPE_PACK;
+ *outDatatype = CDI_DATATYPE_PACK;
long bitsPerValue;
if ( grib_get_long(gh, "bitsPerValue", &bitsPerValue) == 0 )
{
if ( bitsPerValue > 0 && bitsPerValue <= 32 ) *outDatatype = (int)bitsPerValue;
}
}
+
return gh;
}
@@ -49462,8 +49406,8 @@ int gribapiScanTimestep1(stream_t * streamptr)
size_t buffersize = 0;
DateTime datetime0 = { .date = 10101, .time = 0 };
int nrecs_scanned = 0; //Only used for debug output.
- int warn_time = TRUE;
- // int warn_numavg = TRUE;
+ bool warn_time = true;
+ // bool warn_numavg = true;
int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
grib_handle *gh = NULL;
@@ -49478,11 +49422,11 @@ int gribapiScanTimestep1(stream_t * streamptr)
int fileID = streamptr->fileID;
unsigned nrecs = 0;
- while ( TRUE )
+ while ( true )
{
int level1 = 0, level2 = 0;
- size_t recsize = (size_t)gribGetSize(fileID);
- recpos = fileGetPos(fileID);
+ size_t recsize = gribGetSize(fileID);
+ recpos = fileGetPos(fileID);
if ( recsize == 0 )
{
@@ -49496,7 +49440,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
if ( rstatus ) break;
int datatype, comptype = 0;
- long unzipsize;
+ size_t unzipsize;
gh = gribapiGetDiskRepresentation(recsize, &buffersize, &gribbuffer, &datatype, &comptype, &unzipsize);
nrecs_scanned++;
@@ -49548,7 +49492,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
else if ( result == CHECKTIME_INCONSISTENT && warn_time )
{
gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, param, level1, level2);
- warn_time = FALSE;
+ warn_time = false;
}
assert(result == CHECKTIME_OK || result == CHECKTIME_INCONSISTENT);
}
@@ -49559,7 +49503,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
{
Message("Change numavg from %d to %d not allowed!",
taxis->numavg, ISEC1_AvgNum);
- warn_numavg = FALSE;
+ warn_numavg = false;
}
else
{
@@ -49637,7 +49581,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -49647,9 +49591,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
{
streamptr->ntsteps = 0;
for ( int varID = 0; varID < streamptr->nvars; varID++ )
- {
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
- }
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
}
@@ -49664,7 +49606,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
DateTime datetime0 = { LONG_MIN, LONG_MIN };
// int gridID;
int recID;
- // int warn_numavg = TRUE;
+ // bool warn_numavg = true;
grib_handle *gh = NULL;
streamptr->curTsID = 1;
@@ -49700,12 +49642,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
int nrecs_scanned = nrecords; //Only used for debug output
int rindex = 0;
- while ( TRUE )
+ while ( true )
{
if ( rindex > nrecords ) break;
- size_t recsize = (size_t)gribGetSize(fileID);
- recpos = fileGetPos(fileID);
+ size_t recsize = gribGetSize(fileID);
+ recpos = fileGetPos(fileID);
if ( recsize == 0 )
{
streamptr->ntsteps = 2;
@@ -49717,9 +49659,9 @@ int gribapiScanTimestep2(stream_t * streamptr)
rstatus = gribRead(fileID, gribbuffer, &readsize);
if ( rstatus ) break;
- long unzipsize;
- if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
- ensureBufferSize((size_t)unzipsize + 100, &buffersize, &gribbuffer);
+ size_t unzipsize;
+ if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
+ ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
nrecs_scanned++;
gh = grib_handle_new_from_message(NULL, gribbuffer, recsize);
@@ -49765,7 +49707,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
if ( taxis->numavg && warn_numavg &&
(taxis->numavg != ISEC1_AvgNum) )
{
- warn_numavg = FALSE;
+ warn_numavg = false;
}
else
{
@@ -49801,7 +49743,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
}
}
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
if ( CDI_Debug )
@@ -49851,7 +49793,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
if ( ! streamptr->tsteps[tsID].records[recID].used )
{
int varID = streamptr->tsteps[tsID].records[recID].varID;
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
else
{
@@ -49868,7 +49810,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -49882,7 +49824,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
int gribapiScanTimestep(stream_t * streamptr)
{
int vrecID, recID;
- //int warn_numavg = TRUE;
+ //bool warn_numavg = true;
int nrecs = 0;
int vlistID = streamptr->vlistID;
@@ -49921,12 +49863,12 @@ int gribapiScanTimestep(stream_t * streamptr)
DateTime datetime0 = { LONG_MIN, LONG_MIN };
grib_handle *gh = NULL;
char varname[256];
- while ( TRUE )
+ while ( true )
{
if ( rindex > nrecs ) break;
- size_t recsize = (size_t)gribGetSize(fileID);
- recpos = fileGetPos(fileID);
+ size_t recsize = gribGetSize(fileID);
+ recpos = fileGetPos(fileID);
if ( recsize == 0 )
{
streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -49945,9 +49887,9 @@ int gribapiScanTimestep(stream_t * streamptr)
break;
}
- long unzipsize;
- if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
- ensureBufferSize((size_t)unzipsize + 100, &buffersize, &gribbuffer);
+ size_t unzipsize;
+ if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
+ ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
nrecs_scanned++;
gh = grib_handle_new_from_message(NULL, gribbuffer, recsize);
@@ -49993,7 +49935,7 @@ int gribapiScanTimestep(stream_t * streamptr)
if ( taxis->numavg && warn_numavg &&
(taxis->numavg != ISEC1_AvgNum) )
{
- warn_numavg = FALSE;
+ warn_numavg = false;
}
else
{
@@ -50039,7 +49981,7 @@ int gribapiScanTimestep(stream_t * streamptr)
}
}
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
if ( CDI_Debug )
@@ -50089,7 +50031,7 @@ int gribapiScanTimestep(stream_t * streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = 1;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -50113,8 +50055,8 @@ int gribapiScanTimestep(stream_t * streamptr)
#undef gribWarning
#endif
-int gribapiDecode(void *gribbuffer, int gribsize, double *data, long gridsize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID)
+int gribapiDecode(void *gribbuffer, size_t gribsize, double *data, size_t gridsize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID)
{
int status = 0;
long lpar;
@@ -50145,8 +50087,8 @@ int gribapiDecode(void *gribbuffer, int gribsize, double *data, long gridsize,
// printf("values_size = %d numberOfPoints = %ld\n", datasize, numberOfPoints);
- if ( gridsize != (long) datasize )
- Error("Internal problem: gridsize(%ld) != datasize(%zu)!", gridsize, datasize);
+ if ( gridsize != datasize )
+ Error("Internal problem: gridsize(%zu) != datasize(%zu)!", gridsize, datasize);
size_t dummy = datasize;
GRIB_CHECK(grib_get_double_array(gh, "values", data, &dummy), 0);
@@ -50352,10 +50294,12 @@ void gribapiDefStepUnits(int editionNumber, grib_handle *gh, int timeunit, int p
else if ( grib2ProDefTempHasStatisticalDef(proDefTempNum) )
{
GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitForTimeRange", unitsOfTime), 0);
- // GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
}
else
{
+ // NOTE KNMI: HIRLAM model files LAMH_D11 are in grib1 and do NOT have key indicatorOfUnitForTimeRange
+ // Watch out for compatibility issues.
GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
}
}
@@ -50368,25 +50312,10 @@ int gribapiDefSteptype(int editionNumber, grib_handle *gh, int productDefinition
size_t len = 64;
const char *stepType;
- static struct {
- long productionTemplate;
- const char sname[8];
- } ts_tab[] = {
- [TSTEP_INSTANT] = { 0, "instant" },
- [TSTEP_AVG] = { 8, "avg" },
- [TSTEP_ACCUM] = { 8, "accum" },
- [TSTEP_MAX] = { 8, "max" },
- [TSTEP_MIN] = { 8, "min" },
- [TSTEP_DIFF] = { 8, "diff" },
- [TSTEP_RMS] = { 8, "rms" },
- [TSTEP_SD] = { 8, "sd" },
- [TSTEP_COV] = { 8, "cov" },
- [TSTEP_RATIO] = { 8, "ratio" }
- };
if (tsteptype >= TSTEP_INSTANT && tsteptype <= TSTEP_RATIO)
{
- stepType = ts_tab[tsteptype].sname;
- proDefTempNum = ts_tab[tsteptype].productionTemplate;
+ stepType = cdiGribAPI_ts_str_map[tsteptype].sname;
+ proDefTempNum = cdiGribAPI_ts_str_map[tsteptype].productionTemplate;
}
else
{
@@ -50447,7 +50376,7 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
int factor = getTimeunitFactor(timeunit);
- if ( !(int) fmod(days*86400.0 + secs, factor) )
+ if ( !(int)(fmod(days*86400.0 + secs, factor)))
{
int proDefTempNum = gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
@@ -50526,18 +50455,18 @@ struct gribApiMsg {
};
static struct gribApiMsg
-getGribApiCompTypeMsg(grib_handle *gh, int comptype, int gridsize)
+getGribApiCompTypeMsg(int comptype, size_t gridsize)
{
const char *mesg;
size_t len;
- if ( comptype == COMPRESS_JPEG && gridsize > 1 )
+ if ( comptype == CDI_COMPRESS_JPEG && gridsize > 1 )
{
static const char mesg_grid_jpeg[] = "grid_jpeg";
len = sizeof (mesg_grid_jpeg) - 1;
mesg = mesg_grid_jpeg;
}
- else if ( comptype == COMPRESS_SZIP && gridsize > 1 )
+ else if ( comptype == CDI_COMPRESS_SZIP && gridsize > 1 )
{
static const char mesg_grid_ccsds[] = "grid_ccsds";
len = sizeof (mesg_grid_ccsds) - 1;
@@ -50555,12 +50484,14 @@ getGribApiCompTypeMsg(grib_handle *gh, int comptype, int gridsize)
static
-void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, bool lieee, int datatype, int nmiss, int gcinit)
+void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, bool lieee, int datatype, size_t nmiss, int gcinit)
{
UNUSED(nmiss);
+ bool lrotated = false;
+ bool lcurvi = false;
int gridtype = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
if ( editionNumber <= 1 )
if ( gridtype == GRID_GME || gridtype == GRID_UNSTRUCTURED )
@@ -50568,8 +50499,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
if ( gridtype == GRID_GENERIC )
{
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int xsize = (int) gridInqXsize(gridID);
+ int ysize = (int) gridInqYsize(gridID);
if ( (ysize == 32 || ysize == 48 || ysize == 64 ||
ysize == 96 || ysize == 160 || ysize == 192 ||
@@ -50593,13 +50524,36 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
}
else if ( gridtype == GRID_CURVILINEAR )
{
- static bool lwarn = true;
- if ( lwarn && gridsize > 1 )
- {
- lwarn = false;
- Warning("Curvilinear grids are unsupported in GRIB format! Created wrong Grid Description Section!");
- }
- gridtype = GRID_LONLAT;
+ int projID = gridInqProj(gridID);
+ if ( projID != CDI_UNDEFID && gridInqType(projID) == GRID_PROJECTION )
+ {
+ gridID = projID;
+ gridtype = GRID_PROJECTION;
+ }
+ else
+ {
+ static bool lwarning = true;
+ if ( lwarning && gridsize > 1 )
+ {
+ lwarning = false;
+ Warning("Curvilinear grid is unsupported in GRIB format! Created wrong Grid Description Section!");
+ }
+ lcurvi = true;
+ gridtype = GRID_LONLAT;
+ }
+ }
+
+ if ( gridtype == GRID_PROJECTION )
+ {
+ if ( gridInqProjType(gridID) == CDI_PROJ_RLL )
+ {
+ gridtype = GRID_LONLAT;
+ lrotated = true;
+ }
+ else if ( gridInqProjType(gridID) == CDI_PROJ_LCC )
+ {
+ gridtype = GRID_LCC;
+ }
}
if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
@@ -50608,8 +50562,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
if ( comptype )
{
- struct gribApiMsg gaMsg
- = getGribApiCompTypeMsg(gh, comptype, gridsize);
+ struct gribApiMsg gaMsg = getGribApiCompTypeMsg(comptype, gridsize);
size_t len = gaMsg.msgLen;
const char *mesg = gaMsg.msg;
GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
@@ -50627,45 +50580,40 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
{
double xfirst = 0, xlast = 0, xinc = 0;
double yfirst = 0, ylast = 0, yinc = 0;
- double latIncr;
- {
- const char *mesg;
- size_t len;
- if ( gridtype == GRID_GAUSSIAN )
- {
- static const char mesg_gaussian[] = "regular_gg";
- len = sizeof (mesg_gaussian) - 1;
- mesg = mesg_gaussian;
- }
- else if ( gridtype == GRID_GAUSSIAN_REDUCED )
- {
- static const char mesg_gaussian_reduced[] = "reduced_gg";
- len = sizeof (mesg_gaussian_reduced) - 1;
- mesg = mesg_gaussian_reduced;
- }
- else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
- {
- static const char mesg_rot_lonlat[] = "rotated_ll";
- len = sizeof (mesg_rot_lonlat) - 1;
- mesg = mesg_rot_lonlat;
- }
- else
- {
- static const char mesg_regular_ll[] = "regular_ll";
- len = sizeof (mesg_regular_ll) - 1;
- mesg = mesg_regular_ll;
- }
- GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
- }
+ const char *mesg;
+ size_t len;
+ if ( gridtype == GRID_GAUSSIAN )
+ {
+ static const char mesg_gaussian[] = "regular_gg";
+ len = sizeof(mesg_gaussian) - 1;
+ mesg = mesg_gaussian;
+ }
+ else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+ {
+ static const char mesg_gaussian_reduced[] = "reduced_gg";
+ len = sizeof(mesg_gaussian_reduced) - 1;
+ mesg = mesg_gaussian_reduced;
+ }
+ else if ( lrotated )
+ {
+ static const char mesg_rot_lonlat[] = "rotated_ll";
+ len = sizeof(mesg_rot_lonlat) - 1;
+ mesg = mesg_rot_lonlat;
+ }
+ else
+ {
+ static const char mesg_regular_ll[] = "regular_ll";
+ len = sizeof(mesg_regular_ll) - 1;
+ mesg = mesg_regular_ll;
+ }
+ GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
- long nlon = gridInqXsize(gridID);
- long nlat = gridInqYsize(gridID);
+ int nlon = (int) gridInqXsize(gridID);
+ int nlat = (int) gridInqYsize(gridID);
if ( gridtype == GRID_GAUSSIAN_REDUCED )
{
- //GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize), 0);
-
nlon = 0;
int *rowlon = (int *) Malloc((size_t)nlat*sizeof(int));
@@ -50673,38 +50621,32 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
gridInqRowlon(gridID, rowlon);
for ( int i = 0; i < nlat; ++i ) pl[i] = rowlon[i];
- GRIB_CHECK(grib_set_long_array(gh, "pl", pl, nlat), 0);
+ GRIB_CHECK(grib_set_long_array(gh, "pl", pl, (size_t)nlat), 0);
Free(pl);
Free(rowlon);
xfirst = 0;
- xlast = 360.-360./(nlat*2);
- xinc = 360./(nlat*2);
+ xinc = 360. * 0.5 / (double)nlat;
+ xlast = 360. - 360. * 0.5 / (double)nlat;
}
else
{
- if ( nlon == 0 )
- {
- nlon = 1;
- }
+ if ( nlon == 0 ) nlon = 1;
else
{
- xfirst = gridInqXval(gridID, 0);
- xlast = gridInqXval(gridID, nlon-1);
- xinc = gridInqXinc(gridID);
+ xfirst = gridInqXval(gridID, 0);
+ xlast = gridInqXval(gridID, (lcurvi ? nlon*nlat : nlon) - 1);
+ xinc = fabs(gridInqXinc(gridID));
}
}
- if ( nlat == 0 )
- {
- nlat = 1;
- }
+ if ( nlat == 0 ) nlat = 1;
else
{
- yfirst = gridInqYval(gridID, 0);
- ylast = gridInqYval(gridID, nlat-1);
- yinc = gridInqYinc(gridID);
+ yfirst = gridInqYval(gridID, 0);
+ ylast = gridInqYval(gridID, (lcurvi ? nlon*nlat : nlat) - 1);
+ yinc = fabs(gridInqYinc(gridID));
}
if ( gridtype != GRID_GAUSSIAN_REDUCED ) GRIB_CHECK(my_grib_set_long(gh, "Ni", nlon), 0);
@@ -50717,14 +50659,14 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees", ylast), 0);
{
- long jscan = 0;
- if ( yfirst < ylast ) jscan = 1;
+ long iscan = xfirst > xlast;
+ GRIB_CHECK(my_grib_set_long(gh, "iScansNegatively", iscan), 0);
+ }
+ {
+ long jscan = yfirst < ylast;
GRIB_CHECK(my_grib_set_long(gh, "jScansPositively", jscan), 0);
}
- /*
- if ( fabs(xinc*1000 - ISEC2_LonIncr) > FLT_EPSILON )
- ISEC2_LonIncr = 0;
- */
+
if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
{
int np = gridInqNP(gridID);
@@ -50733,140 +50675,124 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
}
else
{
- latIncr = yinc;
- if ( latIncr < 0 ) latIncr = -latIncr;
- GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", latIncr), 0);
- /*
- if ( fabs(yinc*1000 - ISEC2_LatIncr) > FLT_EPSILON )
- ISEC2_LatIncr = 0;
- */
+ GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", yinc), 0);
}
- /*
- if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
- if ( ISEC2_LonIncr != 0 && ISEC2_LatIncr == 0 ) ISEC2_LatIncr = ISEC2_LonIncr;
-
- if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
- if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
- if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
- ISEC2_ResFlag = 0;
- else
- ISEC2_ResFlag = 128;
- */
- if ( gridIsRotated(gridID) )
+ if ( lrotated )
{
- double xpole = gridInqXpole(gridID);
- double ypole = gridInqYpole(gridID);
- double angle = gridInqAngle(gridID);
- /* change from north to south pole */
- if ( fabs(ypole) > 0 ) ypole = -ypole;
- xpole = xpole + 180;
- if ( fabs(angle) > 0 ) angle = -angle;
- GRIB_CHECK(my_grib_set_double(gh, "latitudeOfSouthernPoleInDegrees", ypole), 0);
- GRIB_CHECK(my_grib_set_double(gh, "longitudeOfSouthernPoleInDegrees", xpole), 0);
- GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0);
- }
-
- /* East -> West */
- //if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
+ double xpole = 0, ypole = 0, angle = 0;
+ gridInqParamRLL(gridID, &xpole, &ypole, &angle);
- /* South -> North */
- //if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
+ xpole += 180;
+ if ( fabs(ypole) > 0 ) ypole = -ypole; // change from north to south pole
+ if ( fabs(angle) > 0 ) angle = -angle;
+ GRIB_CHECK(my_grib_set_double(gh, "latitudeOfSouthernPoleInDegrees", ypole), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "longitudeOfSouthernPoleInDegrees", xpole), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0);
+ }
if ( editionNumber != 2 ) { lieee = false; comptype = 0; }
- {
- const char *mesg;
- size_t len;
- if ( lieee )
- {
- static const char mesg_grid_ieee[] = "grid_ieee";
- len = sizeof (mesg_grid_ieee) - 1;
- mesg = mesg_grid_ieee;
- }
- else
- {
- struct gribApiMsg gaMsg
- = getGribApiCompTypeMsg(gh, comptype, gridsize);
- len = gaMsg.msgLen;
- mesg = gaMsg.msg;
- }
- GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
- if ( lieee )
- GRIB_CHECK(my_grib_set_long(gh, "precision",
- datatype == DATATYPE_FLT64 ? 2 : 1), 0);
+ if ( lieee )
+ {
+ static const char mesg_grid_ieee[] = "grid_ieee";
+ len = sizeof (mesg_grid_ieee) - 1;
+ mesg = mesg_grid_ieee;
+ }
+ else
+ {
+ struct gribApiMsg gaMsg = getGribApiCompTypeMsg(comptype, gridsize);
+ len = gaMsg.msgLen;
+ mesg = gaMsg.msg;
+ }
+ GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+ if ( lieee )
+ GRIB_CHECK(my_grib_set_long(gh, "precision", datatype == CDI_DATATYPE_FLT64 ? 2 : 1), 0);
- }
+ long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID);
+ if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
break;
}
case GRID_LCC:
{
- double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
- int projflag, scanflag;
+ int xsize = (int) gridInqXsize(gridID);
+ int ysize = (int) gridInqYsize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
+ gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
+ gridVerifyGribParamLCC(grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
+ if ( xval_0 < 0 ) xval_0 += 360;
+ bool lsouth = (lat_1 < 0);
+ if ( lsouth ) { lat_1 = -lat_2; lat_2 = -lat_2; }
+ int projflag = 0;
+ if ( lsouth ) gribbyte_set_bit(&projflag, 1);
- gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
- &projflag, &scanflag);
+ double xinc = gridInqXinc(gridID);
+ double yinc = gridInqYinc(gridID);
static const char mesg[] = "lambert";
- size_t len = sizeof (mesg) -1;
+ size_t len = sizeof(mesg) -1;
GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
GRIB_CHECK(my_grib_set_long(gh, "Nx", xsize), 0);
GRIB_CHECK(my_grib_set_long(gh, "Ny", ysize), 0);
-
- /* FIXME: lround should probably be round here */
- GRIB_CHECK(my_grib_set_double(gh, "DxInMetres", (double)lround(xincm)), 0);
- /* FIXME: lround should probably be round here */
- GRIB_CHECK(my_grib_set_double(gh, "DyInMetres", (double)lround(yincm)), 0);
- GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", originLon), 0);
- GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", originLat), 0);
- GRIB_CHECK(my_grib_set_double(gh, "LoVInDegrees", lonParY), 0);
- GRIB_CHECK(my_grib_set_double(gh, "Latin1InDegrees", lat1), 0);
- GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat2), 0);
-
+ GRIB_CHECK(my_grib_set_long(gh, "DxInMetres", lround(xinc)), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "DyInMetres", lround(yinc)), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", xval_0), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", yval_0), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "LoVInDegrees", lon_0), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "Latin1InDegrees", lat_1), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat_2), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "projectionCentreFlag", projflag), 0);
+
+ long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID);
+ if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
+ long earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
+ if ( earthIsOblate ) GRIB_CHECK(my_grib_set_long(gh, "earthIsOblate", earthIsOblate), 0);
+
+ int scanflag = 0;
+ gribbyte_set_bit(&scanflag, 2);
if ( editionNumber <= 1 )
- {
- GRIB_CHECK(my_grib_set_long(gh, "projectionCenterFlag", projflag), 0);
- GRIB_CHECK(my_grib_set_long(gh, "scanningMode", scanflag), 0);
- }
+ GRIB_CHECK(my_grib_set_long(gh, "scanningMode", (long)scanflag), 0);
break;
}
case GRID_SPECTRAL:
{
- static const char mesg[] = "sh";
- size_t len = sizeof (mesg) -1;
- GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-
- int trunc = gridInqTrunc(gridID);
- GRIB_CHECK(my_grib_set_long(gh, "J", trunc), 0);
- GRIB_CHECK(my_grib_set_long(gh, "K", trunc), 0);
- GRIB_CHECK(my_grib_set_long(gh, "M", trunc), 0);
-
- // GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridsize), 0);
+ {
+ static const char mesg[] = "sh";
+ size_t len = sizeof (mesg) -1;
+ GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+ }
+ {
+ int trunc = gridInqTrunc(gridID);
+ enum { numTruncAtt = 3 };
+ static const char truncAttNames[numTruncAtt][2] = { "J", "K", "M" };
+ for (size_t i = 0; i < numTruncAtt; ++i)
+ GRIB_CHECK(my_grib_set_long(gh, truncAttNames[i], trunc), 0);
+ }
+ // GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", (long)gridsize), 0);
/*
if ( lieee )
{
printf("spectral_ieee\n");
- if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize, 0);
+ if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", (long)gridsize, 0);
static const char mesg[] = "spectral_ieee";
size_t len = sizeof (mesg) -1;
GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
}
else */ if ( gridInqComplexPacking(gridID) )
{
- if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize), 0);
+ if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", (long)gridsize), 0);
static const char mesg[] = "spectral_complex";
size_t len = sizeof (mesg) -1;
GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-
- GRIB_CHECK(my_grib_set_long(gh, "JS", 20), 0);
- GRIB_CHECK(my_grib_set_long(gh, "KS", 20), 0);
- GRIB_CHECK(my_grib_set_long(gh, "MS", 20), 0);
+ enum { numTruncAtt = 3 };
+ static const char truncAttNames[numTruncAtt][3]
+ = { "JS", "KS", "MS" };
+ for (size_t i = 0; i < numTruncAtt; ++i)
+ GRIB_CHECK(my_grib_set_long(gh, truncAttNames[i], 20), 0);
}
else
{
@@ -50881,17 +50807,19 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
{
GRIB_CHECK(my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_GME), 0);
- GRIB_CHECK(my_grib_set_long(gh, "nd", gridInqGMEnd(gridID)), 0);
- GRIB_CHECK(my_grib_set_long(gh, "Ni", gridInqGMEni(gridID)), 0);
- GRIB_CHECK(my_grib_set_long(gh, "n2", gridInqGMEni2(gridID)), 0);
- GRIB_CHECK(my_grib_set_long(gh, "n3", gridInqGMEni3(gridID)), 0);
+ int nd = 0, ni = 0, ni2 = 0, ni3 = 0;
+ gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
+ GRIB_CHECK(my_grib_set_long(gh, "nd", nd), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "Ni", ni), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "n2", ni2), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "n3", ni3), 0);
GRIB_CHECK(my_grib_set_long(gh, "latitudeOfThePolePoint", 90000000), 0);
GRIB_CHECK(my_grib_set_long(gh, "longitudeOfThePolePoint", 0), 0);
- GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridsize), 0);
- GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", gridsize), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", (long)gridsize), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", (long)gridsize), 0);
- if ( comptype == COMPRESS_SZIP )
+ if ( comptype == CDI_COMPRESS_SZIP )
{
static const char mesg[] = "grid_ccsds";
size_t len = sizeof (mesg) -1;
@@ -50927,7 +50855,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
Warning("Can't write UUID!");
}
- if ( comptype == COMPRESS_SZIP )
+ if ( comptype == CDI_COMPRESS_SZIP )
{
static const char mesg[] = "grid_ccsds";
size_t len = sizeof (mesg) -1;
@@ -50948,16 +50876,14 @@ static
void getLevelFactor(double level, long *factor, long *out_scaled_value)
{
double scaled_value = level;
- /* FIXME: lround might be better here */
- long iscaled_value = (long) round(scaled_value);
+ long iscaled_value = lround(scaled_value);
long i;
const double eps = 1.e-8;
for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
{
scaled_value *= 10.;
- /* FIXME: lround might be better here */
- iscaled_value = (long)round(scaled_value);
+ iscaled_value = lround(scaled_value);
}
(*factor) = i;
@@ -50968,7 +50894,7 @@ static
void gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
{
bool lset = false;
- if ( (leveltype == 99 || leveltype == 100) && gribEditionNumber(gh) == 1 )
+ if ( (leveltype == GRIB1_LTYPE_ISOBARIC_PA || leveltype == 99 || leveltype == 100) && gribEditionNumber(gh) == 1 )
{
if ( gribGetLong(gh, "indicatorOfTypeOfLevel") != leveltype ) lset = true;
}
@@ -51013,34 +50939,17 @@ void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2
}
}
-
-/*
-void grib_verfiy_zaxis(int zaxisID, double sf)
-{
- printf("grb_verfiy_vlist called\n");
- int zaxisID = vlistZaxis(vlistID, index);
- int nlevels = zaxisInqSize(zaxisID);
- int zaxistype = zaxisInqType(zaxisID);
- double *levels = (double *) Malloc(nlevels*sizeof(double));
- int *ilevels = (int *) Malloc(nlevels*sizeof(int));
- zaxisInqLevels(zaxisID, levels);
- for ( int i = 0; i < nlevels; ++i )
- printf("level %d %g\n", i+1, levels[i]);
- Free(ilevels);
- Free(levels);
-}
-*/
-
static
-void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit, int proddef_template_num)
+void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelID, int gcinit, int proddef_template_num)
{
+ char units[CDI_MAX_NAME];
bool lbounds = false;
double dlevel1 = 0, dlevel2 = 0;
int zaxistype = zaxisInqType(zaxisID);
long ltype = zaxisInqLtype(zaxisID);
long ltype2 = zaxisInqLtype2(zaxisID);
- double level = zaxisInqLevel(zaxisID, levelID);
+ double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
@@ -51081,7 +50990,6 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
if ( zaxistype == ZAXIS_HEIGHT )
{
double sf = 1;
- char units[128];
zaxisInqUnits(zaxisID, units);
if ( units[1] == 'm' && !units[2] )
{
@@ -51129,13 +51037,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
case ZAXIS_ATMOSPHERE:
{
if ( editionNumber <= 1 )
- {
- grib1DefLevel(gh, gcinit, grib_ltype, lbounds, level, dlevel1, dlevel2);
- }
+ grib1DefLevel(gh, gcinit, grib_ltype, lbounds, level, dlevel1, dlevel2);
else
- {
- grib2DefLevel(gh, gcinit, grib_ltype, grib_ltype, lbounds, level, dlevel1, dlevel2);
- }
+ grib2DefLevel(gh, gcinit, grib_ltype, grib_ltype, lbounds, level, dlevel1, dlevel2);
break;
}
@@ -51168,7 +51072,6 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
{
if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
- char units[128];
zaxisInqUnits(zaxisID, units);
if ( memcmp(units, "Pa", 2) != 0 )
{
@@ -51181,7 +51084,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
{
double dum;
if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
- grib_ltype = GRIB1_LTYPE_99;
+ grib_ltype = GRIB1_LTYPE_ISOBARIC_PA;
else
level /= 100;
@@ -51208,7 +51111,6 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
}
case ZAXIS_DEPTH_BELOW_LAND:
{
- char units[128];
zaxisInqUnits(zaxisID, units);
double sf; //scalefactor
@@ -51286,11 +51188,430 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
}
}
+
+int gribapiGetScanningMode(grib_handle *gh)
+{
+ long iScansNegatively;
+ long jScansPositively;
+ long jPointsAreConsecutive;
+
+ GRIB_CHECK(grib_get_long(gh, "iScansNegatively", &iScansNegatively), 0);
+ GRIB_CHECK(grib_get_long(gh, "jScansPositively", &jScansPositively), 0);
+ GRIB_CHECK(grib_get_long(gh, "jPointsAreConsecutive", &jPointsAreConsecutive), 0);
+ int scanningMode
+ = 128*(bool)iScansNegatively
+ + 64 *(bool)jScansPositively
+ + 32 *(bool)jPointsAreConsecutive;
+ if (cdiDebugExt>=30)
+ printf("gribapiGetScanningMode(): Scanning mode = %02d (%1d%1d%1d)*32; \n",\
+ scanningMode,(int)jPointsAreConsecutive,(int)jScansPositively,(int)iScansNegatively);
+
+ return scanningMode;
+}
+
+
+void gribapiSetScanningMode(grib_handle *gh, int scanningMode)
+{
+ // 127: reserved for testing; generated test data will be in 64 scanning mode
+ //if (scanningMode== 127) scanningMode = 64;
+
+ long iScansNegatively = (scanningMode & 128)/128;
+ long jScansPositively = (scanningMode & 64)/64;
+ long jPointsAreConsecutive = (scanningMode & 32)/32;
+
+ if (cdiDebugExt>=30)
+ {
+ long paramId, levelTypeId, levelId, uvRelativeToGrid;
+ GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &uvRelativeToGrid), 0);
+ GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", ¶mId), 0);
+ GRIB_CHECK(grib_get_long(gh, "indicatorOfTypeOfLevel", &levelTypeId), 0);
+ GRIB_CHECK(grib_get_long(gh, "level", &levelId), 0);
+ printf("gribapiSetScanningMode(): (param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d (%1d%1d%1d)*32; uvRelativeToGrid = %02d\n",\
+ (int)paramId, (int)levelTypeId, (int)levelId,
+ scanningMode,(int)jPointsAreConsecutive,(int)jScansPositively,(int)iScansNegatively,
+ (int)uvRelativeToGrid);
+ }
+
+ GRIB_CHECK(my_grib_set_long(gh, "iScansNegatively", iScansNegatively), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "jScansPositively", jScansPositively), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "jPointsAreConsecutive", jPointsAreConsecutive), 0);
+}
+
+
+static void gribapiSetUvRelativeToGrid(grib_handle *gh, int mode)
+{
+ long uvRelativeToGridMode = mode;
+ long uvRelativeToGridModeOld;
+
+ GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &uvRelativeToGridModeOld), 0);
+
+ if (cdiDebugExt>=30)
+ printf("gribapiSetUvRelativeToGrid(): uvRelativeToGrid: %02d (old) => %02d (new); \n",(int)uvRelativeToGridModeOld,(int)uvRelativeToGridMode);
+
+ GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGridMode), 0);
+}
+
+
+ /*
+ TABLE 8. SCANNING MODE FLAG
+
+ (GDS Octet 28)
+ BIT VALUE MEANING
+ 1 0 Points scan in +i direction
+ 1 Points scan in -i direction
+ 2 0 Points scan in -j direction
+ 1 Points scan in +j direction
+ 3 0 Adjacent points in i direction are consecutive
+ (FORTRAN: (I,J))
+ 1 Adjacent points in j direction are consecutive
+ (FORTRAN: (J,I))
+
+ => Scanning Mode 0 0 0 0 0 0 0 0 (00 dec) +i, -j; i direction consecutive (row-major order West->East & North->South)
+ => Scanning Mode 0 1 0 0 0 0 0 0 (64 dec) +i, +j; i direction consecutive (row-major order West->East & South->North )
+ => Scanning Mode 1 1 0 0 0 0 0 0 (96 dec) +i, +j; j direction consecutive (column-major order South->North & West->East )
+
+ NOTE: South->North - As if you would plot the data as image on the screen
+ where [0,0] of the data is the top-left pixel.
+
+ grib2ppm LAMH_D11_201302150000_00000_oro | display ppm:-
+ ImageMagick (display): [0,0] of an image belongs to the top-left pixel
+ [DEFAULT] : 64 dec
+
+ iScansNegatively = 0;
+ jScansPositively = 1;
+ jPointsAreConsecutive = 0; => Scanning Mode 64
+
+ cdo selindexbox,1,726,100,550 LAMH_D11_201302150000_00000_oro LAMH_D11_201302150000_00000_oro_cropped
+ grib2ppm LAMH_D11_201302150000_00000_oro_cropped | /usr/bin/display ppm:- &
+ # ^^^ this image will be missing the souther parts of data
+
+ grib2ppm LAMH_D11_201302150000_00000_oro | /usr/bin/display ppm:- &
+ # ^ full domain data
+ */
+
+#ifdef HIRLAM_EXTENSIONS
+static void
+verticallyFlipGridDefinitionWhenScanningModeChanged(grib_handle *gh, double yfirst, double ylast, double yinc )
+{
+ /*
+ Nj = 550;
+ latitudeOfFirstGridPointInDegrees = -30.8;
+ latitudeOfLastGridPointInDegrees = 24.1;
+ iScansNegatively = 0;
+ jScansPositively = 0;
+ jPointsAreConsecutive = 0;
+ jDirectionIncrementInDegrees = 0.1;
+
+ When switching from scanning mode 0 <=> 64
+ yfirst = -30.8 + (550-1)*0.1
+
+ yfirst = yfirst + (ysize-1) * yinc
+ yinc = -1.0*yinc
+
+ */
+
+
+ //long jDim=0;
+ //GRIB_CHECK(grib_get_long(gh, "Nj", &jDim), 0);
+
+ double latitudeOfFirstGridPointInDegrees;
+ double latitudeOfLastGridPointInDegrees;
+ double jDirectionIncrementInDegrees;
+
+ //GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &latitudeOfFirstGridPointInDegrees), 0); // yfirst
+ //GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees", &latitudeOfLastGridPointInDegrees), 0); // ylast
+ //GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &jDirectionIncrementInDegrees), 0); // yinc
+
+ if (cdiDebugExt>=10)
+ {
+ Message(" BEFORE: yfirst = %f; ylast = %f; yinc = %f; ", yfirst,ylast, yinc);
+ }
+
+ GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", ylast), 0);
+ GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees", yfirst), 0);
+ //yinc *= -1.0; // don't set yinc here ...
+ //GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", yinc), 0);
+
+ if (cdiDebugExt>=10)
+ {
+ GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &latitudeOfFirstGridPointInDegrees), 0); // yfirst
+ GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees", &latitudeOfLastGridPointInDegrees), 0); // ylast
+ GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &jDirectionIncrementInDegrees), 0); // yinc
+ Message("CHANGED INTO: yfirst = %f, ylast = %f, yinc = %f",latitudeOfFirstGridPointInDegrees,latitudeOfLastGridPointInDegrees, jDirectionIncrementInDegrees);
+ }
+}
+
+static void
+convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
+ size_t gridsize, size_t iDim, size_t jDim)
+{
+ size_t i,j;
+ size_t idxIN, idxOUT;
+
+ // 127: reserved for testing; it will generate test data in 64 scanning mode
+ if (scanModeOUT== 127) // fill with testdata ...
+ {
+ scanModeOUT = 64;
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): Generating test data in 64 scanning mode..\n");
+ for (j=0; j<jDim; j++)
+ {
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ {
+ idxIN = i + jXiDim;
+ data[idxIN] = (double) (100.0*j +i);
+ }
+ }
+ }
+
+ if ( (iDim*jDim)!= gridsize)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): ERROR: (iDim*jDim)!= gridsize; (%zu * %zu) != %zu\n", iDim,jDim, gridsize);
+ return;
+ }
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): scanModeIN=%02d => scanModeOUT=%02d ; where: (iDim * jDim == gridsize) (%zu*%zu == %zu)\n",scanModeIN, scanModeOUT, iDim,jDim, gridsize);
+
+ if (cdiDebugExt>=100)
+ {
+ printf("convertDataScanningMode(): data IN:\n");
+ for (j=0; j<jDim; j++)
+ {
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ {
+ idxIN = i + jXiDim;
+ printf("%03.0f, ",data[idxIN]);
+ }
+ printf("\n");
+ }
+ }
+
+ if (scanModeIN==scanModeOUT)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): INFO: Nothing to do; scanModeIN==scanModeOUT..\n");
+ return;
+ }
+
+ if (0)
+ {
+ return;
+ if (scanModeOUT==00)
+ {
+ if (cdiDebugExt>0) printf("convertDataScanningMode(): Leave data unchaged BUT set scanModeOUT=00.\n");
+ // CHECK: Looks like that GRIB-API provide (no matter what) data in the scannning mode 00, even it is store in the gribfile as 64 !!
+ return;
+ }
+ }
+ double *dataCopy = (double *) malloc(gridsize*sizeof(double));
+ memcpy((void*)dataCopy,(void*) data, gridsize*sizeof(double));
+
+ if (scanModeIN==64) // Scanning Mode (00 dec) +i, -j; i direction consecutive (row-major order West->East & South->North )
+ { // Scanning Mode (64 dec) +i, +j; i direction consecutive (row-major order West->East & North->South )
+ // Scanning Mode (96 dec) +i, +j; j direction consecutive (column-major order North->South & West->East )
+ if (scanModeOUT==00)
+ // CHECK: Looks like that GRIB-API provide (no matter what) data in the scannning mode 00, even it is store in the gribfile as 64 !!
+#define VERTICAL_FLIP
+#ifdef VERTICAL_FLIP
+ { // flip the data vertically ..
+ idxIN= 0; idxOUT= (jDim-1)*iDim;
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): copying rows nr. (%04d : %04d)\n",0,jDim-1);
+ for (j=0; j<jDim; j++)
+ {
+ memcpy((void*)&data[idxOUT], (void*)&dataCopy[idxIN], iDim*sizeof(double));
+ idxIN += iDim; idxOUT -= iDim;
+ }
+ } // end if (scanModeOUT==00)*/
+#endif
+#ifdef HORIZONTAL_FLIP
+ { // flip data horizontally ...
+ if (1)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): copying columns nr. (%04d : %04d);\n", 0, iDim-1);
+ for (i=0; i<iDim; i++)
+ {
+ for (j=0; j<jDim; j++)
+ {
+ size_t jXiDim = j*iDim;
+ idxIN = i + jXiDim;
+ //data[idxIN] = (double) (100.0*j +i); // just some testdata ..
+ idxOUT = iDim - i -1 + jXiDim;
+ //printf("[%03d=>%03d] = %f;",idxIN,idxOUT,dataCopy[idxIN]);
+ data[idxOUT] = dataCopy[idxIN];
+ }
+ }
+ }
+ } // end if (scanModeOUT==00)
+#endif
+
+ if (scanModeOUT==96)
+ { // transpose the data
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): transpose data rows=>columns nr. (%04d : %04zu) => (%04d : %04zu);\n", 0, iDim-1, 0, jDim-1);
+ for (j=0; j<jDim; j++)
+ {
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ {
+ idxIN = i + jXiDim;
+ idxOUT = j + i*jDim;
+ //printf("[%03d=>%03d] = %f;",idxIN,idxOUT,dataCopy[idxIN]);
+ data[idxOUT] = dataCopy[idxIN];
+ }
+ //printf(".\n");
+ }
+ } // end if (scanModeOUT==96)
+ } // end if (scanModeIN==64)
+
+ if (scanModeIN==00) // Scanning Mode (00 dec) +i, -j; i direction consecutive (row-major order West->East & South->North )
+ { // Scanning Mode (64 dec) +i, +j; i direction consecutive (row-major order West->East & North->South )
+ // Scanning Mode (96 dec) +i, +j; j direction consecutive (column-major order North->South & West->East )
+ if (scanModeOUT==64)
+ { // flip the data vertically ..
+ idxIN= 0; idxOUT= (jDim-1)*iDim;
+ for (j=0; j<jDim; j++)
+ {
+ if (cdiDebugExt>=25) printf("convertDataScanningMode(): copying row nr. %04zu; [idxIN=%08zu] => [idxOUT=%08zu]\n",j, idxIN, idxOUT);
+ memcpy((void*)&data[idxOUT], (void*)&dataCopy[idxIN], iDim*sizeof(double));
+ idxIN += iDim; idxOUT -= iDim;
+ }
+ } // end if (scanModeOUT==64)
+
+ if (scanModeOUT==96)
+ { // transpose the data
+ size_t jInv;
+ for (j=0; j<jDim; j++)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
+ jInv = (jDim-1) -j;
+ for (i=0; i<iDim; i++)
+ data[j + i*jDim] = dataCopy[i + jInv*iDim]; // source data has -j
+ }
+ } // end if (scanModeOUT==96)
+ } // end if (scanModeIN==00)
+
+ if (scanModeIN==96) // Scanning Mode (00 dec) +i, -j; i direction consecutive (row-major order West->East & South->North )
+ { // Scanning Mode (64 dec) +i, +j; i direction consecutive (row-major order West->East & North->South )
+ // Scanning Mode (96 dec) +i, +j; j direction consecutive (column-major order North->South & West->East )
+ if (scanModeOUT==64)
+ { // transpose the data
+ for (j=0; j<jDim; j++)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ //data[j + i*jDim] = dataCopy[i + j*iDim];
+ data[i + jXiDim] = dataCopy[j + i*jDim];
+ }
+ } // end if (scanModeOUT==64)
+
+ if (scanModeOUT==00)
+ { // transpose the data
+ idxIN= 0; idxOUT= 0;
+ size_t jInv;
+ for (j=0; j<jDim; j++)
+ {
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
+ jInv = (jDim-1) -j;
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ //data[jInv + iXjDim] = dataCopy[i + jXiDim]; // target data has -j
+ data[i + jXiDim] = dataCopy[jInv + i*jDim]; // target data has -j
+ }
+ } // end if (scanModeOUT==00)
+ } // end if (scanModeIN==96)
+
+ if (cdiDebugExt>=100)
+ {
+ printf("convertDataScanningMode(): data OUT (new scanning mode):\n");
+ for (j=0; j<jDim; j++)
+ {
+ size_t jXiDim = j*iDim;
+ for (i=0; i<iDim; i++)
+ {
+ idxIN = i + jXiDim;
+ printf("%03.0f, ",data[idxIN]);
+ }
+ printf("\n");
+ }
+ }
+
+ free(dataCopy); return;
+}
+#endif //HIRLAM_EXTENSIONS
+
+static
+void gribapiSetExtMode(grib_handle *gh, int gridID, size_t datasize, const double *data)
+{
+ /*
+ Nj = 550;
+ latitudeOfFirstGridPointInDegrees = -30.8;
+ latitudeOfLastGridPointInDegrees = 24.1;
+ iScansNegatively = 0;
+ jScansPositively = 0;
+ jPointsAreConsecutive = 0;
+ jDirectionIncrementInDegrees = 0.1; */
+#ifndef HIRLAM_EXTENSIONS
+ (void)data;
+ (void)datasize;
+#endif
+ int gridtype = gridInqType(gridID);
+ if ( gridtype == GRID_GENERIC || gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN ||
+ gridtype == GRID_GAUSSIAN_REDUCED || gridtype == GRID_PROJECTION )
+ {
+#ifdef HIRLAM_EXTENSIONS
+ int scanModeIN = gridInqScanningMode(gridID);
+
+ if (cdiDebugExt>=100)
+ {
+ size_t gridsize = gridInqSize(gridID);
+ Message("(scanModeIN=%d; gridsize=%zu", scanModeIN, gridsize);
+ }
+
+ if ( cdiGribDataScanningMode.active ) // allowed modes: <0, 64, 96>; Default is 64
+ {
+ size_t iDim = gridInqXsize(gridID);
+ size_t jDim = gridInqYsize(gridID);
+
+ double yfirst = gridInqYval(gridID, 0);
+ double ylast = gridInqYval(gridID, jDim-1);
+ double yinc = gridInqYinc(gridID);
+
+ int scanModeOUT = cdiGribDataScanningMode.value;
+ convertDataScanningMode(scanModeIN, scanModeOUT, (double*)data, datasize, iDim, jDim);
+ // This will overrule the old scanning mode of the given grid
+ if (cdiDebugExt>=10) Message("Set GribDataScanningMode (%d) => (%d)", scanModeIN, cdiGribDataScanningMode.value);
+ gribapiSetScanningMode(gh, cdiGribDataScanningMode.value);
+
+ if (((scanModeIN==00) && (cdiGribDataScanningMode.value==64)) ||
+ ((scanModeIN==64) && (cdiGribDataScanningMode.value==00)) )
+ verticallyFlipGridDefinitionWhenScanningModeChanged(gh, yfirst, ylast, yinc);
+ }
+ else
+ {
+ if (cdiDebugExt>=100) Message("Set GribDataScanningMode => (%d) based on used grid", scanModeIN);
+ gribapiSetScanningMode(gh, scanModeIN);
+ }
+#endif
+
+ if ( cdiGribChangeModeUvRelativeToGrid.active )
+ {
+ // this will overrule/change the UvRelativeToGrid flag;
+ // typically when the wind is rotated with respect to north pole
+ if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d ( note grid has: %d)", cdiGribChangeModeUvRelativeToGrid.mode, gridInqUvRelativeToGrid(gridID));
+ GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", (long) cdiGribChangeModeUvRelativeToGrid.mode), 0);
+ }
+ else
+ {
+ if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d based on used grid", gridInqUvRelativeToGrid(gridID));
+ gribapiSetUvRelativeToGrid(gh, gridInqUvRelativeToGrid(gridID));
+ }
+ }
+}
+
/* #define GRIBAPIENCODETEST 1 */
size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const double *data, int nmiss, void **gribbuffer, size_t *gribbuffersize,
+ size_t datasize, const double *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize,
int comptype, void *gribContainer)
{
size_t recsize = 0;
@@ -51303,8 +51624,9 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
long editionNumber = 2;
char name[256];
char stdname[256];
- gribContainer_t *gc = (gribContainer_t *) gribContainer;
+
// extern unsigned char _grib_template_GRIB2[];
+ cdi_check_gridsize_int_limit("GRIB", datasize);
int param = vlistInqVarParam(vlistID, varID);
int datatype = vlistInqVarDatatype(vlistID, varID);
@@ -51317,8 +51639,11 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
#if defined(GRIBAPIENCODETEST)
grib_handle *gh = (grib_handle *) gribHandleNew(editionNumber);
#else
+ gribContainer_t *gc = (gribContainer_t *) gribContainer;
+ assert(gc != NULL);
grib_handle *gh = (struct grib_handle *)gc->gribHandle;
#endif
+
GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
if ( editionNumber == 2 )
@@ -51336,14 +51661,15 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
}
*/
- gribapiDefTime((int)editionNumber, productDefinitionTemplate, typeOfGeneratingProcess, gh, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID), gc->init);
+ gribapiDefTime((int)editionNumber, productDefinitionTemplate, typeOfGeneratingProcess,
+ gh, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID), gc->init);
if ( ! gc->init ) gribapiDefInstitut(gh, vlistID, varID);
if ( ! gc->init ) gribapiDefModel(gh, vlistID, varID);
if ( ! gc->init ) gribapiDefParam((int)editionNumber, gh, param, name, stdname);
- if ( editionNumber == 2 && (datatype == DATATYPE_FLT32 || datatype == DATATYPE_FLT64) ) lieee = true;
+ if ( editionNumber == 2 && (datatype == CDI_DATATYPE_FLT32 || datatype == CDI_DATATYPE_FLT64) ) lieee = true;
/* bitsPerValue have to be defined before call to DefGrid (complex packing) */
// if ( lieee == false )
@@ -51354,7 +51680,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
gribapiDefGrid((int)editionNumber, gh, gridID, comptype, lieee, datatype, nmiss, gc->init);
- gribapiDefLevel((int)editionNumber, gh, param, zaxisID, levelID, gc->init, productDefinitionTemplate);
+ gribapiDefLevel((int)editionNumber, gh, zaxisID, levelID, gc->init, productDefinitionTemplate);
vlist_t *vlistptr = vlist_to_pointer(vlistID);
//if (!gc->init)
@@ -51370,7 +51696,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
{
//DR: Fix for multi-level fields (otherwise only the 1st level is correct)
if ( zaxisInqSize(zaxisID)==(levelID+1) )
- vlistptr->vars[varID].opt_grib_kvpair[i].update = FALSE;
+ vlistptr->vars[varID].opt_grib_kvpair[i].update = false;
if (vlistptr->vars[varID].opt_grib_kvpair[i].data_type == t_double)
{
@@ -51402,7 +51728,9 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
GRIB_CHECK(my_grib_set_double(gh, "missingValue", vlistInqVarMissval(vlistID, varID)), 0);
}
- GRIB_CHECK(grib_set_double_array(gh, "values", data, (size_t)datasize), 0);
+ gribapiSetExtMode(gh, gridID, datasize, data);
+
+ GRIB_CHECK(grib_set_double_array(gh, "values", data, datasize), 0);
/* get the size of coded message */
GRIB_CHECK(grib_get_message(gh, (const void **)&dummy, &recsize), 0);
@@ -51417,10 +51745,24 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
gribHandleDelete(gh);
#endif
- gc->init = TRUE;
+ gc->init = true;
return recsize;
}
+
+
+void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype, int lev)
+{
+ long indicatorOfParameter, indicatorOfTypeOfLevel, level; // timeRangeIndicator: could be included later
+ indicatorOfParameter = code;
+ indicatorOfTypeOfLevel = ltype;
+ level = lev;
+
+ if (indicatorOfParameter!=-1) GRIB_CHECK(my_grib_set_long(gh, "indicatorOfParameter", indicatorOfParameter), 0);
+ if (indicatorOfTypeOfLevel!=-1) GRIB_CHECK(my_grib_set_long(gh, "indicatorOfTypeOfLevel", indicatorOfTypeOfLevel), 0);
+ if (level!=-1) GRIB_CHECK(my_grib_set_long(gh, "level", level), 0);
+}
+
#endif
/*
@@ -51432,20 +51774,28 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
* require-trailing-newline: t
* End:
*/
-#if defined (HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#endif
+#ifdef HAVE_LIBNETCDF
+static inline bool
+filetypeIsNetCDF(int filetype)
+{
+ return filetype == CDI_FILETYPE_NC
+ || filetype == CDI_FILETYPE_NC2
+ || filetype == CDI_FILETYPE_NC5
+ || filetype == CDI_FILETYPE_NC4
+ || filetype == CDI_FILETYPE_NC4C;
+}
+#endif
void streamDefHistory(int streamID, int length, const char *history)
{
#ifdef HAVE_LIBNETCDF
stream_t *streamptr = stream_to_pointer(streamID);
- if ( streamptr->filetype == FILETYPE_NC ||
- streamptr->filetype == FILETYPE_NC2 ||
- streamptr->filetype == FILETYPE_NC4 ||
- streamptr->filetype == FILETYPE_NC4C )
+ if ( filetypeIsNetCDF(streamptr->filetype) )
{
char *histstring;
size_t len;
@@ -51474,10 +51824,7 @@ int streamInqHistorySize(int streamID)
#ifdef HAVE_LIBNETCDF
stream_t *streamptr = stream_to_pointer(streamID);
- if ( streamptr->filetype == FILETYPE_NC ||
- streamptr->filetype == FILETYPE_NC2 ||
- streamptr->filetype == FILETYPE_NC4 ||
- streamptr->filetype == FILETYPE_NC4C )
+ if ( filetypeIsNetCDF(streamptr->filetype) )
{
size = cdfInqHistorySize(streamptr);
}
@@ -51493,10 +51840,7 @@ void streamInqHistoryString(int streamID, char *history)
#ifdef HAVE_LIBNETCDF
stream_t *streamptr = stream_to_pointer(streamID);
- if ( streamptr->filetype == FILETYPE_NC ||
- streamptr->filetype == FILETYPE_NC2 ||
- streamptr->filetype == FILETYPE_NC4 ||
- streamptr->filetype == FILETYPE_NC4C )
+ if ( filetypeIsNetCDF(streamptr->filetype) )
{
cdfInqHistoryString(streamptr, history);
}
@@ -51516,57 +51860,35 @@ void streamInqHistoryString(int streamID, char *history)
#if defined (HAVE_CONFIG_H)
#endif
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <float.h>
-#include <math.h>
-
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
-
-#define SINGLE_PRECISION 4
-#define DOUBLE_PRECISION 8
#if defined (HAVE_LIBIEG)
-
typedef struct {
int param;
int level;
-} IEGCOMPVAR;
+} iegcompvar_t;
-static int iegInqDatatype(int prec)
+static
+int iegInqDatatype(int prec)
{
- int datatype;
-
- if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
- else datatype = DATATYPE_FLT32;
-
- return (datatype);
+ return (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
}
-
-static int iegDefDatatype(int datatype)
+static
+int iegDefDatatype(int datatype)
{
- int prec;
-
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
Error("CDI/IEG library does not support complex numbers!");
- if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
- datatype = DATATYPE_FLT32;
+ if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 )
+ datatype = CDI_DATATYPE_FLT32;
- if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
- else prec = SINGLE_PRECISION;
-
- return (prec);
+ return (datatype == CDI_DATATYPE_FLT64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
}
/* not used
@@ -51586,7 +51908,7 @@ int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
*levelID = -1;
status = iegRead(fileID, iegp);
- if ( status != 0 ) return (0);
+ if ( status != 0 ) return 0;
icode = IEG_P_Parameter(iegp->ipdb);
if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
@@ -51596,51 +51918,43 @@ int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
*varID = vlistInqVarID(vlistID, icode);
- if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+ if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
zaxisID = vlistInqVarZaxis(vlistID, *varID);
*levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
- return (1);
+ return 1;
}
*/
-void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void iegReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
- int vlistID, fileID;
- int status;
- int recID, vrecID, tsID;
- off_t recpos;
- int varID, gridID;
- int i, size;
- double missval;
- void *iegp = streamptr->record->exsep;
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- vrecID = streamptr->tsteps[tsID].curRecID;
- recID = streamptr->tsteps[tsID].recIDs[vrecID];
- recpos = streamptr->tsteps[tsID].records[recID].position;
- varID = streamptr->tsteps[tsID].records[recID].varID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int tsID = streamptr->curTsID;
+ int vrecID = streamptr->tsteps[tsID].curRecID;
+ int recID = streamptr->tsteps[tsID].recIDs[vrecID];
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ off_t recpos = streamptr->tsteps[tsID].records[recID].position;
fileSetPos(fileID, recpos, SEEK_SET);
- status = iegRead(fileID, iegp);
+ void *iegp = streamptr->record->exsep;
+ int status = iegRead(fileID, iegp);
if ( status != 0 )
Error("Could not read IEG record!");
iegInqDataDP(iegp, data);
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- size = gridInqSize(gridID);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
- for ( i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -51700,19 +52014,18 @@ int iegGetZaxisType(int iegleveltype)
}
}
- return (leveltype);
+ return leveltype;
}
static void iegDefTime(int *pdb, int date, int time, int taxisID)
{
- int year, month, day, hour, minute, second;
int timetype = -1;
-
if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
{
+ int year, month, day, hour, minute, second;
cdiDecodeDate(date, &year, &month, &day);
cdiDecodeTime(time, &hour, &minute, &second);
@@ -51763,21 +52076,27 @@ calc_resfac(double xfirst, double xlast, double xinc, double yfirst, double ylas
}
}
- return (resfac);
+ return resfac;
}
static
void iegDefGrid(int *gdb, int gridID)
{
+ int projID = gridInqProj(gridID);
+ if ( projID != CDI_UNDEFID && gridInqProjType(projID) == CDI_PROJ_RLL ) gridID = projID;
+
int gridtype = gridInqType(gridID);
- if ( gridtype == GRID_GENERIC )
- {
- int xsize, ysize;
+ int projtype = CDI_UNDEFID;
+ if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL ) projtype = CDI_PROJ_RLL;
- xsize = gridInqXsize(gridID);
- ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
+ cdi_check_gridsize_int_limit("IEG", xsize*ysize);
+
+ if ( gridtype == GRID_GENERIC )
+ {
if ( (ysize == 32 || ysize == 48 || ysize == 64 ||
ysize == 96 || ysize == 160) &&
(xsize == 2*ysize || xsize == 1) )
@@ -51801,39 +52120,32 @@ void iegDefGrid(int *gdb, int gridID)
gridtype = GRID_LONLAT;
}
- if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
+ bool lrotated = (projtype == CDI_PROJ_RLL);
+
+ if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
{
double xfirst = 0, xlast = 0, xinc = 0;
double yfirst = 0, ylast = 0, yinc = 0;
- int nlon = gridInqXsize(gridID),
- nlat = gridInqYsize(gridID);
-
- if ( nlon == 0 )
- {
- nlon = 1;
- }
+ if ( xsize == 0 ) xsize = 1;
else
{
- xfirst = gridInqXval(gridID, 0);
- xlast = gridInqXval(gridID, nlon-1);
+ xfirst = gridInqXval(gridID, 0);
+ xlast = gridInqXval(gridID, xsize-1);
xinc = gridInqXinc(gridID);
}
- if ( nlat == 0 )
- {
- nlat = 1;
- }
+ if ( ysize == 0 ) ysize = 1;
else
{
- yfirst = gridInqYval(gridID, 0);
- ylast = gridInqYval(gridID, nlat-1);
+ yfirst = gridInqYval(gridID, 0);
+ ylast = gridInqYval(gridID, ysize-1);
yinc = gridInqYinc(gridID);
}
if ( gridtype == GRID_GAUSSIAN )
IEG_G_GridType(gdb) = 4;
- else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
+ else if ( lrotated )
IEG_G_GridType(gdb) = 10;
else
IEG_G_GridType(gdb) = 0;
@@ -51844,8 +52156,8 @@ void iegDefGrid(int *gdb, int gridID)
IEG_G_ResFac(gdb) = iresfac;
- IEG_G_NumLon(gdb) = nlon;
- IEG_G_NumLat(gdb) = nlat;
+ IEG_G_NumLon(gdb) = (int)xsize;
+ IEG_G_NumLat(gdb) = (int)ysize;
IEG_G_FirstLat(gdb) = (int)lround(yfirst*resfac);
IEG_G_LastLat(gdb) = (int)lround(ylast*resfac);
IEG_G_FirstLon(gdb) = (int)lround(xfirst*resfac);
@@ -51855,7 +52167,7 @@ void iegDefGrid(int *gdb, int gridID)
IEG_G_LonIncr(gdb) = 0;
if ( gridtype == GRID_GAUSSIAN )
- IEG_G_LatIncr(gdb) = nlat/2;
+ IEG_G_LatIncr(gdb) = (int)ysize/2;
else
{
IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
@@ -51871,15 +52183,15 @@ void iegDefGrid(int *gdb, int gridID)
if ( IEG_G_NumLon(gdb) == 1 && IEG_G_NumLat(gdb) > 1 )
if ( IEG_G_LonIncr(gdb) == 0 && IEG_G_LatIncr(gdb) != 0 ) IEG_G_LonIncr(gdb) = IEG_G_LatIncr(gdb);
- if ( IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0 )
- IEG_G_ResFlag(gdb) = 0;
- else
- IEG_G_ResFlag(gdb) = 128;
+ IEG_G_ResFlag(gdb) = (IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0) ? 0 : 128;
- if ( gridIsRotated(gridID) )
+ if ( lrotated )
{
- IEG_G_LatSP(gdb) = - (int)lround(gridInqYpole(gridID) * resfac);
- IEG_G_LonSP(gdb) = (int)lround((gridInqXpole(gridID) + 180) * resfac);
+ double xpole = 0, ypole = 0, angle = 0;
+ gridInqParamRLL(gridID, &xpole, &ypole, &angle);
+
+ IEG_G_LatSP(gdb) = - (int)lround(ypole * resfac);
+ IEG_G_LonSP(gdb) = (int)lround((xpole + 180) * resfac);
IEG_G_Size(gdb) = 42;
}
else
@@ -51896,19 +52208,25 @@ void iegDefGrid(int *gdb, int gridID)
}
static
+void pdbDefLevel(int *pdb, int leveltype, int level1, int level2)
+{
+ IEG_P_LevelType(pdb) = leveltype;
+ IEG_P_Level1(pdb) = level1;
+ IEG_P_Level2(pdb) = level2;
+}
+
+static
void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
{
double level;
- int ilevel, leveltype;
- static int vct_warning = 1;
+ int ilevel;
- leveltype = zaxisInqType(zaxisID);
+ int leveltype = zaxisInqType(zaxisID);
if ( leveltype == ZAXIS_GENERIC )
{
Message("Changed zaxis type from %s to %s",
- zaxisNamePtr(leveltype),
- zaxisNamePtr(ZAXIS_PRESSURE));
+ zaxisNamePtr(leveltype), zaxisNamePtr(ZAXIS_PRESSURE));
leveltype = ZAXIS_PRESSURE;
zaxisChangeType(zaxisID, leveltype);
zaxisDefUnits(zaxisID, "Pa");
@@ -51920,36 +52238,26 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
{
case ZAXIS_SURFACE:
{
- IEG_P_LevelType(pdb) = IEG_LTYPE_SURFACE;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = (int)(zaxisInqLevel(zaxisID, levelID));
+ pdbDefLevel(pdb, IEG_LTYPE_SURFACE, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
break;
}
case ZAXIS_HYBRID:
{
- int vctsize;
-
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID_LAYER;
- IEG_P_Level1(pdb) = (int)(zaxisInqLbound(zaxisID, levelID));
- IEG_P_Level2(pdb) = (int)(zaxisInqUbound(zaxisID, levelID));
- }
+ pdbDefLevel(pdb, IEG_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
+ (int)(zaxisInqUbound(zaxisID, levelID)));
else
- {
- IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = (int)(zaxisInqLevel(zaxisID, levelID));
- }
+ pdbDefLevel(pdb, IEG_LTYPE_HYBRID, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
- vctsize = zaxisInqVctSize(zaxisID);
+ int vctsize = zaxisInqVctSize(zaxisID);
if ( vctsize > 100 )
{
+ static bool vct_warning = true;
/* IEG_G_NumVCP(gdb) = 0; */
if ( vct_warning )
{
Warning("VCT size of %d is too large (maximum is 100). Set to 0!", vctsize);
- vct_warning = 0;
+ vct_warning = false;
}
}
else
@@ -51963,11 +52271,10 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
case ZAXIS_PRESSURE:
{
double dum;
- char units[128];
+ char units[CDI_MAX_NAME];
level = zaxisInqLevel(zaxisID, levelID);
- if ( level < 0 )
- Warning("pressure level of %f Pa is below 0.", level);
+ if ( level < 0 ) Warning("pressure level of %f Pa is below 0.", level);
zaxisInqUnits(zaxisID, units);
if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
@@ -51975,81 +52282,43 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
ilevel = (int) level;
if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
- {
- IEG_P_LevelType(pdb) = IEG_LTYPE_99;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
- }
+ pdbDefLevel(pdb, IEG_LTYPE_99, 0, ilevel);
else
- {
- IEG_P_LevelType(pdb) = IEG_LTYPE_ISOBARIC;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel/100;
- }
- break;
+ pdbDefLevel(pdb, IEG_LTYPE_ISOBARIC, 0, ilevel/100);
+
+ break;
}
case ZAXIS_HEIGHT:
{
level = zaxisInqLevel(zaxisID, levelID);
-
- ilevel = (int) level;
- IEG_P_LevelType(pdb) = IEG_LTYPE_HEIGHT;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
-
+ pdbDefLevel(pdb, IEG_LTYPE_HEIGHT, 0, (int)level);
break;
}
case ZAXIS_ALTITUDE:
{
level = zaxisInqLevel(zaxisID, levelID);
-
- ilevel = (int) level;
- IEG_P_LevelType(pdb) = IEG_LTYPE_ALTITUDE;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
-
+ pdbDefLevel(pdb, IEG_LTYPE_ALTITUDE, 0, (int)level);
break;
}
case ZAXIS_DEPTH_BELOW_LAND:
{
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
- {
- IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH_LAYER;
- IEG_P_Level1(pdb) = (int)(zaxisInqLbound(zaxisID, levelID));
- IEG_P_Level2(pdb) = (int)(zaxisInqUbound(zaxisID, levelID));
- }
+ pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)), (int)(zaxisInqUbound(zaxisID, levelID)));
else
- {
- level = zaxisInqLevel(zaxisID, levelID);
-
- ilevel = (int) level;
- IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
- }
+ pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
break;
}
case ZAXIS_DEPTH_BELOW_SEA:
{
level = zaxisInqLevel(zaxisID, levelID);
-
- ilevel = (int) level;
- IEG_P_LevelType(pdb) = IEG_LTYPE_SEADEPTH;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
-
+ pdbDefLevel(pdb, IEG_LTYPE_SEADEPTH, 0, (int)level);
break;
}
case ZAXIS_ISENTROPIC:
{
level = zaxisInqLevel(zaxisID, levelID);
-
- ilevel = (int) level;
- IEG_P_LevelType(pdb) = 113;
- IEG_P_Level1(pdb) = 0;
- IEG_P_Level2(pdb) = ilevel;
-
+ pdbDefLevel(pdb, 113, 0, (int)level);
break;
}
default:
@@ -52069,68 +52338,55 @@ void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
void iegDefRecord(stream_t *streamptr)
{
- int vlistID;
- int gridID;
- int date, time;
- int datatype;
- int i;
- int param, pdis, pcat, pnum;
- int varID, levelID, tsID, zaxisID;
- int byteorder;
- iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+ Record *record = streamptr->record;
+ iegrec_t *iegp = (iegrec_t*) record->exsep;
- vlistID = streamptr->vlistID;
- byteorder = streamptr->byteorder;
+ int vlistID = streamptr->vlistID;
+ int byteorder = streamptr->byteorder;
- varID = streamptr->record->varID;
- levelID = streamptr->record->levelID;
- tsID = streamptr->curTsID;
+ int varID = record->varID;
+ int levelID = record->levelID;
+ int tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
iegInitMem(iegp);
- for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+ for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
iegp->byteswap = getByteswap(byteorder);
- param = vlistInqVarParam(vlistID, varID);
+ int param = vlistInqVarParam(vlistID, varID);
+ int pdis, pcat, pnum;
cdiDecodeParam(param, &pnum, &pcat, &pdis);
IEG_P_Parameter(iegp->ipdb) = pnum;
if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
- date = streamptr->tsteps[tsID].taxis.vdate;
- time = streamptr->tsteps[tsID].taxis.vtime;
+ int date = streamptr->tsteps[tsID].taxis.vdate;
+ int time = streamptr->tsteps[tsID].taxis.vtime;
iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
iegDefGrid(iegp->igdb, gridID);
iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);
- datatype = streamptr->record->prec;
-
- iegp->dprec = iegDefDatatype(datatype);
+ iegp->dprec = iegDefDatatype(record->prec);
}
void iegWriteRecord(stream_t *streamptr, const double *data)
{
- int fileID;
- int i, gridsize, gridID;
- double refval;
- iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+ Record *record = streamptr->record;
+ iegrec_t *iegp = (iegrec_t*) record->exsep;
- fileID = streamptr->fileID;
- gridID = streamptr->record->gridID;
-
- gridsize = gridInqSize(gridID);
+ int fileID = streamptr->fileID;
+ size_t gridsize = gridInqSize(record->gridID);
- refval = data[0];
- for ( i = 1; i < gridsize; i++ )
+ double refval = data[0];
+ for ( size_t i = 1; i < gridsize; i++ )
if ( data[i] < refval ) refval = data[i];
iegp->refval = refval;
iegDefDataDP(iegp, data);
-
iegWrite(fileID, iegp);
}
@@ -52138,7 +52394,6 @@ static
void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
size_t recsize, off_t position, int prec)
{
- int levelID = 0;
int vlistID = streamptr->vlistID;
int tsID = streamptr->curTsID;
int recID = recordNewEntry(streamptr, tsID);
@@ -52164,18 +52419,20 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
record->ilevel2 = level2;
record->ltype = IEG_P_LevelType(pdb);
- int gridtype =
- ( IEG_G_GridType(gdb) == 0 || IEG_G_GridType(gdb) == 10 ) ? GRID_LONLAT :
- ( IEG_G_GridType(gdb) == 4 ) ? GRID_GAUSSIAN : GRID_GENERIC;
+ int gridtype = (IEG_G_GridType(gdb) == 0) ? GRID_LONLAT :
+ (IEG_G_GridType(gdb) == 10) ? GRID_PROJECTION :
+ (IEG_G_GridType(gdb) == 4) ? GRID_GAUSSIAN : GRID_GENERIC;
grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
grid_init(grid);
cdiGridTypeInit(grid, gridtype, IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb));
- grid->xsize = IEG_G_NumLon(gdb);
- grid->ysize = IEG_G_NumLat(gdb);
- grid->xinc = 0;
- grid->yinc = 0;
- grid->xdef = 0;
+ size_t xsize = (size_t)IEG_G_NumLon(gdb);
+ size_t ysize = (size_t)IEG_G_NumLat(gdb);
+ grid->x.size = xsize;
+ grid->y.size = ysize;
+ grid->x.inc = 0;
+ grid->y.inc = 0;
+ grid->x.flag = 0;
int iresfac = IEG_G_ResFac(gdb);
if ( iresfac == 0 ) iresfac = 1000;
@@ -52183,78 +52440,65 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
/* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
{
- if ( grid->xsize > 1 )
+ if ( xsize > 1 )
{
if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
- grid->xinc = IEG_G_LonIncr(gdb) * resfac;
+ grid->x.inc = IEG_G_LonIncr(gdb) * resfac;
else
- grid->xinc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (grid->xsize - 1);
+ grid->x.inc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (xsize - 1);
/* correct xinc if necessary */
if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
{
- double xinc = 360. / grid->xsize;
- /* FIXME: why not use grid->xinc != xinc as condition? */
- if ( fabs(grid->xinc-xinc) > 0.0 )
+ double xinc = 360. / xsize;
+ /* FIXME: why not use grid->x.inc != xinc as condition? */
+ if ( fabs(grid->x.inc-xinc) > 0.0 )
{
- grid->xinc = xinc;
- if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+ grid->x.inc = xinc;
+ if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
}
}
}
- grid->xfirst = IEG_G_FirstLon(gdb) * resfac;
- grid->xlast = IEG_G_LastLon(gdb) * resfac;
- grid->xdef = 2;
+ grid->x.first = IEG_G_FirstLon(gdb) * resfac;
+ grid->x.last = IEG_G_LastLon(gdb) * resfac;
+ grid->x.flag = 2;
}
- grid->ydef = 0;
+ grid->y.flag = 0;
/* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
{
- if ( grid->ysize > 1 )
+ if ( ysize > 1 )
{
if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
- grid->yinc = IEG_G_LatIncr(gdb) * resfac;
+ grid->y.inc = IEG_G_LatIncr(gdb) * resfac;
else
- grid->yinc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (grid->ysize - 1);
+ grid->y.inc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (ysize - 1);
}
- grid->yfirst = IEG_G_FirstLat(gdb) * resfac;
- grid->ylast = IEG_G_LastLat(gdb) * resfac;
- grid->ydef = 2;
+ grid->y.first = IEG_G_FirstLat(gdb) * resfac;
+ grid->y.last = IEG_G_LastLat(gdb) * resfac;
+ grid->y.flag = 2;
}
- /*
- grid->xfirst= IEG_G_FirstLon(gdb) * resfac;
- grid->xlast = IEG_G_LastLon(gdb) * resfac;
- grid->xinc = IEG_G_LonIncr(gdb) * resfac;
- grid->xdef = 2;
- grid->yfirst= IEG_G_FirstLat(gdb) * resfac;
- grid->ylast = IEG_G_LastLat(gdb) * resfac;
- grid->yinc = IEG_G_LatIncr(gdb) * resfac;
- grid->ydef = 2;
- */
- grid->xvals = NULL;
- grid->yvals = NULL;
- grid->isRotated = FALSE;
+ double xpole = 0, ypole = 0;
if ( IEG_G_GridType(gdb) == 10 )
{
- grid->isRotated = TRUE;
- grid->ypole = - IEG_G_LatSP(gdb) * resfac;
- grid->xpole = IEG_G_LonSP(gdb) * resfac - 180;
- grid->angle = 0;
+ xpole = IEG_G_LonSP(gdb) * resfac - 180;
+ ypole = - IEG_G_LatSP(gdb) * resfac;
+ grid->projtype = CDI_PROJ_RLL;
}
- struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+ struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
int gridID = gridAdded.Id;
- if (!gridAdded.isNew) Free(grid);
+ if ( !gridAdded.isNew ) Free(grid);
+ else if ( gridtype == GRID_PROJECTION ) gridDefParamRLL(gridID, xpole, ypole, 0);
int leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
-
if ( leveltype == ZAXIS_HYBRID )
{
double tmpvct[100];
size_t vctsize = (size_t)IEG_G_NumVCP(gdb);
- for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
- for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
+ for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
+ for ( size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
varDefVCT(vctsize, tmpvct);
}
@@ -52264,6 +52508,7 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
int datatype = iegInqDatatype(prec);
int varID;
+ int levelID = 0;
varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1,
NULL, NULL, NULL, NULL, NULL, NULL);
@@ -52275,20 +52520,18 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
streamptr->nrecs++;
if ( CDI_Debug )
- Message("varID = %d gridID = %d levelID = %d",
- varID, gridID, levelID);
+ Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
}
#if 0
static
void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
- int level, int xsize, int ysize)
+ int level, size_t xsize, size_t ysize)
{
int varID = 0;
int levelID = 0;
- record_t *record;
- record = &streamptr->tsteps[tsID].records[recID];
+ record_t *record = &streamptr->tsteps[tsID].records[recID];
if ( param != (*record).param || level != (*record).ilevel )
Error("inconsistent timestep");
@@ -52308,17 +52551,15 @@ void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int
}
#endif
-static void iegDateTime(int *pdb, int *date, int *time)
+static
+void iegDateTime(int *pdb, int *date, int *time)
{
- int ryear, rmonth, rday, rhour, rminute;
-
- ryear = IEG_P_Year(pdb);
+ int ryear = IEG_P_Year(pdb);
+ int rmonth = IEG_P_Month(pdb);
+ int rday = IEG_P_Day(pdb);
- rmonth = IEG_P_Month(pdb);
- rday = IEG_P_Day(pdb);
-
- rhour = IEG_P_Hour(pdb);
- rminute = IEG_P_Minute(pdb);
+ int rhour = IEG_P_Hour(pdb);
+ int rminute = IEG_P_Minute(pdb);
if ( rminute == -1 ) rminute = 0;
@@ -52329,51 +52570,39 @@ static void iegDateTime(int *pdb, int *date, int *time)
static
void iegScanTimestep1(stream_t *streamptr)
{
- int prec = 0;
- int status;
- int fileID;
- int tabnum;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
DateTime datetime0 = { LONG_MIN, LONG_MIN };
- int tsID;
- int varID;
- size_t recsize;
off_t recpos;
- int nrecords, nrecs, recID;
- int taxisID = -1;
- taxis_t *taxis;
- int vlistID;
- IEGCOMPVAR compVar, compVar0;
+ iegcompvar_t compVar, compVar0;
iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
streamptr->curTsID = 0;
- tsID = tstepsNewEntry(streamptr);
- taxis = &streamptr->tsteps[tsID].taxis;
+ int tsID = tstepsNewEntry(streamptr);
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
if ( tsID != 0 )
Error("Internal problem! tstepsNewEntry returns %d", tsID);
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
- nrecs = 0;
- while ( TRUE )
+ int nrecs = 0;
+ while ( true )
{
recpos = fileGetPos(fileID);
- status = iegRead(fileID, iegp);
+ int status = iegRead(fileID, iegp);
if ( status != 0 )
{
streamptr->ntsteps = 1;
break;
}
- recsize = (size_t)(fileGetPos(fileID) - recpos);
+ size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
- prec = iegp->dprec;
- rcode = IEG_P_Parameter(iegp->ipdb);
- tabnum = IEG_P_CodeTable(iegp->ipdb);
- param = cdiEncodeParam(rcode, tabnum, 255);
+ int prec = iegp->dprec;
+ int rcode = IEG_P_Parameter(iegp->ipdb);
+ int tabnum = IEG_P_CodeTable(iegp->ipdb);
+ int param = cdiEncodeParam(rcode, tabnum, 255);
+ int rlevel = 0;
if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
rlevel = IEG_P_Level1(iegp->ipdb);
else
@@ -52381,6 +52610,7 @@ void iegScanTimestep1(stream_t *streamptr)
if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+ int vdate = 0, vtime = 0;
iegDateTime(iegp->ipdb, &vdate, &vtime);
if ( nrecs == 0 )
@@ -52392,12 +52622,13 @@ void iegScanTimestep1(stream_t *streamptr)
{
compVar.param = param;
compVar.level = rlevel;
+ int recID = 0;
for ( recID = 0; recID < nrecs; recID++ )
{
compVar0.param = streamptr->tsteps[0].records[recID].param;
compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 ) break;
+ if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 ) break;
}
if ( recID < nrecs ) break;
DateTime datetime = { .date = vdate, .time = vtime};
@@ -52417,17 +52648,17 @@ void iegScanTimestep1(stream_t *streamptr)
cdi_generate_vars(streamptr);
- taxisID = taxisCreate(TAXIS_ABSOLUTE);
+ int taxisID = taxisCreate(TAXIS_ABSOLUTE);
taxis->type = TAXIS_ABSOLUTE;
taxis->vdate = (int)datetime0.date;
taxis->vtime = (int)datetime0.time;
- vlistID = streamptr->vlistID;
+ int vlistID = streamptr->vlistID;
vlistDefTaxis(vlistID, taxisID);
vlist_check_contents(vlistID);
- nrecords = streamptr->tsteps[0].nallrecs;
+ int nrecords = streamptr->tsteps[0].nallrecs;
if ( nrecords < streamptr->tsteps[0].recordSize )
{
streamptr->tsteps[0].recordSize = nrecords;
@@ -52438,7 +52669,7 @@ void iegScanTimestep1(stream_t *streamptr)
streamptr->tsteps[0].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
streamptr->tsteps[0].nrecs = nrecords;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
streamptr->tsteps[0].recIDs[recID] = recID;
if ( streamptr->ntsteps == -1 )
@@ -52447,7 +52678,7 @@ void iegScanTimestep1(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -52456,10 +52687,8 @@ void iegScanTimestep1(stream_t *streamptr)
if ( taxis->vdate == 0 && taxis->vtime == 0 )
{
streamptr->ntsteps = 0;
- for ( varID = 0; varID < streamptr->nvars; varID++ )
- {
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
- }
+ for ( int varID = 0; varID < streamptr->nvars; varID++ )
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
}
}
@@ -52467,67 +52696,55 @@ void iegScanTimestep1(stream_t *streamptr)
static
int iegScanTimestep2(stream_t *streamptr)
{
- int status;
- int fileID;
- int tabnum;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
- int tsID;
- int varID;
- size_t recsize;
off_t recpos = 0;
- int nrecords, nrecs, recID, rindex;
- int nextstep;
- taxis_t *taxis;
- int vlistID;
- IEGCOMPVAR compVar, compVar0;
+ iegcompvar_t compVar, compVar0;
iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
streamptr->curTsID = 1;
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
- tsID = streamptr->rtsteps;
+ int tsID = streamptr->rtsteps;
if ( tsID != 1 )
Error("Internal problem! unexpected timestep %d", tsID+1);
- taxis = &streamptr->tsteps[tsID].taxis;
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
cdi_create_records(streamptr, tsID);
- nrecords = streamptr->tsteps[0].nallrecs;
+ int nrecords = streamptr->tsteps[0].nallrecs;
streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
streamptr->tsteps[1].nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
streamptr->tsteps[1].recIDs[recID] = -1;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
{
- varID = streamptr->tsteps[0].records[recID].varID;
streamptr->tsteps[tsID].records[recID].position =
streamptr->tsteps[0].records[recID].position;
streamptr->tsteps[tsID].records[recID].size =
streamptr->tsteps[0].records[recID].size;
}
- for ( rindex = 0; rindex <= nrecords; rindex++ )
+ for ( int rindex = 0; rindex <= nrecords; rindex++ )
{
recpos = fileGetPos(fileID);
- status = iegRead(fileID, iegp);
+ int status = iegRead(fileID, iegp);
if ( status != 0 )
{
streamptr->ntsteps = 2;
break;
}
- recsize = (size_t)(fileGetPos(fileID) - recpos);
+ size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
- rcode = IEG_P_Parameter(iegp->ipdb);
- tabnum = IEG_P_CodeTable(iegp->ipdb);
- param = cdiEncodeParam(rcode, tabnum, 255);
+ int rcode = IEG_P_Parameter(iegp->ipdb);
+ int tabnum = IEG_P_CodeTable(iegp->ipdb);
+ int param = cdiEncodeParam(rcode, tabnum, 255);
+ int rlevel = 0;
if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
rlevel = IEG_P_Level1(iegp->ipdb);
else
@@ -52535,6 +52752,7 @@ int iegScanTimestep2(stream_t *streamptr)
if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+ int vdate = 0, vtime = 0;
iegDateTime(iegp->ipdb, &vdate, &vtime);
if ( rindex == 0 )
@@ -52546,21 +52764,22 @@ int iegScanTimestep2(stream_t *streamptr)
compVar.param = param;
compVar.level = rlevel;
- nextstep = FALSE;
+ bool nextstep = false;
+ int recID = 0;
for ( recID = 0; recID < nrecords; recID++ )
{
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 )
+ if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 )
{
if ( streamptr->tsteps[tsID].records[recID].used )
{
- nextstep = TRUE;
+ nextstep = true;
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
break;
@@ -52571,7 +52790,7 @@ int iegScanTimestep2(stream_t *streamptr)
char paramstr[32];
cdiParamToString(param, paramstr, sizeof(paramstr));
Warning("param %s level %d not defined at timestep 1", paramstr, rlevel);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
if ( nextstep ) break;
@@ -52584,25 +52803,25 @@ int iegScanTimestep2(stream_t *streamptr)
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
+ if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) != 0 )
{
Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d",
tsID, recID,
streamptr->tsteps[tsID].records[recID].param, param,
streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
streamptr->tsteps[1].records[recID].position = recpos;
}
- nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ int nrecs = 0;
+ for ( int recID = 0; recID < nrecords; recID++ )
{
if ( ! streamptr->tsteps[tsID].records[recID].used )
{
- varID = streamptr->tsteps[tsID].records[recID].varID;
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
else
{
@@ -52619,47 +52838,35 @@ int iegScanTimestep2(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
- return (0);
+ return 0;
}
int iegInqContents(stream_t *streamptr)
{
- int fileID;
- int status = 0;
-
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
streamptr->curTsID = 0;
iegScanTimestep1(streamptr);
+ int status = 0;
if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
fileSetPos(fileID, 0, SEEK_SET);
- return (status);
+ return status;
}
static
long iegScanTimestep(stream_t *streamptr)
{
- int status;
- int fileID;
- int tsID;
- int tabnum;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
- size_t recsize = 0;
off_t recpos = 0;
- int recID;
- taxis_t *taxis;
- int rindex, nrecs = 0;
- IEGCOMPVAR compVar, compVar0;
+ iegcompvar_t compVar, compVar0;
iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
if ( CDI_Debug )
@@ -52673,9 +52880,10 @@ long iegScanTimestep(stream_t *streamptr)
if ( streamptr->rtsteps == 0 )
Error("Internal problem! Missing contents.");
- tsID = streamptr->rtsteps;
- taxis = &streamptr->tsteps[tsID].taxis;
+ int tsID = streamptr->rtsteps;
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+ int nrecs = 0;
if ( streamptr->tsteps[tsID].recordSize == 0 )
{
cdi_create_records(streamptr, tsID);
@@ -52685,28 +52893,29 @@ long iegScanTimestep(stream_t *streamptr)
streamptr->tsteps[tsID].nrecs = nrecs;
streamptr->tsteps[tsID].recIDs
= (int *) Malloc((size_t)nrecs * sizeof (int));
- for ( recID = 0; recID < nrecs; recID++ )
+ for ( int recID = 0; recID < nrecs; recID++ )
streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
- for ( rindex = 0; rindex <= nrecs; rindex++ )
+ for ( int rindex = 0; rindex <= nrecs; rindex++ )
{
recpos = fileGetPos(fileID);
- status = iegRead(fileID, iegp);
+ int status = iegRead(fileID, iegp);
if ( status != 0 )
{
streamptr->ntsteps = streamptr->rtsteps + 1;
break;
}
- recsize = (size_t)(fileGetPos(fileID) - recpos);
+ size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
- rcode = IEG_P_Parameter(iegp->ipdb);
- tabnum = IEG_P_CodeTable(iegp->ipdb);
- param = cdiEncodeParam(rcode, tabnum, 255);
+ int rcode = IEG_P_Parameter(iegp->ipdb);
+ int tabnum = IEG_P_CodeTable(iegp->ipdb);
+ int param = cdiEncodeParam(rcode, tabnum, 255);
+ int rlevel = 0;
if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
rlevel = IEG_P_Level1(iegp->ipdb);
else
@@ -52714,11 +52923,12 @@ long iegScanTimestep(stream_t *streamptr)
if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+ int vdate = 0, vtime = 0;
iegDateTime(iegp->ipdb, &vdate, &vtime);
// if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
if ( rindex == nrecs ) continue;
- recID = streamptr->tsteps[tsID].recIDs[rindex];
+ int recID = streamptr->tsteps[tsID].recIDs[rindex];
if ( rindex == 0 )
{
@@ -52732,7 +52942,7 @@ long iegScanTimestep(stream_t *streamptr)
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
+ if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) != 0 )
{
Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d",
tsID, recID,
@@ -52756,7 +52966,7 @@ long iegScanTimestep(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = 1;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -52770,113 +52980,51 @@ long iegScanTimestep(stream_t *streamptr)
streamptr->ntsteps = tsID;
}
- return (streamptr->ntsteps);
+ return streamptr->ntsteps;
}
int iegInqTimestep(stream_t *streamptr, int tsID)
{
- int nrecs;
-
if ( tsID == 0 && streamptr->rtsteps == 0 )
Error("Call to cdiInqContents missing!");
if ( CDI_Debug )
Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
- long ntsteps = UNDEFID;
- while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+ long ntsteps = CDI_UNDEFID;
+ while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
ntsteps = iegScanTimestep(streamptr);
- if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
- {
- nrecs = 0;
- }
- else
+ int nrecs = 0;
+ if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
{
streamptr->curTsID = tsID;
nrecs = streamptr->tsteps[tsID].nrecs;
}
- return (nrecs);
+ return nrecs;
}
-void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
- int vlistID, fileID;
- int levID, nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int tsid;
- int recID;
- int i;
- double missval;
- void *iegp = streamptr->record->exsep;
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- /* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
- currentfilepos = fileGetPos(fileID);
-
- for (levID = 0; levID < nlevs; levID++)
- {
- /* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
- fileSetPos(fileID, recpos, SEEK_SET);
- iegRead(fileID, iegp);
- iegInqDataDP(iegp, &data[levID*gridsize]);
- }
- fileSetPos(fileID, currentfilepos, SEEK_SET);
-
- *nmiss = 0;
- for ( i = 0; i < nlevs*gridsize; i++ )
- if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
- {
- data[i] = missval;
- (*nmiss)++;
- }
-}
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
-
-void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
-{
- int vlistID, fileID;
- int nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int tsid;
- int recID;
- int i;
- double missval;
void *iegp = streamptr->record->exsep;
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d",
- nlevs, gridID, gridsize);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ int tsid = streamptr->curTsID;
- currentfilepos = fileGetPos(fileID);
+ off_t currentfilepos = fileGetPos(fileID);
/* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
+ int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+ off_t recpos = streamptr->tsteps[tsid].records[recID].position;
fileSetPos(fileID, recpos, SEEK_SET);
iegRead(fileID, iegp);
iegInqDataDP(iegp, data);
@@ -52884,7 +53032,7 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
fileSetPos(fileID, currentfilepos, SEEK_SET);
*nmiss = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -52893,101 +53041,70 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
- int fileID;
- int levID, nlevs, gridID, gridsize;
- int zaxisID;
- int datatype;
- int tsID;
- int vlistID;
- int i;
- int date, time;
- int param, pdis, pcat, pnum;
- double refval;
- iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
- if ( CDI_Debug )
- Message("streamID = %d varID = %d", streamptr->self, varID);
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
- iegInitMem(iegp);
- for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+ for ( size_t levID = 0; levID < nlevs; levID++)
+ iegReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
+}
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- nlevs = zaxisInqSize(zaxisID);
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+{
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
+
+ iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+ iegInitMem(iegp);
+ for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int tsID = streamptr->curTsID;
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
- param = vlistInqVarParam(vlistID, varID);
+ int param = vlistInqVarParam(vlistID, varID);
+ int pdis, pcat, pnum;
cdiDecodeParam(param, &pnum, &pcat, &pdis);
IEG_P_Parameter(iegp->ipdb) = pnum;
if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
- date = streamptr->tsteps[tsID].taxis.vdate;
- time = streamptr->tsteps[tsID].taxis.vtime;
+ int date = streamptr->tsteps[tsID].taxis.vdate;
+ int time = streamptr->tsteps[tsID].taxis.vtime;
iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
iegDefGrid(iegp->igdb, gridID);
+ iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
- datatype = vlistInqVarDatatype(vlistID, varID);
+ iegp->dprec = iegDefDatatype(vlistInqVarDatatype(vlistID, varID));
- iegp->dprec = iegDefDatatype(datatype);
-
- for ( levID = 0; levID < nlevs; levID++ )
- {
- iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
+ size_t gridsize = gridInqSize(gridID);
- refval = data[0];
- for ( i = 1; i < gridsize; i++ )
- if ( data[levID*gridsize+i] < refval ) refval = data[levID*gridsize+i];
+ double refval = data[0];
+ for ( size_t i = 1; i < gridsize; i++ )
+ if ( data[i] < refval ) refval = data[i];
- iegp->refval = refval;
+ iegp->refval = refval;
- iegDefDataDP(iegp, &data[levID*gridsize]);
- iegWrite(fileID, iegp);
- }
+ iegDefDataDP(iegp, data);
+ iegWrite(fileID, iegp);
}
-void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
{
- int fileID;
- int gridID;
- int zaxisID;
- /* double level; */
- int datatype;
- /* int tsID; */
- int vlistID;
- /* int param, date, time, datasize; */
- iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- /* tsID = streamptr->curTsID; */
- gridID = vlistInqVarGrid(vlistID, varID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- (void)levID;
- /* level = zaxisInqLevel(zaxisID, levID); */
-
- if ( CDI_Debug )
- Message("gridID = %d zaxisID = %d", gridID, zaxisID);
-
- /* param = vlistInqVarParam(vlistID, varID); */
- /* date = streamptr->tsteps[tsID].taxis.vdate; */
- /* time = streamptr->tsteps[tsID].taxis.vtime; */
- /* datasize = gridInqSize(gridID); */
-
- datatype = vlistInqVarDatatype(vlistID, varID);
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
- iegp->dprec = iegDefDatatype(datatype);
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
- iegDefDataDP(iegp, data);
- iegWrite(fileID, iegp);
+ for ( size_t levID = 0; levID < nlevs; levID++ )
+ iegWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
}
#endif /* HAVE_LIBIEG */
@@ -53000,7 +53117,7 @@ void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
* require-trailing-newline: t
* End:
*/
-#if defined (HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#endif
#include <limits.h>
@@ -53016,7 +53133,7 @@ void recordInitEntry(record_t *record)
record->size = 0;
record->param = 0;
record->ilevel = CDI_UNDEFID;
- record->used = FALSE;
+ record->used = false;
record->varID = CDI_UNDEFID;
record->levelID = CDI_UNDEFID;
memset(record->varname, 0, sizeof(record->varname));
@@ -53078,18 +53195,19 @@ int recordNewEntry(stream_t *streamptr, int tsID)
static
void cdiInitRecord(stream_t *streamptr)
{
- streamptr->record = (Record *) Malloc(sizeof(Record));
+ Record *record = (Record *) Malloc(sizeof(Record));
+ streamptr->record = record;
- streamptr->record->param = 0;
- streamptr->record->level = 0;
- streamptr->record->date = 0;
- streamptr->record->time = 0;
- streamptr->record->gridID = 0;
- streamptr->record->buffer = NULL;
- streamptr->record->buffersize = 0;
- streamptr->record->position = 0;
- streamptr->record->varID = 0;
- streamptr->record->levelID = CDI_UNDEFID;
+ record->param = 0;
+ record->level = 0;
+ record->date = 0;
+ record->time = 0;
+ record->gridID = 0;
+ record->buffer = NULL;
+ record->buffersize = 0;
+ record->position = 0;
+ record->varID = 0;
+ record->levelID = CDI_UNDEFID;
}
@@ -53122,7 +53240,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
*levelID = streamptr->vars[*varID].recordTable[isub].lindex[lindex];
if ( CDI_Debug )
- Message("tsID = %d, recID = %d, varID = %d, levelID = %d\n", tsID, recID, *varID, *levelID);
+ Message("tsID = %d, recID = %d, varID = %d, levelID = %d", tsID, recID, *varID, *levelID);
streamptr->curTsID = tsID;
streamptr->tsteps[tsID].curRecID = rindex;
@@ -53162,43 +53280,45 @@ void streamDefRecord(int streamID, int varID, int levelID)
int param = vlistInqVarParam(vlistID, varID);
int level = (int)(zaxisInqLevel(zaxisID, levelID));
- streamptr->record->varID = varID;
- streamptr->record->levelID = levelID;
- streamptr->record->param = param;
- streamptr->record->level = level;
- streamptr->record->date = streamptr->tsteps[tsID].taxis.vdate;
- streamptr->record->time = streamptr->tsteps[tsID].taxis.vtime;
- streamptr->record->gridID = gridID;
- streamptr->record->prec = vlistInqVarDatatype(vlistID, varID);
+ Record *record = streamptr->record;
+ record->varID = varID;
+ record->levelID = levelID;
+ record->param = param;
+ record->level = level;
+ record->date = streamptr->tsteps[tsID].taxis.vdate;
+ record->time = streamptr->tsteps[tsID].taxis.vtime;
+ record->gridID = gridID;
+ record->prec = vlistInqVarDatatype(vlistID, varID);
switch (streamptr->filetype)
{
#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
grbDefRecord(streamptr);
break;
#endif
#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
+ case CDI_FILETYPE_SRV:
srvDefRecord(streamptr);
break;
#endif
#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
+ case CDI_FILETYPE_EXT:
extDefRecord(streamptr);
break;
#endif
#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+ case CDI_FILETYPE_IEG:
iegDefRecord(streamptr);
break;
#endif
#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
cdfDefRecord(streamptr);
break;
@@ -53216,24 +53336,26 @@ void streamCopyRecord(int streamID2, int streamID1)
*streamptr2 = stream_to_pointer(streamID2);
int filetype1 = streamptr1->filetype,
filetype2 = streamptr2->filetype,
- filetype = FILETYPE_UNDEF;
+ filetype = CDI_FILETYPE_UNDEF;
if ( filetype1 == filetype2 ) filetype = filetype2;
else
{
switch (filetype1)
{
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
switch (filetype2)
{
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
- Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
+ // Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
filetype = filetype2;
break;
}
@@ -53241,37 +53363,38 @@ void streamCopyRecord(int streamID2, int streamID1)
}
}
- if ( filetype == FILETYPE_UNDEF )
+ if ( filetype == CDI_FILETYPE_UNDEF )
Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
switch (filetype)
{
#if defined (HAVE_LIBGRIB)
- case FILETYPE_GRB:
- case FILETYPE_GRB2:
+ case CDI_FILETYPE_GRB:
+ case CDI_FILETYPE_GRB2:
grbCopyRecord(streamptr2, streamptr1);
break;
#endif
#if defined (HAVE_LIBSERVICE)
- case FILETYPE_SRV:
+ case CDI_FILETYPE_SRV:
srvCopyRecord(streamptr2, streamptr1);
break;
#endif
#if defined (HAVE_LIBEXTRA)
- case FILETYPE_EXT:
+ case CDI_FILETYPE_EXT:
extCopyRecord(streamptr2, streamptr1);
break;
#endif
#if defined (HAVE_LIBIEG)
- case FILETYPE_IEG:
+ case CDI_FILETYPE_IEG:
iegCopyRecord(streamptr2, streamptr1);
break;
#endif
#if defined (HAVE_LIBNETCDF)
- case FILETYPE_NC:
- case FILETYPE_NC2:
- case FILETYPE_NC4:
- case FILETYPE_NC4C:
+ case CDI_FILETYPE_NC:
+ case CDI_FILETYPE_NC2:
+ case CDI_FILETYPE_NC4:
+ case CDI_FILETYPE_NC4C:
+ case CDI_FILETYPE_NC5:
cdfCopyRecord(streamptr2, streamptr1);
break;
#endif
@@ -53287,7 +53410,6 @@ void streamCopyRecord(int streamID2, int streamID1)
void cdi_create_records(stream_t *streamptr, int tsID)
{
unsigned nrecords, maxrecords;
- record_t *records;
tsteps_t *sourceTstep = streamptr->tsteps;
tsteps_t *destTstep = sourceTstep + tsID;
@@ -53321,7 +53443,7 @@ void cdi_create_records(stream_t *streamptr, int tsID)
{
int varID = sourceTstep->records[recID].varID;
nrecords += (varID == CDI_UNDEFID /* varID = CDI_UNDEFID for write mode !!! */
- || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
+ || vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT);
// printf("varID nrecords %d %d %d \n", varID, nrecords, vlistInqVarTsteptype(vlistID, varID));
}
}
@@ -53331,10 +53453,8 @@ void cdi_create_records(stream_t *streamptr, int tsID)
}
// printf("tsID, nrecords %d %d\n", tsID, nrecords);
- if ( maxrecords > 0 )
- records = (record_t *) Malloc(maxrecords*sizeof(record_t));
- else
- records = NULL;
+ record_t *records = NULL;
+ if ( maxrecords > 0 ) records = (record_t *) Malloc(maxrecords*sizeof(record_t));
destTstep->records = records;
destTstep->recordSize = (int)maxrecords;
@@ -53355,16 +53475,42 @@ void cdi_create_records(stream_t *streamptr, int tsID)
destTstep->records[recID].used = curRecord->used;
if ( curRecord->used != CDI_UNDEFID && curRecord->varID != -1 ) /* curRecord->varID = -1 for write mode !!! */
{
- if ( vlistInqVarTsteptype(vlistID, curRecord->varID) != TSTEP_CONSTANT )
+ if ( vlistInqVarTimetype(vlistID, curRecord->varID) != TIME_CONSTANT )
{
destTstep->records[recID].position = CDI_UNDEFID;
destTstep->records[recID].size = 0;
- destTstep->records[recID].used = FALSE;
+ destTstep->records[recID].used = false;
}
}
}
}
}
+
+
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name)
+{
+ int fileID1 = streamptr1->fileID;
+ int fileID2 = streamptr2->fileID;
+
+ int tsID = streamptr1->curTsID;
+ int vrecID = streamptr1->tsteps[tsID].curRecID;
+ int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
+ off_t recpos = streamptr1->tsteps[tsID].records[recID].position;
+ size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
+
+ if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
+ Error("Cannot seek input file for %s record copy!", container_name);
+
+ char *buffer = (char *) Malloc(recsize);
+
+ if (fileRead(fileID1, buffer, recsize) != recsize)
+ Error("Failed to read record from %s file for copying!", container_name);
+
+ if (fileWrite(fileID2, buffer, recsize) != recsize)
+ Error("Failed to write record to %s file when copying!", container_name);
+
+ Free(buffer);
+}
/*
* Local Variables:
* c-file-style: "Java"
@@ -53377,54 +53523,33 @@ void cdi_create_records(stream_t *streamptr, int tsID)
#if defined (HAVE_CONFIG_H)
#endif
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
-#define SINGLE_PRECISION 4
-#define DOUBLE_PRECISION 8
#if defined (HAVE_LIBSERVICE)
-
typedef struct {
int param;
int level;
-} SRVCOMPVAR;
+} srvcompvar_t;
-static int srvInqDatatype(int prec)
+static
+int srvInqDatatype(int prec)
{
- int datatype;
-
- if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
- else datatype = DATATYPE_FLT32;
-
- return (datatype);
+ return (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
}
-
-static int srvDefDatatype(int datatype)
+static
+int srvDefDatatype(int datatype)
{
- int prec;
-
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
Error("CDI/SERVICE library does not support complex numbers!");
- if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
- datatype = DATATYPE_FLT32;
+ if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 )
+ datatype = CDI_DATATYPE_FLT32;
- if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
- else prec = SINGLE_PRECISION;
-
- return (prec);
+ return (datatype == CDI_DATATYPE_FLT64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
}
/* not used
@@ -53454,25 +53579,18 @@ int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
*varID = vlistInqVarID(vlistID, icode);
- if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+ if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
zaxisID = vlistInqVarZaxis(vlistID, *varID);
*levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
- return (1);
+ return 1;
}
*/
-void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void srvReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
- int status;
- int header[8];
- int gridID;
- int i, size;
- double missval;
- void *srvp = streamptr->record->exsep;
-
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
int tsID = streamptr->curTsID;
@@ -53483,21 +53601,23 @@ void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
fileSetPos(fileID, recpos, SEEK_SET);
- status = srvRead(fileID, srvp);
+ void *srvp = streamptr->record->exsep;
+ int status = srvRead(fileID, srvp);
if ( status != 0 )
Error("Failed to read record from SRV file");
+ int header[8];
srvInqHeader(srvp, header);
srvInqDataDP(srvp, data);
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- size = gridInqSize(gridID);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
- for ( i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -53514,20 +53634,21 @@ void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
void srvDefRecord(stream_t *streamptr)
{
- int header[8];
- Record *restrict record = streamptr->record;
- srvrec_t *restrict srvp = (srvrec_t*) record->exsep;
- int gridID = record->gridID;
+ Record *record = streamptr->record;
+ srvrec_t *srvp = (srvrec_t*) record->exsep;
int pdis, pcat, pnum;
cdiDecodeParam(record->param, &pnum, &pcat, &pdis);
+
+ int header[8];
header[0] = pnum;
header[1] = record->level;
header[2] = record->date;
header[3] = record->time;
- int xsize = gridInqXsize(gridID),
- ysize = gridInqYsize(gridID);
+ int gridID = record->gridID;
+ size_t xsize = gridInqXsize(gridID),
+ ysize = gridInqYsize(gridID);
if ( xsize == 0 || ysize == 0 )
{
xsize = gridInqSize(gridID);
@@ -53537,13 +53658,14 @@ void srvDefRecord(stream_t *streamptr)
if ( gridInqSize(gridID) != xsize*ysize )
Error("Internal problem with gridsize!");
- header[4] = xsize;
- header[5] = ysize;
+ cdi_check_gridsize_int_limit("SERVICE", gridInqSize(gridID));
+
+ header[4] = (int)xsize;
+ header[5] = (int)ysize;
header[6] = 0;
header[7] = 0;
int datatype = record->prec;
-
srvp->dprec = srvDefDatatype(datatype);
srvDefHeader(srvp, header);
@@ -53560,7 +53682,7 @@ void srvWriteRecord(stream_t *streamptr, const double *data)
}
static
-void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
+void srv_add_record(stream_t *streamptr, int param, int level, size_t xsize, size_t ysize,
size_t recsize, off_t position, int prec)
{
int vlistID = streamptr->vlistID;
@@ -53573,14 +53695,12 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
record->param = param;
record->ilevel = level;
- grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
+ grid_t *grid = (grid_t*) Malloc(sizeof(*grid));
grid_init(grid);
cdiGridTypeInit(grid, GRID_GENERIC, xsize*ysize);
- grid->xsize = xsize;
- grid->ysize = ysize;
- grid->xvals = NULL;
- grid->yvals = NULL;
- struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+ grid->x.size = xsize;
+ grid->y.size = ysize;
+ struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
int gridID = gridAdded.Id;
if (!gridAdded.isNew) Free(grid);
/*
@@ -53605,8 +53725,7 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
streamptr->nrecs++;
if ( CDI_Debug )
- Message("varID = %d gridID = %d levelID = %d",
- varID, gridID, levelID);
+ Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
}
static
@@ -53626,11 +53745,10 @@ void srvScanTimestep1(stream_t *streamptr)
taxis = &streamptr->tsteps[tsID].taxis;
}
-
int fileID = streamptr->fileID;
int nrecs = 0;
- while ( TRUE )
+ while ( true )
{
int header[8];
recpos = fileGetPos(fileID);
@@ -53713,7 +53831,7 @@ void srvScanTimestep1(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -53723,7 +53841,7 @@ void srvScanTimestep1(stream_t *streamptr)
{
streamptr->ntsteps = 0;
for ( int varID = 0; varID < streamptr->nvars; varID++ )
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
}
}
@@ -53732,54 +53850,43 @@ static
int srvScanTimestep2(stream_t *streamptr)
{
int header[8];
- int status;
- int fileID;
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
- int tsID;
- int varID;
off_t recpos = 0;
- int nrecords, nrecs, recID, rindex;
- int nextstep;
- taxis_t *taxis;
- int vlistID;
- SRVCOMPVAR compVar, compVar0;
+ srvcompvar_t compVar, compVar0;
void *srvp = streamptr->record->exsep;
streamptr->curTsID = 1;
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
- tsID = streamptr->rtsteps;
+ int tsID = streamptr->rtsteps;
if ( tsID != 1 )
Error("Internal problem! unexpected timestep %d", tsID+1);
- taxis = &streamptr->tsteps[tsID].taxis;
+ taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
cdi_create_records(streamptr, tsID);
- nrecords = streamptr->tsteps[0].nallrecs;
+ int nrecords = streamptr->tsteps[0].nallrecs;
streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
streamptr->tsteps[1].nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
streamptr->tsteps[1].recIDs[recID] = -1;
- for ( recID = 0; recID < nrecords; recID++ )
+ for ( int recID = 0; recID < nrecords; recID++ )
{
- varID = streamptr->tsteps[0].records[recID].varID;
streamptr->tsteps[tsID].records[recID].position =
streamptr->tsteps[0].records[recID].position;
streamptr->tsteps[tsID].records[recID].size =
streamptr->tsteps[0].records[recID].size;
}
- for ( rindex = 0; rindex <= nrecords; rindex++ )
+ for ( int rindex = 0; rindex <= nrecords; rindex++ )
{
recpos = fileGetPos(fileID);
- status = srvRead(fileID, srvp);
+ int status = srvRead(fileID, srvp);
if ( status != 0 )
{
streamptr->ntsteps = 2;
@@ -53789,12 +53896,12 @@ int srvScanTimestep2(stream_t *streamptr)
srvInqHeader(srvp, header);
- rcode = header[0];
- rlevel = header[1];
- vdate = header[2];
- vtime = header[3];
+ int rcode = header[0];
+ int rlevel = header[1];
+ int vdate = header[2];
+ int vtime = header[3];
- param = cdiEncodeParam(rcode, 255, 255);
+ int param = cdiEncodeParam(rcode, 255, 255);
if ( rindex == 0 )
{
@@ -53805,21 +53912,22 @@ int srvScanTimestep2(stream_t *streamptr)
compVar.param = param;
compVar.level = rlevel;
- nextstep = FALSE;
+ bool nextstep = false;
+ int recID;
for ( recID = 0; recID < nrecords; recID++ )
{
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 )
+ if ( memcmp(&compVar0, &compVar, sizeof(srvcompvar_t)) == 0 )
{
if ( streamptr->tsteps[tsID].records[recID].used )
{
- nextstep = TRUE;
+ nextstep = true;
}
else
{
- streamptr->tsteps[tsID].records[recID].used = TRUE;
+ streamptr->tsteps[tsID].records[recID].used = true;
streamptr->tsteps[tsID].recIDs[rindex] = recID;
}
break;
@@ -53828,7 +53936,7 @@ int srvScanTimestep2(stream_t *streamptr)
if ( recID == nrecords )
{
Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
if ( nextstep ) break;
@@ -53841,25 +53949,25 @@ int srvScanTimestep2(stream_t *streamptr)
compVar0.param = streamptr->tsteps[tsID].records[recID].param;
compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
- if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
+ if ( memcmp(&compVar0, &compVar, sizeof(srvcompvar_t)) != 0 )
{
Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d",
tsID, recID,
streamptr->tsteps[tsID].records[recID].param, param,
streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
- return (CDI_EUFSTRUCT);
+ return CDI_EUFSTRUCT;
}
streamptr->tsteps[1].records[recID].position = recpos;
}
- nrecs = 0;
- for ( recID = 0; recID < nrecords; recID++ )
+ int nrecs = 0;
+ for ( int recID = 0; recID < nrecords; recID++ )
{
if ( ! streamptr->tsteps[tsID].records[recID].used )
{
- varID = streamptr->tsteps[tsID].records[recID].varID;
- vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+ int varID = streamptr->tsteps[tsID].records[recID].varID;
+ vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
}
else
{
@@ -53876,44 +53984,37 @@ int srvScanTimestep2(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = TRUE;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
- return (0);
+ return 0;
}
int srvInqContents(stream_t *streamptr)
{
- int fileID;
- int status = 0;
-
- fileID = streamptr->fileID;
-
streamptr->curTsID = 0;
srvScanTimestep1(streamptr);
+ int status = 0;
if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
+ int fileID = streamptr->fileID;
fileSetPos(fileID, 0, SEEK_SET);
- return (status);
+ return status;
}
static
long srvScanTimestep(stream_t *streamptr)
{
int header[8];
- int status;
- int fileID;
/* int rxsize = 0, rysize = 0; */
- int param = 0;
- int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
off_t recpos = 0;
int recID;
- int rindex, nrecs = 0;
+ int nrecs = 0;
void *srvp = streamptr->record->exsep;
/*
if ( CDI_Debug )
@@ -53939,14 +54040,14 @@ long srvScanTimestep(stream_t *streamptr)
for ( recID = 0; recID < nrecs; recID++ )
streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
- fileID = streamptr->fileID;
+ int fileID = streamptr->fileID;
fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
- for ( rindex = 0; rindex <= nrecs; rindex++ )
+ for ( int rindex = 0; rindex <= nrecs; rindex++ )
{
recpos = fileGetPos(fileID);
- status = srvRead(fileID, srvp);
+ int status = srvRead(fileID, srvp);
if ( status != 0 )
{
streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -53956,14 +54057,14 @@ long srvScanTimestep(stream_t *streamptr)
srvInqHeader(srvp, header);
- rcode = header[0];
- rlevel = header[1];
- vdate = header[2];
- vtime = header[3];
+ int rcode = header[0];
+ int rlevel = header[1];
+ int vdate = header[2];
+ int vtime = header[3];
/* rxsize = header[4]; */
/* rysize = header[5]; */
- param = cdiEncodeParam(rcode, 255, 255);
+ int param = cdiEncodeParam(rcode, 255, 255);
// if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
if ( rindex == nrecs ) continue;
@@ -54001,7 +54102,7 @@ long srvScanTimestep(stream_t *streamptr)
if ( tsID != streamptr->rtsteps )
Error("Internal error. tsID = %d", tsID);
- streamptr->tsteps[tsID-1].next = 1;
+ streamptr->tsteps[tsID-1].next = true;
streamptr->tsteps[tsID].position = recpos;
}
@@ -54015,128 +54116,61 @@ long srvScanTimestep(stream_t *streamptr)
streamptr->ntsteps = tsID;
}
- return (streamptr->ntsteps);
+ return streamptr->ntsteps;
}
int srvInqTimestep(stream_t *streamptr, int tsID)
{
- long ntsteps;
- int nrecs;
-
if ( tsID == 0 && streamptr->rtsteps == 0 )
Error("Call to cdiInqContents missing!");
if ( CDI_Debug )
Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
- ntsteps = UNDEFID;
- while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+ long ntsteps = CDI_UNDEFID;
+ while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
ntsteps = srvScanTimestep(streamptr);
- if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != UNDEFID )
- {
- nrecs = 0;
- }
- else
+ int nrecs = 0;
+ if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
{
streamptr->curTsID = tsID;
nrecs = streamptr->tsteps[tsID].nrecs;
}
- return (nrecs);
+ return nrecs;
}
-void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
- int vlistID, fileID;
- int levID, nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int header[8];
- int tsid;
- int recID;
- int i;
- double missval;
- void *srvp = streamptr->record->exsep;
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- /* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
- currentfilepos = fileGetPos(fileID);
-
- for (levID = 0; levID < nlevs; levID++)
- {
- /* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
- fileSetPos(fileID, recpos, SEEK_SET);
- if (srvRead(fileID, srvp) < 0)
- abort();
- srvInqHeader(srvp, header);
- srvInqDataDP(srvp, &data[levID*gridsize]);
- }
- fileSetPos(fileID, currentfilepos, SEEK_SET);
-
- *nmiss = 0;
- for ( i = 0; i < nlevs*gridsize; i++ )
- if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
- {
- data[i] = missval;
- (*nmiss)++;
- }
-}
-
-
-void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
-{
- int vlistID, fileID;
- int nlevs, gridID, gridsize;
- off_t recpos, currentfilepos;
- int header[8];
- int tsid;
- int recID;
- int i;
- double missval;
void *srvp = streamptr->record->exsep;
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
- nlevs = streamptr->vars[varID].recordTable[0].nlevs;
- missval = vlistInqVarMissval(vlistID, varID);
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- tsid = streamptr->curTsID;
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d",
- nlevs, gridID, gridsize);
+ double missval = vlistInqVarMissval(vlistID, varID);
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ int tsid = streamptr->curTsID;
- currentfilepos = fileGetPos(fileID);
+ off_t currentfilepos = fileGetPos(fileID);
/* NOTE: tiles are not supported here! */
- recID = streamptr->vars[varID].recordTable[0].recordID[levID];
- recpos = streamptr->tsteps[tsid].records[recID].position;
+ int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+ off_t recpos = streamptr->tsteps[tsid].records[recID].position;
fileSetPos(fileID, recpos, SEEK_SET);
- if (srvRead(fileID, srvp) < 0)
- abort();
+ if ( srvRead(fileID, srvp) < 0 ) abort();
+ int header[8];
srvInqHeader(srvp, header);
srvInqDataDP(srvp, data);
fileSetPos(fileID, currentfilepos, SEEK_SET);
*nmiss = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -54145,105 +54179,39 @@ void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
- int fileID;
- int levID, nlevs, gridID, gridsize;
- int zaxisID;
- double level;
- int header[8];
- int xsize, ysize;
- int datatype;
- int tsID;
- int vlistID;
- int pdis, pcat, pnum;
- srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-
- if ( CDI_Debug )
- Message("streamID = %d varID = %d", streamptr->self, varID);
-
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- nlevs = zaxisInqSize(zaxisID);
-
- if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
- cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
-
- header[0] = pnum;
- header[2] = streamptr->tsteps[tsID].taxis.vdate;
- header[3] = streamptr->tsteps[tsID].taxis.vtime;
-
- xsize = gridInqXsize(gridID);
- ysize = gridInqYsize(gridID);
- if ( xsize == 0 || ysize == 0 )
- {
- xsize = gridInqSize(gridID);
- ysize = 1;
- }
- if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
- if ( gridInqSize(gridID) != xsize*ysize )
- Error("Internal problem with gridsize!");
-
- header[4] = xsize;
- header[5] = ysize;
- header[6] = 0;
- header[7] = 0;
-
- datatype = vlistInqVarDatatype(vlistID, varID);
-
- srvp->dprec = srvDefDatatype(datatype);
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
- for ( levID = 0; levID < nlevs; levID++ )
- {
- level = zaxisInqLevel(zaxisID, levID);
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
- header[1] = (int) level;
- srvDefHeader(srvp, header);
- srvDefDataDP(srvp, &data[levID*gridsize]);
- srvWrite(fileID, srvp);
- }
+ for ( size_t levID = 0; levID < nlevs; levID++)
+ srvReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
}
void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
{
- int fileID;
- int gridID;
- int zaxisID;
- double level;
- int header[8];
- int xsize, ysize;
- int datatype;
- int tsID;
- int vlistID;
- int pdis, pcat, pnum;
- srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+ if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
- vlistID = streamptr->vlistID;
- fileID = streamptr->fileID;
- tsID = streamptr->curTsID;
- gridID = vlistInqVarGrid(vlistID, varID);
- zaxisID = vlistInqVarZaxis(vlistID, varID);
- level = zaxisInqLevel(zaxisID, levID);
-
- if ( CDI_Debug )
- Message("gridID = %d zaxisID = %d", gridID, zaxisID);
+ int vlistID = streamptr->vlistID;
+ int fileID = streamptr->fileID;
+ int tsID = streamptr->curTsID;
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int pdis, pcat, pnum;
cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+ int header[8];
header[0] = pnum;
- header[1] = (int) level;
+ header[1] = (int)(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID));
header[2] = streamptr->tsteps[tsID].taxis.vdate;
header[3] = streamptr->tsteps[tsID].taxis.vtime;
- xsize = gridInqXsize(gridID);
- ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
if ( xsize == 0 || ysize == 0 )
{
xsize = gridInqSize(gridID);
@@ -54253,13 +54221,16 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
if ( gridInqSize(gridID) != xsize*ysize )
Error("Internal problem with gridsize!");
+ cdi_check_gridsize_int_limit("SERVICE", gridInqSize(gridID));
+
header[4] = xsize;
header[5] = ysize;
header[6] = 0;
header[7] = 0;
- datatype = vlistInqVarDatatype(vlistID, varID);
+ int datatype = vlistInqVarDatatype(vlistID, varID);
+ srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
srvp->dprec = srvDefDatatype(datatype);
srvDefHeader(srvp, header);
@@ -54267,7 +54238,21 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
srvWrite(fileID, srvp);
}
+
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
+{
+ if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
+
+ int vlistID = streamptr->vlistID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
+
+ for ( size_t levID = 0; levID < nlevs; levID++ )
+ srvWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
+}
+
#endif /* HAVE_LIBSERVICE */
+
/*
* Local Variables:
* c-file-style: "Java"
@@ -54280,8 +54265,6 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
#if defined (HAVE_CONFIG_H)
#endif
-#include <string.h>
-
@@ -54297,7 +54280,7 @@ static
void streamvar_init_entry(stream_t *streamptr, int varID)
{
streamptr->vars[varID].ncvarid = CDI_UNDEFID;
- streamptr->vars[varID].defmiss = 0;
+ streamptr->vars[varID].defmiss = false;
streamptr->vars[varID].subtypeSize = 0;
streamptr->vars[varID].recordTable = NULL;
@@ -54312,30 +54295,24 @@ static
int streamvar_new_entry(stream_t *streamptr)
{
int varID = 0;
- int streamvarSize;
- svarinfo_t *streamvar;
-
- streamvarSize = streamptr->varsAllocated;
- streamvar = streamptr->vars;
+ int streamvarSize = streamptr->varsAllocated;
+ svarinfo_t *streamvar = streamptr->vars;
/*
Look for a free slot in streamvar.
(Create the table the first time through).
*/
if ( ! streamvarSize )
{
- int i;
-
streamvarSize = 2;
- streamvar
- = (svarinfo_t *) Malloc((size_t)streamvarSize * sizeof(svarinfo_t));
+ streamvar = (svarinfo_t *) Malloc((size_t)streamvarSize * sizeof(svarinfo_t));
if ( streamvar == NULL )
{
Message("streamvarSize = %d", streamvarSize);
SysError("Allocation of svarinfo_t failed");
}
- for ( i = 0; i < streamvarSize; i++ )
- streamvar[i].isUsed = FALSE;
+ for ( int i = 0; i < streamvarSize; i++ )
+ streamvar[i].isUsed = false;
}
else
{
@@ -54350,11 +54327,8 @@ int streamvar_new_entry(stream_t *streamptr)
*/
if ( varID == streamvarSize )
{
- int i;
-
streamvarSize = 2*streamvarSize;
- streamvar
- = (svarinfo_t *) Realloc(streamvar,
+ streamvar = (svarinfo_t *) Realloc(streamvar,
(size_t)streamvarSize * sizeof (svarinfo_t));
if ( streamvar == NULL )
{
@@ -54363,8 +54337,8 @@ int streamvar_new_entry(stream_t *streamptr)
}
varID = streamvarSize/2;
- for ( i = varID; i < streamvarSize; i++ )
- streamvar[i].isUsed = FALSE;
+ for ( int i = varID; i < streamvarSize; i++ )
+ streamvar[i].isUsed = false;
}
streamptr->varsAllocated = streamvarSize;
@@ -54372,8 +54346,9 @@ int streamvar_new_entry(stream_t *streamptr)
streamvar_init_entry(streamptr, varID);
- streamptr->vars[varID].isUsed = TRUE;
- return (varID);
+ streamptr->vars[varID].isUsed = true;
+
+ return varID;
}
@@ -54383,7 +54358,7 @@ allocate_record_table_entry(stream_t *streamptr, int varID, int subID, int nlevs
int *level = (int *) Malloc((size_t)nlevs * sizeof (int));
int *lindex = (int *) Malloc((size_t)nlevs * sizeof (int));
- for (int levID = 0; levID < nlevs; levID++ )
+ for ( int levID = 0; levID < nlevs; levID++ )
{
level[levID] = CDI_UNDEFID;
lindex[levID] = levID;
@@ -54428,7 +54403,7 @@ int stream_new_var(stream_t *streamptr, int gridID, int zaxisID, int tilesetID)
streamptr->vars[varID].subtypeID = tilesetID;
- return (varID);
+ return varID;
}
/*
* Local Variables:
@@ -54449,20 +54424,20 @@ int stream_new_var(stream_t *streamptr, int gridID, int zaxisID, int tilesetID)
static
size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int date, int time, int tsteptype, int numavg,
- size_t datasize, const void *data, int nmiss, void **gribbuffer,
+ size_t datasize, const void *data, size_t nmiss, void **gribbuffer,
int comptype, void *gribContainer)
{
size_t nbytes = 0;
#ifdef HAVE_LIBCGRIBEX
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
size_t gribbuffersize = datasize*4+3000;
*gribbuffer = Malloc(gribbuffersize);
nbytes = cgribexEncode(memtype, varID, levelID, vlistID, gridID, zaxisID,
date, time, tsteptype, numavg,
- (long) datasize, data, nmiss, *gribbuffer, gribbuffersize);
+ datasize, data, nmiss, *gribbuffer, gribbuffersize);
}
else
#endif
@@ -54483,7 +54458,7 @@ size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID,
(long) datasize, datap, nmiss, gribbuffer, &gribbuffersize,
comptype, gribContainer);
- if ( memtype == MEMTYPE_FLOAT ) free((void*)datap);
+ if ( memtype == MEMTYPE_FLOAT ) Free((void*)datap);
}
#else
{
@@ -54505,7 +54480,7 @@ size_t grbSzip(int filetype, void *gribbuffer, size_t gribbuffersize)
/* memcpy(buffer, gribbuffer, gribbuffersize); */
size_t nbytes = 0;
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
nbytes = (size_t)gribZip((unsigned char *)gribbuffer, (long) gribbuffersize, (unsigned char *)buffer, (long) buffersize);
}
@@ -54546,12 +54521,91 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
size_t nbytes = recsize;
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
- long unzipsize;
- int izip = gribGetZip((long)recsize, gribbuffer, &unzipsize);
+ if ( cdiGribChangeParameterID.active )
+ {
+ // Even if you are stream-copy records you might need to change a bit of grib-header !
+#if defined HAVE_LIBCGRIBEX
+ void *gh = cgribex_handle_new_from_meassage((void*) gribbuffer, recsize);
+ cgribexChangeParameterIdentification(gh, cdiGribChangeParameterID.code, cdiGribChangeParameterID.ltype, cdiGribChangeParameterID.lev);
+ cgribex_handle_delete(gh);
+#elif defined HAVE_LIBGRIB_API
+ void *gh = (void*)grib_handle_new_from_message(NULL, (void*) gribbuffer, recsize);
+ gribapiChangeParameterIdentification(gh, cdiGribChangeParameterID.code, cdiGribChangeParameterID.ltype, cdiGribChangeParameterID.lev);
+ grib_handle_delete(gh);
+#endif
+ cdiGribChangeParameterID.active = false; // after grib attributes have been changed turn it off again
+ }
+ }
+
+#ifdef HIRLAM_EXTENSIONS
+ // Even if you are stream-copy records you might need to change a bit of grib-header !
+
+ if ( cdiGribDataScanningMode.active )
+ // allowed modes: <0, 64, 96>; Default is 64
+ // This will overrule the old scanning mode of the given grid
+ {
+ grib_handle *gh = NULL;
+ gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
+
+ int scanModeIN = gribapiGetScanningMode(gh);
+
+ grib_handle_delete(gh);
+
+ if (cdiDebugExt>=20) Message("Change GribDataScanningMode => %d (scanModeIN = %d)", cdiGribDataScanningMode.value, scanModeIN);
+
+ if (scanModeIN != cdiGribDataScanningMode.value)
+ {
+ //int zip;
+ size_t nmiss = 0;
+
+ int vlistID = streamptr1->vlistID;
+ int varID = streamptr1->tsteps[tsID].records[recID].varID;
+ int levelID = streamptr1->tsteps[tsID].records[recID].levelID;
+ //gribbuffer = (unsigned char *) streamptr->record->buffer;
+ // allocate above ..
+ int gridID = vlistInqVarGrid(vlistID, varID);
+
+ size_t gridsize = vlistGridsizeMax(vlistID);
+ if ( vlistNumber(vlistID) != CDI_REAL ) gridsize *= 2;
+ double *data = (double *) malloc(gridsize*sizeof(double));
+ //int missval = vlistInqVarMissval(vlistID, varID);
+
+ //streamptr->numvals += gridsize;
+
+ // memtype: MEMTYPE_FLOAT or MEMTYPE_DOUBLE
+ //int statusDC = grbDecode(filetype, MEMTYPE_DOUBLE, gribbuffer, recsize, data, gridsize, streamptr1->unreduced, &nmiss, missval, vlistID, varID);
+ //int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *data, size_t datasize,
+ // int unreduced, size_t *nmiss, double missval, int vlistID, int varID);
+
+ //streamptr1->tsteps[tsID].records[recID].zip = zip;
+ //gribapiSetScanningMode(gh, cdoGribDataScanningMode); // T.B.D. this will be done by grbDecode..
+
+ //varID = streamptr1->record->varID;
+ //levelID = streamptr1->record->levelID;
+
+ if (cdiDebugExt>=20) Message(" processing varID %d; levelID %d",varID,levelID);
+
+ grb_write_var_slice(streamptr2, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+ //grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
- if ( izip == 0 && streamptr2->comptype == COMPRESS_SZIP )
+ //grb_write_var(streamptr2, varID, MEMTYPE_DOUBLE, data, nmiss);
+ //grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
+ //grb_write_var_slice(streamptr2, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+
+ free(data);
+ free(gribbuffer);
+ }
+ }
+#endif // HIRLAM_EXTENSIONS
+
+ if ( filetype == CDI_FILETYPE_GRB )
+ {
+ size_t unzipsize;
+ int izip = gribGetZip(recsize, gribbuffer, &unzipsize);
+
+ if ( izip == 0 && streamptr2->comptype == CDI_COMPRESS_SZIP )
nbytes = grbSzip(filetype, gribbuffer, nbytes);
}
@@ -54568,7 +54622,7 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
}
-void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
+void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
void *gribbuffer = NULL;
void *gc = NULL;
@@ -54583,17 +54637,15 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
int tsID = streamptr->curTsID;
int date = streamptr->tsteps[tsID].taxis.vdate;
int time = streamptr->tsteps[tsID].taxis.vtime;
- int numavg = 0;
- if ( vlistInqVarTimave(vlistID, varID) )
- numavg = streamptr->tsteps[tsID].taxis.numavg;
+ int numavg = (tsteptype == TSTEP_AVG) ? streamptr->tsteps[tsID].taxis.numavg : 0;
if ( CDI_Debug )
Message("gridID = %d zaxisID = %d", gridID, zaxisID);
- size_t datasize = (size_t)gridInqSize(gridID);
+ size_t datasize = gridInqSize(gridID);
#ifdef HAVE_LIBCGRIBEX
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
}
else
@@ -54608,9 +54660,9 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
#endif
}
- if ( comptype != COMPRESS_JPEG && comptype != COMPRESS_SZIP ) comptype = COMPRESS_NONE;
+ if ( comptype != CDI_COMPRESS_JPEG && comptype != CDI_COMPRESS_SZIP ) comptype = CDI_COMPRESS_NONE;
- if ( filetype == FILETYPE_GRB && comptype == COMPRESS_JPEG )
+ if ( filetype == CDI_FILETYPE_GRB && comptype == CDI_COMPRESS_JPEG )
{
static int ljpeg_warn = 1;
if ( ljpeg_warn ) Warning("JPEG compression of GRIB1 records not available!");
@@ -54620,11 +54672,10 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
size_t nbytes = grbEncode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
datasize, data, nmiss, &gribbuffer, comptype, gc);
- if ( filetype == FILETYPE_GRB && streamptr->comptype == COMPRESS_SZIP )
+ if ( filetype == CDI_FILETYPE_GRB && streamptr->comptype == CDI_COMPRESS_SZIP )
nbytes = grbSzip(filetype, gribbuffer, nbytes);
- size_t (*myFileWrite)(int fileID, const void *restrict buffer,
- size_t len, int tsID)
+ size_t (*myFileWrite)(int fileID, const void *restrict buffer, size_t len, int tsID)
= (size_t (*)(int, const void *restrict, size_t, int))
namespaceSwitchGet(NSSWITCH_FILE_WRITE).func;
size_t nwrite = myFileWrite(fileID, gribbuffer, nbytes, tsID);
@@ -54639,22 +54690,22 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
}
-void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
{
int vlistID = streamptr->vlistID,
gridID = vlistInqVarGrid(vlistID, varID),
- gridsize = gridInqSize(gridID),
zaxisID = vlistInqVarZaxis(vlistID, varID),
nlevs = zaxisInqSize(zaxisID);
+ size_t gridsize = gridInqSize(gridID);
double missval = vlistInqVarMissval(vlistID, varID);
- size_t chunkLen = (size_t)gridsize;
+ size_t chunkLen = gridsize;
if ( memtype == MEMTYPE_FLOAT )
for ( int levelID = 0; levelID < nlevs; levelID++ )
{
const float *restrict fdata = ((const float *)data)+levelID*gridsize;
- int nmiss_slice = 0;
+ size_t nmiss_slice = 0;
if ( nmiss )
for ( size_t i = 0; i < chunkLen; ++i )
nmiss_slice += DBL_IS_EQUAL(fdata[i], missval);
@@ -54666,7 +54717,7 @@ void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data
{
const double *restrict ddata = ((const double *)data)+levelID*gridsize;
- int nmiss_slice = 0;
+ size_t nmiss_slice = 0;
if ( nmiss )
for ( size_t i = 0; i < chunkLen; ++i )
nmiss_slice += DBL_IS_EQUAL(ddata[i], missval);
@@ -54676,7 +54727,7 @@ void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data
}
-void grb_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+void grb_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss)
{
int varID = streamptr->record->varID;
int levelID = streamptr->record->levelID;
@@ -54694,20 +54745,20 @@ void grb_write_record(stream_t *streamptr, int memtype, const void *data, int nm
static
-int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *data, size_t datasize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID)
+int grbDecode(int filetype, int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID)
{
int status = 0;
#if defined (HAVE_LIBCGRIBEX)
- if ( filetype == FILETYPE_GRB )
+ if ( filetype == CDI_FILETYPE_GRB )
{
#if defined (HAVE_LIBGRIB_API)
extern int cdiNAdditionalGRIBKeys;
if ( cdiNAdditionalGRIBKeys > 0 )
Error("CGRIBEX decode does not support reading of additional GRIB keys!");
#endif
- status = cgribexDecode(memtype, gribbuffer, gribsize, data, (long) datasize, unreduced, nmiss, missval);
+ status = cgribexDecode(memtype, gribbuffer, gribsize, data, datasize, unreduced, nmiss, missval);
}
else
#endif
@@ -54717,14 +54768,14 @@ int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *d
if ( memtype == MEMTYPE_FLOAT )
datap = Malloc(datasize*sizeof(double));
- status = gribapiDecode(gribbuffer, gribsize, datap, (long) datasize, unreduced, nmiss, missval, vlistID, varID);
+ status = gribapiDecode(gribbuffer, gribsize, datap, datasize, unreduced, nmiss, missval, vlistID, varID);
if ( memtype == MEMTYPE_FLOAT )
{
float *dataf = (float*) data;
double *datad = (double*) datap;
for ( size_t i = 0; i < datasize; ++i ) dataf[i] = (float) datad[i];
- free((void*)datap);
+ Free((void*)datap);
}
}
#else
@@ -54742,12 +54793,12 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
{
int zip = 0;
int izip;
- long unzipsize;
+ size_t unzipsize;
size_t igribsize = *gribsize;
size_t ogribsize = *gribsize;
- if ( (izip = gribGetZip((long)igribsize, (unsigned char *)gribbuffer, &unzipsize)) > 0 )
+ if ( (izip = gribGetZip(igribsize, (unsigned char *)gribbuffer, &unzipsize)) > 0 )
{
zip = izip;
if ( izip == 128 ) /* szip */
@@ -54755,10 +54806,10 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
unsigned char *itmpbuffer = NULL;
size_t itmpbuffersize = 0;
- if ( unzipsize < (long) igribsize )
+ if ( unzipsize < igribsize )
{
- fprintf(stderr, "Decompressed size smaller than compressed size (in %ld; out %ld)!\n", (long)igribsize, unzipsize);
- return (0);
+ fprintf(stderr, "Decompressed size smaller than compressed size (in %zu; out %zu)!\n", igribsize, unzipsize);
+ return 0;
}
if ( itmpbuffersize < igribsize )
@@ -54771,7 +54822,7 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
- ogribsize = (size_t)gribUnzip((unsigned char *)gribbuffer, unzipsize, itmpbuffer, (long)igribsize);
+ ogribsize = (size_t)gribUnzip((unsigned char *)gribbuffer, (long)unzipsize, itmpbuffer, (long)igribsize);
Free(itmpbuffer);
@@ -54789,7 +54840,7 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
}
-void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
+void grb_read_record(stream_t * streamptr, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -54805,7 +54856,7 @@ void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
int varID = streamptr->tsteps[tsID].records[recID].varID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
streamptr->numvals += gridsize;
@@ -54818,11 +54869,11 @@ void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, data, (size_t)gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+ grbDecode(filetype, memtype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
}
-void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int *nmiss)
+void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -54833,14 +54884,14 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
int tsID = streamptr->curTsID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
off_t currentfilepos = fileGetPos(fileID);
int isub = subtypeInqActiveIndex(streamptr->vars[varID].subtypeID);
int nlevs = streamptr->vars[varID].recordTable[0].nlevs;
if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+ Message("nlevs = %d gridID = %d gridsize = %zu", nlevs, gridID, gridsize);
*nmiss = 0;
for (int levelID = 0; levelID < nlevs; levelID++ )
{
@@ -54854,7 +54905,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
double missval = vlistInqVarMissval(vlistID, varID);
- int imiss;
+ size_t imiss;
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
@@ -54864,7 +54915,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
else
datap = (double*)data + levelID*gridsize;
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, datap, (size_t)gridsize,
+ grbDecode(filetype, memtype, gribbuffer, recsize, datap, gridsize,
streamptr->unreduced, &imiss, missval, vlistID, varID);
*nmiss += imiss;
@@ -54874,7 +54925,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
}
-void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss)
+void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -54882,11 +54933,11 @@ void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
int vlistID = streamptr->vlistID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
int tsID = streamptr->curTsID;
if ( CDI_Debug )
- Message("gridID = %d gridsize = %d", gridID, gridsize);
+ Message("gridID = %d gridsize = %zu", gridID, gridsize);
int fileID = streamptr->fileID;
@@ -54908,26 +54959,54 @@ void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
double missval = vlistInqVarMissval(vlistID, varID);
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, data, (size_t)gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+ grbDecode(filetype, memtype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
fileSetPos(fileID, currentfilepos, SEEK_SET);
}
#endif
+#ifndef VLIST_VAR_H
+#define VLIST_VAR_H
+
#ifdef HAVE_CONFIG_H
#endif
-#ifdef HAVE_LIBNETCDF
+#ifndef _VLIST_H
+#endif
+
+int vlistVarGetPackSize(vlist_t *p, int varID, void *context);
+void vlistVarPack(vlist_t *p, int varID,
+ char * buffer, int bufferSize, int * pos, void *context);
+void vlistVarUnpack(int vlistID,
+ char * buf, int size, int *position, int, void *context);
+int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB);
+void vlistDefVarIOrank ( int, int, int );
+int vlistInqVarIOrank ( int, int );
+
+void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
+const char *vlistInqVarNamePtr(int vlistID, int varID);
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
+#endif
+
+#ifdef HAVE_LIBNETCDF
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
{
-#if defined (HAVE_NETCDF4)
+#if defined(HAVE_NETCDF4)
int retval;
/* Set chunking, shuffle, and deflate. */
int shuffle = 1;
@@ -54935,56 +55014,55 @@ void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
if ( deflate_level < 1 || deflate_level > 9 ) deflate_level = 1;
- if ((retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)))
+ if ( (retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)) )
{
Error("nc_def_var_deflate failed, status = %d", retval);
}
#else
-
- static int lwarn = TRUE;
+ static bool lwarn = true;
if ( lwarn )
{
- lwarn = FALSE;
+ lwarn = false;
Warning("Deflate compression failed, NetCDF4 not available!");
}
#endif
}
-static
+
int cdfDefDatatype(int datatype, int filetype)
{
int xtype = NC_FLOAT;
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
Error("CDI/NetCDF library does not support complex numbers!");
- if ( filetype == FILETYPE_NC4 )
+ if ( filetype == CDI_FILETYPE_NC4 )
{
- if ( datatype == DATATYPE_INT8 ) xtype = NC_BYTE;
- else if ( datatype == DATATYPE_INT16 ) xtype = NC_SHORT;
- else if ( datatype == DATATYPE_INT32 ) xtype = NC_INT;
+ if ( datatype == CDI_DATATYPE_INT8 ) xtype = NC_BYTE;
+ else if ( datatype == CDI_DATATYPE_INT16 ) xtype = NC_SHORT;
+ else if ( datatype == CDI_DATATYPE_INT32 ) xtype = NC_INT;
#if defined (HAVE_NETCDF4)
- else if ( datatype == DATATYPE_UINT8 ) xtype = NC_UBYTE;
- else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
- else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
+ else if ( datatype == CDI_DATATYPE_UINT8 ) xtype = NC_UBYTE;
+ else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_USHORT;
+ else if ( datatype == CDI_DATATYPE_UINT32 ) xtype = NC_UINT;
#else
- else if ( datatype == DATATYPE_UINT8 ) xtype = NC_SHORT;
- else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
- else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
+ else if ( datatype == CDI_DATATYPE_UINT8 ) xtype = NC_SHORT;
+ else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_INT;
+ else if ( datatype == CDI_DATATYPE_UINT32 ) xtype = NC_INT;
#endif
- else if ( datatype == DATATYPE_FLT64 ) xtype = NC_DOUBLE;
- else xtype = NC_FLOAT;
+ else if ( datatype == CDI_DATATYPE_FLT64 ) xtype = NC_DOUBLE;
+ else xtype = NC_FLOAT;
}
else
{
- if ( datatype == DATATYPE_INT8 ) xtype = NC_BYTE;
- else if ( datatype == DATATYPE_INT16 ) xtype = NC_SHORT;
- else if ( datatype == DATATYPE_INT32 ) xtype = NC_INT;
- else if ( datatype == DATATYPE_UINT8 ) xtype = NC_SHORT;
- else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
- else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
- else if ( datatype == DATATYPE_FLT64 ) xtype = NC_DOUBLE;
- else xtype = NC_FLOAT;
+ if ( datatype == CDI_DATATYPE_INT8 ) xtype = NC_BYTE;
+ else if ( datatype == CDI_DATATYPE_INT16 ) xtype = NC_SHORT;
+ else if ( datatype == CDI_DATATYPE_INT32 ) xtype = NC_INT;
+ else if ( datatype == CDI_DATATYPE_UINT8 ) xtype = NC_SHORT;
+ else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_INT;
+ else if ( datatype == CDI_DATATYPE_UINT32 ) xtype = NC_INT;
+ else if ( datatype == CDI_DATATYPE_FLT64 ) xtype = NC_DOUBLE;
+ else xtype = NC_FLOAT;
}
return xtype;
@@ -54993,7 +55071,7 @@ int cdfDefDatatype(int datatype, int filetype)
static
void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
{
- if ( streamptr->vars[varID].defmiss == FALSE )
+ if ( streamptr->vars[varID].defmiss == false )
{
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
@@ -55006,12 +55084,18 @@ void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
- cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+ if ( lcheck == 0 ||
+ streamptr->ncmode != 2 ||
+ streamptr->filetype == CDI_FILETYPE_NC ||
+ streamptr->filetype == CDI_FILETYPE_NC2||
+ streamptr->filetype == CDI_FILETYPE_NC5 )
+ cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+
cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
- streamptr->vars[varID].defmiss = TRUE;
+ streamptr->vars[varID].defmiss = true;
}
}
@@ -55022,7 +55106,7 @@ void cdfDefInstitut(stream_t *streamptr)
int fileID = streamptr->fileID;
int instID = vlistInqInstitut(vlistID);
- if ( instID != UNDEFID )
+ if ( instID != CDI_UNDEFID )
{
const char *longname = institutInqLongnamePtr(instID);
if ( longname )
@@ -55045,7 +55129,7 @@ void cdfDefSource(stream_t *streamptr)
int fileID = streamptr->fileID;
int modelID = vlistInqModel(vlistID);
- if ( modelID != UNDEFID )
+ if ( modelID != CDI_UNDEFID )
{
const char *longname = modelInqNamePtr(modelID);
if ( longname )
@@ -55064,7 +55148,7 @@ void cdfDefSource(stream_t *streamptr)
static inline
void *resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
{
- if (reqSize > *bufSize)
+ if ( reqSize > *bufSize )
{
*buf = Realloc(*buf, reqSize);
*bufSize = reqSize;
@@ -55072,8 +55156,8 @@ void *resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
return *buf;
}
-static
-void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID)
+
+void cdfDefineAttributes(int cdiID, int varID, int fileID, int ncvarID)
{
int atttype, attlen;
size_t len;
@@ -55082,37 +55166,47 @@ void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID)
size_t attBufSize = 0;
int natts;
- vlistInqNatts(vlistID, varID, &natts);
+ cdiInqNatts(cdiID, varID, &natts);
- for ( int iatt = 0; iatt < natts; iatt++ )
+ for ( int iatt = 0; iatt < natts; ++iatt )
{
- vlistInqAtt(vlistID, varID, iatt, attname, &atttype, &attlen);
+ cdiInqAtt(cdiID, varID, iatt, attname, &atttype, &attlen);
if ( attlen == 0 ) continue;
- if ( atttype == DATATYPE_TXT )
+ if ( atttype == CDI_DATATYPE_TXT )
{
size_t attSize = (size_t)attlen*sizeof(char);
char *atttxt = (char *)resizeBuf(&attBuf, &attBufSize, attSize);
- vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
+ cdiInqAttTxt(cdiID, varID, attname, attlen, atttxt);
len = (size_t)attlen;
cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
}
- else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
+ else if ( atttype == CDI_DATATYPE_INT8 || atttype == CDI_DATATYPE_UINT8 ||
+ atttype == CDI_DATATYPE_INT16 || atttype == CDI_DATATYPE_UINT16 ||
+ atttype == CDI_DATATYPE_INT32 || atttype == CDI_DATATYPE_UINT32 )
{
size_t attSize = (size_t)attlen*sizeof(int);
int *attint = (int *)resizeBuf(&attBuf, &attBufSize, attSize);
- vlistInqAttInt(vlistID, varID, attname, attlen, &attint[0]);
+ cdiInqAttInt(cdiID, varID, attname, attlen, &attint[0]);
len = (size_t)attlen;
- cdf_put_att_int(fileID, ncvarID, attname, atttype == DATATYPE_INT16 ? NC_SHORT : NC_INT, len, attint);
+ nc_type xtype = (atttype == CDI_DATATYPE_INT8) ? NC_BYTE :
+ (atttype == CDI_DATATYPE_INT16) ? NC_SHORT :
+#if defined (HAVE_NETCDF4)
+ (atttype == CDI_DATATYPE_UINT8) ? NC_UBYTE :
+ (atttype == CDI_DATATYPE_UINT16) ? NC_USHORT :
+ (atttype == CDI_DATATYPE_UINT32) ? NC_UINT :
+#endif
+ NC_INT;
+ cdf_put_att_int(fileID, ncvarID, attname, xtype, len, attint);
}
- else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
+ else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
{
size_t attSize = (size_t)attlen * sizeof(double);
double *attflt = (double *)resizeBuf(&attBuf, &attBufSize, attSize);
- vlistInqAttFlt(vlistID, varID, attname, attlen, attflt);
+ cdiInqAttFlt(cdiID, varID, attname, attlen, attflt);
len = (size_t)attlen;
- if ( atttype == DATATYPE_FLT32 )
+ if ( atttype == CDI_DATATYPE_FLT32 )
{
float attflt_sp[len];
for ( size_t i = 0; i < len; ++i ) attflt_sp[i] = (float)attflt[i];
@@ -55122,7 +55216,7 @@ void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID)
cdf_put_att_double(fileID, ncvarID, attname, NC_DOUBLE, len, attflt);
}
}
-
+
Free(attBuf);
}
@@ -55138,7 +55232,7 @@ void cdfDefGlobalAtts(stream_t *streamptr)
cdfDefInstitut(streamptr);
int natts;
- vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
+ cdiInqNatts(vlistID, CDI_GLOBAL, &natts);
if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
@@ -55156,7 +55250,7 @@ void cdfDefLocalAtts(stream_t *streamptr)
int fileID = streamptr->fileID;
if ( streamptr->localatts ) return;
- if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
+ if ( vlistInqInstitut(vlistID) != CDI_UNDEFID ) return;
streamptr->localatts = 1;
@@ -55165,7 +55259,7 @@ void cdfDefLocalAtts(stream_t *streamptr)
for ( int varID = 0; varID < streamptr->nvars; varID++ )
{
int instID = vlistInqVarInstitut(vlistID, varID);
- if ( instID != UNDEFID )
+ if ( instID != CDI_UNDEFID )
{
int ncvarid = streamptr->vars[varID].ncvarid;
const char *name = institutInqNamePtr(instID);
@@ -55181,14 +55275,47 @@ void cdfDefLocalAtts(stream_t *streamptr)
}
static
+void cdf_get_gmapvarname(int gridID, char *gmapvarname)
+{
+ int pgridID = gridID;
+ char mapping[CDI_MAX_NAME]; mapping[0] = 0;
+ cdiGridInqKeyStr(pgridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+
+ if ( !mapping[0] )
+ {
+ int projID = gridInqProj(gridID);
+ if ( projID != CDI_UNDEFID )
+ {
+ pgridID = projID;
+ cdiGridInqKeyStr(pgridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
+ }
+ }
+
+ if ( mapping[0] )
+ cdiGridInqKeyStr(pgridID, CDI_KEY_MAPPING, CDI_MAX_NAME, gmapvarname);
+}
+
+static
+int nc_grid_index(stream_t *streamptr, int gridID)
+{
+ int index = 0;
+ int vlistID = streamptr->vlistID;
+ int ngrids = vlistNgrids(vlistID);
+ for ( index = 0; index < ngrids; ++index )
+ if ( streamptr->ncgrid[index].gridID == gridID ) break;
+
+ assert(index < ngrids);
+
+ return index;
+}
+
+static
int cdfDefVar(stream_t *streamptr, int varID)
{
int ncvarid = -1;
- int xid = UNDEFID, yid = UNDEFID;
+ int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
size_t xsize = 0, ysize = 0;
- char varname[CDI_MAX_NAME];
int dims[4];
- int lchunk = FALSE;
size_t chunks[4] = {0,0,0,0};
int ndims = 0;
int tablenum;
@@ -55196,22 +55323,21 @@ int cdfDefVar(stream_t *streamptr, int varID)
size_t iax = 0;
char axis[5];
int ensID, ensCount, forecast_type;
- int retval;
int fileID = streamptr->fileID;
if ( CDI_Debug )
Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
- if ( streamptr->vars[varID].ncvarid != UNDEFID )
+ if ( streamptr->vars[varID].ncvarid != CDI_UNDEFID )
return streamptr->vars[varID].ncvarid;
- int vlistID = streamptr->vlistID;
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
- int code = vlistInqVarCode(vlistID, varID);
- int param = vlistInqVarParam(vlistID, varID);
+ int vlistID = streamptr->vlistID;
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int timetype = vlistInqVarTimetype(vlistID, varID);
+ int code = vlistInqVarCode(vlistID, varID);
+ int param = vlistInqVarParam(vlistID, varID);
int pnum, pcat, pdis;
cdiDecodeParam(param, &pnum, &pcat, &pdis);
@@ -55219,26 +55345,26 @@ int cdfDefVar(stream_t *streamptr, int varID)
vlistInqVarDimorder(vlistID, varID, &dimorder);
- int gridsize = gridInqSize(gridID);
- if ( gridsize > 1 ) lchunk = TRUE;
+ size_t gridsize = gridInqSize(gridID);
+ bool lchunk = (gridsize >= 16);
int gridtype = gridInqType(gridID);
- int gridindex = vlistGridIndex(vlistID, gridID);
+ int gridindex = nc_grid_index(streamptr, gridID);
if ( gridtype != GRID_TRAJECTORY )
{
- xid = streamptr->xdimID[gridindex];
- yid = streamptr->ydimID[gridindex];
- if ( xid != UNDEFID ) cdf_inq_dimlen(fileID, xid, &xsize);
- if ( yid != UNDEFID ) cdf_inq_dimlen(fileID, yid, &ysize);
+ xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+ if ( xid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, xid, &xsize);
+ if ( yid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, yid, &ysize);
}
int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
int zid = streamptr->zaxisID[zaxisindex];
- int zaxis_is_scalar = FALSE;
- if ( zid == UNDEFID ) zaxis_is_scalar = zaxisInqScalar(zaxisID);
+ bool zaxis_is_scalar = false;
+ if ( zid == CDI_UNDEFID ) zaxis_is_scalar = zaxisInqScalar(zaxisID) > 0;
- if ( dimorder[0] != 3 ) lchunk = FALSE; /* ZYX and ZXY */
+ if ( dimorder[0] != 3 ) lchunk = false; /* ZYX and ZXY */
- if ( ((dimorder[0]>0)+(dimorder[1]>0)+(dimorder[2]>0)) < ((xid!=UNDEFID)+(yid!=UNDEFID)+(zid!=UNDEFID)) )
+ if ( ((dimorder[0]>0)+(dimorder[1]>0)+(dimorder[2]>0)) < ((xid!=CDI_UNDEFID)+(yid!=CDI_UNDEFID)+(zid!=CDI_UNDEFID)) )
{
printf("zid=%d yid=%d xid=%d\n", zid, yid, xid);
Error("Internal problem, dimension order missing!");
@@ -55246,45 +55372,49 @@ int cdfDefVar(stream_t *streamptr, int varID)
int tid = streamptr->basetime.ncdimid;
- if ( tsteptype != TSTEP_CONSTANT )
+ if ( vlistHasTime(vlistID) && timetype != TIME_CONSTANT )
{
- if ( tid == UNDEFID ) Error("Internal problem, time undefined!");
+ if ( tid == CDI_UNDEFID ) Error("Internal problem, time undefined!");
chunks[ndims] = 1;
dims[ndims++] = tid;
axis[iax++] = 'T';
}
/*
- if ( zid != UNDEFID ) axis[iax++] = 'Z';
- if ( zid != UNDEFID ) chunks[ndims] = 1;
- if ( zid != UNDEFID ) dims[ndims++] = zid;
+ if ( zid != CDI_UNDEFID ) axis[iax++] = 'Z';
+ if ( zid != CDI_UNDEFID ) chunks[ndims] = 1;
+ if ( zid != CDI_UNDEFID ) dims[ndims++] = zid;
- if ( yid != UNDEFID ) chunks[ndims] = ysize;
- if ( yid != UNDEFID ) dims[ndims++] = yid;
+ if ( yid != CDI_UNDEFID ) chunks[ndims] = ysize;
+ if ( yid != CDI_UNDEFID ) dims[ndims++] = yid;
- if ( xid != UNDEFID ) chunks[ndims] = xsize;
- if ( xid != UNDEFID ) dims[ndims++] = xid;
+ if ( xid != CDI_UNDEFID ) chunks[ndims] = xsize;
+ if ( xid != CDI_UNDEFID ) dims[ndims++] = xid;
*/
+ size_t chunk_size_max = 65536;
for ( int id = 0; id < 3; ++id )
{
- if ( dimorder[id] == 3 && zid != UNDEFID )
+ if ( dimorder[id] == 3 && zid != CDI_UNDEFID )
{
axis[iax++] = 'Z';
chunks[ndims] = 1;
dims[ndims] = zid;
ndims++;
}
- else if ( dimorder[id] == 2 && yid != UNDEFID )
+ else if ( dimorder[id] == 2 && yid != CDI_UNDEFID )
{
- if ( chunktype == CHUNK_LINES )
- chunks[ndims] = 1;
+ if ( chunktype == CDI_CHUNK_AUTO )
+ chunks[ndims] = (chunk_size_max > gridsize) ? ysize : chunk_size_max/xsize;
else
- chunks[ndims] = ysize;
+ chunks[ndims] = (chunktype == CDI_CHUNK_LINES) ? 1 : ysize;
dims[ndims] = yid;
ndims++;
}
- else if ( dimorder[id] == 1 && xid != UNDEFID )
+ else if ( dimorder[id] == 1 && xid != CDI_UNDEFID )
{
- chunks[ndims] = xsize;
+ if ( chunktype == CDI_CHUNK_AUTO && yid == CDI_UNDEFID )
+ chunks[ndims] = (chunk_size_max > xsize) ? xsize : chunk_size_max;
+ else
+ chunks[ndims] = xsize;
dims[ndims] = xid;
ndims++;
}
@@ -55293,36 +55423,31 @@ int cdfDefVar(stream_t *streamptr, int varID)
if ( CDI_Debug )
fprintf(stderr, "chunktype %d chunks %d %d %d %d\n", chunktype, (int)chunks[0], (int)chunks[1], (int)chunks[2], (int)chunks[3]);
- int tableID = vlistInqVarTable(vlistID, varID);
-
- const char *name = vlistInqVarNamePtr(vlistID, varID);
- const char *longname = vlistInqVarLongnamePtr(vlistID, varID);
- const char *stdname = vlistInqVarStdnamePtr(vlistID, varID);
- const char *units = vlistInqVarUnitsPtr(vlistID, varID);
+ char varname[CDI_MAX_NAME];
+ char name[CDI_MAX_NAME]; name[0] = 0;
+ char longname[CDI_MAX_NAME]; longname[0] = 0;
+ char stdname[CDI_MAX_NAME]; stdname[0] = 0;
+ char units[CDI_MAX_NAME]; units[0] = 0;
+ if ( vlistInqVarNamePtr(vlistID, varID) ) vlistInqVarName(vlistID, varID, name);
+ vlistInqVarLongname(vlistID, varID, longname);
+ vlistInqVarStdname(vlistID, varID, stdname);
+ vlistInqVarUnits(vlistID, varID, units);
- if ( name == NULL ) name = tableInqParNamePtr(tableID, code);
- if ( longname == NULL ) longname = tableInqParLongnamePtr(tableID, code);
- if ( units == NULL ) units = tableInqParUnitsPtr(tableID, code);
- if ( name )
+ int tableID = vlistInqVarTable(vlistID, varID);
+ if ( !name[0] ) tableInqEntry(tableID, code, -1, name, longname, units);
+ if ( name[0] )
{
- int checkname;
- int iz;
- int status;
-
sprintf(varname, "%s", name);
- checkname = TRUE;
- iz = 0;
+ bool checkname = true;
+ int iz = 0;
while ( checkname )
{
if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
- status = nc_inq_varid(fileID, varname, &ncvarid);
- if ( status != NC_NOERR )
- {
- checkname = FALSE;
- }
+ int status = nc_inq_varid(fileID, varname, &ncvarid);
+ if ( status != NC_NOERR ) checkname = false;
if ( checkname ) iz++;
@@ -55337,7 +55462,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
Warning("Changed multiple entry of variable name '%s' to '%s'!", name, varname);
}
- name = varname;
+ strcpy(name, varname);
}
else
{
@@ -55351,7 +55476,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
char *varname2 = varname+strlen(varname);
- int checkname = TRUE;
+ bool checkname = true;
int iz = 0;
while ( checkname )
@@ -55359,14 +55484,14 @@ int cdfDefVar(stream_t *streamptr, int varID)
if ( iz ) sprintf(varname2, "_%d", iz+1);
int status = nc_inq_varid(fileID, varname, &ncvarid);
- if ( status != NC_NOERR ) checkname = FALSE;
+ if ( status != NC_NOERR ) checkname = false;
if ( checkname ) iz++;
if ( iz >= CDI_MAX_NAME ) break;
}
- name = varname;
+ strcpy(name, varname);
code = 0;
pdis = 255;
}
@@ -55379,20 +55504,13 @@ int cdfDefVar(stream_t *streamptr, int varID)
cdf_def_var(fileID, name, (nc_type) xtype, ndims, dims, &ncvarid);
#if defined (HAVE_NETCDF4)
- if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
- {
- if ( chunktype == CHUNK_AUTO )
- retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
- else
- retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks);
-
- if ( retval ) Error("nc_def_var_chunking failed, status = %d", retval);
- }
+ if ( lchunk && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C) )
+ cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks);
#endif
- if ( streamptr->comptype == COMPRESS_ZIP )
+ if ( streamptr->comptype == CDI_COMPRESS_ZIP )
{
- if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
+ if ( lchunk && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C) )
{
cdfDefVarDeflate(fileID, ncvarid, streamptr->complevel);
}
@@ -55400,53 +55518,19 @@ int cdfDefVar(stream_t *streamptr, int varID)
{
if ( lchunk )
{
- static int lwarn = TRUE;
-
+ static bool lwarn = true;
if ( lwarn )
{
- lwarn = FALSE;
+ lwarn = false;
Warning("Deflate compression is only available for NetCDF4!");
}
}
}
}
- if ( streamptr->comptype == COMPRESS_SZIP )
- {
- if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
- {
-#if defined (NC_SZIP_NN_OPTION_MASK)
- cdfDefVarSzip(fileID, ncvarid);
-#else
- static int lwarn = TRUE;
-
- if ( lwarn )
- {
- lwarn = FALSE;
- Warning("NetCDF4/SZIP compression not available!");
- }
-#endif
- }
- else
- {
- static int lwarn = TRUE;
-
- if ( lwarn )
- {
- lwarn = FALSE;
- Warning("SZIP compression is only available for NetCDF4!");
- }
- }
- }
-
- if ( stdname && *stdname )
- cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(stdname), stdname);
-
- if ( longname && *longname )
- cdf_put_att_text(fileID, ncvarid, "long_name", strlen(longname), longname);
-
- if ( units && *units )
- cdf_put_att_text(fileID, ncvarid, "units", strlen(units), units);
+ if ( *stdname ) cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(stdname), stdname);
+ if ( *longname ) cdf_put_att_text(fileID, ncvarid, "long_name", strlen(longname), longname);
+ if ( *units ) cdf_put_att_text(fileID, ncvarid, "units", strlen(units), units);
if ( code > 0 && pdis == 255 )
cdf_put_att_int(fileID, ncvarid, "code", NC_INT, 1, &code);
@@ -55458,17 +55542,16 @@ int cdfDefVar(stream_t *streamptr, int varID)
cdf_put_att_text(fileID, ncvarid, "param", strlen(paramstr), paramstr);
}
- if ( tableID != UNDEFID )
+ if ( tableID != CDI_UNDEFID )
{
tablenum = tableInqNum(tableID);
if ( tablenum > 0 )
cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
}
- char coordinates[CDI_MAX_NAME];
- coordinates[0] = 0;
+ char coordinates[CDI_MAX_NAME]; coordinates[0] = 0;
- if ( zaxis_is_scalar )
+ if ( zaxis_is_scalar || zaxisInqType(zaxisID) == ZAXIS_CHAR )
{
int nczvarID = streamptr->nczvarID[zaxisindex];
if ( nczvarID != CDI_UNDEFID )
@@ -55479,42 +55562,28 @@ int cdfDefVar(stream_t *streamptr, int varID)
}
}
- if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT && gridtype != GRID_CURVILINEAR )
+ if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT && gridtype != GRID_GAUSSIAN &&
+ gridtype != GRID_PROJECTION && gridtype != GRID_CURVILINEAR && gridtype != GRID_CHARXY )
{
size_t len = strlen(gridNamePtr(gridtype));
if ( len > 0 )
- cdf_put_att_text(fileID, ncvarid, "grid_type", len, gridNamePtr(gridtype));
+ cdf_put_att_text(fileID, ncvarid, "CDI_grid_type", len, gridNamePtr(gridtype));
}
- if ( gridIsRotated(gridID) )
- {
- char mapping[] = "rotated_pole";
- cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
- }
+ char gmapvarname[CDI_MAX_NAME]; gmapvarname[0] = 0;
- if ( gridtype == GRID_SINUSOIDAL )
- {
- char mapping[] = "sinusoidal";
- cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
- }
- else if ( gridtype == GRID_LAEA )
- {
- char mapping[] = "laea";
- cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
- }
- else if ( gridtype == GRID_LCC2 )
- {
- char mapping[] = "Lambert_Conformal";
- cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
- }
- else if ( gridtype == GRID_TRAJECTORY )
+ cdf_get_gmapvarname(gridID, gmapvarname);
+
+ if ( gmapvarname[0] ) cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(gmapvarname), gmapvarname);
+
+ if ( gridtype == GRID_TRAJECTORY )
{
- cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "tlon tlat" );
+ cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "lon lat" );
}
- else if ( gridtype == GRID_LONLAT && xid == UNDEFID && yid == UNDEFID && gridsize == 1 )
+ else if ( gridtype == GRID_LONLAT && xid == CDI_UNDEFID && yid == CDI_UNDEFID && gridsize == 1 )
{
- int ncxvarID = streamptr->ncxvarID[gridindex];
- int ncyvarID = streamptr->ncyvarID[gridindex];
+ int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
+ int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
if ( ncyvarID != CDI_UNDEFID )
{
size_t len = strlen(coordinates);
@@ -55531,20 +55600,39 @@ int cdfDefVar(stream_t *streamptr, int varID)
else if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
{
char cellarea[CDI_MAX_NAME] = "area: ";
- int ncxvarID = streamptr->ncxvarID[gridindex];
- int ncyvarID = streamptr->ncyvarID[gridindex];
- int ncavarID = streamptr->ncavarID[gridindex];
- if ( ncyvarID != CDI_UNDEFID )
+ int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
+ int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
+ int ncavarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_A];
+ // CMOR order: coordinates = "lat lon"
+ if ( cdiCoordinatesLonLat )
{
- size_t len = strlen(coordinates);
- if ( len ) coordinates[len++] = ' ';
- cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+ if ( ncxvarID != CDI_UNDEFID )
+ {
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncxvarID, coordinates+len);
+ }
+ if ( ncyvarID != CDI_UNDEFID )
+ {
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+ }
}
- if ( ncxvarID != CDI_UNDEFID )
+ else
{
- size_t len = strlen(coordinates);
- if ( len ) coordinates[len++] = ' ';
- cdf_inq_varname(fileID, ncxvarID, coordinates+len);
+ if ( ncyvarID != CDI_UNDEFID )
+ {
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+ }
+ if ( ncxvarID != CDI_UNDEFID )
+ {
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncxvarID, coordinates+len);
+ }
}
if ( ncavarID != CDI_UNDEFID )
@@ -55570,20 +55658,35 @@ int cdfDefVar(stream_t *streamptr, int varID)
cdf_put_att_text(fileID, ncvarid, "axis", iax, axis);
cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1, &gridTruncation);
}
+ else if ( gridtype == GRID_CHARXY )
+ {
+ if ( gridInqXIsc(gridID) )
+ {
+ int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncxvarID, coordinates+len);
+ }
+ else if ( gridInqYIsc(gridID) )
+ {
+ int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
+ size_t len = strlen(coordinates);
+ if ( len ) coordinates[len++] = ' ';
+ cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+ }
+ }
size_t len = strlen(coordinates);
if ( len ) cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
/* if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) */
{
- int laddoffset, lscalefactor;
- double addoffset, scalefactor;
int astype = NC_DOUBLE;
- addoffset = vlistInqVarAddoffset(vlistID, varID);
- scalefactor = vlistInqVarScalefactor(vlistID, varID);
- laddoffset = IS_NOT_EQUAL(addoffset, 0);
- lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+ double addoffset = vlistInqVarAddoffset(vlistID, varID);
+ double scalefactor = vlistInqVarScalefactor(vlistID, varID);
+ bool laddoffset = IS_NOT_EQUAL(addoffset, 0);
+ bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
if ( laddoffset || lscalefactor )
{
@@ -55600,7 +55703,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
}
}
- if ( dtype == DATATYPE_UINT8 && xtype == NC_BYTE )
+ if ( dtype == CDI_DATATYPE_UINT8 && xtype == NC_BYTE )
{
int validrange[2] = {0, 255};
cdf_put_att_int(fileID, ncvarid, "valid_range", NC_SHORT, 2, validrange);
@@ -55639,14 +55742,6 @@ int cdfDefVar(stream_t *streamptr, int varID)
cdf_put_att_int(fileID, ncvarid, "realization", NC_INT, 1, &ensID);
cdf_put_att_int(fileID, ncvarid, "ensemble_members", NC_INT, 1, &ensCount);
cdf_put_att_int(fileID, ncvarid, "forecast_init_type", NC_INT, 1, &forecast_type);
-
-#ifdef DBG
- if( DBG )
- {
- fprintf( stderr, "cdfDefVar :\n EnsID %d\n Enscount %d\n Forecast init type %d\n", ensID,
- ensCount, forecast_type );
- }
-#endif
}
/* Attributes */
@@ -55687,25 +55782,23 @@ void cdfEndDef(stream_t *streamptr)
static
void cdfWriteGridTraj(stream_t *streamptr, int gridID)
{
- int vlistID = streamptr->vlistID;
- int fileID = streamptr->fileID;
-
- int gridindex = vlistGridIndex(vlistID, gridID);
- int lonID = streamptr->xdimID[gridindex];
- int latID = streamptr->ydimID[gridindex];
+ int gridindex = nc_grid_index(streamptr, gridID);
+ int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
double xlon = gridInqXval(gridID, 0);
double xlat = gridInqYval(gridID, 0);
int tsID = streamptr->curTsID;
size_t index = (size_t)tsID;
+ int fileID = streamptr->fileID;
cdf_put_var1_double(fileID, lonID, &index, &xlon);
cdf_put_var1_double(fileID, latID, &index, &xlat);
}
static
void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, size_t nvals, size_t xsize, size_t ysize,
- int swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
+ bool swapxy, size_t *start, size_t *count, int memtype, const void *data, size_t nmiss)
{
const double *pdata_dp = (const double *) data;
double *mdata_dp = NULL;
@@ -55714,7 +55807,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
float *mdata_sp = NULL;
float *sdata_sp = NULL;
- /* if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
+ /* if ( dtype == CDI_DATATYPE_INT8 || dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32 ) */
{
double missval = vlistInqVarMissval(vlistID, varID);
double addoffset = vlistInqVarAddoffset(vlistID, varID);
@@ -55782,8 +55875,8 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
}
}
- if ( dtype == DATATYPE_UINT8 || dtype == DATATYPE_INT8 ||
- dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 )
+ if ( dtype == CDI_DATATYPE_UINT8 || dtype == CDI_DATATYPE_INT8 ||
+ dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32 )
{
if ( memtype == MEMTYPE_FLOAT )
{
@@ -55796,7 +55889,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
for ( size_t i = 0; i < nvals; i++ ) mdata_sp[i] = roundf(mdata_sp[i]);
- if ( dtype == DATATYPE_UINT8 )
+ if ( dtype == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -55818,7 +55911,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
for ( size_t i = 0; i < nvals; i++ ) mdata_dp[i] = round(mdata_dp[i]);
- if ( dtype == DATATYPE_UINT8 )
+ if ( dtype == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -55833,9 +55926,8 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
if ( CDF_Debug && memtype != MEMTYPE_FLOAT )
{
- double fmin, fmax;
- fmin = 1.0e200;
- fmax = -1.0e200;
+ double fmin = 1.0e200;
+ double fmax = -1.0e200;
for ( size_t i = 0; i < nvals; ++i )
{
if ( !DBL_IS_EQUAL(pdata_dp[i], missval) )
@@ -55849,7 +55941,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
}
}
- if ( swapxy ) // implemented only for cdf_write_var_slice()
+ if ( swapxy ) // implemented only for cdf_write_var_slice()
{
size_t gridsize = xsize*ysize;
if ( memtype == MEMTYPE_FLOAT )
@@ -55882,7 +55974,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
}
-void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
@@ -55890,9 +55982,8 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
size_t size;
size_t start[5];
size_t count[5];
- int swapxy = FALSE;
- int ndims = 0;
- int idim;
+ bool swapxy = false;
+ size_t ndims = 0;
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -55902,44 +55993,42 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
long ntsteps = streamptr->ntsteps;
if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
- if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
int ncvarid = cdfDefVar(streamptr, varID);
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int timetype = vlistInqVarTimetype(vlistID, varID);
- int xid = UNDEFID, yid = UNDEFID;
+ int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
if ( gridInqType(gridID) == GRID_TRAJECTORY )
{
cdfWriteGridTraj(streamptr, gridID);
}
else
{
- int gridindex = vlistGridIndex(vlistID, gridID);
- xid = streamptr->xdimID[gridindex];
- yid = streamptr->ydimID[gridindex];
+ int gridindex = nc_grid_index(streamptr, gridID);
+ xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
}
int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
int zid = streamptr->zaxisID[zaxisindex];
- if ( tsteptype != TSTEP_CONSTANT )
+ if ( timetype != TIME_CONSTANT )
{
start[ndims] = (size_t)ntsteps - 1;
count[ndims] = 1;
ndims++;
}
- if ( zid != UNDEFID )
+ if ( zid != CDI_UNDEFID )
{
start[ndims] = 0;
count[ndims] = (size_t)zaxisInqSize(zaxisID);
ndims++;
}
- if ( yid != UNDEFID )
+ if ( yid != CDI_UNDEFID )
{
start[ndims] = 0;
cdf_inq_dimlen(fileID, yid, &size);
@@ -55948,7 +56037,7 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
ndims++;
}
- if ( xid != UNDEFID )
+ if ( xid != CDI_UNDEFID )
{
start[ndims] = 0;
cdf_inq_dimlen(fileID, xid, &size);
@@ -55958,7 +56047,7 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
}
if ( CDI_Debug )
- for (idim = 0; idim < ndims; idim++)
+ for (size_t idim = 0; idim < ndims; idim++)
Message("dim = %d start = %d count = %d", idim, start[idim], count[idim]);
if ( streamptr->ncmode == 1 )
@@ -55971,24 +56060,23 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID)) * (size_t)(zaxisInqSize(zaxisID));
+ size_t nvals = gridInqSize(gridID) * (size_t)(zaxisInqSize(zaxisID));
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss)
+ const int rect[][2], const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
- int xid = UNDEFID, yid = UNDEFID;
+ int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
size_t xsize = 0, ysize = 0;
size_t start[5];
size_t count[5];
- int swapxy = FALSE;
- int ndims = 0;
- int idim;
+ bool swapxy = false;
+ size_t ndims = 0;
int streamID = streamptr->self;
if ( CDI_Debug )
@@ -55998,16 +56086,13 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
int fileID = streamInqFileID(streamID);
long ntsteps = streamptr->ntsteps;
- if ( CDI_Debug )
- Message("ntsteps = %ld", ntsteps);
-
- if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+ if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
int ncvarid = cdfDefVar(streamptr, varID);
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int timetype = vlistInqVarTimetype(vlistID, varID);
if ( gridInqType(gridID) == GRID_TRAJECTORY )
{
@@ -56015,21 +56100,21 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
}
else
{
- int gridindex = vlistGridIndex(vlistID, gridID);
- xid = streamptr->xdimID[gridindex];
- yid = streamptr->ydimID[gridindex];
+ int gridindex = nc_grid_index(streamptr, gridID);
+ xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
}
int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
int zid = streamptr->zaxisID[zaxisindex];
- if ( tsteptype != TSTEP_CONSTANT )
+ if ( timetype != TIME_CONSTANT )
{
start[ndims] = (size_t)ntsteps - 1;
count[ndims] = 1;
ndims++;
}
- if ( zid != UNDEFID )
+ if ( zid != CDI_UNDEFID )
{
int size = zaxisInqSize(zaxisID);
xassert(rect[2][0] >= 0 && rect[2][0] <= rect[2][1]
@@ -56038,7 +56123,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
count[ndims] = (size_t)rect[2][1] - (size_t)rect[2][0] + 1;
ndims++;
}
- if ( yid != UNDEFID )
+ if ( yid != CDI_UNDEFID )
{
size_t size;
cdf_inq_dimlen(fileID, yid, &size);
@@ -56048,7 +56133,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
count[ndims] = (size_t)rect[1][1] - (size_t)rect[1][0] + 1;
ndims++;
}
- if ( xid != UNDEFID )
+ if ( xid != CDI_UNDEFID )
{
size_t size;
cdf_inq_dimlen(fileID, xid, &size);
@@ -56060,7 +56145,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
}
if ( CDI_Debug )
- for (idim = 0; idim < ndims; idim++)
+ for (size_t idim = 0; idim < ndims; idim++)
Message("dim = %d start = %d count = %d", idim, start[idim], count[idim]);
if ( streamptr->ncmode == 1 )
@@ -56073,14 +56158,14 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID)) * (size_t)(zaxisInqSize(zaxisID));
+ size_t nvals = gridInqSize(gridID) * (size_t)(zaxisInqSize(zaxisID));
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals,
xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
-void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
+void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
@@ -56088,7 +56173,7 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
size_t start[5];
size_t count[5];
int dimorder[3];
- int xid = UNDEFID, yid = UNDEFID;
+ int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -56098,13 +56183,11 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
long ntsteps = streamptr->ntsteps;
if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
- if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
int ncvarid = cdfDefVar(streamptr, varID);
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int timetype = vlistInqVarTimetype(vlistID, varID);
vlistInqVarDimorder(vlistID, varID, &dimorder);
if ( gridInqType(gridID) == GRID_TRAJECTORY )
@@ -56113,18 +56196,18 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
}
else
{
- int gridindex = vlistGridIndex(vlistID, gridID);
- xid = streamptr->xdimID[gridindex];
- yid = streamptr->ydimID[gridindex];
+ int gridindex = nc_grid_index(streamptr, gridID);
+ xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
}
int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
int zid = streamptr->zaxisID[zaxisindex];
- int swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != UNDEFID && yid != UNDEFID;
+ bool swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != CDI_UNDEFID && yid != CDI_UNDEFID;
size_t ndims = 0;
- if ( tsteptype != TSTEP_CONSTANT )
+ if ( timetype != TIME_CONSTANT )
{
start[ndims] = (size_t)ntsteps - 1;
count[ndims] = 1;
@@ -56133,20 +56216,20 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
for ( int id = 0; id < 3; ++id )
{
- if ( dimorder[id] == 3 && zid != UNDEFID )
+ if ( dimorder[id] == 3 && zid != CDI_UNDEFID )
{
start[ndims] = (size_t)levelID;
count[ndims] = 1;
ndims++;
}
- else if ( dimorder[id] == 2 && yid != UNDEFID )
+ else if ( dimorder[id] == 2 && yid != CDI_UNDEFID )
{
start[ndims] = 0;
cdf_inq_dimlen(fileID, yid, &ysize);
count[ndims] = ysize;
ndims++;
}
- else if ( dimorder[id] == 1 && xid != UNDEFID )
+ else if ( dimorder[id] == 1 && xid != CDI_UNDEFID )
{
start[ndims] = 0;
cdf_inq_dimlen(fileID, xid, &xsize);
@@ -56163,13 +56246,13 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
- size_t nvals = (size_t)(gridInqSize(gridID));
+ size_t nvals = gridInqSize(gridID);
cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
}
-void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss)
{
int varID = streamptr->record->varID;
int levelID = streamptr->record->levelID;
@@ -56178,6 +56261,16 @@ void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nm
}
#endif
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
#ifdef HAVE_CONFIG_H
#endif
@@ -56188,10 +56281,6 @@ void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nm
-#undef UNDEFID
-#define UNDEFID CDI_UNDEFID
-
-
static
void cdfReadGridTraj(stream_t *streamptr, int gridID)
{
@@ -56199,8 +56288,8 @@ void cdfReadGridTraj(stream_t *streamptr, int gridID)
int fileID = streamptr->fileID;
int gridindex = vlistGridIndex(vlistID, gridID);
- int lonID = streamptr->xdimID[gridindex];
- int latID = streamptr->ydimID[gridindex];
+ int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
+ int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
int tsID = streamptr->curTsID;
size_t index = (size_t)tsID;
@@ -56218,22 +56307,22 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
{
int vlistID = streamptr->vlistID;
int tsID = streamptr->curTsID;
- int gridID = vlistInqVarGrid(vlistID, varID);
- int zaxisID = vlistInqVarZaxis(vlistID, varID);
- int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int timetype = vlistInqVarTimetype(vlistID, varID);
int gridindex = vlistGridIndex(vlistID, gridID);
if ( CDI_Debug ) Message("tsID = %d", tsID);
- int xid = UNDEFID, yid = UNDEFID;
+ int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
if ( gridInqType(gridID) == GRID_TRAJECTORY )
{
cdfReadGridTraj(streamptr, gridID);
}
else
{
- xid = streamptr->xdimID[gridindex];
- yid = streamptr->ydimID[gridindex];
+ xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
}
int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
int zid = streamptr->zaxisID[zaxisindex];
@@ -56245,10 +56334,10 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
(*count)[ndims] = length; \
ndims++; \
} while(0)
- if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
- if ( zid != UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
- if ( yid != UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
- if ( xid != UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
+ if ( timetype != TIME_CONSTANT ) addDimension((size_t)tsID, 1);
+ if ( zid != CDI_UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
+ if ( yid != CDI_UNDEFID ) addDimension(0, gridInqYsize(gridID));
+ if ( xid != CDI_UNDEFID ) addDimension(0, gridInqXsize(gridID));
#undef addDimension
assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
@@ -56486,18 +56575,12 @@ void transpose2dArrayDP(size_t inWidth, size_t inHeight, double *data)
*/
for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
- {
- for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
- {
- for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
- {
- for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
- {
- out[x][y] = temp[y][x];
- }
- }
- }
- }
+ for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
+ for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
+ for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
+ {
+ out[x][y] = temp[y][x];
+ }
Free(temp[0]);
}
@@ -56527,18 +56610,12 @@ void transpose2dArraySP(size_t inWidth, size_t inHeight, float *data)
*/
for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
- {
- for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
- {
- for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
- {
- for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
- {
- out[x][y] = temp[y][x];
- }
- }
- }
- }
+ for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
+ for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
+ for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
+ {
+ out[x][y] = temp[y][x];
+ }
Free(temp);
}
@@ -56549,7 +56626,7 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
int gridId = vlistInqVarGrid(streamptr->vlistID, varId);
int gridindex = vlistGridIndex(streamptr->vlistID, gridId);
- (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = UNDEFID;
+ (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = CDI_UNDEFID;
switch ( gridInqType(gridId) )
{
case GRID_TRAJECTORY:
@@ -56557,12 +56634,12 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
break;
case GRID_UNSTRUCTURED:
- (*outDimIds)[0] = streamptr->xdimID[gridindex];
+ (*outDimIds)[0] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
break;
default:
- (*outDimIds)[0] = streamptr->xdimID[gridindex];
- (*outDimIds)[1] = streamptr->ydimID[gridindex];
+ (*outDimIds)[0] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+ (*outDimIds)[1] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
break;
}
@@ -56574,8 +56651,8 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
static
int cdfGetSkipDim(int fileId, int ncvarid, int (*dimIds)[3])
{
- if((*dimIds)[0] != UNDEFID) return 0;
- if((*dimIds)[1] != UNDEFID) return 0;
+ if((*dimIds)[0] != CDI_UNDEFID) return 0;
+ if((*dimIds)[1] != CDI_UNDEFID) return 0;
int nvdims;
cdf_inq_varndims(fileId, ncvarid, &nvdims);
if(nvdims != 3) return 0;
@@ -56607,8 +56684,8 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
int ncvarid = streamptr->vars[varId].ncvarid;
int gridId = vlistInqVarGrid(vlistId, varId);
- int tsteptype = vlistInqVarTsteptype(vlistId, varId);
- int gridsize = gridInqSize(gridId);
+ int timetype = vlistInqVarTimetype(vlistId, varId);
+ size_t gridsize = gridInqSize(gridId);
streamptr->numvals += gridsize;
@@ -56620,7 +56697,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
int dimorder[3];
vlistInqVarDimorder(vlistId, varId, &dimorder);
- *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != UNDEFID && dimIds[1] != UNDEFID ;
+ *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != CDI_UNDEFID && dimIds[1] != CDI_UNDEFID ;
int ndims = 0;
@@ -56630,17 +56707,16 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
ndims++; \
} while(0)
- if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
+ if ( timetype != TIME_CONSTANT ) addDimension((size_t)tsID, 1);
if ( skipdim == 1 ) addDimension(0, 1);
for ( int id = 0; id < 3; ++id )
{
size_t size;
int curDimId = dimIds[dimorder[id]-1];
- if ( curDimId == UNDEFID ) continue;
+ if ( curDimId == CDI_UNDEFID ) continue;
switch ( dimorder[id] )
{
- Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
case 1:
case 2:
cdf_inq_dimlen(fileId, curDimId, &size);
@@ -56675,7 +56751,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
}
static
-void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void cdfReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -56693,7 +56769,7 @@ void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
cdf_get_vara_double(fileID, ncvarid, start, count, data);
- size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
+ size_t size = gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
@@ -56707,7 +56783,7 @@ void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
}
static
-void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
+void cdfReadVarSP(stream_t *streamptr, int varID, float *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
@@ -56725,7 +56801,7 @@ void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
cdf_get_vara_float(fileID, ncvarid, start, count, data);
- size_t size = (size_t)gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
+ size_t size = gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
@@ -56739,7 +56815,7 @@ void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
}
-void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss)
+void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss)
{
if ( memtype == MEMTYPE_DOUBLE )
cdfReadVarDP(streamptr, varID, (double*) data, nmiss);
@@ -56748,7 +56824,7 @@ void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *
}
static
-void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
+void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss)
{
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
@@ -56762,11 +56838,11 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
- size_t gridsize = (size_t)gridInqSize(gridId);
- size_t xsize = (size_t)gridInqXsize(gridId);
- size_t ysize = (size_t)gridInqYsize(gridId);
+ size_t gridsize = gridInqSize(gridId);
+ size_t xsize = gridInqXsize(gridId);
+ size_t ysize = gridInqYsize(gridId);
- if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
+ if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT32 )
{
float *data_fp = (float *) Malloc(gridsize*sizeof(*data_fp));
cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
@@ -56778,7 +56854,7 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
{
cdf_get_vara_double(fileID, ncvarid, start, count, data);
- if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
+ if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -56805,7 +56881,7 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
}
static
-void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss)
+void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, size_t *nmiss)
{
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
@@ -56819,11 +56895,11 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
- size_t gridsize = (size_t)gridInqSize(gridId);
- size_t xsize = (size_t)gridInqXsize(gridId);
- size_t ysize = (size_t)gridInqYsize(gridId);
+ size_t gridsize = gridInqSize(gridId);
+ size_t xsize = gridInqXsize(gridId);
+ size_t ysize = gridInqYsize(gridId);
- if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT64 )
+ if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT64 )
{
double *data_dp = (double *) Malloc(gridsize*sizeof(*data_dp));
cdf_get_vara_double(fileID, ncvarid, start, count, data_dp);
@@ -56835,7 +56911,7 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
{
cdf_get_vara_float(fileID, ncvarid, start, count, data);
- if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
+ if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -56862,7 +56938,7 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
}
-void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss)
+void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss)
{
if ( memtype == MEMTYPE_DOUBLE )
cdfReadVarSliceDP(streamptr, varID, levelID, (double*) data, nmiss);
@@ -56871,7 +56947,7 @@ void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
}
-void cdf_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss)
+void cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
@@ -57825,8 +57901,8 @@ void swap8byte(void *ptr, size_t size)
* require-trailing-newline: t
* End:
*/
-#ifndef _TABLEPAR_H
-#define _TABLEPAR_H
+#ifndef TABLEPAR_H
+#define TABLEPAR_H
enum {
TABLE_DUP_NAME = 1 << 0,
@@ -57836,18 +57912,21 @@ enum {
typedef struct
{
- int id; /* Parameter number (GRIB) */
- int dupflags; /* keep track of which attributes got strdup'ed */
- const char *name; /* Parameter name */
- const char *longname; /* Parameter long name */
- const char *units; /* Parameter units */
+ int id; // Parameter number (GRIB)
+ int ltype; // Level type (GRIB)
+ int dupflags; // keep track of which attributes got strdup'ed
+ const char *name; // Parameter name
+ const char *longname; // Parameter long name
+ const char *units; // Parameter units
}
-PAR;
+param_type;
-static void tableLink(int tableID, const PAR *pars, int npars);
+static void tableLink(int tableID, const param_type *pars, int npars);
int tableDef(int modelID, int tablegribID, const char *tablename);
+int tableInqParCode(int tableID, char *name, int *code);
+
#endif
/*
* Local Variables:
@@ -57859,1432 +57938,1418 @@ int tableDef(int modelID, int tablegribID, const char *tablename);
* End:
*/
/* Automatically generated, do not edit! */
-#ifndef _TABLE_H
-#define _TABLE_H
-
-static const PAR echam4[] = {
- { 4, 0, "precip", "total precipitation", "m/s" },
- { 34, 0, "low_cld", "low cloud", NULL },
- { 35, 0, "mid_cld", "mid cloud", NULL },
- { 36, 0, "hih_cld", "high cloud", NULL },
- { 129, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
- { 130, 0, "t", "temperature", "K" },
- { 131, 0, "u", "u-velocity", "m/s" },
- { 132, 0, "v", "v-velocity", "m/s" },
- { 133, 0, "sq", "specific humidity", "kg/kg" },
- { 134, 0, "aps", "Surface pressure", "Pa" },
- { 135, 0, "omega", "vertical velocity", "Pa/s" },
- { 138, 0, "svo", "vorticity", "1/s" },
- { 139, 0, "ts", "surface temperature", "K" },
- { 140, 0, "ws", "soil wetness", "m" },
- { 141, 0, "sn", "snow depth", "m" },
- { 142, 0, "aprl", "large scale precipitation", "m/s" },
- { 143, 0, "aprc", "convective precipitation", "m/s" },
- { 144, 0, "aprs", "snow fall", "m/s" },
- { 145, 0, "vdis", "boundary layer dissipation", "W/m^2" },
- { 146, 0, "ahfs", "surface sensible heat flux", "W/m^2" },
- { 147, 0, "ahfl", "surface latent heat flux", "W/m^2" },
- { 148, 0, "stream", "streamfunction", "m^2/s" },
- { 149, 0, "velopot", "velocity potential", "m^2/s" },
- { 151, 0, "slp", "mean sea level pressure", "Pa" },
- { 152, 0, "lsp", "log surface pressure", NULL },
- { 153, 0, "sx", "liquid water content", "kg/kg" },
- { 155, 0, "sd", "divergence", "1/s" },
- { 156, 0, "geopoth", "geopotential height", "m" },
- { 157, 0, "rhumidity", "relative humidity", "fraction" },
- { 158, 0, "var158", "tendency of surface pressure", "Pa/s" },
- { 159, 0, "ustar3", "ustar3", "m^3/s^3" },
- { 160, 0, "runoff", "surface runoff", "m/s" },
- { 161, 0, "alwc", "liquid water content", "kg/kg" },
- { 162, 0, "aclc", "cloud cover", "fraction" },
- { 163, 0, "aclcv", "total cloud cover", "fraction" },
- { 164, 0, "aclcov", "total cloud cover", "fraction" },
- { 165, 0, "u10", "10m u-velocity", "m/s" },
- { 166, 0, "v10", "10m v-velocity", "m/s" },
- { 167, 0, "temp2", "2m temperature", "K" },
- { 168, 0, "dew2", "2m dew point temperature", "K" },
- { 169, 0, "tsurf", "surface temperature", "K" },
- { 170, 0, "td", "deep soil temperature", "K" },
- { 171, 0, "wind10", "10m windspeed", "m/s" },
- { 172, 0, "slm", "land sea mask", "fraction" },
- { 173, 0, "az0", "surface roughness length", "m" },
- { 174, 0, "alb", "surface background albedo", "fraction" },
- { 175, 0, "albedo", "surface albedo", "fraction" },
- { 176, 0, "srads", "net surface solar radiation", "W/m^2" },
- { 177, 0, "trads", "net surface thermal radiation", "W/m^2" },
- { 178, 0, "srad0", "net top solar radiation", "W/m^2" },
- { 179, 0, "trad0", "top thermal radiation (OLR)", "W/m^2" },
- { 180, 0, "ustr", "surface u-stress", "Pa" },
- { 181, 0, "vstr", "surface v-stress", "Pa" },
- { 182, 0, "evap", "surface evaporation", "m/s" },
- { 183, 0, "tdcl", "soil temperature", "K" },
- { 185, 0, "srafs", "net surf. solar radiation (clear sky)", "W/m^2" },
- { 186, 0, "trafs", "net surf. thermal radiation (clear sky)", "W/m^2" },
- { 187, 0, "sraf0", "net top solar radiation (clear sky)", "W/m^2" },
- { 188, 0, "traf0", "net top thermal radiation (clear sky)", "W/m^2" },
- { 189, 0, "sclfs", "surface solar cloud forcing", "W/m^2" },
- { 190, 0, "tclfs", "surface thermal cloud forcing", "W/m^2" },
- { 191, 0, "sclf0", "top solar cloud forcing", "W/m^2" },
- { 192, 0, "tclf0", "top thermal cloud forcing", "W/m^2" },
- { 193, 0, "wl", "skin reservoir content", "m" },
- { 194, 0, "wlm1", "skin reservoir content of plants", "m" },
- { 195, 0, "ustrgw", "u-gravity wave stress", "Pa" },
- { 196, 0, "vstrgw", "v-gravity wave stress", "Pa" },
- { 197, 0, "vdisgw", "gravity wave dissipation", "W/m^2" },
- { 198, 0, "vgrat", "vegetation ratio", "fraction" },
- { 199, 0, "varor", "orographic variance", "m^2" },
- { 200, 0, "vlt", "leaf area index", NULL },
- { 201, 0, "t2max", "maximum 2m-temperature", "K" },
- { 202, 0, "t2min", "minimum 2m-temperature", "K" },
- { 203, 0, "srad0u", "top solar radiation upward", "W/m^2" },
- { 204, 0, "sradsu", "surface solar radiation upward", "W/m^2" },
- { 205, 0, "tradsu", "surface thermal radiation upward", "W/m^2" },
- { 206, 0, "tsn", "snow temperature", "K" },
- { 207, 0, "td3", "soil temperature 3", "K" },
- { 208, 0, "td4", "soil temperature 4", "K" },
- { 209, 0, "td5", "soil temperature 5", "K" },
- { 210, 0, "seaice", "sea ice cover", "fraction" },
- { 211, 0, "siced", "sea ice depth", "m" },
- { 212, 0, "forest", "vegetation type", "fraction" },
- { 213, 0, "teff", "(effective) sea-ice skin temperature", "K" },
- { 214, 0, "tsmax", "maximum surface temperature", "K" },
- { 215, 0, "tsmin", "minimum surface temperature", "K" },
- { 216, 0, "wimax", "maximum 10m-wind speed", "m/s" },
- { 217, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
- { 218, 0, "snmel", "snow melt", "m/s" },
- { 219, 0, "runtoc", "surface runoff into ocean", NULL },
- { 220, 0, "tslin", "land: residual surface heat budget", "W/m^2" },
- { 221, 0, "dsnac", "snow depth change", "m/s" },
- { 222, 0, "alwcac", "liquid water content", "kg/kg" },
- { 223, 0, "aclcac", "cloud cover", "fraction" },
- { 224, 0, "tke", "turbulent kinetic energy", NULL },
- { 225, 0, "tkem1", "turbulent kinetic energy (t-1)", NULL },
- { 226, 0, "fao", "FAO data set (soil data flags)", NULL },
- { 227, 0, "rgcgn", "heat capacity of soil", NULL },
- { 228, 0, "sodif", "soil diffusivity", NULL },
- { 229, 0, "wsmx", "field capacity of soil", "m" },
- { 230, 0, "qvi", "vertically integrated specific humidity", "kg/m^2" },
- { 231, 0, "alwcvi", "vertically integrated liquid water cont.", "kg/m^2" },
- { 232, 0, "glac", "glacier mask", "fraction" },
- { 233, 0, "runlnd", "surface runoff not running into ocean", NULL },
- { 259, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", NULL },
- { 260, 0, "precip", "total precipitation", "m/s" },
- { 261, 0, "net_top", "total top radiation", NULL },
- { 262, 0, "net_bot", "total surface radiation", NULL },
- { 263, 0, "net_heat", "net surface heat flux", NULL },
- { 264, 0, "net_water", "total surface water", NULL },
- { 268, 0, "sw_atm", NULL, NULL },
- { 269, 0, "lw_atm", NULL, NULL },
- { 270, 0, "net_atm", NULL, NULL },
- { 271, 0, "surf_runoff", "surface runoff", NULL },
- { 275, 0, "fresh_water", NULL, NULL },
+#ifndef TABLE_H
+#define TABLE_H
+
+static const param_type echam4[] = {
+ { 4, -1, 0, "precip", "total precipitation", "m/s" },
+ { 34, -1, 0, "low_cld", "low cloud", NULL },
+ { 35, -1, 0, "mid_cld", "mid cloud", NULL },
+ { 36, -1, 0, "hih_cld", "high cloud", NULL },
+ { 129, -1, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
+ { 130, -1, 0, "t", "temperature", "K" },
+ { 131, -1, 0, "u", "u-velocity", "m/s" },
+ { 132, -1, 0, "v", "v-velocity", "m/s" },
+ { 133, -1, 0, "sq", "specific humidity", "kg/kg" },
+ { 134, -1, 0, "aps", "Surface pressure", "Pa" },
+ { 135, -1, 0, "omega", "vertical velocity", "Pa/s" },
+ { 138, -1, 0, "svo", "vorticity", "1/s" },
+ { 139, -1, 0, "ts", "surface temperature", "K" },
+ { 140, -1, 0, "ws", "soil wetness", "m" },
+ { 141, -1, 0, "sn", "snow depth", "m" },
+ { 142, -1, 0, "aprl", "large scale precipitation", "m/s" },
+ { 143, -1, 0, "aprc", "convective precipitation", "m/s" },
+ { 144, -1, 0, "aprs", "snow fall", "m/s" },
+ { 145, -1, 0, "vdis", "boundary layer dissipation", "W/m^2" },
+ { 146, -1, 0, "ahfs", "surface sensible heat flux", "W/m^2" },
+ { 147, -1, 0, "ahfl", "surface latent heat flux", "W/m^2" },
+ { 148, -1, 0, "stream", "streamfunction", "m^2/s" },
+ { 149, -1, 0, "velopot", "velocity potential", "m^2/s" },
+ { 151, -1, 0, "slp", "mean sea level pressure", "Pa" },
+ { 152, -1, 0, "lsp", "log surface pressure", NULL },
+ { 153, -1, 0, "sx", "liquid water content", "kg/kg" },
+ { 155, -1, 0, "sd", "divergence", "1/s" },
+ { 156, -1, 0, "geopoth", "geopotential height", "m" },
+ { 157, -1, 0, "rhumidity", "relative humidity", "fraction" },
+ { 158, -1, 0, "var158", "tendency of surface pressure", "Pa/s" },
+ { 159, -1, 0, "ustar3", "ustar3", "m^3/s^3" },
+ { 160, -1, 0, "runoff", "surface runoff", "m/s" },
+ { 161, -1, 0, "alwc", "liquid water content", "kg/kg" },
+ { 162, -1, 0, "aclc", "cloud cover", "fraction" },
+ { 163, -1, 0, "aclcv", "total cloud cover", "fraction" },
+ { 164, -1, 0, "aclcov", "total cloud cover", "fraction" },
+ { 165, -1, 0, "u10", "10m u-velocity", "m/s" },
+ { 166, -1, 0, "v10", "10m v-velocity", "m/s" },
+ { 167, -1, 0, "temp2", "2m temperature", "K" },
+ { 168, -1, 0, "dew2", "2m dew point temperature", "K" },
+ { 169, -1, 0, "tsurf", "surface temperature", "K" },
+ { 170, -1, 0, "td", "deep soil temperature", "K" },
+ { 171, -1, 0, "wind10", "10m windspeed", "m/s" },
+ { 172, -1, 0, "slm", "land sea mask", "fraction" },
+ { 173, -1, 0, "az0", "surface roughness length", "m" },
+ { 174, -1, 0, "alb", "surface background albedo", "fraction" },
+ { 175, -1, 0, "albedo", "surface albedo", "fraction" },
+ { 176, -1, 0, "srads", "net surface solar radiation", "W/m^2" },
+ { 177, -1, 0, "trads", "net surface thermal radiation", "W/m^2" },
+ { 178, -1, 0, "srad0", "net top solar radiation", "W/m^2" },
+ { 179, -1, 0, "trad0", "top thermal radiation (OLR)", "W/m^2" },
+ { 180, -1, 0, "ustr", "surface u-stress", "Pa" },
+ { 181, -1, 0, "vstr", "surface v-stress", "Pa" },
+ { 182, -1, 0, "evap", "surface evaporation", "m/s" },
+ { 183, -1, 0, "tdcl", "soil temperature", "K" },
+ { 185, -1, 0, "srafs", "net surf. solar radiation (clear sky)", "W/m^2" },
+ { 186, -1, 0, "trafs", "net surf. thermal radiation (clear sky)", "W/m^2" },
+ { 187, -1, 0, "sraf0", "net top solar radiation (clear sky)", "W/m^2" },
+ { 188, -1, 0, "traf0", "net top thermal radiation (clear sky)", "W/m^2" },
+ { 189, -1, 0, "sclfs", "surface solar cloud forcing", "W/m^2" },
+ { 190, -1, 0, "tclfs", "surface thermal cloud forcing", "W/m^2" },
+ { 191, -1, 0, "sclf0", "top solar cloud forcing", "W/m^2" },
+ { 192, -1, 0, "tclf0", "top thermal cloud forcing", "W/m^2" },
+ { 193, -1, 0, "wl", "skin reservoir content", "m" },
+ { 194, -1, 0, "wlm1", "skin reservoir content of plants", "m" },
+ { 195, -1, 0, "ustrgw", "u-gravity wave stress", "Pa" },
+ { 196, -1, 0, "vstrgw", "v-gravity wave stress", "Pa" },
+ { 197, -1, 0, "vdisgw", "gravity wave dissipation", "W/m^2" },
+ { 198, -1, 0, "vgrat", "vegetation ratio", "fraction" },
+ { 199, -1, 0, "varor", "orographic variance", "m^2" },
+ { 200, -1, 0, "vlt", "leaf area index", NULL },
+ { 201, -1, 0, "t2max", "maximum 2m-temperature", "K" },
+ { 202, -1, 0, "t2min", "minimum 2m-temperature", "K" },
+ { 203, -1, 0, "srad0u", "top solar radiation upward", "W/m^2" },
+ { 204, -1, 0, "sradsu", "surface solar radiation upward", "W/m^2" },
+ { 205, -1, 0, "tradsu", "surface thermal radiation upward", "W/m^2" },
+ { 206, -1, 0, "tsn", "snow temperature", "K" },
+ { 207, -1, 0, "td3", "soil temperature 3", "K" },
+ { 208, -1, 0, "td4", "soil temperature 4", "K" },
+ { 209, -1, 0, "td5", "soil temperature 5", "K" },
+ { 210, -1, 0, "seaice", "sea ice cover", "fraction" },
+ { 211, -1, 0, "siced", "sea ice depth", "m" },
+ { 212, -1, 0, "forest", "vegetation type", "fraction" },
+ { 213, -1, 0, "teff", "(effective) sea-ice skin temperature", "K" },
+ { 214, -1, 0, "tsmax", "maximum surface temperature", "K" },
+ { 215, -1, 0, "tsmin", "minimum surface temperature", "K" },
+ { 216, -1, 0, "wimax", "maximum 10m-wind speed", "m/s" },
+ { 217, -1, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
+ { 218, -1, 0, "snmel", "snow melt", "m/s" },
+ { 219, -1, 0, "runtoc", "surface runoff into ocean", NULL },
+ { 220, -1, 0, "tslin", "land: residual surface heat budget", "W/m^2" },
+ { 221, -1, 0, "dsnac", "snow depth change", "m/s" },
+ { 222, -1, 0, "alwcac", "liquid water content", "kg/kg" },
+ { 223, -1, 0, "aclcac", "cloud cover", "fraction" },
+ { 224, -1, 0, "tke", "turbulent kinetic energy", NULL },
+ { 225, -1, 0, "tkem1", "turbulent kinetic energy (t-1)", NULL },
+ { 226, -1, 0, "fao", "FAO data set (soil data flags)", NULL },
+ { 227, -1, 0, "rgcgn", "heat capacity of soil", NULL },
+ { 228, -1, 0, "sodif", "soil diffusivity", NULL },
+ { 229, -1, 0, "wsmx", "field capacity of soil", "m" },
+ { 230, -1, 0, "qvi", "vertically integrated specific humidity", "kg/m^2" },
+ { 231, -1, 0, "alwcvi", "vertically integrated liquid water cont.", "kg/m^2" },
+ { 232, -1, 0, "glac", "glacier mask", "fraction" },
+ { 233, -1, 0, "runlnd", "surface runoff not running into ocean", NULL },
+ { 259, -1, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", NULL },
+ { 260, -1, 0, "precip", "total precipitation", "m/s" },
+ { 261, -1, 0, "net_top", "total top radiation", NULL },
+ { 262, -1, 0, "net_bot", "total surface radiation", NULL },
+ { 263, -1, 0, "net_heat", "net surface heat flux", NULL },
+ { 264, -1, 0, "net_water", "total surface water", NULL },
+ { 268, -1, 0, "sw_atm", NULL, NULL },
+ { 269, -1, 0, "lw_atm", NULL, NULL },
+ { 270, -1, 0, "net_atm", NULL, NULL },
+ { 271, -1, 0, "surf_runoff", "surface runoff", NULL },
+ { 275, -1, 0, "fresh_water", NULL, NULL },
};
-static const PAR echam5[] = {
- { 4, 0, "precip", "total precipitation", "kg/m^2s" },
- { 79, 0, "swnirac", "net surface NIR flux acc.", "W/m^2" },
- { 80, 0, "swdifnirac", "fraction of diffuse NIR acc.", "W/m^2" },
- { 81, 0, "swvisac", "net surface visible flux acc.", "W/m^2" },
- { 82, 0, "swdifvisac", "fraction of diffuse visible acc.", "W/m^2" },
- { 83, 0, "ocu", "ocean eastw. velocity (coupled mode)", "m/s" },
- { 84, 0, "ocv", "ocean northw. velocity (coupled mode)", "m/s" },
- { 85, 0, "tradl", "net LW radiation 200mb", "W/m^2" },
- { 86, 0, "sradl", "net SW radiation 200mb", "W/m^2" },
- { 87, 0, "trafl", "net LW radiation 200mb (clear sky)", "W/m^2" },
- { 88, 0, "srafl", "net SW radiation 200mb (clear sky)", "W/m^2" },
- { 89, 0, "amlcorac", "mixed layer flux correction", "W/m^2" },
- { 90, 0, "amlheatac", "mixed layer heat content", "J/m^2" },
- { 91, 0, "trfliac", "net LW radiation over ice", "W/m^2" },
- { 92, 0, "trflwac", "net LW radiation over water", "W/m^2" },
- { 93, 0, "trfllac", "net LW radiation over land", "W/m^2" },
- { 94, 0, "sofliac", "net SW radiation over ice", "W/m^2" },
- { 95, 0, "soflwac", "net SW radiation over water", "W/m^2" },
- { 96, 0, "sofllac", "net SW radiation over land", "W/m^2" },
- { 97, 0, "friac", "ice cover (fraction of grid box)", NULL },
- { 102, 0, "tsi", "surface temperature of ice", "K" },
- { 103, 0, "tsw", "surface temperature of water", "K" },
- { 104, 0, "ustri", "zonal wind stress over ice", "Pa" },
- { 105, 0, "vstri", "meridional wind stress over ice", "Pa" },
- { 106, 0, "ustrw", "zonal wind stress over water", "Pa" },
- { 107, 0, "vstrw", "meridional wind stress over water", "Pa" },
- { 108, 0, "ustrl", "zonal wind stress over land", "Pa" },
- { 109, 0, "vstrl", "meridional wind stress over land", "Pa" },
- { 110, 0, "ahfliac", "latent heat flux over ice", "W/m^2" },
- { 111, 0, "ahflwac", "latent heat flux over water", "W/m^2" },
- { 112, 0, "ahfllac", "latent heat flux over land", "W/m^2" },
- { 113, 0, "evapiac", "evaporation over ice", "kg/m^2s" },
- { 114, 0, "evapwac", "evaporation over water", "kg/m^2s" },
- { 115, 0, "evaplac", "evaporation over land", "kg/m^2s" },
- { 116, 0, "az0i", "roughness length over ice", "m" },
- { 117, 0, "az0w", "roughness length over water", "m" },
- { 118, 0, "az0l", "roughness length over land", "m" },
- { 119, 0, "ahfsiac", "sensible heat flux over ice", "W/m^2" },
- { 120, 0, "ahfswac", "sensible heat flux over water", "W/m^2" },
- { 121, 0, "ahfslac", "sensible heat flux over land", "W/m^2" },
- { 122, 0, "alsoi", "albedo of ice", NULL },
- { 123, 0, "alsow", "albedo of water", NULL },
- { 124, 0, "alsol", "albedo of land", NULL },
- { 125, 0, "ahfice", "conductive heat flux through ice", "W/m^2" },
- { 126, 0, "qres", "residual heat flux for melting sea ice", "W/m^2" },
- { 127, 0, "alake", "lake fraction", NULL },
- { 128, 0, "rintop", "low level inversion", NULL },
- { 129, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
- { 130, 0, "t", "temperature", "K" },
- { 131, 0, "u", "u-velocity", "m/s" },
- { 132, 0, "v", "v-velocity", "m/s" },
- { 133, 0, "q", "specific humidity", "kg/kg" },
- { 134, 0, "aps", "surface pressure", "Pa" },
- { 135, 0, "omega", "vertical velocity", "Pa/s" },
- { 136, 0, "acdnc", "cloud droplet number concentration", "1/m^3" },
- { 137, 0, "apmeb", "(P-E) error", "kg/m^2s" },
- { 138, 0, "svo", "vorticity", "1/s" },
- { 139, 0, "tslm1", "surface temperature of land", "K" },
- { 140, 0, "ws", "soil wetness", "m" },
- { 141, 0, "sn", "water equivalent snow depth", "m" },
- { 142, 0, "aprl", "large scale precipitation", "kg/m^2s" },
- { 143, 0, "aprc", "convective precipitation", "kg/m^2s" },
- { 144, 0, "aprs", "snow fall", "kg/m^2s" },
- { 145, 0, "vdis", "boundary layer dissipation", "W/m^2" },
- { 146, 0, "ahfs", "sensible heat flux", "W/m^2" },
- { 147, 0, "ahfl", "latent heat flux", "W/m^2" },
- { 148, 0, "stream", "streamfunction", "m^2/s" },
- { 149, 0, "velopot", "velocity potential", "m^2/s" },
- { 150, 0, "xivi", "vertically integrated cloud ice", "kg/m^2" },
- { 151, 0, "slp", "mean sea level pressure", "Pa" },
- { 152, 0, "lsp", "log surface pressure", NULL },
- { 153, 0, "xl", "cloud water", "kg/kg" },
- { 154, 0, "xi", "cloud ice", "kg/kg" },
- { 155, 0, "sd", "divergence", "1/s" },
- { 156, 0, "geopoth", "geopotential height", "m" },
- { 157, 0, "rhumidity", "relative humidity", NULL },
- { 159, 0, "wind10w", "10m windspeed over water", "m/s" },
- { 160, 0, "runoff", "surface runoff and drainage", "kg/m^2s" },
- { 161, 0, "drain", "drainage", "kg/m^2s" },
- { 162, 0, "aclc", "cloud cover", NULL },
- { 164, 0, "aclcov", "total cloud cover", NULL },
- { 165, 0, "u10", "10m u-velocity", "m/s" },
- { 166, 0, "v10", "10m v-velocity", "m/s" },
- { 167, 0, "temp2", "2m temperature", "K" },
- { 168, 0, "dew2", "2m dew point temperature", "K" },
- { 169, 0, "tsurf", "surface temperature", "K" },
- { 170, 0, "xvar", "variance of total water amount", "kg/kg" },
- { 171, 0, "wind10", "10m windspeed", "m/s" },
- { 172, 0, "slm", "land sea mask (1. = land, 0. = sea/lakes)", NULL },
- { 173, 0, "az0", "roughness length", "m" },
- { 174, 0, "alb", "surface background albedo", NULL },
- { 175, 0, "albedo", "surface albedo", NULL },
- { 176, 0, "srads", "net surface SW radiation", "W/m^2" },
- { 177, 0, "trads", "net surface LW radiation", "W/m^2" },
- { 178, 0, "srad0", "net top SW radiation", "W/m^2" },
- { 179, 0, "trad0", "net top LW radiation (-OLR)", "W/m^2" },
- { 180, 0, "ustr", "u-stress", "Pa" },
- { 181, 0, "vstr", "v-stress", "Pa" },
- { 182, 0, "evap", "evaporation", "kg/m^2s" },
- { 183, 0, "xskew", "skewness of total water amount qv+qi+ql", NULL },
- { 184, 0, "srad0d", "top incoming SW radiation", "W/m^2" },
- { 185, 0, "srafs", "net surface SW radiation (clear sky)", "W/m^2" },
- { 186, 0, "trafs", "net surface LW radiation (clear sky)", "W/m^2" },
- { 187, 0, "sraf0", "net top SW radiation (clear sky)", "W/m^2" },
- { 188, 0, "traf0", "net top LW radiation (clear sky)", "W/m^2" },
- { 189, 0, "sclfs", "net surface SW cloud forcing (176-185)", "W/m^2" },
- { 190, 0, "tclfs", "net surface LW cloud forcing (177-186)", "W/m^2" },
- { 191, 0, "sclf0", "net SW top cloud forcing (178-187)", "W/m^2" },
- { 192, 0, "tclf0", "net LW top cloud forcing (179-188)", "W/m^2" },
- { 193, 0, "wl", "skin reservoir content", "m" },
- { 194, 0, "slf", "fractional land cover", NULL },
- { 195, 0, "ustrgw", "u-gravity wave stress", "Pa" },
- { 196, 0, "vstrgw", "v-gravity wave stress", "Pa" },
- { 197, 0, "vdisgw", "gravity wave dissipation", "W/m^2" },
- { 198, 0, "vgrat", "vegetation ratio", NULL },
- { 199, 0, "orostd", "orographic standard deviation", "m" },
- { 200, 0, "vlt", "leaf area index", NULL },
- { 201, 0, "t2max", "maximum 2m-temperature", "K" },
- { 202, 0, "t2min", "minimum 2m-temperature", "K" },
- { 203, 0, "srad0u", "top SW radiation upward", "W/m^2" },
- { 204, 0, "sradsu", "surface SW radiation upward", "W/m^2" },
- { 205, 0, "tradsu", "surface LW radiation upward", "W/m^2" },
- { 206, 0, "grndflux", "surface ground heat flux", NULL },
- { 207, 0, "tsoil", "deep soil temperatures (5 layers)", "K" },
- { 208, 0, "ahfcon", "conductive heat flux through ice", "W/m^2" },
- { 209, 0, "ahfres", "res. heat flux for melting ice", "W/m^2" },
- { 210, 0, "seaice", "ice cover (fraction of ice+water)", NULL },
- { 211, 0, "siced", "ice thickness", "m" },
- { 212, 0, "forest", "forest fraction", NULL },
- { 213, 0, "gld", "glacier thickness", "m" },
- { 214, 0, "sni", "water equivalent of snow on ice", "m" },
- { 215, 0, "rogl", "glacier runoff", "kg/m^2s" },
- { 216, 0, "wimax", "maximum 10m-wind speed", "m/s" },
- { 217, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
- { 218, 0, "snmel", "snow melt", "kg/m^2s" },
- { 219, 0, "runtoc", "surface runoff into ocean", "kg/m^2s" },
- { 220, 0, "runlnd", "surface runoff not running into ocean", "kg/m^2s" },
- { 221, 0, "apmegl", "P-E over land ice", "kg/m^2s" },
- { 222, 0, "snacl", "snow accumulation over land", "kg/m^2s" },
- { 223, 0, "aclcac", "cloud cover", NULL },
- { 224, 0, "tke", "turbulent kinetic energy", "m^2/s^2" },
- { 225, 0, "tkem1", "turbulent kinetic energy (t-1)", "m^2/s^2" },
- { 226, 0, "fao", "FAO data set (soil data flags) 0...5", NULL },
- { 227, 0, "rgcgn", "heat capacity of soil", NULL },
- { 228, 0, "sodif", "soil diffusivity", "m^2/s" },
- { 229, 0, "wsmx", "field capacity of soil", "m" },
- { 230, 0, "qvi", "vertically integrated water vapor", "kg/m^2" },
- { 231, 0, "xlvi", "vertically integrated cloud water", "kg/m^2" },
- { 232, 0, "glac", "fraction of land covered by glaciers", NULL },
- { 233, 0, "snc", "snow depth at the canopy", "m" },
- { 234, 0, "rtype", "type of convection", "0...3" },
- { 235, 0, "abso4", "anthropogenic sulfur burden", "kg/m^2" },
- { 236, 0, "ao3", "ipcc ozone", "kg/m^2" },
- { 237, 0, "tropo", "WMO defined tropopause height", "Pa" },
- { 259, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", "m/s" },
- { 260, 0, "precip", "total precipitation (142+143)", "kg/m^2s" },
- { 261, 0, "net_top", "total top radiation (178+179)", "W/m^2" },
- { 262, 0, "net_bot", "total surface radiation (176+177)", "W/m^2" },
- { 272, 0, "mastrfu", "mass stream function", "kg/s" },
+static const param_type echam5[] = {
+ { 4, -1, 0, "precip", "total precipitation", "kg/m^2s" },
+ { 79, -1, 0, "swnirac", "net surface NIR flux acc.", "W/m^2" },
+ { 80, -1, 0, "swdifnirac", "fraction of diffuse NIR acc.", "W/m^2" },
+ { 81, -1, 0, "swvisac", "net surface visible flux acc.", "W/m^2" },
+ { 82, -1, 0, "swdifvisac", "fraction of diffuse visible acc.", "W/m^2" },
+ { 83, -1, 0, "ocu", "ocean eastw. velocity (coupled mode)", "m/s" },
+ { 84, -1, 0, "ocv", "ocean northw. velocity (coupled mode)", "m/s" },
+ { 85, -1, 0, "tradl", "net LW radiation 200mb", "W/m^2" },
+ { 86, -1, 0, "sradl", "net SW radiation 200mb", "W/m^2" },
+ { 87, -1, 0, "trafl", "net LW radiation 200mb (clear sky)", "W/m^2" },
+ { 88, -1, 0, "srafl", "net SW radiation 200mb (clear sky)", "W/m^2" },
+ { 89, -1, 0, "amlcorac", "mixed layer flux correction", "W/m^2" },
+ { 90, -1, 0, "amlheatac", "mixed layer heat content", "J/m^2" },
+ { 91, -1, 0, "trfliac", "net LW radiation over ice", "W/m^2" },
+ { 92, -1, 0, "trflwac", "net LW radiation over water", "W/m^2" },
+ { 93, -1, 0, "trfllac", "net LW radiation over land", "W/m^2" },
+ { 94, -1, 0, "sofliac", "net SW radiation over ice", "W/m^2" },
+ { 95, -1, 0, "soflwac", "net SW radiation over water", "W/m^2" },
+ { 96, -1, 0, "sofllac", "net SW radiation over land", "W/m^2" },
+ { 97, -1, 0, "friac", "ice cover (fraction of grid box)", NULL },
+ { 102, -1, 0, "tsi", "surface temperature of ice", "K" },
+ { 103, -1, 0, "tsw", "surface temperature of water", "K" },
+ { 104, -1, 0, "ustri", "zonal wind stress over ice", "Pa" },
+ { 105, -1, 0, "vstri", "meridional wind stress over ice", "Pa" },
+ { 106, -1, 0, "ustrw", "zonal wind stress over water", "Pa" },
+ { 107, -1, 0, "vstrw", "meridional wind stress over water", "Pa" },
+ { 108, -1, 0, "ustrl", "zonal wind stress over land", "Pa" },
+ { 109, -1, 0, "vstrl", "meridional wind stress over land", "Pa" },
+ { 110, -1, 0, "ahfliac", "latent heat flux over ice", "W/m^2" },
+ { 111, -1, 0, "ahflwac", "latent heat flux over water", "W/m^2" },
+ { 112, -1, 0, "ahfllac", "latent heat flux over land", "W/m^2" },
+ { 113, -1, 0, "evapiac", "evaporation over ice", "kg/m^2s" },
+ { 114, -1, 0, "evapwac", "evaporation over water", "kg/m^2s" },
+ { 115, -1, 0, "evaplac", "evaporation over land", "kg/m^2s" },
+ { 116, -1, 0, "az0i", "roughness length over ice", "m" },
+ { 117, -1, 0, "az0w", "roughness length over water", "m" },
+ { 118, -1, 0, "az0l", "roughness length over land", "m" },
+ { 119, -1, 0, "ahfsiac", "sensible heat flux over ice", "W/m^2" },
+ { 120, -1, 0, "ahfswac", "sensible heat flux over water", "W/m^2" },
+ { 121, -1, 0, "ahfslac", "sensible heat flux over land", "W/m^2" },
+ { 122, -1, 0, "alsoi", "albedo of ice", NULL },
+ { 123, -1, 0, "alsow", "albedo of water", NULL },
+ { 124, -1, 0, "alsol", "albedo of land", NULL },
+ { 125, -1, 0, "ahfice", "conductive heat flux through ice", "W/m^2" },
+ { 126, -1, 0, "qres", "residual heat flux for melting sea ice", "W/m^2" },
+ { 127, -1, 0, "alake", "lake fraction", NULL },
+ { 128, -1, 0, "rintop", "low level inversion", NULL },
+ { 129, -1, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
+ { 130, -1, 0, "t", "temperature", "K" },
+ { 131, -1, 0, "u", "u-velocity", "m/s" },
+ { 132, -1, 0, "v", "v-velocity", "m/s" },
+ { 133, -1, 0, "q", "specific humidity", "kg/kg" },
+ { 134, -1, 0, "aps", "surface pressure", "Pa" },
+ { 135, -1, 0, "omega", "vertical velocity", "Pa/s" },
+ { 136, -1, 0, "acdnc", "cloud droplet number concentration", "1/m^3" },
+ { 137, -1, 0, "apmeb", "(P-E) error", "kg/m^2s" },
+ { 138, -1, 0, "svo", "vorticity", "1/s" },
+ { 139, -1, 0, "tslm1", "surface temperature of land", "K" },
+ { 140, -1, 0, "ws", "soil wetness", "m" },
+ { 141, -1, 0, "sn", "water equivalent snow depth", "m" },
+ { 142, -1, 0, "aprl", "large scale precipitation", "kg/m^2s" },
+ { 143, -1, 0, "aprc", "convective precipitation", "kg/m^2s" },
+ { 144, -1, 0, "aprs", "snow fall", "kg/m^2s" },
+ { 145, -1, 0, "vdis", "boundary layer dissipation", "W/m^2" },
+ { 146, -1, 0, "ahfs", "sensible heat flux", "W/m^2" },
+ { 147, -1, 0, "ahfl", "latent heat flux", "W/m^2" },
+ { 148, -1, 0, "stream", "streamfunction", "m^2/s" },
+ { 149, -1, 0, "velopot", "velocity potential", "m^2/s" },
+ { 150, -1, 0, "xivi", "vertically integrated cloud ice", "kg/m^2" },
+ { 151, -1, 0, "slp", "mean sea level pressure", "Pa" },
+ { 152, -1, 0, "lsp", "log surface pressure", NULL },
+ { 153, -1, 0, "xl", "cloud water", "kg/kg" },
+ { 154, -1, 0, "xi", "cloud ice", "kg/kg" },
+ { 155, -1, 0, "sd", "divergence", "1/s" },
+ { 156, -1, 0, "geopoth", "geopotential height", "m" },
+ { 157, -1, 0, "rhumidity", "relative humidity", NULL },
+ { 159, -1, 0, "wind10w", "10m windspeed over water", "m/s" },
+ { 160, -1, 0, "runoff", "surface runoff and drainage", "kg/m^2s" },
+ { 161, -1, 0, "drain", "drainage", "kg/m^2s" },
+ { 162, -1, 0, "aclc", "cloud cover", NULL },
+ { 164, -1, 0, "aclcov", "total cloud cover", NULL },
+ { 165, -1, 0, "u10", "10m u-velocity", "m/s" },
+ { 166, -1, 0, "v10", "10m v-velocity", "m/s" },
+ { 167, -1, 0, "temp2", "2m temperature", "K" },
+ { 168, -1, 0, "dew2", "2m dew point temperature", "K" },
+ { 169, -1, 0, "tsurf", "surface temperature", "K" },
+ { 170, -1, 0, "xvar", "variance of total water amount", "kg/kg" },
+ { 171, -1, 0, "wind10", "10m windspeed", "m/s" },
+ { 172, -1, 0, "slm", "land sea mask (1. = land, 0. = sea/lakes)", NULL },
+ { 173, -1, 0, "az0", "roughness length", "m" },
+ { 174, -1, 0, "alb", "surface background albedo", NULL },
+ { 175, -1, 0, "albedo", "surface albedo", NULL },
+ { 176, -1, 0, "srads", "net surface SW radiation", "W/m^2" },
+ { 177, -1, 0, "trads", "net surface LW radiation", "W/m^2" },
+ { 178, -1, 0, "srad0", "net top SW radiation", "W/m^2" },
+ { 179, -1, 0, "trad0", "net top LW radiation (-OLR)", "W/m^2" },
+ { 180, -1, 0, "ustr", "u-stress", "Pa" },
+ { 181, -1, 0, "vstr", "v-stress", "Pa" },
+ { 182, -1, 0, "evap", "evaporation", "kg/m^2s" },
+ { 183, -1, 0, "xskew", "skewness of total water amount qv+qi+ql", NULL },
+ { 184, -1, 0, "srad0d", "top incoming SW radiation", "W/m^2" },
+ { 185, -1, 0, "srafs", "net surface SW radiation (clear sky)", "W/m^2" },
+ { 186, -1, 0, "trafs", "net surface LW radiation (clear sky)", "W/m^2" },
+ { 187, -1, 0, "sraf0", "net top SW radiation (clear sky)", "W/m^2" },
+ { 188, -1, 0, "traf0", "net top LW radiation (clear sky)", "W/m^2" },
+ { 189, -1, 0, "sclfs", "net surface SW cloud forcing (176-185)", "W/m^2" },
+ { 190, -1, 0, "tclfs", "net surface LW cloud forcing (177-186)", "W/m^2" },
+ { 191, -1, 0, "sclf0", "net SW top cloud forcing (178-187)", "W/m^2" },
+ { 192, -1, 0, "tclf0", "net LW top cloud forcing (179-188)", "W/m^2" },
+ { 193, -1, 0, "wl", "skin reservoir content", "m" },
+ { 194, -1, 0, "slf", "fractional land cover", NULL },
+ { 195, -1, 0, "ustrgw", "u-gravity wave stress", "Pa" },
+ { 196, -1, 0, "vstrgw", "v-gravity wave stress", "Pa" },
+ { 197, -1, 0, "vdisgw", "gravity wave dissipation", "W/m^2" },
+ { 198, -1, 0, "vgrat", "vegetation ratio", NULL },
+ { 199, -1, 0, "orostd", "orographic standard deviation", "m" },
+ { 200, -1, 0, "vlt", "leaf area index", NULL },
+ { 201, -1, 0, "t2max", "maximum 2m-temperature", "K" },
+ { 202, -1, 0, "t2min", "minimum 2m-temperature", "K" },
+ { 203, -1, 0, "srad0u", "top SW radiation upward", "W/m^2" },
+ { 204, -1, 0, "sradsu", "surface SW radiation upward", "W/m^2" },
+ { 205, -1, 0, "tradsu", "surface LW radiation upward", "W/m^2" },
+ { 206, -1, 0, "grndflux", "surface ground heat flux", NULL },
+ { 207, -1, 0, "tsoil", "deep soil temperatures (5 layers)", "K" },
+ { 208, -1, 0, "ahfcon", "conductive heat flux through ice", "W/m^2" },
+ { 209, -1, 0, "ahfres", "res. heat flux for melting ice", "W/m^2" },
+ { 210, -1, 0, "seaice", "ice cover (fraction of ice+water)", NULL },
+ { 211, -1, 0, "siced", "ice thickness", "m" },
+ { 212, -1, 0, "forest", "forest fraction", NULL },
+ { 213, -1, 0, "gld", "glacier thickness", "m" },
+ { 214, -1, 0, "sni", "water equivalent of snow on ice", "m" },
+ { 215, -1, 0, "rogl", "glacier runoff", "kg/m^2s" },
+ { 216, -1, 0, "wimax", "maximum 10m-wind speed", "m/s" },
+ { 217, -1, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
+ { 218, -1, 0, "snmel", "snow melt", "kg/m^2s" },
+ { 219, -1, 0, "runtoc", "surface runoff into ocean", "kg/m^2s" },
+ { 220, -1, 0, "runlnd", "surface runoff not running into ocean", "kg/m^2s" },
+ { 221, -1, 0, "apmegl", "P-E over land ice", "kg/m^2s" },
+ { 222, -1, 0, "snacl", "snow accumulation over land", "kg/m^2s" },
+ { 223, -1, 0, "aclcac", "cloud cover", NULL },
+ { 224, -1, 0, "tke", "turbulent kinetic energy", "m^2/s^2" },
+ { 225, -1, 0, "tkem1", "turbulent kinetic energy (t-1)", "m^2/s^2" },
+ { 226, -1, 0, "fao", "FAO data set (soil data flags) 0...5", NULL },
+ { 227, -1, 0, "rgcgn", "heat capacity of soil", NULL },
+ { 228, -1, 0, "sodif", "soil diffusivity", "m^2/s" },
+ { 229, -1, 0, "wsmx", "field capacity of soil", "m" },
+ { 230, -1, 0, "qvi", "vertically integrated water vapor", "kg/m^2" },
+ { 231, -1, 0, "xlvi", "vertically integrated cloud water", "kg/m^2" },
+ { 232, -1, 0, "glac", "fraction of land covered by glaciers", NULL },
+ { 233, -1, 0, "snc", "snow depth at the canopy", "m" },
+ { 234, -1, 0, "rtype", "type of convection", "0...3" },
+ { 235, -1, 0, "abso4", "anthropogenic sulfur burden", "kg/m^2" },
+ { 236, -1, 0, "ao3", "ipcc ozone", "kg/m^2" },
+ { 237, -1, 0, "tropo", "WMO defined tropopause height", "Pa" },
+ { 259, -1, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", "m/s" },
+ { 260, -1, 0, "precip", "total precipitation (142+143)", "kg/m^2s" },
+ { 261, -1, 0, "net_top", "total top radiation (178+179)", "W/m^2" },
+ { 262, -1, 0, "net_bot", "total surface radiation (176+177)", "W/m^2" },
+ { 272, -1, 0, "mastrfu", "mass stream function", "kg/s" },
};
-static const PAR echam6[] = {
- { 4, 0, "precip", "total precipitation", "kg m-2 s-1" },
- { 34, 0, "low_cld", "low cloud", NULL },
- { 35, 0, "mid_cld", "mid cloud", NULL },
- { 36, 0, "hih_cld", "high cloud", NULL },
- { 68, 0, "fage", "aging factor of snow on ice", NULL },
- { 69, 0, "snifrac", "fraction of ice covered with snow", NULL },
- { 70, 0, "barefrac", "bare ice fraction", NULL },
- { 71, 0, "alsom", "albedo of melt ponds", NULL },
- { 72, 0, "alsobs", "albedo of bare ice and snow", NULL },
- { 73, 0, "sicepdw", "melt pond depth on sea-ice", "m" },
- { 74, 0, "sicepdi", "ice thickness on melt pond", "m" },
- { 75, 0, "tsicepdi", "ice temperature on frozen melt pond", "K" },
- { 76, 0, "sicepres", "residual heat flux", "W m-2" },
- { 77, 0, "ameltdepth", "total melt pond depth", "m" },
- { 78, 0, "ameltfrac", "fractional area of melt ponds on sea-ice", NULL },
- { 79, 0, "albedo_vis_dir", "surface albedo visible range direct", NULL },
- { 80, 0, "albedo_nir_dir", "surface albedo NIR range direct", NULL },
- { 81, 0, "albedo_vis_dif", "surface albedo visible range diffuse", NULL },
- { 82, 0, "albedo_nir_dif", "surface albedo NIR range diffuse", NULL },
- { 83, 0, "ocu", "ocean eastw. velocity (coupled mode)", "m/s" },
- { 84, 0, "ocv", "ocean northw. velocity (coupled mode)", "m/s" },
- { 85, 0, "tradl", "thermal radiation 200mb", "W m-2" },
- { 86, 0, "sradl", "solar radiation 200mb", "W m-2" },
- { 87, 0, "trafl", "thermal radiation 200mb (clear sky)", "W m-2" },
- { 88, 0, "srafl", "solar radiation 200mb (clear sky)", "W m-2" },
- { 89, 0, "amlcorac", "mixed layer flux correction", "W m-2" },
- { 90, 0, "amlheatac", "mixed layer heat content", "J m-2" },
- { 91, 0, "trfliac", "LW flux over ice", "W m-2" },
- { 92, 0, "trflwac", "LW flux over water", "W m-2" },
- { 93, 0, "trfllac", "LW flux over land", "W m-2" },
- { 94, 0, "sofliac", "SW flux over ice", "W m-2" },
- { 95, 0, "soflwac", "SW flux over water", "W m-2" },
- { 96, 0, "sofllac", "SW flux over land", "W m-2" },
- { 97, 0, "friac", "ice cover (fraction of grid box)", NULL },
- { 102, 0, "tsi", "surface temperature of ice", "K" },
- { 103, 0, "tsw", "surface temperature of water", "K" },
- { 104, 0, "ustri", "zonal wind stress over ice", "Pa" },
- { 105, 0, "vstri", "meridional wind stress over ice", "Pa" },
- { 106, 0, "ustrw", "zonal wind stress over water", "Pa" },
- { 107, 0, "vstrw", "meridional wind stress over water", "Pa" },
- { 108, 0, "ustrl", "zonal wind stress over land", "Pa" },
- { 109, 0, "vstrl", "meridional wind stress over land", "Pa" },
- { 110, 0, "ahfliac", "latent heat flux over ice", "W m-2" },
- { 111, 0, "ahflwac", "latent heat flux over water", "W m-2" },
- { 112, 0, "ahfllac", "latent heat flux over land", "W m-2" },
- { 113, 0, "evapiac", "evaporation over ice", "kg m-2 s-1" },
- { 114, 0, "evapwac", "evaporation over water", "kg m-2 s-1" },
- { 115, 0, "evaplac", "evaporation over land", "kg m-2 s-1" },
- { 116, 0, "az0i", "roughness length over ice", "m" },
- { 117, 0, "az0w", "roughness length over water", "m" },
- { 118, 0, "az0l", "roughness length over land", "m" },
- { 119, 0, "ahfsiac", "sensible heat flux over ice", "W m-2" },
- { 120, 0, "ahfswac", "sensible heat flux over water", "W m-2" },
- { 121, 0, "ahfslac", "sensible heat flux over land", "W m-2" },
- { 122, 0, "alsoi", "albedo of ice", NULL },
- { 123, 0, "alsow", "albedo of water", NULL },
- { 124, 0, "alsol", "albedo of land", NULL },
- { 125, 0, "ahfice", "conductive heat flux", "W m-2" },
- { 126, 0, "qres", "residual heat flux for melting sea ice", "W m-2" },
- { 127, 0, "alake", "lake fraction of grid box", "fraction" },
- { 128, 0, "rintop", "low level inversion", NULL },
- { 129, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
- { 130, 0, "t", "temperature", "K" },
- { 131, 0, "u", "u-velocity", "m/s" },
- { 132, 0, "v", "v-velocity", "m/s" },
- { 133, 0, "q", "specific humidity", "kg/kg" },
- { 134, 0, "aps", "surface pressure", "Pa" },
- { 135, 0, "omega", "vertical velocity", "Pa/s" },
- { 136, 0, "acdnc", "cloud droplet number concentration", "1 m-3" },
- { 137, 0, "apmeb", "vert. integr. tendencies of water", "kg m-2 s-1" },
- { 138, 0, "svo", "vorticity", "1/s" },
- { 139, 0, "tslm1", "surface temperature of land", "K" },
- { 140, 0, "ws", "soil wetness", "m" },
- { 141, 0, "sn", "snow depth", "m" },
- { 142, 0, "aprl", "large scale precipitation", "kg m-2 s-1" },
- { 143, 0, "aprc", "convective precipitation", "kg m-2 s-1" },
- { 144, 0, "aprs", "snow fall", "kg m-2 s-1" },
- { 145, 0, "vdis", "boundary layer dissipation", "W m-2" },
- { 146, 0, "ahfs", "sensible heat flux", "W m-2" },
- { 147, 0, "ahfl", "latent heat flux", "W m-2" },
- { 148, 0, "stream", "streamfunction", "m^2/s" },
- { 149, 0, "velopot", "velocity potential", "m^2/s" },
- { 150, 0, "xivi", "vertically integrated cloud ice", "kg m-2" },
- { 151, 0, "slp", "mean sea level pressure", "Pa" },
- { 152, 0, "lsp", "log surface pressure", NULL },
- { 153, 0, "xl", "cloud water", "kg/kg" },
- { 154, 0, "xi", "cloud ice", "kg/kg" },
- { 155, 0, "sd", "divergence", "1/s" },
- { 156, 0, "geopoth", "geopotential height", "m" },
- { 157, 0, "rhumidity", "relative humidity", "fraction" },
- { 158, 0, "var158", "tendency of surface pressure", "Pa/s" },
- { 159, 0, "wind10w", "10m windspeed over water", "m/s" },
- { 160, 0, "runoff", "surface runoff and drainage", "kg m-2 s-1" },
- { 161, 0, "drain", "drainage", "kg m-2 s-1" },
- { 162, 0, "aclc", "cloud cover", NULL },
- { 163, 0, "aclcv", "total cloud cover", NULL },
- { 164, 0, "aclcov", "total cloud cover (mean)", NULL },
- { 165, 0, "u10", "10m u-velocity", "m/s" },
- { 166, 0, "v10", "10m v-velocity", "m/s" },
- { 167, 0, "temp2", "2m temperature", "K" },
- { 168, 0, "dew2", "2m dew point temperature", "K" },
- { 169, 0, "tsurf", "surface temperature", "K" },
- { 170, 0, "xvar", "variance of total water amount qv+qi+ql", "kg/kg" },
- { 171, 0, "wind10", "10m windspeed", "m/s" },
- { 172, 0, "slm", "land sea mask (1. = land, 0. = sea/lakes)", NULL },
- { 173, 0, "az0", "roughness length", "m" },
- { 174, 0, "alb", "surface background albedo", NULL },
- { 175, 0, "albedo", "surface albedo", NULL },
- { 176, 0, "srads", "net surface solar radiation", "W m-2" },
- { 177, 0, "trads", "net surface thermal radiation", "W m-2" },
- { 178, 0, "srad0", "net top solar radiation", "W m-2" },
- { 179, 0, "trad0", "top thermal radiation (OLR)", "W m-2" },
- { 180, 0, "ustr", "u-stress", "Pa" },
- { 181, 0, "vstr", "v-stress", "Pa" },
- { 182, 0, "evap", "evaporation", "kg m-2 s-1" },
- { 183, 0, "xskew", "skewness of total water amount qv+qi+ql", NULL },
- { 184, 0, "srad0d", "top incoming solar radiation", "W m-2" },
- { 185, 0, "srafs", "net surf. solar radiation (clear sky)", "W m-2" },
- { 186, 0, "trafs", "net surf. thermal radiation (clear sky)", "W m-2" },
- { 187, 0, "sraf0", "net top solar radiation (clear sky)", "W m-2" },
- { 188, 0, "traf0", "net top thermal radiation (clear sky)", "W m-2" },
- { 189, 0, "sclfs", "surface solar cloud forcing", "W m-2" },
- { 190, 0, "tclfs", "surface thermal cloud forcing", "W m-2" },
- { 191, 0, "sclf0", "SW top cloud forcing (178-187)", "W m-2" },
- { 192, 0, "tclf0", "LW top cloud forcing (179-188)", "W m-2" },
- { 193, 0, "wl", "skin reservoir content", "m" },
- { 194, 0, "slf", "sea land fraction", NULL },
- { 195, 0, "ustrgw", "u-gravity wave stress", "Pa" },
- { 196, 0, "vstrgw", "v-gravity wave stress", "Pa" },
- { 197, 0, "vdisgw", "gravity wave dissipation", "W m-2" },
- { 198, 0, "vgrat", "vegetation ratio", NULL },
- { 199, 0, "orostd", "orographic standard deviation", "m" },
- { 200, 0, "vlt", "leaf area index", NULL },
- { 201, 0, "t2max", "maximum 2m-temperature", "K" },
- { 202, 0, "t2min", "minimum 2m-temperature", "K" },
- { 203, 0, "srad0u", "top solar radiation upward", "W m-2" },
- { 204, 0, "sradsu", "surface solar radiation upward", "W m-2" },
- { 205, 0, "tradsu", "surface thermal radiation upward", "W m-2" },
- { 206, 0, "grndflux", "surface ground heat flux", NULL },
- { 207, 0, "tsoil", "deep soil temperatures (5 layers)", "K" },
- { 208, 0, "ahfcon", "conductive heat flux through ice", "W m-2" },
- { 209, 0, "ahfres", "melting of ice", "W m-2" },
- { 210, 0, "seaice", "ice cover (fraction of 1-SLM)", NULL },
- { 211, 0, "siced", "ice depth", "m" },
- { 212, 0, "forest", "forest fraction", NULL },
- { 213, 0, "gld", "glacier depth", "m" },
- { 214, 0, "sni", "water equivalent of snow on ice", "m" },
- { 215, 0, "rogl", "glacier runoff", "kg m-2 s-1" },
- { 216, 0, "wimax", "maximum 10m-wind speed", "m/s" },
- { 217, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
- { 218, 0, "snmel", "snow melt", "kg m-2 s-1" },
- { 219, 0, "runtoc", "surface runoff into ocean", "kg m-2 s-1" },
- { 220, 0, "runlnd", "surface runoff not running into ocean", "kg m-2 s-1" },
- { 221, 0, "apmegl", "P-E over land ice", "kg m-2 s-1" },
- { 222, 0, "snacl", "snow accumulation over land", "kg m-2 s-1" },
- { 223, 0, "aclcac", "cloud cover", NULL },
- { 224, 0, "tke", "turbulent kinetic energy", "m^2/s^2" },
- { 225, 0, "tkem1", "turbulent kinetic energy (t-1)", "m^2/s^2" },
- { 226, 0, "fao", "FAO data set (soil data flags)", "0...5" },
- { 227, 0, "rgcgn", "heat capacity of soil", NULL },
- { 228, 0, "sodif", "diffusivity of soil and land ice", "m^2/s" },
- { 229, 0, "wsmx", "field capacity of soil", "m" },
- { 230, 0, "qvi", "vertically integrated water vapor", "kg m-2" },
- { 231, 0, "xlvi", "vertically integrated cloud water", "kg m-2" },
- { 232, 0, "glac", "fraction of land covered by glaciers", NULL },
- { 233, 0, "snc", "snow depth at the canopy", "m" },
- { 234, 0, "rtype", "type of convection", "0...3" },
- { 235, 0, "abso4", "antropogenic sulfur burden", "kg m-2" },
- { 236, 0, "ao3", "ipcc ozone", "kg m-2" },
- { 237, 0, "tropo", "WMO defined tropopause height", "Pa" },
- { 259, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", "m/s" },
- { 260, 0, "precip", "total precipitation (142+143)", "kg m-2 s-1" },
- { 261, 0, "net_top", "total top radiation (178+179)", "W m-2" },
- { 262, 0, "net_bot", "total surface radiation (176+177)", "W m-2" },
- { 272, 0, "mastfru", "mass stream function", "kg/s" },
+static const param_type echam6[] = {
+ { 4, -1, 0, "precip", "total precipitation", "kg m-2 s-1" },
+ { 34, -1, 0, "low_cld", "low cloud", NULL },
+ { 35, -1, 0, "mid_cld", "mid cloud", NULL },
+ { 36, -1, 0, "hih_cld", "high cloud", NULL },
+ { 68, -1, 0, "fage", "aging factor of snow on ice", NULL },
+ { 69, -1, 0, "snifrac", "fraction of ice covered with snow", NULL },
+ { 70, -1, 0, "barefrac", "bare ice fraction", NULL },
+ { 71, -1, 0, "alsom", "albedo of melt ponds", NULL },
+ { 72, -1, 0, "alsobs", "albedo of bare ice and snow", NULL },
+ { 73, -1, 0, "sicepdw", "melt pond depth on sea-ice", "m" },
+ { 74, -1, 0, "sicepdi", "ice thickness on melt pond", "m" },
+ { 75, -1, 0, "tsicepdi", "ice temperature on frozen melt pond", "K" },
+ { 76, -1, 0, "sicepres", "residual heat flux", "W m-2" },
+ { 77, -1, 0, "ameltdepth", "total melt pond depth", "m" },
+ { 78, -1, 0, "ameltfrac", "fractional area of melt ponds on sea-ice", NULL },
+ { 79, -1, 0, "albedo_vis_dir", "surface albedo visible range direct", NULL },
+ { 80, -1, 0, "albedo_nir_dir", "surface albedo NIR range direct", NULL },
+ { 81, -1, 0, "albedo_vis_dif", "surface albedo visible range diffuse", NULL },
+ { 82, -1, 0, "albedo_nir_dif", "surface albedo NIR range diffuse", NULL },
+ { 83, -1, 0, "ocu", "ocean eastw. velocity (coupled mode)", "m/s" },
+ { 84, -1, 0, "ocv", "ocean northw. velocity (coupled mode)", "m/s" },
+ { 85, -1, 0, "tradl", "thermal radiation 200mb", "W m-2" },
+ { 86, -1, 0, "sradl", "solar radiation 200mb", "W m-2" },
+ { 87, -1, 0, "trafl", "thermal radiation 200mb (clear sky)", "W m-2" },
+ { 88, -1, 0, "srafl", "solar radiation 200mb (clear sky)", "W m-2" },
+ { 89, -1, 0, "amlcorac", "mixed layer flux correction", "W m-2" },
+ { 90, -1, 0, "amlheatac", "mixed layer heat content", "J m-2" },
+ { 91, -1, 0, "trfliac", "LW flux over ice", "W m-2" },
+ { 92, -1, 0, "trflwac", "LW flux over water", "W m-2" },
+ { 93, -1, 0, "trfllac", "LW flux over land", "W m-2" },
+ { 94, -1, 0, "sofliac", "SW flux over ice", "W m-2" },
+ { 95, -1, 0, "soflwac", "SW flux over water", "W m-2" },
+ { 96, -1, 0, "sofllac", "SW flux over land", "W m-2" },
+ { 97, -1, 0, "friac", "ice cover (fraction of grid box)", NULL },
+ { 102, -1, 0, "tsi", "surface temperature of ice", "K" },
+ { 103, -1, 0, "tsw", "surface temperature of water", "K" },
+ { 104, -1, 0, "ustri", "zonal wind stress over ice", "Pa" },
+ { 105, -1, 0, "vstri", "meridional wind stress over ice", "Pa" },
+ { 106, -1, 0, "ustrw", "zonal wind stress over water", "Pa" },
+ { 107, -1, 0, "vstrw", "meridional wind stress over water", "Pa" },
+ { 108, -1, 0, "ustrl", "zonal wind stress over land", "Pa" },
+ { 109, -1, 0, "vstrl", "meridional wind stress over land", "Pa" },
+ { 110, -1, 0, "ahfliac", "latent heat flux over ice", "W m-2" },
+ { 111, -1, 0, "ahflwac", "latent heat flux over water", "W m-2" },
+ { 112, -1, 0, "ahfllac", "latent heat flux over land", "W m-2" },
+ { 113, -1, 0, "evapiac", "evaporation over ice", "kg m-2 s-1" },
+ { 114, -1, 0, "evapwac", "evaporation over water", "kg m-2 s-1" },
+ { 115, -1, 0, "evaplac", "evaporation over land", "kg m-2 s-1" },
+ { 116, -1, 0, "az0i", "roughness length over ice", "m" },
+ { 117, -1, 0, "az0w", "roughness length over water", "m" },
+ { 118, -1, 0, "az0l", "roughness length over land", "m" },
+ { 119, -1, 0, "ahfsiac", "sensible heat flux over ice", "W m-2" },
+ { 120, -1, 0, "ahfswac", "sensible heat flux over water", "W m-2" },
+ { 121, -1, 0, "ahfslac", "sensible heat flux over land", "W m-2" },
+ { 122, -1, 0, "alsoi", "albedo of ice", NULL },
+ { 123, -1, 0, "alsow", "albedo of water", NULL },
+ { 124, -1, 0, "alsol", "albedo of land", NULL },
+ { 125, -1, 0, "ahfice", "conductive heat flux", "W m-2" },
+ { 126, -1, 0, "qres", "residual heat flux for melting sea ice", "W m-2" },
+ { 127, -1, 0, "alake", "lake fraction of grid box", "fraction" },
+ { 128, -1, 0, "rintop", "low level inversion", NULL },
+ { 129, -1, 0, "geosp", "surface geopotential (orography)", "m^2/s^2" },
+ { 130, -1, 0, "t", "temperature", "K" },
+ { 131, -1, 0, "u", "u-velocity", "m/s" },
+ { 132, -1, 0, "v", "v-velocity", "m/s" },
+ { 133, -1, 0, "q", "specific humidity", "kg/kg" },
+ { 134, -1, 0, "aps", "surface pressure", "Pa" },
+ { 135, -1, 0, "omega", "vertical velocity", "Pa/s" },
+ { 136, -1, 0, "acdnc", "cloud droplet number concentration", "1 m-3" },
+ { 137, -1, 0, "apmeb", "vert. integr. tendencies of water", "kg m-2 s-1" },
+ { 138, -1, 0, "svo", "vorticity", "1/s" },
+ { 139, -1, 0, "tslm1", "surface temperature of land", "K" },
+ { 140, -1, 0, "ws", "soil wetness", "m" },
+ { 141, -1, 0, "sn", "snow depth", "m" },
+ { 142, -1, 0, "aprl", "large scale precipitation", "kg m-2 s-1" },
+ { 143, -1, 0, "aprc", "convective precipitation", "kg m-2 s-1" },
+ { 144, -1, 0, "aprs", "snow fall", "kg m-2 s-1" },
+ { 145, -1, 0, "vdis", "boundary layer dissipation", "W m-2" },
+ { 146, -1, 0, "ahfs", "sensible heat flux", "W m-2" },
+ { 147, -1, 0, "ahfl", "latent heat flux", "W m-2" },
+ { 148, -1, 0, "stream", "streamfunction", "m^2/s" },
+ { 149, -1, 0, "velopot", "velocity potential", "m^2/s" },
+ { 150, -1, 0, "xivi", "vertically integrated cloud ice", "kg m-2" },
+ { 151, -1, 0, "slp", "mean sea level pressure", "Pa" },
+ { 152, -1, 0, "lsp", "log surface pressure", NULL },
+ { 153, -1, 0, "xl", "cloud water", "kg/kg" },
+ { 154, -1, 0, "xi", "cloud ice", "kg/kg" },
+ { 155, -1, 0, "sd", "divergence", "1/s" },
+ { 156, -1, 0, "geopoth", "geopotential height", "m" },
+ { 157, -1, 0, "rhumidity", "relative humidity", "fraction" },
+ { 158, -1, 0, "var158", "tendency of surface pressure", "Pa/s" },
+ { 159, -1, 0, "wind10w", "10m windspeed over water", "m/s" },
+ { 160, -1, 0, "runoff", "surface runoff and drainage", "kg m-2 s-1" },
+ { 161, -1, 0, "drain", "drainage", "kg m-2 s-1" },
+ { 162, -1, 0, "aclc", "cloud cover", NULL },
+ { 163, -1, 0, "aclcv", "total cloud cover", NULL },
+ { 164, -1, 0, "aclcov", "total cloud cover (mean)", NULL },
+ { 165, -1, 0, "u10", "10m u-velocity", "m/s" },
+ { 166, -1, 0, "v10", "10m v-velocity", "m/s" },
+ { 167, -1, 0, "temp2", "2m temperature", "K" },
+ { 168, -1, 0, "dew2", "2m dew point temperature", "K" },
+ { 169, -1, 0, "tsurf", "surface temperature", "K" },
+ { 170, -1, 0, "xvar", "variance of total water amount qv+qi+ql", "kg/kg" },
+ { 171, -1, 0, "wind10", "10m windspeed", "m/s" },
+ { 172, -1, 0, "slm", "land sea mask (1. = land, 0. = sea/lakes)", NULL },
+ { 173, -1, 0, "az0", "roughness length", "m" },
+ { 174, -1, 0, "alb", "surface background albedo", NULL },
+ { 175, -1, 0, "albedo", "surface albedo", NULL },
+ { 176, -1, 0, "srads", "net surface solar radiation", "W m-2" },
+ { 177, -1, 0, "trads", "net surface thermal radiation", "W m-2" },
+ { 178, -1, 0, "srad0", "net top solar radiation", "W m-2" },
+ { 179, -1, 0, "trad0", "top thermal radiation (OLR)", "W m-2" },
+ { 180, -1, 0, "ustr", "u-stress", "Pa" },
+ { 181, -1, 0, "vstr", "v-stress", "Pa" },
+ { 182, -1, 0, "evap", "evaporation", "kg m-2 s-1" },
+ { 183, -1, 0, "xskew", "skewness of total water amount qv+qi+ql", NULL },
+ { 184, -1, 0, "srad0d", "top incoming solar radiation", "W m-2" },
+ { 185, -1, 0, "srafs", "net surf. solar radiation (clear sky)", "W m-2" },
+ { 186, -1, 0, "trafs", "net surf. thermal radiation (clear sky)", "W m-2" },
+ { 187, -1, 0, "sraf0", "net top solar radiation (clear sky)", "W m-2" },
+ { 188, -1, 0, "traf0", "net top thermal radiation (clear sky)", "W m-2" },
+ { 189, -1, 0, "sclfs", "surface solar cloud forcing", "W m-2" },
+ { 190, -1, 0, "tclfs", "surface thermal cloud forcing", "W m-2" },
+ { 191, -1, 0, "sclf0", "SW top cloud forcing (178-187)", "W m-2" },
+ { 192, -1, 0, "tclf0", "LW top cloud forcing (179-188)", "W m-2" },
+ { 193, -1, 0, "wl", "skin reservoir content", "m" },
+ { 194, -1, 0, "slf", "sea land fraction", NULL },
+ { 195, -1, 0, "ustrgw", "u-gravity wave stress", "Pa" },
+ { 196, -1, 0, "vstrgw", "v-gravity wave stress", "Pa" },
+ { 197, -1, 0, "vdisgw", "gravity wave dissipation", "W m-2" },
+ { 198, -1, 0, "vgrat", "vegetation ratio", NULL },
+ { 199, -1, 0, "orostd", "orographic standard deviation", "m" },
+ { 200, -1, 0, "vlt", "leaf area index", NULL },
+ { 201, -1, 0, "t2max", "maximum 2m-temperature", "K" },
+ { 202, -1, 0, "t2min", "minimum 2m-temperature", "K" },
+ { 203, -1, 0, "srad0u", "top solar radiation upward", "W m-2" },
+ { 204, -1, 0, "sradsu", "surface solar radiation upward", "W m-2" },
+ { 205, -1, 0, "tradsu", "surface thermal radiation upward", "W m-2" },
+ { 206, -1, 0, "grndflux", "surface ground heat flux", NULL },
+ { 207, -1, 0, "tsoil", "deep soil temperatures (5 layers)", "K" },
+ { 208, -1, 0, "ahfcon", "conductive heat flux through ice", "W m-2" },
+ { 209, -1, 0, "ahfres", "melting of ice", "W m-2" },
+ { 210, -1, 0, "seaice", "ice cover (fraction of 1-SLM)", NULL },
+ { 211, -1, 0, "siced", "ice depth", "m" },
+ { 212, -1, 0, "forest", "forest fraction", NULL },
+ { 213, -1, 0, "gld", "glacier depth", "m" },
+ { 214, -1, 0, "sni", "water equivalent of snow on ice", "m" },
+ { 215, -1, 0, "rogl", "glacier runoff", "kg m-2 s-1" },
+ { 216, -1, 0, "wimax", "maximum 10m-wind speed", "m/s" },
+ { 217, -1, 0, "topmax", "maximum height of convective cloud tops", "Pa" },
+ { 218, -1, 0, "snmel", "snow melt", "kg m-2 s-1" },
+ { 219, -1, 0, "runtoc", "surface runoff into ocean", "kg m-2 s-1" },
+ { 220, -1, 0, "runlnd", "surface runoff not running into ocean", "kg m-2 s-1" },
+ { 221, -1, 0, "apmegl", "P-E over land ice", "kg m-2 s-1" },
+ { 222, -1, 0, "snacl", "snow accumulation over land", "kg m-2 s-1" },
+ { 223, -1, 0, "aclcac", "cloud cover", NULL },
+ { 224, -1, 0, "tke", "turbulent kinetic energy", "m^2/s^2" },
+ { 225, -1, 0, "tkem1", "turbulent kinetic energy (t-1)", "m^2/s^2" },
+ { 226, -1, 0, "fao", "FAO data set (soil data flags)", "0...5" },
+ { 227, -1, 0, "rgcgn", "heat capacity of soil", NULL },
+ { 228, -1, 0, "sodif", "diffusivity of soil and land ice", "m^2/s" },
+ { 229, -1, 0, "wsmx", "field capacity of soil", "m" },
+ { 230, -1, 0, "qvi", "vertically integrated water vapor", "kg m-2" },
+ { 231, -1, 0, "xlvi", "vertically integrated cloud water", "kg m-2" },
+ { 232, -1, 0, "glac", "fraction of land covered by glaciers", NULL },
+ { 233, -1, 0, "snc", "snow depth at the canopy", "m" },
+ { 234, -1, 0, "rtype", "type of convection", "0...3" },
+ { 235, -1, 0, "abso4", "antropogenic sulfur burden", "kg m-2" },
+ { 236, -1, 0, "ao3", "ipcc ozone", "kg m-2" },
+ { 237, -1, 0, "tropo", "WMO defined tropopause height", "Pa" },
+ { 259, -1, 0, "windspeed", "windspeed (sqrt(u^2+v^2))", "m/s" },
+ { 260, -1, 0, "precip", "total precipitation (142+143)", "kg m-2 s-1" },
+ { 261, -1, 0, "net_top", "total top radiation (178+179)", "W m-2" },
+ { 262, -1, 0, "net_bot", "total surface radiation (176+177)", "W m-2" },
+ { 272, -1, 0, "mastfru", "mass stream function", "kg/s" },
};
-static const PAR mpiom1[] = {
- { 2, 0, "THO", "temperature", "C" },
- { 5, 0, "SAO", "salinity", "psu" },
- { 3, 0, "UKO", "zon. velocity", "m/s" },
- { 4, 0, "VKE", "mer. velocity", "m/s" },
- { 303, 0, "UKOMFL", "zon. velocity (divergence free)", "m/s" },
- { 304, 0, "VKEMFL", "mer. velocity (divergence free)", "m/s" },
- { 7, 0, "WO", "ver. velocity", "m/s" },
- { 8, 0, "RHO", "insitu density", "kg/m**3" },
- { 6, 0, "PO", "pressure", "Pa" },
- { 67, 0, "EMINPO", "freshwaterflux by restoring", "m/s" },
- { 70, 0, "FLUM", "total heatflux", "W/m**2" },
- { 79, 0, "PEM", "total freshwaterflux", "m/s" },
- { 13, 0, "SICTHO", "ice thickness", "m" },
- { 15, 0, "SICOMO", "ice compactness", "frac." },
- { 35, 0, "SICUO", "zon. ice velocity", "m/s" },
- { 36, 0, "SICVE", "mer. ice velocity", "m/s" },
- { 92, 0, "TAFO", "surface air temperature", "C" },
- { 164, 0, "FCLOU", "cloud cover", NULL },
- { 52, 0, "TXO", "surface u-stress", "Pa/1025." },
- { 53, 0, "TYE", "surface v-stress", "Pa/1025." },
- { 260, 0, "FPREC", "prescr. precipitation", "m/s" },
- { 80, 0, "FSWR", "downward shortwave rad.", "W/m**2" },
- { 81, 0, "FTDEW", "dewpoint temperature", "K" },
- { 171, 0, "FU10", "10m windspeed", "m/s" },
- { 141, 0, "SICSNO", "snow thickness", "m" },
- { 176, 0, "QSWO", "heat flux shortwave", "W/m**2" },
- { 177, 0, "QLWO", "heat flux longwave", "W/m**2" },
- { 147, 0, "QLAO", "heat flux latent", "W/m**2" },
- { 146, 0, "QSEO", "heat flux sensible", "W/m**2" },
- { 65, 0, "PRECO", "net freshwater flux + runoff", "m/s" },
- { 1, 0, "ZO", "sealevel", "m" },
- { 82, 0, "Z1O", "sealevel change", "m" },
- { 69, 0, "KCONDEP", "depth of convection", "level" },
- { 27, 0, "PSIUWE", "hor. bar. streamfunction", "Sv" },
- { 83, 0, "AMLD", "mixed layer depth", "m" },
- { 172, 0, "WETO", "landseamask (pressure points)", NULL },
- { 507, 0, "AMSUE", "landseamask (vector points v)", NULL },
- { 508, 0, "AMSUO", "landseamask (vector points u)", NULL },
- { 84, 0, "DEPTO", "depth at pressure points", "m" },
- { 484, 0, "DEUTO", "depth at vector points (u)", "m" },
- { 584, 0, "DEUTE", "depth at vector points (v)", "m" },
- { 184, 0, "DDUO", "level thickness (vector u )", "m" },
- { 284, 0, "DDUE", "level thickness (vector v )", "m" },
- { 384, 0, "DDPO", "level thickness (pressure )", "m" },
- { 85, 0, "DLXP", "grid distance x", "m" },
- { 86, 0, "DLYP", "grid distance y", "m" },
- { 185, 0, "DLXU", "grid distance x (vector u)", "m" },
- { 186, 0, "DLYU", "grid distance y (vector u)", "m" },
- { 285, 0, "DLXV", "grid distance x (vector v)", "m" },
- { 286, 0, "DLYV", "grid distance y (vector v)", "m" },
- { 54, 0, "GILA", "latitude in radiants", "rad" },
- { 55, 0, "GIPH", "longitude in radiants", "rad" },
- { 354, 0, "ALAT", "latitude in degrees (pressure)", "deg" },
- { 355, 0, "ALON", "longitude in degrees (pressure)", "deg" },
- { 154, 0, "ALATU", "latitude in degrees (vector u)", "deg" },
- { 155, 0, "ALONU", "longitude in degrees (vector u)", "deg" },
- { 254, 0, "ALATV", "latitude in degrees (vector v)", "deg" },
- { 255, 0, "ALONV", "longitude in degrees (vector v)", "deg" },
- { 110, 0, "AVO", "vertical impuls diffusion", "m**2/s" },
- { 111, 0, "DVO", "vertical T,S diffusion", "m**2/s" },
- { 142, 0, "SICTRU", "seaice transport x", "m**2/s" },
- { 143, 0, "SICTRV", "seaice transport y", "m**2/s" },
- { 612, 0, "WTMIX", "wind mixing", "m**2/s" },
- { 183, 0, "zmld", "mixed layer depth (SJ)", "m" },
- { 207, 0, "WGO", "GM vertical velocity", "m/s" },
- { 305, 0, "rivrun", "RiverRunoff", "m/s" },
- { 158, 0, "TMCDO", "mon. mean depth of convection", "level" },
- { 247, 0, "DQSWO", "heatflux sw over water", "W/m**2" },
- { 248, 0, "DQLWO", "heatflux lw over water", "W/m**2" },
- { 249, 0, "DQSEO", "heatflux se over water", "W/m**2" },
- { 250, 0, "DQLAO", "heatflux la over water", "W/m**2" },
- { 251, 0, "DQTHO", "heatflux net over water", "W/m**2" },
- { 252, 0, "DQSWI", "heatflux sw over seaice", "W/m**2" },
- { 253, 0, "DQLWI", "heatflux lw over seaice", "W/m**2" },
- { 254, 0, "DQSEI", "heatflux se over seaice", "W/m**2" },
- { 255, 0, "DQLAI", "heatflux la over seaice", "W/m**2" },
- { 256, 0, "DQTHI", "heatflux net over seaice", "W/m**2" },
- { 257, 0, "DTICEO", "Equi. temp over seaice", "K" },
- { 270, 0, "AOFLNHWO", "oasis net heat flux water", "W/m**2" },
- { 271, 0, "AOFLSHWO", "oasis downward short wave", "W/m**2" },
- { 272, 0, "AOFLRHIO", "oasis residual heat flux ice", "W/m**2" },
- { 273, 0, "AOFLCHIO", "oasis conduct. heat flux ice", "W/m**2" },
- { 274, 0, "AOFLFRWO", "oasis fluid fresh water flux", "m/s" },
- { 275, 0, "AOFLFRIO", "oasis solid fresh water flux", "m/s" },
- { 276, 0, "AOFLTXWO", "oasis wind stress water x", "Pa/102" },
- { 277, 0, "AOFLTYWO", "oasis wind stress water y", "Pa/102" },
- { 278, 0, "AOFLTXIO", "oasis wind stress ice x", "Pa/102" },
- { 279, 0, "AOFLTYIO", "oasis wind stress ice x", "Pa/102" },
- { 280, 0, "AOFLWSVO", "oasis wind speed", "m/s" },
+static const param_type mpiom1[] = {
+ { 2, -1, 0, "THO", "temperature", "C" },
+ { 5, -1, 0, "SAO", "salinity", "psu" },
+ { 3, -1, 0, "UKO", "zon. velocity", "m/s" },
+ { 4, -1, 0, "VKE", "mer. velocity", "m/s" },
+ { 303, -1, 0, "UKOMFL", "zon. velocity (divergence free)", "m/s" },
+ { 304, -1, 0, "VKEMFL", "mer. velocity (divergence free)", "m/s" },
+ { 7, -1, 0, "WO", "ver. velocity", "m/s" },
+ { 8, -1, 0, "RHO", "insitu density", "kg/m**3" },
+ { 6, -1, 0, "PO", "pressure", "Pa" },
+ { 67, -1, 0, "EMINPO", "freshwaterflux by restoring", "m/s" },
+ { 70, -1, 0, "FLUM", "total heatflux", "W/m**2" },
+ { 79, -1, 0, "PEM", "total freshwaterflux", "m/s" },
+ { 13, -1, 0, "SICTHO", "ice thickness", "m" },
+ { 15, -1, 0, "SICOMO", "ice compactness", "frac." },
+ { 35, -1, 0, "SICUO", "zon. ice velocity", "m/s" },
+ { 36, -1, 0, "SICVE", "mer. ice velocity", "m/s" },
+ { 92, -1, 0, "TAFO", "surface air temperature", "C" },
+ { 164, -1, 0, "FCLOU", "cloud cover", NULL },
+ { 52, -1, 0, "TXO", "surface u-stress", "Pa/1025." },
+ { 53, -1, 0, "TYE", "surface v-stress", "Pa/1025." },
+ { 260, -1, 0, "FPREC", "prescr. precipitation", "m/s" },
+ { 80, -1, 0, "FSWR", "downward shortwave rad.", "W/m**2" },
+ { 81, -1, 0, "FTDEW", "dewpoint temperature", "K" },
+ { 171, -1, 0, "FU10", "10m windspeed", "m/s" },
+ { 141, -1, 0, "SICSNO", "snow thickness", "m" },
+ { 176, -1, 0, "QSWO", "heat flux shortwave", "W/m**2" },
+ { 177, -1, 0, "QLWO", "heat flux longwave", "W/m**2" },
+ { 147, -1, 0, "QLAO", "heat flux latent", "W/m**2" },
+ { 146, -1, 0, "QSEO", "heat flux sensible", "W/m**2" },
+ { 65, -1, 0, "PRECO", "net freshwater flux + runoff", "m/s" },
+ { 1, -1, 0, "ZO", "sealevel", "m" },
+ { 82, -1, 0, "Z1O", "sealevel change", "m" },
+ { 69, -1, 0, "KCONDEP", "depth of convection", "level" },
+ { 27, -1, 0, "PSIUWE", "hor. bar. streamfunction", "Sv" },
+ { 83, -1, 0, "AMLD", "mixed layer depth", "m" },
+ { 172, -1, 0, "WETO", "landseamask (pressure points)", NULL },
+ { 507, -1, 0, "AMSUE", "landseamask (vector points v)", NULL },
+ { 508, -1, 0, "AMSUO", "landseamask (vector points u)", NULL },
+ { 84, -1, 0, "DEPTO", "depth at pressure points", "m" },
+ { 484, -1, 0, "DEUTO", "depth at vector points (u)", "m" },
+ { 584, -1, 0, "DEUTE", "depth at vector points (v)", "m" },
+ { 184, -1, 0, "DDUO", "level thickness (vector u )", "m" },
+ { 284, -1, 0, "DDUE", "level thickness (vector v )", "m" },
+ { 384, -1, 0, "DDPO", "level thickness (pressure )", "m" },
+ { 85, -1, 0, "DLXP", "grid distance x", "m" },
+ { 86, -1, 0, "DLYP", "grid distance y", "m" },
+ { 185, -1, 0, "DLXU", "grid distance x (vector u)", "m" },
+ { 186, -1, 0, "DLYU", "grid distance y (vector u)", "m" },
+ { 285, -1, 0, "DLXV", "grid distance x (vector v)", "m" },
+ { 286, -1, 0, "DLYV", "grid distance y (vector v)", "m" },
+ { 54, -1, 0, "GILA", "latitude in radiants", "rad" },
+ { 55, -1, 0, "GIPH", "longitude in radiants", "rad" },
+ { 354, -1, 0, "ALAT", "latitude in degrees (pressure)", "deg" },
+ { 355, -1, 0, "ALON", "longitude in degrees (pressure)", "deg" },
+ { 154, -1, 0, "ALATU", "latitude in degrees (vector u)", "deg" },
+ { 155, -1, 0, "ALONU", "longitude in degrees (vector u)", "deg" },
+ { 254, -1, 0, "ALATV", "latitude in degrees (vector v)", "deg" },
+ { 255, -1, 0, "ALONV", "longitude in degrees (vector v)", "deg" },
+ { 110, -1, 0, "AVO", "vertical impuls diffusion", "m**2/s" },
+ { 111, -1, 0, "DVO", "vertical T,S diffusion", "m**2/s" },
+ { 142, -1, 0, "SICTRU", "seaice transport x", "m**2/s" },
+ { 143, -1, 0, "SICTRV", "seaice transport y", "m**2/s" },
+ { 612, -1, 0, "WTMIX", "wind mixing", "m**2/s" },
+ { 183, -1, 0, "zmld", "mixed layer depth (SJ)", "m" },
+ { 207, -1, 0, "WGO", "GM vertical velocity", "m/s" },
+ { 305, -1, 0, "rivrun", "RiverRunoff", "m/s" },
+ { 158, -1, 0, "TMCDO", "mon. mean depth of convection", "level" },
+ { 247, -1, 0, "DQSWO", "heatflux sw over water", "W/m**2" },
+ { 248, -1, 0, "DQLWO", "heatflux lw over water", "W/m**2" },
+ { 249, -1, 0, "DQSEO", "heatflux se over water", "W/m**2" },
+ { 250, -1, 0, "DQLAO", "heatflux la over water", "W/m**2" },
+ { 251, -1, 0, "DQTHO", "heatflux net over water", "W/m**2" },
+ { 252, -1, 0, "DQSWI", "heatflux sw over seaice", "W/m**2" },
+ { 253, -1, 0, "DQLWI", "heatflux lw over seaice", "W/m**2" },
+ { 254, -1, 0, "DQSEI", "heatflux se over seaice", "W/m**2" },
+ { 255, -1, 0, "DQLAI", "heatflux la over seaice", "W/m**2" },
+ { 256, -1, 0, "DQTHI", "heatflux net over seaice", "W/m**2" },
+ { 257, -1, 0, "DTICEO", "Equi. temp over seaice", "K" },
+ { 270, -1, 0, "AOFLNHWO", "oasis net heat flux water", "W/m**2" },
+ { 271, -1, 0, "AOFLSHWO", "oasis downward short wave", "W/m**2" },
+ { 272, -1, 0, "AOFLRHIO", "oasis residual heat flux ice", "W/m**2" },
+ { 273, -1, 0, "AOFLCHIO", "oasis conduct. heat flux ice", "W/m**2" },
+ { 274, -1, 0, "AOFLFRWO", "oasis fluid fresh water flux", "m/s" },
+ { 275, -1, 0, "AOFLFRIO", "oasis solid fresh water flux", "m/s" },
+ { 276, -1, 0, "AOFLTXWO", "oasis wind stress water x", "Pa/102" },
+ { 277, -1, 0, "AOFLTYWO", "oasis wind stress water y", "Pa/102" },
+ { 278, -1, 0, "AOFLTXIO", "oasis wind stress ice x", "Pa/102" },
+ { 279, -1, 0, "AOFLTYIO", "oasis wind stress ice x", "Pa/102" },
+ { 280, -1, 0, "AOFLWSVO", "oasis wind speed", "m/s" },
};
-static const PAR ecmwf[] = {
- { 1, 0, "STRF", "Stream function", "m**2 s**-1" },
- { 2, 0, "VPOT", "Velocity potential", "m**2 s**-1" },
- { 3, 0, "PT", "Potential temperature", "K" },
- { 4, 0, "EQPT", "Equivalent potential temperature", "K" },
- { 5, 0, "SEPT", "Saturated equivalent potential temperature", "K" },
- { 11, 0, "UDVW", "U component of divergent wind", "m s**-1" },
- { 12, 0, "VDVW", "V component of divergent wind", "m s**-1" },
- { 13, 0, "URTW", "U component of rotational wind", "m s**-1" },
- { 14, 0, "VRTW", "V component of rotational wind", "m s**-1" },
- { 21, 0, "UCTP", "Unbalanced component of temperature", "K" },
- { 22, 0, "UCLN", "Unbalanced component of logarithm of surface pressure", NULL },
- { 23, 0, "UCDV", "Unbalanced component of divergence", "s**-1" },
- { 26, 0, "CL", "Lake cover", NULL },
- { 27, 0, "CVL", "Low vegetation cover", NULL },
- { 28, 0, "CVH", "High vegetation cover", NULL },
- { 29, 0, "TVL", "Type of low vegetation", NULL },
- { 30, 0, "TVH", "Type of high vegetation", NULL },
- { 31, 0, "CI", "Sea-ice cover", NULL },
- { 32, 0, "ASN", "Snow albedo", NULL },
- { 33, 0, "RSN", "Snow density kg", "m**-3" },
- { 34, 0, "SSTK", "Sea surface temperature", "K" },
- { 35, 0, "ISTL1", "Ice surface temperature layer 1", "K" },
- { 36, 0, "ISTL2", "Ice surface temperature layer 2", "K" },
- { 37, 0, "ISTL3", "Ice surface temperature layer 3", "K" },
- { 38, 0, "ISTL4", "Ice surface temperature layer 4", "K" },
- { 39, 0, "SWVL1", "Volumetric soil water layer 1", "m**3 m**-3" },
- { 40, 0, "SWVL2", "Volumetric soil water layer 2", "m**3 m**-3" },
- { 41, 0, "SWVL3", "Volumetric soil water layer 3", "m**3 m**-3" },
- { 42, 0, "SWVL4", "Volumetric soil water layer 4", "m**3 m**-3" },
- { 43, 0, "SLT", "Soil type", NULL },
- { 44, 0, "ES", "Snow evaporation m of water", NULL },
- { 45, 0, "SMLT", "Snowmelt m of water", NULL },
- { 46, 0, "SDUR", "Solar duration", "s" },
- { 47, 0, "DSRP", "Direct solar radiation", "w m**-2" },
- { 48, 0, "MAGSS", "Magnitude of surface stress", "N m**-2 s" },
- { 49, 0, "WG10", "Wind gust at 10 metres", "m s**-1" },
- { 50, 0, "LSPF", "Large-scale precipitation fraction", "s" },
- { 51, 0, "MX2T24", "Maximum 2 metre temperature", "K" },
- { 52, 0, "MN2T24", "Minimum 2 metre temperature", "K" },
- { 53, 0, "MONT", "Montgomery potential", "m**2 s**-2" },
- { 54, 0, "PRES", "Pressure", "Pa" },
- { 55, 0, "MEAN2T24", "Mean 2 metre temperature past 24 hours", "K" },
- { 56, 0, "MEAN2D24", "Mean 2 metre dewpoint temperature past 24 hours", "K" },
- { 60, 0, "PV", "Potential vorticity", "K m**2 kg**-1 s**-1" },
- { 127, 0, "AT", "Atmospheric tide", NULL },
- { 128, 0, "BV", "Budget values", NULL },
- { 129, 0, "Z", "Geopotential", "m**2 s**-2" },
- { 130, 0, "T", "Temperature", "K" },
- { 131, 0, "U", "U velocity", "m s**-1" },
- { 132, 0, "V", "V velocity", "m s**-1" },
- { 133, 0, "Q", "Specific humidity", "kg kg**-1" },
- { 134, 0, "SP", "Surface pressure", "Pa" },
- { 135, 0, "W", "Vertical velocity", "Pa s**-1" },
- { 136, 0, "TCW", "Total column water", "kg m**-2" },
- { 137, 0, "TCWV", "Total column water vapour", "kg m**-2" },
- { 138, 0, "VO", "Vorticity (relative)", "s**-1" },
- { 139, 0, "STL1", "Soil temperature level 1", "K" },
- { 140, 0, "SWL1", "Soil wetness level 1 m of water", NULL },
- { 141, 0, "SD", "Snow depth 1 m of water equivalent", NULL },
- { 142, 0, "LSP", "Stratiform precipitation (Large scale precipitation)", "m" },
- { 143, 0, "CP", "Convective precipitation", "m" },
- { 144, 0, "SF", "Snowfall (convective + stratiform)", "m" },
- { 145, 0, "BLD", "Boundary layer dissipation", "W m**-2 s" },
- { 146, 0, "SSHF", "Surface sensible heat flux", "W m**-2 s" },
- { 147, 0, "SLHF", "Surface latent heat flux", "W m**-2 s" },
- { 148, 0, "CHNK", "Charnock", NULL },
- { 149, 0, "SNR", "Surface net radiation", "W m**-2 s" },
- { 150, 0, "TNR", "Top net radiation", NULL },
- { 151, 0, "MSL", "Mean sea-level pressure", "Pa" },
- { 152, 0, "LNSP", "Logarithm of surface pressure", NULL },
- { 153, 0, "SWHR", "Short-wave heating rate", "K" },
- { 154, 0, "LWHR", "Long-wave heating rate", "K" },
- { 155, 0, "D", "Divergence", "s**-1" },
- { 156, 0, "GH", "Height m Geopotential height", NULL },
- { 157, 0, "R", "Relative humidity", "%" },
- { 158, 0, "TSP", "Tendency of surface pressure", "Pa s**-1" },
- { 159, 0, "BLH", "Boundary layer height", "m" },
- { 160, 0, "SDOR", "Standard deviation of orography", NULL },
- { 161, 0, "ISOR", "Anisotropy of sub-gridscale orography", NULL },
- { 162, 0, "ANOR", "Angle of sub-gridscale orography", "rad" },
- { 163, 0, "SLOR", "Slope of sub-gridscale orography", NULL },
- { 164, 0, "TCC", "Total cloud cover", NULL },
- { 165, 0, "U10M", "10 metre U wind component", "m s**-1" },
- { 166, 0, "V10M", "10 metre V wind component", "m s**-1" },
- { 167, 0, "T2M", "2 metre temperature", "K" },
- { 168, 0, "D2M", "2 metre dewpoint temperature", "K" },
- { 169, 0, "SSRD", "Surface solar radiation downwards", "W m**-2 s" },
- { 170, 0, "STL2", "Soil temperature level 2", "K" },
- { 171, 0, "SWL2", "Soil wetness level 2", "m of water" },
- { 172, 0, "LSM", "Land/sea mask", NULL },
- { 173, 0, "SR", "Surface roughness", "m" },
- { 174, 0, "AL", "Albedo", NULL },
- { 175, 0, "STRD", "Surface thermal radiation downwards", "W m**-2 s" },
- { 176, 0, "SSR", "Surface solar radiation", "W m**-2 s" },
- { 177, 0, "STR", "Surface thermal radiation", "W m**-2 s" },
- { 178, 0, "TSR", "Top solar radiation", "W m**-2 s" },
- { 179, 0, "TTR", "Top thermal radiation", "W m**-2 s" },
- { 180, 0, "EWSS", "East/West surface stress", "N m**-2 s" },
- { 181, 0, "NSSS", "North/South surface stress", "N m**-2 s" },
- { 182, 0, "E", "Evaporation", "m of water" },
- { 183, 0, "STL3", "Soil temperature level 3", "K" },
- { 184, 0, "SWL3", "Soil wetness level 3", "m of water" },
- { 185, 0, "CCC", "Convective cloud cover", NULL },
- { 186, 0, "LCC", "Low cloud cover", NULL },
- { 187, 0, "MCC", "Medium cloud cover", NULL },
- { 188, 0, "HCC", "High cloud cover", NULL },
- { 189, 0, "SUND", "Sunshine duration", "s" },
- { 190, 0, "EWOV", "EW component of subgrid orographic variance", "m**2" },
- { 191, 0, "NSOV", "NS component of subgrid orographic variance", "m**2" },
- { 192, 0, "NWOV", "NWSE component of subgrid orographic variance", "m**2" },
- { 193, 0, "NEOV", "NESW component of subgrid orographic variance", "m**2" },
- { 194, 0, "BTMP", "Brightness temperature", "K" },
- { 195, 0, "LGWS", "Lat. component of gravity wave stress", "N m**-2 s" },
- { 196, 0, "MGWS", "Meridional component of gravity wave stress", "N m**-2 s" },
- { 197, 0, "GWD", "Gravity wave dissipation", "W m**-2 s" },
- { 198, 0, "SRC", "Skin reservoir content", "m of water" },
- { 199, 0, "VEG", "Vegetation fraction", NULL },
- { 200, 0, "VSO", "Variance of sub-gridscale orography", "m**2" },
- { 201, 0, "MX2T", "Maximum 2 metre temperature since previous post-processing", "K" },
- { 202, 0, "MN2T", "Minimum 2 metre temperature since previous post-processing", "K" },
- { 203, 0, "O3", "Ozone mass mixing ratio", "kg kg**-1" },
- { 204, 0, "PAW", "Precipiation analysis weights", NULL },
- { 205, 0, "RO", "Runoff", "m" },
- { 206, 0, "TCO3", "Total column ozone", "kg m**-2" },
- { 207, 0, "WS10", "10 meter windspeed", "m s**-1" },
- { 208, 0, "TSRC", "Top net solar radiation, clear sky", "W m**-2" },
- { 209, 0, "TTRC", "Top net thermal radiation, clear sky", "W m**-2" },
- { 210, 0, "SSRC", "Surface net solar radiation, clear sky", "W m**-2" },
- { 211, 0, "STRC", "Surface net thermal radiation, clear sky", "W m**-2" },
- { 212, 0, "SI", "Solar insolation", "W m**-2" },
- { 214, 0, "DHR", "Diabatic heating by radiation", "K" },
- { 215, 0, "DHVD", "Diabatic heating by vertical diffusion", "K" },
- { 216, 0, "DHCC", "Diabatic heating by cumulus convection", "K" },
- { 217, 0, "DHLC", "Diabatic heating large-scale condensation", "K" },
- { 218, 0, "VDZW", "Vertical diffusion of zonal wind", "m s**-1" },
- { 219, 0, "VDMW", "Vertical diffusion of meridional wind", "m s**-1" },
- { 220, 0, "EWGD", "EW gravity wave drag tendency", "m s**-1" },
- { 221, 0, "NSGD", "NS gravity wave drag tendency", "m s**-1" },
- { 222, 0, "CTZW", "Convective tendency of zonal wind", "m s**-1" },
- { 223, 0, "CTMW", "Convective tendency of meridional wind", "m s**-1" },
- { 224, 0, "VDH", "Vertical diffusion of humidity", "kg kg**-1" },
- { 225, 0, "HTCC", "Humidity tendency by cumulus convection", "kg kg**-1" },
- { 226, 0, "HTLC", "Humidity tendency large-scale condensation", "kg kg**-1" },
- { 227, 0, "CRNH", "Change from removing negative humidity", "kg kg**-1" },
- { 228, 0, "TP", "Total precipitation", "m" },
- { 229, 0, "IEWS", "Instantaneous X surface stress", "N m**-2" },
- { 230, 0, "INSS", "Instantaneous Y surface stress", "N m**-2" },
- { 231, 0, "ISHF", "Instantaneous surface heat flux", "W m**-2" },
- { 232, 0, "IE", "Instantaneous moisture flux", "kg m**-2 s" },
- { 233, 0, "ASQ", "Apparent surface humidity", "kg kg**-1" },
- { 234, 0, "LSRH", "Logarithm of surface roughness length for heat", NULL },
- { 235, 0, "SKT", "Skin temperature", "K" },
- { 236, 0, "STL4", "Soil temperature level 4", "K" },
- { 237, 0, "SWL4", "Soil wetness level 4", "m" },
- { 238, 0, "TSN", "Temperature of snow layer", "K" },
- { 239, 0, "CSF", "Convective snowfall", "m of water equivalent" },
- { 240, 0, "LSF", "Large-scale snowfall", "m of water equivalent" },
- { 241, 0, "ACF", "Accumulated cloud fraction tendency", NULL },
- { 242, 0, "ALW", "Accumulated liquid water tendency", NULL },
- { 243, 0, "FAL", "Forecast albedo", NULL },
- { 244, 0, "FSR", "Forecast surface roughness", "m" },
- { 245, 0, "FLSR", "Forecast log of surface roughness for heat", NULL },
- { 246, 0, "CLWC", "Cloud liquid water content", "kg kg**-1" },
- { 247, 0, "CIWC", "Cloud ice water content", "kg kg**-1" },
- { 248, 0, "CC", "Cloud cover", NULL },
- { 249, 0, "AIW", "Accumulated ice water tendency", NULL },
- { 250, 0, "ICE", "Ice age", NULL },
- { 251, 0, "ATTE", "Adiabatic tendency of temperature", "K" },
- { 252, 0, "ATHE", "Adiabatic tendency of humidity", "kg kg**-1" },
- { 253, 0, "ATZE", "Adiabatic tendency of zonal wind", "m s**-1" },
- { 254, 0, "ATMW", "Adiabatic tendency of meridional wind", "m s**-1" },
+static const param_type ecmwf[] = {
+ { 1, -1, 0, "STRF", "Stream function", "m**2 s**-1" },
+ { 2, -1, 0, "VPOT", "Velocity potential", "m**2 s**-1" },
+ { 3, -1, 0, "PT", "Potential temperature", "K" },
+ { 4, -1, 0, "EQPT", "Equivalent potential temperature", "K" },
+ { 5, -1, 0, "SEPT", "Saturated equivalent potential temperature", "K" },
+ { 11, -1, 0, "UDVW", "U component of divergent wind", "m s**-1" },
+ { 12, -1, 0, "VDVW", "V component of divergent wind", "m s**-1" },
+ { 13, -1, 0, "URTW", "U component of rotational wind", "m s**-1" },
+ { 14, -1, 0, "VRTW", "V component of rotational wind", "m s**-1" },
+ { 21, -1, 0, "UCTP", "Unbalanced component of temperature", "K" },
+ { 22, -1, 0, "UCLN", "Unbalanced component of logarithm of surface pressure", NULL },
+ { 23, -1, 0, "UCDV", "Unbalanced component of divergence", "s**-1" },
+ { 26, -1, 0, "CL", "Lake cover", NULL },
+ { 27, -1, 0, "CVL", "Low vegetation cover", NULL },
+ { 28, -1, 0, "CVH", "High vegetation cover", NULL },
+ { 29, -1, 0, "TVL", "Type of low vegetation", NULL },
+ { 30, -1, 0, "TVH", "Type of high vegetation", NULL },
+ { 31, -1, 0, "CI", "Sea-ice cover", NULL },
+ { 32, -1, 0, "ASN", "Snow albedo", NULL },
+ { 33, -1, 0, "RSN", "Snow density kg", "m**-3" },
+ { 34, -1, 0, "SSTK", "Sea surface temperature", "K" },
+ { 35, -1, 0, "ISTL1", "Ice surface temperature layer 1", "K" },
+ { 36, -1, 0, "ISTL2", "Ice surface temperature layer 2", "K" },
+ { 37, -1, 0, "ISTL3", "Ice surface temperature layer 3", "K" },
+ { 38, -1, 0, "ISTL4", "Ice surface temperature layer 4", "K" },
+ { 39, -1, 0, "SWVL1", "Volumetric soil water layer 1", "m**3 m**-3" },
+ { 40, -1, 0, "SWVL2", "Volumetric soil water layer 2", "m**3 m**-3" },
+ { 41, -1, 0, "SWVL3", "Volumetric soil water layer 3", "m**3 m**-3" },
+ { 42, -1, 0, "SWVL4", "Volumetric soil water layer 4", "m**3 m**-3" },
+ { 43, -1, 0, "SLT", "Soil type", NULL },
+ { 44, -1, 0, "ES", "Snow evaporation m of water", NULL },
+ { 45, -1, 0, "SMLT", "Snowmelt m of water", NULL },
+ { 46, -1, 0, "SDUR", "Solar duration", "s" },
+ { 47, -1, 0, "DSRP", "Direct solar radiation", "w m**-2" },
+ { 48, -1, 0, "MAGSS", "Magnitude of surface stress", "N m**-2 s" },
+ { 49, -1, 0, "WG10", "Wind gust at 10 metres", "m s**-1" },
+ { 50, -1, 0, "LSPF", "Large-scale precipitation fraction", "s" },
+ { 51, -1, 0, "MX2T24", "Maximum 2 metre temperature", "K" },
+ { 52, -1, 0, "MN2T24", "Minimum 2 metre temperature", "K" },
+ { 53, -1, 0, "MONT", "Montgomery potential", "m**2 s**-2" },
+ { 54, -1, 0, "PRES", "Pressure", "Pa" },
+ { 55, -1, 0, "MEAN2T24", "Mean 2 metre temperature past 24 hours", "K" },
+ { 56, -1, 0, "MEAN2D24", "Mean 2 metre dewpoint temperature past 24 hours", "K" },
+ { 60, -1, 0, "PV", "Potential vorticity", "K m**2 kg**-1 s**-1" },
+ { 127, -1, 0, "AT", "Atmospheric tide", NULL },
+ { 128, -1, 0, "BV", "Budget values", NULL },
+ { 129, -1, 0, "Z", "Geopotential", "m**2 s**-2" },
+ { 130, -1, 0, "T", "Temperature", "K" },
+ { 131, -1, 0, "U", "U velocity", "m s**-1" },
+ { 132, -1, 0, "V", "V velocity", "m s**-1" },
+ { 133, -1, 0, "Q", "Specific humidity", "kg kg**-1" },
+ { 134, -1, 0, "SP", "Surface pressure", "Pa" },
+ { 135, -1, 0, "W", "Vertical velocity", "Pa s**-1" },
+ { 136, -1, 0, "TCW", "Total column water", "kg m**-2" },
+ { 137, -1, 0, "TCWV", "Total column water vapour", "kg m**-2" },
+ { 138, -1, 0, "VO", "Vorticity (relative)", "s**-1" },
+ { 139, -1, 0, "STL1", "Soil temperature level 1", "K" },
+ { 140, -1, 0, "SWL1", "Soil wetness level 1 m of water", NULL },
+ { 141, -1, 0, "SD", "Snow depth 1 m of water equivalent", NULL },
+ { 142, -1, 0, "LSP", "Stratiform precipitation (Large scale precipitation)", "m" },
+ { 143, -1, 0, "CP", "Convective precipitation", "m" },
+ { 144, -1, 0, "SF", "Snowfall (convective + stratiform)", "m" },
+ { 145, -1, 0, "BLD", "Boundary layer dissipation", "W m**-2 s" },
+ { 146, -1, 0, "SSHF", "Surface sensible heat flux", "W m**-2 s" },
+ { 147, -1, 0, "SLHF", "Surface latent heat flux", "W m**-2 s" },
+ { 148, -1, 0, "CHNK", "Charnock", NULL },
+ { 149, -1, 0, "SNR", "Surface net radiation", "W m**-2 s" },
+ { 150, -1, 0, "TNR", "Top net radiation", NULL },
+ { 151, -1, 0, "MSL", "Mean sea-level pressure", "Pa" },
+ { 152, -1, 0, "LNSP", "Logarithm of surface pressure", NULL },
+ { 153, -1, 0, "SWHR", "Short-wave heating rate", "K" },
+ { 154, -1, 0, "LWHR", "Long-wave heating rate", "K" },
+ { 155, -1, 0, "D", "Divergence", "s**-1" },
+ { 156, -1, 0, "GH", "Height m Geopotential height", NULL },
+ { 157, -1, 0, "R", "Relative humidity", "%" },
+ { 158, -1, 0, "TSP", "Tendency of surface pressure", "Pa s**-1" },
+ { 159, -1, 0, "BLH", "Boundary layer height", "m" },
+ { 160, -1, 0, "SDOR", "Standard deviation of orography", NULL },
+ { 161, -1, 0, "ISOR", "Anisotropy of sub-gridscale orography", NULL },
+ { 162, -1, 0, "ANOR", "Angle of sub-gridscale orography", "rad" },
+ { 163, -1, 0, "SLOR", "Slope of sub-gridscale orography", NULL },
+ { 164, -1, 0, "TCC", "Total cloud cover", NULL },
+ { 165, -1, 0, "U10M", "10 metre U wind component", "m s**-1" },
+ { 166, -1, 0, "V10M", "10 metre V wind component", "m s**-1" },
+ { 167, -1, 0, "T2M", "2 metre temperature", "K" },
+ { 168, -1, 0, "D2M", "2 metre dewpoint temperature", "K" },
+ { 169, -1, 0, "SSRD", "Surface solar radiation downwards", "W m**-2 s" },
+ { 170, -1, 0, "STL2", "Soil temperature level 2", "K" },
+ { 171, -1, 0, "SWL2", "Soil wetness level 2", "m of water" },
+ { 172, -1, 0, "LSM", "Land/sea mask", NULL },
+ { 173, -1, 0, "SR", "Surface roughness", "m" },
+ { 174, -1, 0, "AL", "Albedo", NULL },
+ { 175, -1, 0, "STRD", "Surface thermal radiation downwards", "W m**-2 s" },
+ { 176, -1, 0, "SSR", "Surface solar radiation", "W m**-2 s" },
+ { 177, -1, 0, "STR", "Surface thermal radiation", "W m**-2 s" },
+ { 178, -1, 0, "TSR", "Top solar radiation", "W m**-2 s" },
+ { 179, -1, 0, "TTR", "Top thermal radiation", "W m**-2 s" },
+ { 180, -1, 0, "EWSS", "East/West surface stress", "N m**-2 s" },
+ { 181, -1, 0, "NSSS", "North/South surface stress", "N m**-2 s" },
+ { 182, -1, 0, "E", "Evaporation", "m of water" },
+ { 183, -1, 0, "STL3", "Soil temperature level 3", "K" },
+ { 184, -1, 0, "SWL3", "Soil wetness level 3", "m of water" },
+ { 185, -1, 0, "CCC", "Convective cloud cover", NULL },
+ { 186, -1, 0, "LCC", "Low cloud cover", NULL },
+ { 187, -1, 0, "MCC", "Medium cloud cover", NULL },
+ { 188, -1, 0, "HCC", "High cloud cover", NULL },
+ { 189, -1, 0, "SUND", "Sunshine duration", "s" },
+ { 190, -1, 0, "EWOV", "EW component of subgrid orographic variance", "m**2" },
+ { 191, -1, 0, "NSOV", "NS component of subgrid orographic variance", "m**2" },
+ { 192, -1, 0, "NWOV", "NWSE component of subgrid orographic variance", "m**2" },
+ { 193, -1, 0, "NEOV", "NESW component of subgrid orographic variance", "m**2" },
+ { 194, -1, 0, "BTMP", "Brightness temperature", "K" },
+ { 195, -1, 0, "LGWS", "Lat. component of gravity wave stress", "N m**-2 s" },
+ { 196, -1, 0, "MGWS", "Meridional component of gravity wave stress", "N m**-2 s" },
+ { 197, -1, 0, "GWD", "Gravity wave dissipation", "W m**-2 s" },
+ { 198, -1, 0, "SRC", "Skin reservoir content", "m of water" },
+ { 199, -1, 0, "VEG", "Vegetation fraction", NULL },
+ { 200, -1, 0, "VSO", "Variance of sub-gridscale orography", "m**2" },
+ { 201, -1, 0, "MX2T", "Maximum 2 metre temperature since previous post-processing", "K" },
+ { 202, -1, 0, "MN2T", "Minimum 2 metre temperature since previous post-processing", "K" },
+ { 203, -1, 0, "O3", "Ozone mass mixing ratio", "kg kg**-1" },
+ { 204, -1, 0, "PAW", "Precipiation analysis weights", NULL },
+ { 205, -1, 0, "RO", "Runoff", "m" },
+ { 206, -1, 0, "TCO3", "Total column ozone", "kg m**-2" },
+ { 207, -1, 0, "WS10", "10 meter windspeed", "m s**-1" },
+ { 208, -1, 0, "TSRC", "Top net solar radiation, clear sky", "W m**-2" },
+ { 209, -1, 0, "TTRC", "Top net thermal radiation, clear sky", "W m**-2" },
+ { 210, -1, 0, "SSRC", "Surface net solar radiation, clear sky", "W m**-2" },
+ { 211, -1, 0, "STRC", "Surface net thermal radiation, clear sky", "W m**-2" },
+ { 212, -1, 0, "SI", "Solar insolation", "W m**-2" },
+ { 214, -1, 0, "DHR", "Diabatic heating by radiation", "K" },
+ { 215, -1, 0, "DHVD", "Diabatic heating by vertical diffusion", "K" },
+ { 216, -1, 0, "DHCC", "Diabatic heating by cumulus convection", "K" },
+ { 217, -1, 0, "DHLC", "Diabatic heating large-scale condensation", "K" },
+ { 218, -1, 0, "VDZW", "Vertical diffusion of zonal wind", "m s**-1" },
+ { 219, -1, 0, "VDMW", "Vertical diffusion of meridional wind", "m s**-1" },
+ { 220, -1, 0, "EWGD", "EW gravity wave drag tendency", "m s**-1" },
+ { 221, -1, 0, "NSGD", "NS gravity wave drag tendency", "m s**-1" },
+ { 222, -1, 0, "CTZW", "Convective tendency of zonal wind", "m s**-1" },
+ { 223, -1, 0, "CTMW", "Convective tendency of meridional wind", "m s**-1" },
+ { 224, -1, 0, "VDH", "Vertical diffusion of humidity", "kg kg**-1" },
+ { 225, -1, 0, "HTCC", "Humidity tendency by cumulus convection", "kg kg**-1" },
+ { 226, -1, 0, "HTLC", "Humidity tendency large-scale condensation", "kg kg**-1" },
+ { 227, -1, 0, "CRNH", "Change from removing negative humidity", "kg kg**-1" },
+ { 228, -1, 0, "TP", "Total precipitation", "m" },
+ { 229, -1, 0, "IEWS", "Instantaneous X surface stress", "N m**-2" },
+ { 230, -1, 0, "INSS", "Instantaneous Y surface stress", "N m**-2" },
+ { 231, -1, 0, "ISHF", "Instantaneous surface heat flux", "W m**-2" },
+ { 232, -1, 0, "IE", "Instantaneous moisture flux", "kg m**-2 s" },
+ { 233, -1, 0, "ASQ", "Apparent surface humidity", "kg kg**-1" },
+ { 234, -1, 0, "LSRH", "Logarithm of surface roughness length for heat", NULL },
+ { 235, -1, 0, "SKT", "Skin temperature", "K" },
+ { 236, -1, 0, "STL4", "Soil temperature level 4", "K" },
+ { 237, -1, 0, "SWL4", "Soil wetness level 4", "m" },
+ { 238, -1, 0, "TSN", "Temperature of snow layer", "K" },
+ { 239, -1, 0, "CSF", "Convective snowfall", "m of water equivalent" },
+ { 240, -1, 0, "LSF", "Large-scale snowfall", "m of water equivalent" },
+ { 241, -1, 0, "ACF", "Accumulated cloud fraction tendency", NULL },
+ { 242, -1, 0, "ALW", "Accumulated liquid water tendency", NULL },
+ { 243, -1, 0, "FAL", "Forecast albedo", NULL },
+ { 244, -1, 0, "FSR", "Forecast surface roughness", "m" },
+ { 245, -1, 0, "FLSR", "Forecast log of surface roughness for heat", NULL },
+ { 246, -1, 0, "CLWC", "Cloud liquid water content", "kg kg**-1" },
+ { 247, -1, 0, "CIWC", "Cloud ice water content", "kg kg**-1" },
+ { 248, -1, 0, "CC", "Cloud cover", NULL },
+ { 249, -1, 0, "AIW", "Accumulated ice water tendency", NULL },
+ { 250, -1, 0, "ICE", "Ice age", NULL },
+ { 251, -1, 0, "ATTE", "Adiabatic tendency of temperature", "K" },
+ { 252, -1, 0, "ATHE", "Adiabatic tendency of humidity", "kg kg**-1" },
+ { 253, -1, 0, "ATZE", "Adiabatic tendency of zonal wind", "m s**-1" },
+ { 254, -1, 0, "ATMW", "Adiabatic tendency of meridional wind", "m s**-1" },
};
-static const PAR remo[] = {
- { 14, 0, "FTKVM", "turbulent transfer coefficient of momentum in the atmosphere", NULL },
- { 15, 0, "FTKVH", "turbulent transfer coefficient of heat in the atmosphere", NULL },
- { 38, 0, "U10ER", "10m u-velocity", "m/s" },
- { 39, 0, "V10ER", "10m v-velocity", "m/s" },
- { 40, 0, "CAPE", "convetive available potential energy", NULL },
- { 41, 0, "GHPBL", "height of the planetary boudary layer", "gpm" },
- { 42, 0, "BETA", "BETA", NULL },
- { 43, 0, "WMINLOK", "WMINLOK", NULL },
- { 44, 0, "WMAXLOK", "WMAXLOK", NULL },
- { 45, 0, "VBM10M", "maximum of the expected gust velocity near the surface", "m/s" },
- { 46, 0, "BFLHS", "surface sensible heat flux", "W/m**2" },
- { 47, 0, "BFLQDS", "surface latent heat flux", "W/m**2" },
- { 48, 0, "TMCM", "turbulent transfer coefficient of momentum at the surface", NULL },
- { 49, 0, "TRSOL", "TRSOL", NULL },
- { 50, 0, "TMCH", "turbulent transfer coefficient of heat at the surface", NULL },
- { 51, 0, "EMTEF", "EMTEF", NULL },
- { 52, 0, "TRSOF", "TRSOF", NULL },
- { 53, 0, "DRAIN", "drainage", "mm" },
- { 54, 0, "TSL", "surface temperature (land)", "K" },
- { 55, 0, "TSW", "surface temperature (water)", "K" },
- { 56, 0, "TSI", "surface temperature (ice)", "K" },
- { 57, 0, "USTRL", "surface u-stress (land)", "Pa" },
- { 58, 0, "USTRW", "surface u-stress (water)", "Pa" },
- { 59, 0, "USTRI", "surface u-stress (ice)", "Pa" },
- { 60, 0, "VSTRL", "surface v-stress (land)", "Pa" },
- { 61, 0, "VSTRW", "surface v-stress (water)", "Pa" },
- { 62, 0, "VSTRI", "surface v-stress (ice)", "Pa" },
- { 63, 0, "EVAPL", "surface evaporation (land)", "mm" },
- { 64, 0, "EVAPW", "surface evaporation (water)", "mm" },
- { 65, 0, "EVAPI", "surface evaporation (ice)", "mm" },
- { 66, 0, "AHFLL", "surface latent heat flux (land)", "W/m**2" },
- { 67, 0, "AHFLW", "surface latent heat flux (water)", "W/m**2" },
- { 68, 0, "AHFLI", "surface latent heat flux (ice)", "W/m**2" },
- { 69, 0, "AHFSL", "surface sensible heat flux (land)", "W/m**2" },
- { 70, 0, "AHFSW", "surface sensible heat flux (water)", "W/m**2" },
- { 71, 0, "AHFSI", "surface sensible heat flux (ice)", "W/m**2" },
- { 72, 0, "AZ0L", "surface roughness length (land)", "m" },
- { 73, 0, "AZ0W", "surface roughness length (water)", "m" },
- { 74, 0, "AZ0I", "surface roughness length (ice)", "m" },
- { 75, 0, "ALSOL", "surface albedo (land)", "fract." },
- { 76, 0, "ALSOW", "surface albedo (water)", "fract." },
- { 77, 0, "ALSOI", "surface albedo (ice)", "fract." },
- { 81, 0, "TMCHL", "turbulent transfer coefficient of heat at the surface (land)", NULL },
- { 82, 0, "TMCHW", "turbulent transfer coefficient of heat at the surface (water)", NULL },
- { 83, 0, "TMCHI", "turbulent transfer coefficient of heat at the surface (ice)", NULL },
- { 84, 0, "QDBL", "specific humidity surface (land)", "kg/kg" },
- { 85, 0, "QDBW", "specific humidity surface (water)", "kg/kg" },
- { 86, 0, "QDBI", "specific humidity surface (ice)", "kg/kg" },
- { 87, 0, "BFLHSL", "surface sensible heat flux (land)", "W/m**2" },
- { 88, 0, "BFLHSW", "surface sensible heat flux (water)", "W/m**2" },
- { 89, 0, "BFLHSI", "surface sensible heat flux (ice)", "W/m**2" },
- { 90, 0, "BFLQDSL", "surface latent heat flux (land)", "W/m**2" },
- { 91, 0, "BFLQDSW", "surface latent heat flux (water)", "W/m**2" },
- { 92, 0, "BFLQDSI", "surface latent heat flux (ice)", "W/m**2" },
- { 93, 0, "AHFICE", "sea-ice: conductive heat", "W/m" },
- { 94, 0, "QRES", "residual heat flux for melting sea ice", "W/m**2" },
- { 95, 0, "SRFL", "SRFL", NULL },
- { 96, 0, "QDBOXS", "horizontal transport of water vapour", "kg/m**2" },
- { 97, 0, "QWBOXS", "horizontal transport of cloud water", "kg/m**2" },
- { 98, 0, "EKBOXS", "horizontal transport of kinetic energy", "(3600*J)/m**2" },
- { 99, 0, "FHBOXS", "horizontal transport of sensible heat", "(3600*J)/m**2" },
- { 100, 0, "FIBOXS", "horizontal transport of potential energy", "(3600*J)/m**2" },
- { 101, 0, "TLAMBDA", "heat conductivity of dry soil", "W/(K*m)" },
- { 103, 0, "DLAMBDA", "parameter for increasing the heat conductivity of the soil", NULL },
- { 104, 0, "PORVOL", "pore volume", NULL },
- { 105, 0, "FCAP", "field capacity of soil", NULL },
- { 106, 0, "WI3", "fraction of frozen soil", NULL },
- { 107, 0, "WI4", "fraction of frozen soil", NULL },
- { 108, 0, "WI5", "fraction of frozen soil", NULL },
- { 109, 0, "WI", "fraction of frozen soil", NULL },
- { 110, 0, "WICL", "fraction of frozen soil", NULL },
- { 112, 0, "QDB", "specific humidity surface", "kg/kg" },
- { 129, 0, "FIB", "surface geopotential (orography)", "m" },
- { 130, 0, "T", "temperature", "K" },
- { 131, 0, "U", "u-velocity", "m/s" },
- { 132, 0, "V", "v-velocity", "m/s" },
- { 133, 0, "QD", "specific humidity", "kg/kg" },
- { 134, 0, "PS", "Surface pressure", "Pa" },
- { 135, 0, "VERVEL", "Vertical velocity", "Pa/s" },
- { 138, 0, "SVO", "vorticity", "1/s" },
- { 139, 0, "TS", "surface temperature", "K" },
- { 140, 0, "WS", "soil wetness", "m" },
- { 141, 0, "SN", "snow depth", "m" },
- { 142, 0, "APRL", "large scale precipitation", "mm" },
- { 143, 0, "APRC", "convective precipitation", "mm" },
- { 144, 0, "APRS", "snow fall", "mm" },
- { 145, 0, "VDIS", "boundary layer dissipation", "W/m**2" },
- { 146, 0, "AHFS", "surface sensible heat flux", "W/m**2" },
- { 147, 0, "AHFL", "surface latent heat flux", "W/m**2" },
- { 148, 0, "STREAM", "streamfunction", "m**2/s" },
- { 149, 0, "VELOPOT", "velocity potential", "m**2/s" },
- { 151, 0, "PSRED", "mean sea level pressure", "Pa" },
- { 152, 0, "LSP", "log surface pressure", NULL },
- { 153, 0, "QW", "liquid water content", "kg/kg" },
- { 155, 0, "SD", "divergence", "1/s" },
- { 156, 0, "FI", "geopotential height", "gpm" },
- { 159, 0, "USTAR3", "ustar**3", "m**3/s**3" },
- { 160, 0, "RUNOFF", "surface runoff", "mm" },
- { 162, 0, "ACLC", "cloud cover", "fract." },
- { 163, 0, "ACLCV", "total cloud cover", "fract." },
- { 164, 0, "ACLCOV", "total cloud cover", "fract." },
- { 165, 0, "U10", "10m u-velocity", "m/s" },
- { 166, 0, "V10", "10m v-velocity", "m/s" },
- { 167, 0, "TEMP2", "2m temperature", "K" },
- { 168, 0, "DEW2", "2m dew point temperature", "K" },
- { 169, 0, "TSURF", "surface temperature (land)", "K" },
- { 170, 0, "TD", "deep soil temperature", "K" },
- { 171, 0, "WIND10", "10m windspeed", "m/s" },
- { 172, 0, "BLA", "land sea mask", "fract." },
- { 173, 0, "AZ0", "surface roughness length", "m" },
- { 174, 0, "ALB", "surface background albedo", "fract." },
- { 175, 0, "ALBEDO", "surface albedo", "fract." },
- { 176, 0, "SRADS", "net surface solar radiation", "W/m**2" },
- { 177, 0, "TRADS", "net surface thermal radiation", "W/m**2" },
- { 178, 0, "SRAD0", "net top solar radiation", "W/m**2" },
- { 179, 0, "TRAD0", "top thermal radiation (OLR)", "W/m**2" },
- { 180, 0, "USTR", "surface u-stress", "Pa" },
- { 181, 0, "VSTR", "surface v-stress", "Pa" },
- { 182, 0, "EVAP", "surface evaporation", "mm" },
- { 183, 0, "TDCL", "soil temperature", "K" },
- { 185, 0, "SRAFS", "net surf. solar radiation (clear sky)", "W/m**2" },
- { 186, 0, "TRAFS", "net surf. thermal radiation (clear sky)", "W/m**2" },
- { 187, 0, "SRAF0", "net top solar radiation (clear sky)", "W/m**2" },
- { 188, 0, "TRAF0", "net top thermal radiation (clear sky)", "W/m**2" },
- { 189, 0, "SCLFS", "surface solar cloud forcing", "W/m**2" },
- { 190, 0, "TCLFS", "surface thermal cloud forcing", "W/m**2" },
- { 191, 0, "SCLF0", "top solar cloud forcing", "W/m**2" },
- { 192, 0, "TCLF0", "top thermal cloud forcing", "W/m**2" },
- { 194, 0, "WL", "skin reservoir content", "m" },
- { 195, 0, "USTRGW", "u-gravity wave stress", "Pa" },
- { 196, 0, "VSTRGW", "v-gravity wave stress", "Pa" },
- { 197, 0, "VDISGW", "gravity wave dissipation", "W/m**2" },
- { 198, 0, "VGRAT", "vegetation ratio", NULL },
- { 199, 0, "VAROR", "orographic variance (for surface runoff)", NULL },
- { 200, 0, "VLT", "leaf area index", NULL },
- { 201, 0, "T2MAX", "maximum 2m-temperature", "K" },
- { 202, 0, "T2MIN", "minimum 2m-temperature", "K" },
- { 203, 0, "SRAD0U", "top solar radiation upward", "W/m**2" },
- { 204, 0, "SRADSU", "surface solar radiation upward", "W/m**2" },
- { 205, 0, "TRADSU", "surface thermal radiation upward", "W/m**2" },
- { 206, 0, "TSN", "snow temperature", "K" },
- { 207, 0, "TD3", "soil temperature", "K" },
- { 208, 0, "TD4", "soil temperature", "K" },
- { 209, 0, "TD5", "soil temperature", "K" },
- { 210, 0, "SEAICE", "sea ice cover", "fract." },
- { 211, 0, "SICED", "sea ice depth", "m" },
- { 212, 0, "FOREST", "vegetation type", NULL },
- { 213, 0, "TEFF", "(effective) sea-ice skin temperature", "K" },
- { 214, 0, "TSMAX", "maximum surface temperature", "K" },
- { 215, 0, "TSMIN", "minimum surface temperature", "K" },
- { 216, 0, "WIMAX", "maximum 10m-wind speed", "m/s" },
- { 217, 0, "TOPMAX", "maximum height of convective cloud tops", "Pa" },
- { 218, 0, "SNMEL", "snow melt", "mm" },
- { 220, 0, "TSLIN", "land: residual surface heat budget", "W/m**2" },
- { 221, 0, "DSNAC", "snow depth change", "mm" },
- { 222, 0, "EMTER", "EMTER", NULL },
- { 223, 0, "ACLCAC", "cloud cover", "fract." },
- { 224, 0, "TKE", "turbulent kinetic energy", NULL },
- { 226, 0, "FAO", "FAO data set (soil data flags)", NULL },
- { 227, 0, "RGCGN", "heat capacity of soil", NULL },
- { 229, 0, "WSMX", "field capacity of soil", NULL },
- { 230, 0, "QVI", "vertically integrated specific humidity", "kg/m**2" },
- { 231, 0, "ALWCVI", "vertically integrated liquid water cont.", "kg/m**2" },
- { 232, 0, "GLAC", "glacier mask", NULL },
- { 253, 0, "PHI", "latitude in real coordinates", "degrees_north" },
- { 254, 0, "RLA", "longitude in real coordinates", "degrees_east" },
- { 259, 0, "WINDSPEED", "windspeed (sqrt(u**2+v**2))", NULL },
- { 260, 0, "PRECIP", "total precipitation", NULL },
+static const param_type remo[] = {
+ { 14, -1, 0, "FTKVM", "turbulent transfer coefficient of momentum in the atmosphere", NULL },
+ { 15, -1, 0, "FTKVH", "turbulent transfer coefficient of heat in the atmosphere", NULL },
+ { 38, -1, 0, "U10ER", "10m u-velocity", "m/s" },
+ { 39, -1, 0, "V10ER", "10m v-velocity", "m/s" },
+ { 40, -1, 0, "CAPE", "convetive available potential energy", NULL },
+ { 41, -1, 0, "GHPBL", "height of the planetary boudary layer", "gpm" },
+ { 42, -1, 0, "BETA", "BETA", NULL },
+ { 43, -1, 0, "WMINLOK", "WMINLOK", NULL },
+ { 44, -1, 0, "WMAXLOK", "WMAXLOK", NULL },
+ { 45, -1, 0, "VBM10M", "maximum of the expected gust velocity near the surface", "m/s" },
+ { 46, -1, 0, "BFLHS", "surface sensible heat flux", "W/m**2" },
+ { 47, -1, 0, "BFLQDS", "surface latent heat flux", "W/m**2" },
+ { 48, -1, 0, "TMCM", "turbulent transfer coefficient of momentum at the surface", NULL },
+ { 49, -1, 0, "TRSOL", "TRSOL", NULL },
+ { 50, -1, 0, "TMCH", "turbulent transfer coefficient of heat at the surface", NULL },
+ { 51, -1, 0, "EMTEF", "EMTEF", NULL },
+ { 52, -1, 0, "TRSOF", "TRSOF", NULL },
+ { 53, -1, 0, "DRAIN", "drainage", "mm" },
+ { 54, -1, 0, "TSL", "surface temperature (land)", "K" },
+ { 55, -1, 0, "TSW", "surface temperature (water)", "K" },
+ { 56, -1, 0, "TSI", "surface temperature (ice)", "K" },
+ { 57, -1, 0, "USTRL", "surface u-stress (land)", "Pa" },
+ { 58, -1, 0, "USTRW", "surface u-stress (water)", "Pa" },
+ { 59, -1, 0, "USTRI", "surface u-stress (ice)", "Pa" },
+ { 60, -1, 0, "VSTRL", "surface v-stress (land)", "Pa" },
+ { 61, -1, 0, "VSTRW", "surface v-stress (water)", "Pa" },
+ { 62, -1, 0, "VSTRI", "surface v-stress (ice)", "Pa" },
+ { 63, -1, 0, "EVAPL", "surface evaporation (land)", "mm" },
+ { 64, -1, 0, "EVAPW", "surface evaporation (water)", "mm" },
+ { 65, -1, 0, "EVAPI", "surface evaporation (ice)", "mm" },
+ { 66, -1, 0, "AHFLL", "surface latent heat flux (land)", "W/m**2" },
+ { 67, -1, 0, "AHFLW", "surface latent heat flux (water)", "W/m**2" },
+ { 68, -1, 0, "AHFLI", "surface latent heat flux (ice)", "W/m**2" },
+ { 69, -1, 0, "AHFSL", "surface sensible heat flux (land)", "W/m**2" },
+ { 70, -1, 0, "AHFSW", "surface sensible heat flux (water)", "W/m**2" },
+ { 71, -1, 0, "AHFSI", "surface sensible heat flux (ice)", "W/m**2" },
+ { 72, -1, 0, "AZ0L", "surface roughness length (land)", "m" },
+ { 73, -1, 0, "AZ0W", "surface roughness length (water)", "m" },
+ { 74, -1, 0, "AZ0I", "surface roughness length (ice)", "m" },
+ { 75, -1, 0, "ALSOL", "surface albedo (land)", "fract." },
+ { 76, -1, 0, "ALSOW", "surface albedo (water)", "fract." },
+ { 77, -1, 0, "ALSOI", "surface albedo (ice)", "fract." },
+ { 81, -1, 0, "TMCHL", "turbulent transfer coefficient of heat at the surface (land)", NULL },
+ { 82, -1, 0, "TMCHW", "turbulent transfer coefficient of heat at the surface (water)", NULL },
+ { 83, -1, 0, "TMCHI", "turbulent transfer coefficient of heat at the surface (ice)", NULL },
+ { 84, -1, 0, "QDBL", "specific humidity surface (land)", "kg/kg" },
+ { 85, -1, 0, "QDBW", "specific humidity surface (water)", "kg/kg" },
+ { 86, -1, 0, "QDBI", "specific humidity surface (ice)", "kg/kg" },
+ { 87, -1, 0, "BFLHSL", "surface sensible heat flux (land)", "W/m**2" },
+ { 88, -1, 0, "BFLHSW", "surface sensible heat flux (water)", "W/m**2" },
+ { 89, -1, 0, "BFLHSI", "surface sensible heat flux (ice)", "W/m**2" },
+ { 90, -1, 0, "BFLQDSL", "surface latent heat flux (land)", "W/m**2" },
+ { 91, -1, 0, "BFLQDSW", "surface latent heat flux (water)", "W/m**2" },
+ { 92, -1, 0, "BFLQDSI", "surface latent heat flux (ice)", "W/m**2" },
+ { 93, -1, 0, "AHFICE", "sea-ice: conductive heat", "W/m" },
+ { 94, -1, 0, "QRES", "residual heat flux for melting sea ice", "W/m**2" },
+ { 95, -1, 0, "SRFL", "SRFL", NULL },
+ { 96, -1, 0, "QDBOXS", "horizontal transport of water vapour", "kg/m**2" },
+ { 97, -1, 0, "QWBOXS", "horizontal transport of cloud water", "kg/m**2" },
+ { 98, -1, 0, "EKBOXS", "horizontal transport of kinetic energy", "(3600*J)/m**2" },
+ { 99, -1, 0, "FHBOXS", "horizontal transport of sensible heat", "(3600*J)/m**2" },
+ { 100, -1, 0, "FIBOXS", "horizontal transport of potential energy", "(3600*J)/m**2" },
+ { 101, -1, 0, "TLAMBDA", "heat conductivity of dry soil", "W/(K*m)" },
+ { 103, -1, 0, "DLAMBDA", "parameter for increasing the heat conductivity of the soil", NULL },
+ { 104, -1, 0, "PORVOL", "pore volume", NULL },
+ { 105, -1, 0, "FCAP", "field capacity of soil", NULL },
+ { 106, -1, 0, "WI3", "fraction of frozen soil", NULL },
+ { 107, -1, 0, "WI4", "fraction of frozen soil", NULL },
+ { 108, -1, 0, "WI5", "fraction of frozen soil", NULL },
+ { 109, -1, 0, "WI", "fraction of frozen soil", NULL },
+ { 110, -1, 0, "WICL", "fraction of frozen soil", NULL },
+ { 112, -1, 0, "QDB", "specific humidity surface", "kg/kg" },
+ { 129, -1, 0, "FIB", "surface geopotential (orography)", "m" },
+ { 130, -1, 0, "T", "temperature", "K" },
+ { 131, -1, 0, "U", "u-velocity", "m/s" },
+ { 132, -1, 0, "V", "v-velocity", "m/s" },
+ { 133, -1, 0, "QD", "specific humidity", "kg/kg" },
+ { 134, -1, 0, "PS", "Surface pressure", "Pa" },
+ { 135, -1, 0, "VERVEL", "Vertical velocity", "Pa/s" },
+ { 138, -1, 0, "SVO", "vorticity", "1/s" },
+ { 139, -1, 0, "TS", "surface temperature", "K" },
+ { 140, -1, 0, "WS", "soil wetness", "m" },
+ { 141, -1, 0, "SN", "snow depth", "m" },
+ { 142, -1, 0, "APRL", "large scale precipitation", "mm" },
+ { 143, -1, 0, "APRC", "convective precipitation", "mm" },
+ { 144, -1, 0, "APRS", "snow fall", "mm" },
+ { 145, -1, 0, "VDIS", "boundary layer dissipation", "W/m**2" },
+ { 146, -1, 0, "AHFS", "surface sensible heat flux", "W/m**2" },
+ { 147, -1, 0, "AHFL", "surface latent heat flux", "W/m**2" },
+ { 148, -1, 0, "STREAM", "streamfunction", "m**2/s" },
+ { 149, -1, 0, "VELOPOT", "velocity potential", "m**2/s" },
+ { 151, -1, 0, "PSRED", "mean sea level pressure", "Pa" },
+ { 152, -1, 0, "LSP", "log surface pressure", NULL },
+ { 153, -1, 0, "QW", "liquid water content", "kg/kg" },
+ { 155, -1, 0, "SD", "divergence", "1/s" },
+ { 156, -1, 0, "FI", "geopotential height", "gpm" },
+ { 159, -1, 0, "USTAR3", "ustar**3", "m**3/s**3" },
+ { 160, -1, 0, "RUNOFF", "surface runoff", "mm" },
+ { 162, -1, 0, "ACLC", "cloud cover", "fract." },
+ { 163, -1, 0, "ACLCV", "total cloud cover", "fract." },
+ { 164, -1, 0, "ACLCOV", "total cloud cover", "fract." },
+ { 165, -1, 0, "U10", "10m u-velocity", "m/s" },
+ { 166, -1, 0, "V10", "10m v-velocity", "m/s" },
+ { 167, -1, 0, "TEMP2", "2m temperature", "K" },
+ { 168, -1, 0, "DEW2", "2m dew point temperature", "K" },
+ { 169, -1, 0, "TSURF", "surface temperature (land)", "K" },
+ { 170, -1, 0, "TD", "deep soil temperature", "K" },
+ { 171, -1, 0, "WIND10", "10m windspeed", "m/s" },
+ { 172, -1, 0, "BLA", "land sea mask", "fract." },
+ { 173, -1, 0, "AZ0", "surface roughness length", "m" },
+ { 174, -1, 0, "ALB", "surface background albedo", "fract." },
+ { 175, -1, 0, "ALBEDO", "surface albedo", "fract." },
+ { 176, -1, 0, "SRADS", "net surface solar radiation", "W/m**2" },
+ { 177, -1, 0, "TRADS", "net surface thermal radiation", "W/m**2" },
+ { 178, -1, 0, "SRAD0", "net top solar radiation", "W/m**2" },
+ { 179, -1, 0, "TRAD0", "top thermal radiation (OLR)", "W/m**2" },
+ { 180, -1, 0, "USTR", "surface u-stress", "Pa" },
+ { 181, -1, 0, "VSTR", "surface v-stress", "Pa" },
+ { 182, -1, 0, "EVAP", "surface evaporation", "mm" },
+ { 183, -1, 0, "TDCL", "soil temperature", "K" },
+ { 185, -1, 0, "SRAFS", "net surf. solar radiation (clear sky)", "W/m**2" },
+ { 186, -1, 0, "TRAFS", "net surf. thermal radiation (clear sky)", "W/m**2" },
+ { 187, -1, 0, "SRAF0", "net top solar radiation (clear sky)", "W/m**2" },
+ { 188, -1, 0, "TRAF0", "net top thermal radiation (clear sky)", "W/m**2" },
+ { 189, -1, 0, "SCLFS", "surface solar cloud forcing", "W/m**2" },
+ { 190, -1, 0, "TCLFS", "surface thermal cloud forcing", "W/m**2" },
+ { 191, -1, 0, "SCLF0", "top solar cloud forcing", "W/m**2" },
+ { 192, -1, 0, "TCLF0", "top thermal cloud forcing", "W/m**2" },
+ { 194, -1, 0, "WL", "skin reservoir content", "m" },
+ { 195, -1, 0, "USTRGW", "u-gravity wave stress", "Pa" },
+ { 196, -1, 0, "VSTRGW", "v-gravity wave stress", "Pa" },
+ { 197, -1, 0, "VDISGW", "gravity wave dissipation", "W/m**2" },
+ { 198, -1, 0, "VGRAT", "vegetation ratio", NULL },
+ { 199, -1, 0, "VAROR", "orographic variance (for surface runoff)", NULL },
+ { 200, -1, 0, "VLT", "leaf area index", NULL },
+ { 201, -1, 0, "T2MAX", "maximum 2m-temperature", "K" },
+ { 202, -1, 0, "T2MIN", "minimum 2m-temperature", "K" },
+ { 203, -1, 0, "SRAD0U", "top solar radiation upward", "W/m**2" },
+ { 204, -1, 0, "SRADSU", "surface solar radiation upward", "W/m**2" },
+ { 205, -1, 0, "TRADSU", "surface thermal radiation upward", "W/m**2" },
+ { 206, -1, 0, "TSN", "snow temperature", "K" },
+ { 207, -1, 0, "TD3", "soil temperature", "K" },
+ { 208, -1, 0, "TD4", "soil temperature", "K" },
+ { 209, -1, 0, "TD5", "soil temperature", "K" },
+ { 210, -1, 0, "SEAICE", "sea ice cover", "fract." },
+ { 211, -1, 0, "SICED", "sea ice depth", "m" },
+ { 212, -1, 0, "FOREST", "vegetation type", NULL },
+ { 213, -1, 0, "TEFF", "(effective) sea-ice skin temperature", "K" },
+ { 214, -1, 0, "TSMAX", "maximum surface temperature", "K" },
+ { 215, -1, 0, "TSMIN", "minimum surface temperature", "K" },
+ { 216, -1, 0, "WIMAX", "maximum 10m-wind speed", "m/s" },
+ { 217, -1, 0, "TOPMAX", "maximum height of convective cloud tops", "Pa" },
+ { 218, -1, 0, "SNMEL", "snow melt", "mm" },
+ { 220, -1, 0, "TSLIN", "land: residual surface heat budget", "W/m**2" },
+ { 221, -1, 0, "DSNAC", "snow depth change", "mm" },
+ { 222, -1, 0, "EMTER", "EMTER", NULL },
+ { 223, -1, 0, "ACLCAC", "cloud cover", "fract." },
+ { 224, -1, 0, "TKE", "turbulent kinetic energy", NULL },
+ { 226, -1, 0, "FAO", "FAO data set (soil data flags)", NULL },
+ { 227, -1, 0, "RGCGN", "heat capacity of soil", NULL },
+ { 229, -1, 0, "WSMX", "field capacity of soil", NULL },
+ { 230, -1, 0, "QVI", "vertically integrated specific humidity", "kg/m**2" },
+ { 231, -1, 0, "ALWCVI", "vertically integrated liquid water cont.", "kg/m**2" },
+ { 232, -1, 0, "GLAC", "glacier mask", NULL },
+ { 253, -1, 0, "PHI", "latitude in real coordinates", "degrees_north" },
+ { 254, -1, 0, "RLA", "longitude in real coordinates", "degrees_east" },
+ { 259, -1, 0, "WINDSPEED", "windspeed (sqrt(u**2+v**2))", NULL },
+ { 260, -1, 0, "PRECIP", "total precipitation", NULL },
};
-static const PAR cosmo002[] = {
- { 1, 0, "P", "pressure", "Pa" },
- { 2, 0, "PMSL", "mean sea level pressure", "Pa" },
- { 3, 0, "DPSDT", "surface pressure change", "Pa s-1" },
- { 6, 0, "FI", "geopotential", "m2 s-2" },
- { 8, 0, "HH", "height", "m" },
- { 10, 0, "TO3", "vertical integrated ozone content", "Dobson" },
- { 11, 0, "T", "temperature", "K" },
- { 15, 0, "TMAX", "2m maximum temperature", "K" },
- { 16, 0, "TMIN", "2m minimum temperature", "K" },
- { 17, 0, "TD", "2m dew point temperature", "K" },
- { 31, 0, "DD", "undefined", "undefined" },
- { 32, 0, "FF", "undefined", "undefined" },
- { 33, 0, "U", "U-component of wind", "m s-1" },
- { 34, 0, "V", "V-component of wind", "m s-1" },
- { 39, 0, "OMEGA", "omega", "Pa s-1" },
- { 40, 0, "W", "vertical wind velocity", "m s-1" },
- { 51, 0, "QV", "specific humidity", "kg kg-1" },
- { 52, 0, "RELHUM", "relative humidity", "%" },
- { 54, 0, "TQV", "precipitable water", "kg m-2" },
- { 57, 0, "AEVAP", "surface evaporation", "kg m-2" },
- { 58, 0, "TQI", "vertical integrated cloud ice", "kg m-2" },
- { 59, 0, "TOT_PR", "total precipitation rate", "kg m-2 s-1" },
- { 61, 0, "TOT_PREC", "total precipitation amount", "kg m-2" },
- { 65, 0, "W_SNOW", "surface snow amount", "m" },
- { 66, 0, "H_SNOW", "thickness of snow", "m" },
- { 71, 0, "CLCT", "total cloud cover", "1" },
- { 72, 0, "CLC_CON", "convective cloud area fraction", "1" },
- { 73, 0, "CLCL", "low cloud cover", "1" },
- { 74, 0, "CLCM", "medium cloud cover", "1" },
- { 75, 0, "CLCH", "high cloud cover", "1" },
- { 76, 0, "TQC", "vertical integrated cloud water", "kg m-2" },
- { 78, 0, "SNOW_CON", "convective snowfall", "kg m-2" },
- { 79, 0, "SNOW_GSP", "large scale snowfall", "kg m-2" },
- { 81, 0, "FR_LAND", "land-sea fraction", "1" },
- { 83, 0, "Z0", "surface roughness length", "m" },
- { 84, 0, "ALB_RAD", "surface albedo", "1" },
- { 85, 0, "TSOIL", "soil surface temperature", "K" },
- { 86, 0, "WSOIL", "water content of 1. soil layer", "m" },
- { 87, 0, "PLCOV", "vegetation area fraction", "1" },
- { 90, 0, "RUNOFF", "subsurface runoff", "kg m-2" },
- { 91, 0, "FR_ICE", "sea ice area fraction", "1" },
- { 92, 0, "H_ICE", "sea ice thickness", "m" },
- { 111, 0, "ASOB", "averaged surface net downward shortwave radiation", "W m-2" },
- { 112, 0, "ATHB", "averaged surface net downward longwave radiation", "W m-2" },
- { 113, 0, "ASOB", "averaged TOA net downward shortwave radiation", "W m-2" },
- { 114, 0, "ATHB", "averaged TOA outgoing longwave radiation", "W m-2" },
- { 115, 0, "ASWDIR", "direct downward sw radiation at the surface", "W m-2" },
- { 116, 0, "ASWDIFD", "diffuse downward sw radiation at the surface", "W m-2" },
- { 117, 0, "ASWDIFU", "diffuse upwnward sw radiation at the surface", "W m-2" },
- { 118, 0, "ALWD", "downward lw radiation at the surface", "W m-2" },
- { 119, 0, "ALWU", "upward lw radiation at the surface", "W m-2" },
- { 121, 0, "ALHFL", "averaged surface latent heat flux", "W m-2" },
- { 122, 0, "ASHFL", "averaged surface sensible heat flux", "W m-2" },
- { 124, 0, "AUMFL", "averaged eastward stress", "Pa" },
- { 125, 0, "AVMFL", "averaged northward stress", "Pa" },
- { 128, 0, "SUNSH", "undefined", "undefined" },
- { 129, 0, "SUNSH2", "undefined", "undefined" },
- { 130, 0, "SUN_SUM", "undefined", "undefined" },
- { 131, 0, "SUN_SUM2", "undefined", "undefined" },
- { 133, 0, "FCOR", "undefined", "undefined" },
- { 134, 0, "SKYVIEW", "sky-view factor", "1" },
- { 137, 0, "SWDIR_COR", "topo correction of direct solar radiarion", "1" },
+static const param_type cosmo002[] = {
+ { 1, -1, 0, "P", "pressure", "Pa" },
+ { 2, -1, 0, "PMSL", "mean sea level pressure", "Pa" },
+ { 3, -1, 0, "DPSDT", "surface pressure change", "Pa s-1" },
+ { 6, -1, 0, "FI", "geopotential", "m2 s-2" },
+ { 8, -1, 0, "HH", "height", "m" },
+ { 10, -1, 0, "TO3", "vertical integrated ozone content", "Dobson" },
+ { 11, -1, 0, "T", "temperature", "K" },
+ { 15, -1, 0, "TMAX", "2m maximum temperature", "K" },
+ { 16, -1, 0, "TMIN", "2m minimum temperature", "K" },
+ { 17, -1, 0, "TD", "2m dew point temperature", "K" },
+ { 31, -1, 0, "DD", "undefined", "undefined" },
+ { 32, -1, 0, "FF", "undefined", "undefined" },
+ { 33, -1, 0, "U", "U-component of wind", "m s-1" },
+ { 34, -1, 0, "V", "V-component of wind", "m s-1" },
+ { 39, -1, 0, "OMEGA", "omega", "Pa s-1" },
+ { 40, -1, 0, "W", "vertical wind velocity", "m s-1" },
+ { 51, -1, 0, "QV", "specific humidity", "kg kg-1" },
+ { 52, -1, 0, "RELHUM", "relative humidity", "%" },
+ { 54, -1, 0, "TQV", "precipitable water", "kg m-2" },
+ { 57, -1, 0, "AEVAP", "surface evaporation", "kg m-2" },
+ { 58, -1, 0, "TQI", "vertical integrated cloud ice", "kg m-2" },
+ { 59, -1, 0, "TOT_PR", "total precipitation rate", "kg m-2 s-1" },
+ { 61, -1, 0, "TOT_PREC", "total precipitation amount", "kg m-2" },
+ { 65, -1, 0, "W_SNOW", "surface snow amount", "m" },
+ { 66, -1, 0, "H_SNOW", "thickness of snow", "m" },
+ { 71, -1, 0, "CLCT", "total cloud cover", "1" },
+ { 72, -1, 0, "CLC_CON", "convective cloud area fraction", "1" },
+ { 73, -1, 0, "CLCL", "low cloud cover", "1" },
+ { 74, -1, 0, "CLCM", "medium cloud cover", "1" },
+ { 75, -1, 0, "CLCH", "high cloud cover", "1" },
+ { 76, -1, 0, "TQC", "vertical integrated cloud water", "kg m-2" },
+ { 78, -1, 0, "SNOW_CON", "convective snowfall", "kg m-2" },
+ { 79, -1, 0, "SNOW_GSP", "large scale snowfall", "kg m-2" },
+ { 81, -1, 0, "FR_LAND", "land-sea fraction", "1" },
+ { 83, -1, 0, "Z0", "surface roughness length", "m" },
+ { 84, -1, 0, "ALB_RAD", "surface albedo", "1" },
+ { 85, -1, 0, "TSOIL", "soil surface temperature", "K" },
+ { 86, -1, 0, "WSOIL", "water content of 1. soil layer", "m" },
+ { 87, -1, 0, "PLCOV", "vegetation area fraction", "1" },
+ { 90, -1, 0, "RUNOFF", "subsurface runoff", "kg m-2" },
+ { 91, -1, 0, "FR_ICE", "sea ice area fraction", "1" },
+ { 92, -1, 0, "H_ICE", "sea ice thickness", "m" },
+ { 111, -1, 0, "ASOB", "averaged surface net downward shortwave radiation", "W m-2" },
+ { 112, -1, 0, "ATHB", "averaged surface net downward longwave radiation", "W m-2" },
+ { 113, -1, 0, "ASOB", "averaged TOA net downward shortwave radiation", "W m-2" },
+ { 114, -1, 0, "ATHB", "averaged TOA outgoing longwave radiation", "W m-2" },
+ { 115, -1, 0, "ASWDIR", "direct downward sw radiation at the surface", "W m-2" },
+ { 116, -1, 0, "ASWDIFD", "diffuse downward sw radiation at the surface", "W m-2" },
+ { 117, -1, 0, "ASWDIFU", "diffuse upwnward sw radiation at the surface", "W m-2" },
+ { 118, -1, 0, "ALWD", "downward lw radiation at the surface", "W m-2" },
+ { 119, -1, 0, "ALWU", "upward lw radiation at the surface", "W m-2" },
+ { 121, -1, 0, "ALHFL", "averaged surface latent heat flux", "W m-2" },
+ { 122, -1, 0, "ASHFL", "averaged surface sensible heat flux", "W m-2" },
+ { 124, -1, 0, "AUMFL", "averaged eastward stress", "Pa" },
+ { 125, -1, 0, "AVMFL", "averaged northward stress", "Pa" },
+ { 128, -1, 0, "SUNSH", "undefined", "undefined" },
+ { 129, -1, 0, "SUNSH2", "undefined", "undefined" },
+ { 130, -1, 0, "SUN_SUM", "undefined", "undefined" },
+ { 131, -1, 0, "SUN_SUM2", "undefined", "undefined" },
+ { 133, -1, 0, "FCOR", "undefined", "undefined" },
+ { 134, -1, 0, "SKYVIEW", "sky-view factor", "1" },
+ { 137, -1, 0, "SWDIR_COR", "topo correction of direct solar radiarion", "1" },
};
-static const PAR cosmo201[] = {
- { 5, 0, "APAB", "&", "W m-2" },
- { 13, 0, "SOHR_RAD", "&", "K s-1" },
- { 14, 0, "THHR_RAD", "&", "K s-1" },
- { 20, 0, "DURSUN", "duration of sunshine", "s" },
- { 29, 0, "CLC", "cloud area fraction", "1" },
- { 30, 0, "CLC_SGS", "grid scale cloud area fraction", "1" },
- { 31, 0, "QC", "specific cloud liquid water content", "kg kg-1" },
- { 33, 0, "QI", "specific cloud ice content", "kg kg-1" },
- { 35, 0, "QR", "specific rain content", "kg kg-1" },
- { 36, 0, "QS", "specific snow content", "kg kg-1" },
- { 37, 0, "TQR", "total rain water content vertically integrated", "kg m-2" },
- { 38, 0, "TQS", "total snow content vertically integrated", "kg m-2" },
- { 39, 0, "QG", "specific graupel content", "kg kg-1" },
- { 40, 0, "TQG", "total graupel content vertically integrated", "kg m-2" },
- { 41, 0, "TWATER", "cloud condensed water content", "kg m-2" },
- { 42, 0, "TDIV_HUM", "atmosphere water divergence", "kg m-2" },
- { 43, 0, "QC_RAD", "sub scale specific cloud liquid water content", "kg kg-1" },
- { 44, 0, "QI_RAD", "sub scale specific cloud ice content", "kg kg-1" },
- { 61, 0, "CLW_CON", "convective cloud liquid water", "1" },
- { 68, 0, "HBAS_CON", "height of convective cloud base", "m" },
- { 69, 0, "HTOP_CON", "height of convective cloud top", "m" },
- { 70, 0, "HBAS_CONI", "height of convective cloud base", "m" },
- { 71, 0, "HTOP_CONI", "height of convective cloud top", "m" },
- { 72, 0, "BAS_CON", "index of convective cloud base", "1" },
- { 73, 0, "TOP_CON", "index of convective cloud top", "1" },
- { 74, 0, "DT_CON", "convective tendency of temperature", "K s-1" },
- { 75, 0, "DQV_CON", "convective tendency of specific humidity", "s-1" },
- { 78, 0, "DU_CON", "convective tendency of u-wind component", "m s-2" },
- { 79, 0, "DV_CON", "convective tendency of v-wind component", "m s-2" },
- { 82, 0, "HTOP_DC", "height of dry convection top", "m" },
- { 84, 0, "HZEROCL", "height of freezing level", "m" },
- { 85, 0, "SNOWLMT", "height of the snow fall limit in m above sea level", "m" },
- { 86, 0, "HCBAS", "height of cloud base", "m" },
- { 87, 0, "HCTOP", "height of cloud top", "m" },
- { 91, 0, "C_T_LK", "&", "1" },
- { 92, 0, "GAMSO_LK", "&", "m-1" },
- { 93, 0, "DP_BS_LK", "&", "m" },
- { 94, 0, "H_B1_LK", "&", "m" },
- { 95, 0, "H_ML_LK", "&", "m" },
- { 96, 0, "DEPTH_LK", "lake depth", "m" },
- { 97, 0, "FETCH_LK", "wind fetch over lake", "m" },
- { 99, 0, "QRS", "precipitation water (water loading)", "1" },
- { 100, 0, "PRR_GSP", "mass flux density of large scale rainfall", "kg m-2 s-1" },
- { 101, 0, "PRS_GSP", "mass flux density of large scale snowfall", "kg m-2 s-1" },
- { 102, 0, "RAIN_GSP", "large scale rainfall", "kg m-2" },
- { 111, 0, "PRR_CON", "mass flux density of convective rainfall", "kg m-2 s-1" },
- { 112, 0, "PRS_CON", "mass flux density of convective snowfall", "kg m-2 s-1" },
- { 113, 0, "RAIN_CON", "convective rainfall", "kg m-2" },
- { 129, 0, "FRESHSNW", "freshness of snow", "undefined" },
- { 131, 0, "PRG_GSP", "mass flux density of large scale graupel", "kg m-2 s-1" },
- { 132, 0, "GRAU_GSP", "large scale graupel", "kg m-2" },
- { 133, 0, "RHO_SNOW", "density of snow", "kg m-3" },
- { 139, 0, "PP", "deviation from reference pressure", "Pa" },
- { 140, 0, "RCLD", "standard deviation of saturation deficit", "undefined" },
- { 143, 0, "CAPE_MU", "cape of most unstable parcel", "J kg-1" },
- { 144, 0, "CIN_MU", "convective inhibition of most unstable parcel", "J kg-1" },
- { 145, 0, "CAPE_ML", "cape of mean surface layer parcel", "J kg-1" },
- { 146, 0, "CIN_ML", "convective inhibition of mean surface layer parcel", "J kg-1" },
- { 147, 0, "TKE_CON", "convective turbulent kinetic energy", "undefined" },
- { 148, 0, "TKETENS", "tendency of turbulent kinetic energy", "undefined" },
- { 152, 0, "TKE", "turbulent kinetic energy", "m2 s-2" },
- { 153, 0, "TKVM", "diffusion coefficient of momentum", "m2 s-1" },
- { 154, 0, "TKVH", "diffusion coefficient of heat", "m2 s-1" },
- { 170, 0, "TCM", "drag coefficient of momentum", "1" },
- { 171, 0, "TCH", "drag coefficient of heat", "1" },
- { 187, 0, "VMAX", "maximum turbulent wind gust in 10m", "m s-1" },
- { 190, 0, "TSOIL", "&", "K" },
- { 191, 0, "TSOIL", "&", "K" },
- { 192, 0, "TSOIL", "&", "K" },
- { 193, 0, "TSOIL", "mixed layer temperature", "K" },
- { 194, 0, "TSOIL", "mean temperature of water column", "K" },
- { 197, 0, "TSOIL", "soil temperature", "K" },
- { 198, 0, "W_SO", "soil water content", "m" },
- { 199, 0, "W_SO_ICE", "soil frozen water content", "m" },
- { 200, 0, "W_I", "canopy water amount", "m" },
- { 203, 0, "TSOIL", "snow surface temperature", "K" },
- { 215, 0, "TSOIL", "temperature of ice upper surface", "K" },
- { 230, 0, "dBZ", "unattenuated radar reflectivity in Rayleigh approximation", "1" },
- { 240, 0, "MFLX_CON", "convective mass flux density", "kg m-2 s-1" },
- { 241, 0, "CAPE_CON", "&", "J kg-1" },
- { 243, 0, "QCVG_CON", "&", "s-1" },
+static const param_type cosmo201[] = {
+ { 5, -1, 0, "APAB", "&", "W m-2" },
+ { 13, -1, 0, "SOHR_RAD", "&", "K s-1" },
+ { 14, -1, 0, "THHR_RAD", "&", "K s-1" },
+ { 20, -1, 0, "DURSUN", "duration of sunshine", "s" },
+ { 29, -1, 0, "CLC", "cloud area fraction", "1" },
+ { 30, -1, 0, "CLC_SGS", "grid scale cloud area fraction", "1" },
+ { 31, -1, 0, "QC", "specific cloud liquid water content", "kg kg-1" },
+ { 33, -1, 0, "QI", "specific cloud ice content", "kg kg-1" },
+ { 35, -1, 0, "QR", "specific rain content", "kg kg-1" },
+ { 36, -1, 0, "QS", "specific snow content", "kg kg-1" },
+ { 37, -1, 0, "TQR", "total rain water content vertically integrated", "kg m-2" },
+ { 38, -1, 0, "TQS", "total snow content vertically integrated", "kg m-2" },
+ { 39, -1, 0, "QG", "specific graupel content", "kg kg-1" },
+ { 40, -1, 0, "TQG", "total graupel content vertically integrated", "kg m-2" },
+ { 41, -1, 0, "TWATER", "cloud condensed water content", "kg m-2" },
+ { 42, -1, 0, "TDIV_HUM", "atmosphere water divergence", "kg m-2" },
+ { 43, -1, 0, "QC_RAD", "sub scale specific cloud liquid water content", "kg kg-1" },
+ { 44, -1, 0, "QI_RAD", "sub scale specific cloud ice content", "kg kg-1" },
+ { 61, -1, 0, "CLW_CON", "convective cloud liquid water", "1" },
+ { 68, -1, 0, "HBAS_CON", "height of convective cloud base", "m" },
+ { 69, -1, 0, "HTOP_CON", "height of convective cloud top", "m" },
+ { 70, -1, 0, "HBAS_CONI", "height of convective cloud base", "m" },
+ { 71, -1, 0, "HTOP_CONI", "height of convective cloud top", "m" },
+ { 72, -1, 0, "BAS_CON", "index of convective cloud base", "1" },
+ { 73, -1, 0, "TOP_CON", "index of convective cloud top", "1" },
+ { 74, -1, 0, "DT_CON", "convective tendency of temperature", "K s-1" },
+ { 75, -1, 0, "DQV_CON", "convective tendency of specific humidity", "s-1" },
+ { 78, -1, 0, "DU_CON", "convective tendency of u-wind component", "m s-2" },
+ { 79, -1, 0, "DV_CON", "convective tendency of v-wind component", "m s-2" },
+ { 82, -1, 0, "HTOP_DC", "height of dry convection top", "m" },
+ { 84, -1, 0, "HZEROCL", "height of freezing level", "m" },
+ { 85, -1, 0, "SNOWLMT", "height of the snow fall limit in m above sea level", "m" },
+ { 86, -1, 0, "HCBAS", "height of cloud base", "m" },
+ { 87, -1, 0, "HCTOP", "height of cloud top", "m" },
+ { 91, -1, 0, "C_T_LK", "&", "1" },
+ { 92, -1, 0, "GAMSO_LK", "&", "m-1" },
+ { 93, -1, 0, "DP_BS_LK", "&", "m" },
+ { 94, -1, 0, "H_B1_LK", "&", "m" },
+ { 95, -1, 0, "H_ML_LK", "&", "m" },
+ { 96, -1, 0, "DEPTH_LK", "lake depth", "m" },
+ { 97, -1, 0, "FETCH_LK", "wind fetch over lake", "m" },
+ { 99, -1, 0, "QRS", "precipitation water (water loading)", "1" },
+ { 100, -1, 0, "PRR_GSP", "mass flux density of large scale rainfall", "kg m-2 s-1" },
+ { 101, -1, 0, "PRS_GSP", "mass flux density of large scale snowfall", "kg m-2 s-1" },
+ { 102, -1, 0, "RAIN_GSP", "large scale rainfall", "kg m-2" },
+ { 111, -1, 0, "PRR_CON", "mass flux density of convective rainfall", "kg m-2 s-1" },
+ { 112, -1, 0, "PRS_CON", "mass flux density of convective snowfall", "kg m-2 s-1" },
+ { 113, -1, 0, "RAIN_CON", "convective rainfall", "kg m-2" },
+ { 129, -1, 0, "FRESHSNW", "freshness of snow", "undefined" },
+ { 131, -1, 0, "PRG_GSP", "mass flux density of large scale graupel", "kg m-2 s-1" },
+ { 132, -1, 0, "GRAU_GSP", "large scale graupel", "kg m-2" },
+ { 133, -1, 0, "RHO_SNOW", "density of snow", "kg m-3" },
+ { 139, -1, 0, "PP", "deviation from reference pressure", "Pa" },
+ { 140, -1, 0, "RCLD", "standard deviation of saturation deficit", "undefined" },
+ { 143, -1, 0, "CAPE_MU", "cape of most unstable parcel", "J kg-1" },
+ { 144, -1, 0, "CIN_MU", "convective inhibition of most unstable parcel", "J kg-1" },
+ { 145, -1, 0, "CAPE_ML", "cape of mean surface layer parcel", "J kg-1" },
+ { 146, -1, 0, "CIN_ML", "convective inhibition of mean surface layer parcel", "J kg-1" },
+ { 147, -1, 0, "TKE_CON", "convective turbulent kinetic energy", "undefined" },
+ { 148, -1, 0, "TKETENS", "tendency of turbulent kinetic energy", "undefined" },
+ { 152, -1, 0, "TKE", "turbulent kinetic energy", "m2 s-2" },
+ { 153, -1, 0, "TKVM", "diffusion coefficient of momentum", "m2 s-1" },
+ { 154, -1, 0, "TKVH", "diffusion coefficient of heat", "m2 s-1" },
+ { 170, -1, 0, "TCM", "drag coefficient of momentum", "1" },
+ { 171, -1, 0, "TCH", "drag coefficient of heat", "1" },
+ { 187, -1, 0, "VMAX", "maximum turbulent wind gust in 10m", "m s-1" },
+ { 190, -1, 0, "TSOIL", "&", "K" },
+ { 191, -1, 0, "TSOIL", "&", "K" },
+ { 192, -1, 0, "TSOIL", "&", "K" },
+ { 193, -1, 0, "TSOIL", "mixed layer temperature", "K" },
+ { 194, -1, 0, "TSOIL", "mean temperature of water column", "K" },
+ { 197, -1, 0, "TSOIL", "soil temperature", "K" },
+ { 198, -1, 0, "W_SO", "soil water content", "m" },
+ { 199, -1, 0, "W_SO_ICE", "soil frozen water content", "m" },
+ { 200, -1, 0, "W_I", "canopy water amount", "m" },
+ { 203, -1, 0, "TSOIL", "snow surface temperature", "K" },
+ { 215, -1, 0, "TSOIL", "temperature of ice upper surface", "K" },
+ { 230, -1, 0, "dBZ", "unattenuated radar reflectivity in Rayleigh approximation", "1" },
+ { 240, -1, 0, "MFLX_CON", "convective mass flux density", "kg m-2 s-1" },
+ { 241, -1, 0, "CAPE_CON", "&", "J kg-1" },
+ { 243, -1, 0, "QCVG_CON", "&", "s-1" },
};
-static const PAR cosmo202[] = {
- { 46, 0, "SSO_STDH", "standard deviation of subgrid scale height", "m" },
- { 47, 0, "SSO_GAMMA", "anisotropy of topography", "-" },
- { 48, 0, "SSO_THETA", "angle between principal axis of orography and global east", "-" },
- { 49, 0, "SSO_SIGMA", "mean slope of subgrid scale orography", "-" },
- { 55, 0, "FR_LAKE", "fraction of inland lake water", "1" },
- { 57, 0, "SOILTYP", "soil type", "1" },
- { 61, 0, "LAI", "leaf area index", "1" },
- { 62, 0, "ROOTDP", "root depth", "m" },
- { 64, 0, "HMO3", "air pressure at ozone maximum", "Pa" },
- { 65, 0, "VIO3", "vertical integrated ozone amount", "Pa" },
- { 67, 0, "PLCOV_MX", "vegetation area fraction maximum", "1" },
- { 68, 0, "PLCOV_MN", "vegetation area fraction minimum", "1" },
- { 69, 0, "LAI_MX", "leaf area index maximum", "1" },
- { 70, 0, "LAI_MN", "leaf area index minimum", "1" },
- { 75, 0, "FOR_E", "ground fraction covered by evergreen forest", "-" },
- { 76, 0, "FOR_D", "ground fraction covered by deciduous forest", "-" },
- { 104, 0, "DQVDT", "tendency of water vapor", "s-1" },
- { 105, 0, "QVSFLX", "surface flux of water vapour", "s-1m-2" },
- { 113, 0, "FC", "coriolis parameter", "s-1" },
- { 114, 0, "RLAT", "latitude", "radian" },
- { 115, 0, "RLON", "longitude", "radian" },
- { 121, 0, "ZTD", "integrated total atmospheric refractivity", "undefined" },
- { 122, 0, "ZWD", "integrated wet atmospheric refractivity", "undefined" },
- { 123, 0, "ZHD", "integrated dry atmospheric refractivity", "undefined" },
- { 180, 0, "O3", "ozone mass mixing ratio", "kg kg-1" },
- { 200, 0, "I131a", "undefined", "undefined" },
- { 201, 0, "I131a_DD", "undefined", "undefined" },
- { 202, 0, "I131a_WD", "undefined", "undefined" },
- { 203, 0, "Cs137", "undefined", "undefined" },
- { 204, 0, "Cs137_DD", "undefined", "undefined" },
- { 205, 0, "Cs137_WD", "undefined", "undefined" },
- { 206, 0, "Te132", "undefined", "undefined" },
- { 207, 0, "Te132_DD", "undefined", "undefined" },
- { 208, 0, "Te132_WD", "undefined", "undefined" },
- { 209, 0, "Zr95", "undefined", "undefined" },
- { 210, 0, "Zr95_DD", "undefined", "undefined" },
- { 211, 0, "Zr95_WD", "undefined", "undefined" },
- { 212, 0, "Kr85", "undefined", "undefined" },
- { 213, 0, "Kr85_DD", "undefined", "undefined" },
- { 214, 0, "Kr85_WD", "undefined", "undefined" },
- { 215, 0, "TRACER", "undefined", "undefined" },
- { 216, 0, "TRACER_DD", "undefined", "undefined" },
- { 217, 0, "TRACER_WD", "undefined", "undefined" },
- { 218, 0, "Xe133", "undefined", "undefined" },
- { 219, 0, "Xe133_DD", "undefined", "undefined" },
- { 220, 0, "Xe133_WD", "undefined", "undefined" },
- { 221, 0, "I131g", "undefined", "undefined" },
- { 222, 0, "I131g_DD", "undefined", "undefined" },
- { 223, 0, "I131g_WD", "undefined", "undefined" },
- { 224, 0, "I131o", "undefined", "undefined" },
- { 225, 0, "I131o_DD", "undefined", "undefined" },
- { 226, 0, "I131o_WD", "undefined", "undefined" },
- { 227, 0, "Ba140", "undefined", "undefined" },
- { 228, 0, "Ba140_DD", "undefined", "undefined" },
- { 229, 0, "Ba140_WD", "undefined", "undefined" },
- { 230, 0, "Sr90", "undefined", "undefined" },
- { 231, 0, "Sr90_DD", "undefined", "undefined" },
- { 232, 0, "Sr90_WD", "undefined", "undefined" },
- { 233, 0, "Ru103", "undefined", "undefined" },
- { 234, 0, "Ru103_DD", "undefined", "undefined" },
- { 235, 0, "Ru103_WD", "undefined", "undefined" },
+static const param_type cosmo202[] = {
+ { 46, -1, 0, "SSO_STDH", "standard deviation of subgrid scale height", "m" },
+ { 47, -1, 0, "SSO_GAMMA", "anisotropy of topography", "-" },
+ { 48, -1, 0, "SSO_THETA", "angle between principal axis of orography and global east", "-" },
+ { 49, -1, 0, "SSO_SIGMA", "mean slope of subgrid scale orography", "-" },
+ { 55, -1, 0, "FR_LAKE", "fraction of inland lake water", "1" },
+ { 57, -1, 0, "SOILTYP", "soil type", "1" },
+ { 61, -1, 0, "LAI", "leaf area index", "1" },
+ { 62, -1, 0, "ROOTDP", "root depth", "m" },
+ { 64, -1, 0, "HMO3", "air pressure at ozone maximum", "Pa" },
+ { 65, -1, 0, "VIO3", "vertical integrated ozone amount", "Pa" },
+ { 67, -1, 0, "PLCOV_MX", "vegetation area fraction maximum", "1" },
+ { 68, -1, 0, "PLCOV_MN", "vegetation area fraction minimum", "1" },
+ { 69, -1, 0, "LAI_MX", "leaf area index maximum", "1" },
+ { 70, -1, 0, "LAI_MN", "leaf area index minimum", "1" },
+ { 75, -1, 0, "FOR_E", "ground fraction covered by evergreen forest", "-" },
+ { 76, -1, 0, "FOR_D", "ground fraction covered by deciduous forest", "-" },
+ { 104, -1, 0, "DQVDT", "tendency of water vapor", "s-1" },
+ { 105, -1, 0, "QVSFLX", "surface flux of water vapour", "s-1m-2" },
+ { 113, -1, 0, "FC", "coriolis parameter", "s-1" },
+ { 114, -1, 0, "RLAT", "latitude", "radian" },
+ { 115, -1, 0, "RLON", "longitude", "radian" },
+ { 121, -1, 0, "ZTD", "integrated total atmospheric refractivity", "undefined" },
+ { 122, -1, 0, "ZWD", "integrated wet atmospheric refractivity", "undefined" },
+ { 123, -1, 0, "ZHD", "integrated dry atmospheric refractivity", "undefined" },
+ { 180, -1, 0, "O3", "ozone mass mixing ratio", "kg kg-1" },
+ { 200, -1, 0, "I131a", "undefined", "undefined" },
+ { 201, -1, 0, "I131a_DD", "undefined", "undefined" },
+ { 202, -1, 0, "I131a_WD", "undefined", "undefined" },
+ { 203, -1, 0, "Cs137", "undefined", "undefined" },
+ { 204, -1, 0, "Cs137_DD", "undefined", "undefined" },
+ { 205, -1, 0, "Cs137_WD", "undefined", "undefined" },
+ { 206, -1, 0, "Te132", "undefined", "undefined" },
+ { 207, -1, 0, "Te132_DD", "undefined", "undefined" },
+ { 208, -1, 0, "Te132_WD", "undefined", "undefined" },
+ { 209, -1, 0, "Zr95", "undefined", "undefined" },
+ { 210, -1, 0, "Zr95_DD", "undefined", "undefined" },
+ { 211, -1, 0, "Zr95_WD", "undefined", "undefined" },
+ { 212, -1, 0, "Kr85", "undefined", "undefined" },
+ { 213, -1, 0, "Kr85_DD", "undefined", "undefined" },
+ { 214, -1, 0, "Kr85_WD", "undefined", "undefined" },
+ { 215, -1, 0, "TRACER", "undefined", "undefined" },
+ { 216, -1, 0, "TRACER_DD", "undefined", "undefined" },
+ { 217, -1, 0, "TRACER_WD", "undefined", "undefined" },
+ { 218, -1, 0, "Xe133", "undefined", "undefined" },
+ { 219, -1, 0, "Xe133_DD", "undefined", "undefined" },
+ { 220, -1, 0, "Xe133_WD", "undefined", "undefined" },
+ { 221, -1, 0, "I131g", "undefined", "undefined" },
+ { 222, -1, 0, "I131g_DD", "undefined", "undefined" },
+ { 223, -1, 0, "I131g_WD", "undefined", "undefined" },
+ { 224, -1, 0, "I131o", "undefined", "undefined" },
+ { 225, -1, 0, "I131o_DD", "undefined", "undefined" },
+ { 226, -1, 0, "I131o_WD", "undefined", "undefined" },
+ { 227, -1, 0, "Ba140", "undefined", "undefined" },
+ { 228, -1, 0, "Ba140_DD", "undefined", "undefined" },
+ { 229, -1, 0, "Ba140_WD", "undefined", "undefined" },
+ { 230, -1, 0, "Sr90", "undefined", "undefined" },
+ { 231, -1, 0, "Sr90_DD", "undefined", "undefined" },
+ { 232, -1, 0, "Sr90_WD", "undefined", "undefined" },
+ { 233, -1, 0, "Ru103", "undefined", "undefined" },
+ { 234, -1, 0, "Ru103_DD", "undefined", "undefined" },
+ { 235, -1, 0, "Ru103_WD", "undefined", "undefined" },
};
-static const PAR cosmo203[] = {
- { 135, 0, "LCL_ML", "undefined", "undefined" },
- { 136, 0, "LFC_ML", "undefined", "undefined" },
- { 137, 0, "CAPE_3KM", "undefined", "undefined" },
- { 138, 0, "SWISS00", "swiss00 index", "1" },
- { 139, 0, "SWISS12", "swiss12 index", "1" },
- { 147, 0, "SLI", "surface lifted index", "K" },
- { 149, 0, "SI", "showalter index", "K" },
- { 155, 0, "BRN", "undefined", "undefined" },
- { 156, 0, "HPBL", "undefined", "undefined" },
- { 203, 0, "CLDEPTH", "normalized cloud depth", "1" },
- { 204, 0, "CLCT_MOD", "modified_total_cloud_cover", "1" },
+static const param_type cosmo203[] = {
+ { 135, -1, 0, "LCL_ML", "undefined", "undefined" },
+ { 136, -1, 0, "LFC_ML", "undefined", "undefined" },
+ { 137, -1, 0, "CAPE_3KM", "undefined", "undefined" },
+ { 138, -1, 0, "SWISS00", "swiss00 index", "1" },
+ { 139, -1, 0, "SWISS12", "swiss12 index", "1" },
+ { 147, -1, 0, "SLI", "surface lifted index", "K" },
+ { 149, -1, 0, "SI", "showalter index", "K" },
+ { 155, -1, 0, "BRN", "undefined", "undefined" },
+ { 156, -1, 0, "HPBL", "undefined", "undefined" },
+ { 203, -1, 0, "CLDEPTH", "normalized cloud depth", "1" },
+ { 204, -1, 0, "CLCT_MOD", "modified_total_cloud_cover", "1" },
};
-static const PAR cosmo205[] = {
- { 1, 0, "SYNME5", "synthetic satellite images Meteosat5", "-" },
- { 2, 0, "SYNME6", "synthetic satellite images Meteosat6", "-" },
- { 3, 0, "SYNME7", "synthetic satellite images Meteosat7", "-" },
- { 4, 0, "SYNMSG", "synthetic satellite images MSG", "-" },
+static const param_type cosmo205[] = {
+ { 1, -1, 0, "SYNME5", "synthetic satellite images Meteosat5", "-" },
+ { 2, -1, 0, "SYNME6", "synthetic satellite images Meteosat6", "-" },
+ { 3, -1, 0, "SYNME7", "synthetic satellite images Meteosat7", "-" },
+ { 4, -1, 0, "SYNMSG", "synthetic satellite images MSG", "-" },
};
-static const PAR cosmo250[] = {
- { 1, 0, "QNH", "sea level air pressure", "hPa" },
- { 11, 0, "TSOIL", "2m temperature", "K" },
- { 12, 0, "TSOIL", "2m temperature", "K" },
- { 13, 0, "D_T_2M_K", "kalman correction to 2m temperature", "K" },
- { 14, 0, "TSOIL", "2m temperature", "K" },
- { 15, 0, "TSOIL", "2m temperature", "K" },
- { 16, 0, "RH_ICE", "relative humidity over ice", "%" },
- { 17, 0, "TD", "dew point temperature", "K" },
- { 18, 0, "D_TD", "dew point depression", "K" },
- { 19, 0, "THETAE", "equivalent potential temperature", "K" },
- { 20, 0, "TD_2M_K", "2m dew point temperature", "K" },
- { 21, 0, "D_TD_2M_K", "kalman correction to 2m dew point temperature", "K" },
- { 22, 0, "TD_2M_OLD", "2m dew point temperature", "K" },
- { 23, 0, "TD_2M_BUZ", "2m dew point temperature", "K" },
- { 24, 0, "HI", "heat index", "Fahrenheit" },
- { 25, 0, "DURSUN_M", "maximum duration of sunshine", "s" },
- { 26, 0, "DURSUN_R", "relative duration of sunshine", "%" },
- { 52, 0, "RH_2M_K", "2m relative humidity", "%" },
- { 53, 0, "D_RH_2M_K", "kalman correction to 2m relative humidity", "%" },
- { 58, 0, "CLI_RATIO", "cloud ice ratio (Qi/Qc+Qi)", "%" },
- { 61, 0, "TOT_SNOW", "total precipitation in snow", "kg/m**2" },
- { 62, 0, "TOT_RAIN", "total precipitation in rain", "kg/m**2" },
- { 63, 0, "TOT_CON", "total convective precipitation", "kg/m**2" },
- { 64, 0, "TOT_GSP", "total large scale precipitation", "kg/m**2" },
- { 65, 0, "SNOW_%", "percentage of precipitation in snow", "%" },
- { 66, 0, "CONV_%", "percentage of convective precipitation", "%" },
- { 67, 0, "VORTP_ABS", "absolute", "VORTP_ABS 67 -1 absolute vorticity" },
- { 68, 0, "VORTP_REL", "relative", "VORTP_REL 68 -1 relative vorticity" },
- { 70, 0, "PDIFF_CON", "pressure difference between cloud base and cloud top", "Pa" },
- { 71, 0, "TTOP_CON", "temperature at cloud top", "K" },
- { 80, 0, "GEM", "emissivity of the ground", "%" },
- { 82, 0, "Z0LOC", "local surface roughness length", "m" },
- { 110, 0, "LUM", "luminosity", "klux" },
- { 111, 0, "GLOB", "global shortwave radiation at surface", "W/m**2" },
- { 112, 0, "LW_IN_TG", "incoming longwave radiation at surface", "W/m**2" },
- { 113, 0, "LW_IN_TS", "incoming longwave radiation at surface", "W/m**2" },
- { 114, 0, "LW_IN_T2M", "incoming longwave radiation at surface", "W/m**2" },
- { 115, 0, "SWISS_WE", "Swiss", "SWISS_WE 115 1 Swiss coordinates" },
- { 116, 0, "SWISS_SN", "Swiss", "SWISS_SN 116 1 Swiss coordinates" },
- { 150, 0, "KOINDEX", "KO index", "K" },
- { 151, 0, "TTINDEX", "total-totals index", "K" },
- { 152, 0, "DCI", "deep convection index", "K" },
- { 153, 0, "SWEAT", "severe weather thread index", "undefined" },
- { 154, 0, "ADEDO2", "adedokun 2 index", "K" },
- { 160, 0, "C_TSTORM", "thunderstorm index using AdaBoost classifier", "undefined" },
- { 161, 0, "CN_TSTORM", "thunderstorm probabilty using AdaBoost classifier", "%" },
- { 200, 0, "WSHEARL", "wind shear between surface and 3 km asl", "1/s" },
- { 201, 0, "WSHEARM", "wind shear between surface and 6 km asl", "1/s" },
- { 202, 0, "WSHEARU", "wind shear between 3 km (or surface) and 6 km asl", "1/s" },
- { 211, 0, "VWIN", "maximum OLD turbulent wind gust in 10m", "m s-1" },
- { 212, 0, "VW10M_20", "maximum 10m wind speed", "m s-1" },
- { 213, 0, "VW10M_25", "duration of VWIN_10M above 25 knots", "s" },
- { 214, 0, "VW10M_30", "duration of VWIN_10M above 30 knots", "s" },
- { 215, 0, "VW10M_35", "duration of VWIN_10M above 35 knots", "s" },
- { 216, 0, "VW10M_40", "duration of VWIN_10M above 40 knots", "s" },
- { 217, 0, "VW10M_45", "duration of VWIN_10M above 45 knots", "s" },
- { 218, 0, "VW10M_50", "duration of VWIN_10M above 50 knots", "s" },
- { 219, 0, "VOLD", "maximum turbulent wind gust in 10m", "m s-1" },
- { 220, 0, "VJPS", "maximum turbulent wind gust in 10m", "m s-1" },
- { 221, 0, "VBRA", "maximum Brasseur turbulent wind gust in 10m", "m s-1" },
- { 222, 0, "VB10M_20", "duration of VBRA_10M above 20 knots", "s" },
- { 223, 0, "VB10M_25", "duration of VBRA_10M above 25 knots", "s" },
- { 224, 0, "VB10M_30", "duration of VBRA_10M above 30 knots", "s" },
- { 225, 0, "VB10M_35", "duration of VBRA_10M above 35 knots", "s" },
- { 226, 0, "VB10M_40", "duration of VBRA_10M above 40 knots", "s" },
- { 227, 0, "VB10M_45", "duration of VBRA_10M above 45 knots", "s" },
- { 228, 0, "VB10M_50", "duration of VBRA_10M above 50 knots", "s" },
- { 231, 0, "VCON", "maximum convective wind gust in 10m", "m s-1" },
- { 232, 0, "VC10M_20", "duration of VCON_10M above 20 knots", "s" },
- { 233, 0, "VC10M_25", "duration of VCON_10M above 25 knots", "s" },
- { 234, 0, "VC10M_30", "duration of VCON_10M above 30 knots", "s" },
- { 235, 0, "VC10M_35", "duration of VCON_10M above 35 knots", "s" },
- { 236, 0, "VC10M_40", "duration of VCON_10M above 40 knots", "s" },
- { 237, 0, "VC10M_45", "duration of VCON_10M above 45 knots", "s" },
- { 238, 0, "VC10M_50", "duration of VCON_10M above 50 knots", "s" },
- { 241, 0, "FMAX", "maximum wind speed at k=ke", "m s-1" },
- { 242, 0, "USTARMAX", "maximal u*=SQRT(Drag_coef)*fmax_10m", "m s-1" },
- { 243, 0, "GLOB_DIF", "global diffuse shortwave radiation at the surface", "W/m**2" },
- { 244, 0, "GLOB_DIR", "global direct (beam) shortwave radiation at the surface", "W/m**2" },
- { 245, 0, "GLOB_vE", "global shortwave radiation on a vertical surface facing east", "W/m**2" },
- { 246, 0, "GLOB_vS", "global shortwave radiation on a vertical surface facing south", "W/m**2" },
- { 247, 0, "GLOB_vW", "global shortwave radiation on a vertical surface facing west", "W/m**2" },
- { 248, 0, "GLOB_vN", "global shortwave radiation on a vertical surface facing north", "W/m**2" },
- { 249, 0, "LW_TG_vS", "incoming longwave radiation on a vertical surface facing south", "W/m**2" },
- { 250, 0, "ENTH", "enthalpy", "kJ/kg" },
- { 251, 0, "ENTH", "enthalpy", "kJ/kg" },
- { 252, 0, "MIXRAT", "mixing ratio", "g/kg" },
- { 253, 0, "MIXRAT", "mixing ratio", "g/kg" },
- { 254, 0, "TW", "wet bulb temperature", "degC" },
- { 255, 0, "TW", "wet bulb temperature", "degC" },
+static const param_type cosmo250[] = {
+ { 1, -1, 0, "QNH", "sea level air pressure", "hPa" },
+ { 11, -1, 0, "TSOIL", "2m temperature", "K" },
+ { 12, -1, 0, "TSOIL", "2m temperature", "K" },
+ { 13, -1, 0, "D_T_2M_K", "kalman correction to 2m temperature", "K" },
+ { 14, -1, 0, "TSOIL", "2m temperature", "K" },
+ { 15, -1, 0, "TSOIL", "2m temperature", "K" },
+ { 16, -1, 0, "RH_ICE", "relative humidity over ice", "%" },
+ { 17, -1, 0, "TD", "dew point temperature", "K" },
+ { 18, -1, 0, "D_TD", "dew point depression", "K" },
+ { 19, -1, 0, "THETAE", "equivalent potential temperature", "K" },
+ { 20, -1, 0, "TD_2M_K", "2m dew point temperature", "K" },
+ { 21, -1, 0, "D_TD_2M_K", "kalman correction to 2m dew point temperature", "K" },
+ { 22, -1, 0, "TD_2M_OLD", "2m dew point temperature", "K" },
+ { 23, -1, 0, "TD_2M_BUZ", "2m dew point temperature", "K" },
+ { 24, -1, 0, "HI", "heat index", "Fahrenheit" },
+ { 25, -1, 0, "DURSUN_M", "maximum duration of sunshine", "s" },
+ { 26, -1, 0, "DURSUN_R", "relative duration of sunshine", "%" },
+ { 52, -1, 0, "RH_2M_K", "2m relative humidity", "%" },
+ { 53, -1, 0, "D_RH_2M_K", "kalman correction to 2m relative humidity", "%" },
+ { 58, -1, 0, "CLI_RATIO", "cloud ice ratio (Qi/Qc+Qi)", "%" },
+ { 61, -1, 0, "TOT_SNOW", "total precipitation in snow", "kg/m**2" },
+ { 62, -1, 0, "TOT_RAIN", "total precipitation in rain", "kg/m**2" },
+ { 63, -1, 0, "TOT_CON", "total convective precipitation", "kg/m**2" },
+ { 64, -1, 0, "TOT_GSP", "total large scale precipitation", "kg/m**2" },
+ { 65, -1, 0, "SNOW_%", "percentage of precipitation in snow", "%" },
+ { 66, -1, 0, "CONV_%", "percentage of convective precipitation", "%" },
+ { 67, -1, 0, "VORTP_ABS", "absolute", "VORTP_ABS 67 -1 absolute vorticity" },
+ { 68, -1, 0, "VORTP_REL", "relative", "VORTP_REL 68 -1 relative vorticity" },
+ { 70, -1, 0, "PDIFF_CON", "pressure difference between cloud base and cloud top", "Pa" },
+ { 71, -1, 0, "TTOP_CON", "temperature at cloud top", "K" },
+ { 80, -1, 0, "GEM", "emissivity of the ground", "%" },
+ { 82, -1, 0, "Z0LOC", "local surface roughness length", "m" },
+ { 110, -1, 0, "LUM", "luminosity", "klux" },
+ { 111, -1, 0, "GLOB", "global shortwave radiation at surface", "W/m**2" },
+ { 112, -1, 0, "LW_IN_TG", "incoming longwave radiation at surface", "W/m**2" },
+ { 113, -1, 0, "LW_IN_TS", "incoming longwave radiation at surface", "W/m**2" },
+ { 114, -1, 0, "LW_IN_T2M", "incoming longwave radiation at surface", "W/m**2" },
+ { 115, -1, 0, "SWISS_WE", "Swiss", "SWISS_WE 115 1 Swiss coordinates" },
+ { 116, -1, 0, "SWISS_SN", "Swiss", "SWISS_SN 116 1 Swiss coordinates" },
+ { 150, -1, 0, "KOINDEX", "KO index", "K" },
+ { 151, -1, 0, "TTINDEX", "total-totals index", "K" },
+ { 152, -1, 0, "DCI", "deep convection index", "K" },
+ { 153, -1, 0, "SWEAT", "severe weather thread index", "undefined" },
+ { 154, -1, 0, "ADEDO2", "adedokun 2 index", "K" },
+ { 160, -1, 0, "C_TSTORM", "thunderstorm index using AdaBoost classifier", "undefined" },
+ { 161, -1, 0, "CN_TSTORM", "thunderstorm probabilty using AdaBoost classifier", "%" },
+ { 200, -1, 0, "WSHEARL", "wind shear between surface and 3 km asl", "1/s" },
+ { 201, -1, 0, "WSHEARM", "wind shear between surface and 6 km asl", "1/s" },
+ { 202, -1, 0, "WSHEARU", "wind shear between 3 km (or surface) and 6 km asl", "1/s" },
+ { 211, -1, 0, "VWIN", "maximum OLD turbulent wind gust in 10m", "m s-1" },
+ { 212, -1, 0, "VW10M_20", "maximum 10m wind speed", "m s-1" },
+ { 213, -1, 0, "VW10M_25", "duration of VWIN_10M above 25 knots", "s" },
+ { 214, -1, 0, "VW10M_30", "duration of VWIN_10M above 30 knots", "s" },
+ { 215, -1, 0, "VW10M_35", "duration of VWIN_10M above 35 knots", "s" },
+ { 216, -1, 0, "VW10M_40", "duration of VWIN_10M above 40 knots", "s" },
+ { 217, -1, 0, "VW10M_45", "duration of VWIN_10M above 45 knots", "s" },
+ { 218, -1, 0, "VW10M_50", "duration of VWIN_10M above 50 knots", "s" },
+ { 219, -1, 0, "VOLD", "maximum turbulent wind gust in 10m", "m s-1" },
+ { 220, -1, 0, "VJPS", "maximum turbulent wind gust in 10m", "m s-1" },
+ { 221, -1, 0, "VBRA", "maximum Brasseur turbulent wind gust in 10m", "m s-1" },
+ { 222, -1, 0, "VB10M_20", "duration of VBRA_10M above 20 knots", "s" },
+ { 223, -1, 0, "VB10M_25", "duration of VBRA_10M above 25 knots", "s" },
+ { 224, -1, 0, "VB10M_30", "duration of VBRA_10M above 30 knots", "s" },
+ { 225, -1, 0, "VB10M_35", "duration of VBRA_10M above 35 knots", "s" },
+ { 226, -1, 0, "VB10M_40", "duration of VBRA_10M above 40 knots", "s" },
+ { 227, -1, 0, "VB10M_45", "duration of VBRA_10M above 45 knots", "s" },
+ { 228, -1, 0, "VB10M_50", "duration of VBRA_10M above 50 knots", "s" },
+ { 231, -1, 0, "VCON", "maximum convective wind gust in 10m", "m s-1" },
+ { 232, -1, 0, "VC10M_20", "duration of VCON_10M above 20 knots", "s" },
+ { 233, -1, 0, "VC10M_25", "duration of VCON_10M above 25 knots", "s" },
+ { 234, -1, 0, "VC10M_30", "duration of VCON_10M above 30 knots", "s" },
+ { 235, -1, 0, "VC10M_35", "duration of VCON_10M above 35 knots", "s" },
+ { 236, -1, 0, "VC10M_40", "duration of VCON_10M above 40 knots", "s" },
+ { 237, -1, 0, "VC10M_45", "duration of VCON_10M above 45 knots", "s" },
+ { 238, -1, 0, "VC10M_50", "duration of VCON_10M above 50 knots", "s" },
+ { 241, -1, 0, "FMAX", "maximum wind speed at k=ke", "m s-1" },
+ { 242, -1, 0, "USTARMAX", "maximal u*=SQRT(Drag_coef)*fmax_10m", "m s-1" },
+ { 243, -1, 0, "GLOB_DIF", "global diffuse shortwave radiation at the surface", "W/m**2" },
+ { 244, -1, 0, "GLOB_DIR", "global direct (beam) shortwave radiation at the surface", "W/m**2" },
+ { 245, -1, 0, "GLOB_vE", "global shortwave radiation on a vertical surface facing east", "W/m**2" },
+ { 246, -1, 0, "GLOB_vS", "global shortwave radiation on a vertical surface facing south", "W/m**2" },
+ { 247, -1, 0, "GLOB_vW", "global shortwave radiation on a vertical surface facing west", "W/m**2" },
+ { 248, -1, 0, "GLOB_vN", "global shortwave radiation on a vertical surface facing north", "W/m**2" },
+ { 249, -1, 0, "LW_TG_vS", "incoming longwave radiation on a vertical surface facing south", "W/m**2" },
+ { 250, -1, 0, "ENTH", "enthalpy", "kJ/kg" },
+ { 251, -1, 0, "ENTH", "enthalpy", "kJ/kg" },
+ { 252, -1, 0, "MIXRAT", "mixing ratio", "g/kg" },
+ { 253, -1, 0, "MIXRAT", "mixing ratio", "g/kg" },
+ { 254, -1, 0, "TW", "wet bulb temperature", "degC" },
+ { 255, -1, 0, "TW", "wet bulb temperature", "degC" },
};
static
void tableDefault(void)
{
- int tableID, instID, modelID;
+ // define table : echam4
+ {
+ int instID = institutInq(98, 255, "MPIMET", NULL);
+ if ( instID == -1 )
+ instID = institutDef(98, 255, "MPIMET", NULL);
- /*
- * define table : echam4
- */
-
- instID = institutInq(98, 255, "MPIMET", NULL);
- if ( instID == -1 )
- instID = institutDef(98, 255, "MPIMET", NULL);
-
- modelID = modelInq(instID, 0, "ECHAM4");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "ECHAM4");
-
- tableID = tableDef(modelID, 128, "echam4");
-
- tableLink(tableID, echam4, sizeof(echam4) / sizeof(PAR));
-
- /*
- * define table : echam5
- */
-
- instID = institutInq(0, 0, "MPIMET", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MPIMET", NULL);
-
- modelID = modelInq(instID, 0, "ECHAM5");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "ECHAM5");
-
- tableID = tableDef(modelID, 128, "echam5");
-
- tableLink(tableID, echam5, sizeof(echam5) / sizeof(PAR));
-
- /*
- * define table : echam6
- */
-
- instID = institutInq(0, 0, "MPIMET", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MPIMET", NULL);
-
- modelID = modelInq(instID, 0, "ECHAM6");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "ECHAM6");
-
- tableID = tableDef(modelID, 128, "echam6");
+ int modelID = modelInq(instID, 0, "ECHAM4");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "ECHAM4");
- tableLink(tableID, echam6, sizeof(echam6) / sizeof(PAR));
+ int tableID = tableDef(modelID, 128, "echam4");
- /*
- * define table : mpiom1
- */
+ tableLink(tableID, echam4, sizeof(echam4) / sizeof(param_type));
+ }
- instID = institutInq(0, 0, "MPIMET", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MPIMET", NULL);
+ // define table : echam5
+ {
+ int instID = institutInq(0, 0, "MPIMET", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MPIMET", NULL);
- modelID = modelInq(instID, 0, "MPIOM1");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "MPIOM1");
+ int modelID = modelInq(instID, 0, "ECHAM5");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "ECHAM5");
- tableID = tableDef(modelID, 128, "mpiom1");
+ int tableID = tableDef(modelID, 128, "echam5");
- tableLink(tableID, mpiom1, sizeof(mpiom1) / sizeof(PAR));
+ tableLink(tableID, echam5, sizeof(echam5) / sizeof(param_type));
+ }
- /*
- * define table : ecmwf
- */
+ // define table : echam6
+ {
+ int instID = institutInq(0, 0, "MPIMET", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MPIMET", NULL);
- instID = institutInq(0, 0, "ECMWF", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "ECMWF", NULL);
+ int modelID = modelInq(instID, 0, "ECHAM6");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "ECHAM6");
- modelID = modelInq(instID, 0, "");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "");
+ int tableID = tableDef(modelID, 128, "echam6");
- tableID = tableDef(modelID, 128, "ecmwf");
+ tableLink(tableID, echam6, sizeof(echam6) / sizeof(param_type));
+ }
- tableLink(tableID, ecmwf, sizeof(ecmwf) / sizeof(PAR));
+ // define table : mpiom1
+ {
+ int instID = institutInq(0, 0, "MPIMET", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MPIMET", NULL);
- /*
- * define table : remo
- */
+ int modelID = modelInq(instID, 0, "MPIOM1");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "MPIOM1");
- instID = institutInq(0, 0, "MPIMET", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MPIMET", NULL);
+ int tableID = tableDef(modelID, 128, "mpiom1");
- modelID = modelInq(instID, 0, "REMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "REMO");
+ tableLink(tableID, mpiom1, sizeof(mpiom1) / sizeof(param_type));
+ }
- tableID = tableDef(modelID, 128, "remo");
+ // define table : ecmwf
+ {
+ int instID = institutInq(0, 0, "ECMWF", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "ECMWF", NULL);
- tableLink(tableID, remo, sizeof(remo) / sizeof(PAR));
+ int modelID = modelInq(instID, 0, "");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "");
- /*
- * define table : cosmo002
- */
+ int tableID = tableDef(modelID, 128, "ecmwf");
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ tableLink(tableID, ecmwf, sizeof(ecmwf) / sizeof(param_type));
+ }
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ // define table : remo
+ {
+ int instID = institutInq(0, 0, "MPIMET", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MPIMET", NULL);
- tableID = tableDef(modelID, 002, "cosmo002");
+ int modelID = modelInq(instID, 0, "REMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "REMO");
- tableLink(tableID, cosmo002, sizeof(cosmo002) / sizeof(PAR));
+ int tableID = tableDef(modelID, 128, "remo");
- /*
- * define table : cosmo201
- */
+ tableLink(tableID, remo, sizeof(remo) / sizeof(param_type));
+ }
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ // define table : cosmo002
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- tableID = tableDef(modelID, 201, "cosmo201");
+ int tableID = tableDef(modelID, 002, "cosmo002");
- tableLink(tableID, cosmo201, sizeof(cosmo201) / sizeof(PAR));
+ tableLink(tableID, cosmo002, sizeof(cosmo002) / sizeof(param_type));
+ }
- /*
- * define table : cosmo202
- */
+ // define table : cosmo201
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ int tableID = tableDef(modelID, 201, "cosmo201");
- tableID = tableDef(modelID, 202, "cosmo202");
+ tableLink(tableID, cosmo201, sizeof(cosmo201) / sizeof(param_type));
+ }
- tableLink(tableID, cosmo202, sizeof(cosmo202) / sizeof(PAR));
+ // define table : cosmo202
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- /*
- * define table : cosmo203
- */
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ int tableID = tableDef(modelID, 202, "cosmo202");
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ tableLink(tableID, cosmo202, sizeof(cosmo202) / sizeof(param_type));
+ }
- tableID = tableDef(modelID, 203, "cosmo203");
+ // define table : cosmo203
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- tableLink(tableID, cosmo203, sizeof(cosmo203) / sizeof(PAR));
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- /*
- * define table : cosmo205
- */
+ int tableID = tableDef(modelID, 203, "cosmo203");
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ tableLink(tableID, cosmo203, sizeof(cosmo203) / sizeof(param_type));
+ }
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ // define table : cosmo205
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- tableID = tableDef(modelID, 205, "cosmo205");
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- tableLink(tableID, cosmo205, sizeof(cosmo205) / sizeof(PAR));
+ int tableID = tableDef(modelID, 205, "cosmo205");
- /*
- * define table : cosmo250
- */
+ tableLink(tableID, cosmo205, sizeof(cosmo205) / sizeof(param_type));
+ }
- instID = institutInq(0, 0, "MCH", NULL);
- if ( instID == -1 )
- instID = institutDef(0, 0, "MCH", NULL);
+ // define table : cosmo250
+ {
+ int instID = institutInq(0, 0, "MCH", NULL);
+ if ( instID == -1 )
+ instID = institutDef(0, 0, "MCH", NULL);
- modelID = modelInq(instID, 0, "COSMO");
- if ( modelID == -1 )
- modelID = modelDef(instID, 0, "COSMO");
+ int modelID = modelInq(instID, 0, "COSMO");
+ if ( modelID == -1 )
+ modelID = modelDef(instID, 0, "COSMO");
- tableID = tableDef(modelID, 250, "cosmo250");
+ int tableID = tableDef(modelID, 250, "cosmo250");
- tableLink(tableID, cosmo250, sizeof(cosmo250) / sizeof(PAR));
+ tableLink(tableID, cosmo250, sizeof(cosmo250) / sizeof(param_type));
+ }
}
-#endif /* _TABLE_H */
+#endif /* TABLE_H */
#if defined (HAVE_CONFIG_H)
#endif
@@ -59293,8 +59358,6 @@ void tableDefault(void)
#include <string.h>
-#undef UNDEFID
-#define UNDEFID -1
/*int TableDefine = 0; */ /* Define new table also if the entry already exist */
/* This is needed for createtable */
@@ -59305,16 +59368,16 @@ void tableDefault(void)
typedef struct
{
- int used;
+ bool used;
int npars;
- PAR *pars;
int modelID;
int number;
char *name;
+ param_type *pars;
}
-PARTAB;
+paramtab_type;
-static PARTAB parTable[MAX_TABLE];
+static paramtab_type parTable[MAX_TABLE];
static int parTableSize = MAX_TABLE;
static int parTableNum = 0;
static int ParTableInit = 0;
@@ -59324,16 +59387,16 @@ static char *tablePath = NULL;
static void tableDefModelID(int tableID, int modelID);
static void tableDefNum(int tableID, int tablenum);
-
-void tableDefEntry(int tableID, int id, const char *name,
+static
+void tableDefEntry(int tableID, int id, int ltype, const char *name,
const char *longname, const char *units)
{
- int item;
-
if ( tableID >= 0 && tableID < MAX_TABLE && parTable[tableID].used) { } else
Error("Invalid table ID %d", tableID);
- item = parTable[tableID].npars++;
+
+ int item = parTable[tableID].npars++;
parTable[tableID].pars[item].id = id;
+ parTable[tableID].pars[item].ltype = ltype;
parTable[tableID].pars[item].dupflags = 0;
parTable[tableID].pars[item].name = NULL;
parTable[tableID].pars[item].longname = NULL;
@@ -59356,13 +59419,12 @@ void tableDefEntry(int tableID, int id, const char *name,
}
}
-static void tableLink(int tableID, const PAR *pars, int npars)
+static void tableLink(int tableID, const param_type *pars, int npars)
{
- int item;
-
- for ( item = 0; item < npars; item++ )
+ for ( int item = 0; item < npars; item++ )
{
parTable[tableID].pars[item].id = pars[item].id;
+ parTable[tableID].pars[item].ltype = pars[item].ltype;
parTable[tableID].pars[item].dupflags = 0;
parTable[tableID].pars[item].name = pars[item].name;
parTable[tableID].pars[item].longname = pars[item].longname;
@@ -59374,19 +59436,17 @@ static void tableLink(int tableID, const PAR *pars, int npars)
static void parTableInitEntry(int tableID)
{
- parTable[tableID].used = 0;
+ parTable[tableID].used = false;
parTable[tableID].pars = NULL;
parTable[tableID].npars = 0;
- parTable[tableID].modelID = UNDEFID;
- parTable[tableID].number = UNDEFID;
+ parTable[tableID].modelID = CDI_UNDEFID;
+ parTable[tableID].number = CDI_UNDEFID;
parTable[tableID].name = NULL;
}
static void tableGetPath(void)
{
- char *path;
-
- path = getenv("TABLEPATH");
+ char *path = getenv("TABLEPATH");
if ( path ) tablePath = strdupx(path);
/*
@@ -59448,10 +59508,10 @@ static int tableNewEntry()
if ( tableID == parTableSize )
Error("no more entries!");
- parTable[tableID].used = 1;
+ parTable[tableID].used = true;
parTableNum++;
- return (tableID);
+ return tableID;
}
static int
@@ -59472,9 +59532,9 @@ decodeForm1(char *pline, char *name, char *longname, char *units)
name[len] = 0;
}
else
- return (0);
+ return 0;
- if ( pline[0] == 0 ) return (0);
+ if ( pline[0] == 0 ) return 0;
/* Format 1 : code name add mult longname [units] */
/* FIXME: successful parse isn't verified */
@@ -59511,7 +59571,7 @@ decodeForm1(char *pline, char *name, char *longname, char *units)
pstart++;
while ( isspace((int) *pstart) ) pstart++;
pend = strchr(pstart, ']');
- if ( ! pend ) return (0);
+ if ( ! pend ) return 0;
pend--;
while ( isspace((int) *pend) ) pend--;
len = (size_t)(pend - pstart + 1);
@@ -59523,7 +59583,7 @@ decodeForm1(char *pline, char *name, char *longname, char *units)
}
}
- return (0);
+ return 0;
}
static int
@@ -59549,7 +59609,7 @@ decodeForm2(char *pline, char *name, char *longname, char *units)
memcpy(name, pline, len);
name[len] = 0;
}
- return (0);
+ return 0;
}
else
{
@@ -59597,24 +59657,22 @@ decodeForm2(char *pline, char *name, char *longname, char *units)
units[len] = 0;
}
- return (0);
+ return 0;
}
+
int tableRead(const char *tablefile)
{
char line[1024], *pline;
int lnr = 0;
- int id;
char name[256], longname[256], units[256];
- int tableID = UNDEFID;
int err;
- char *tablename;
- FILE *tablefp;
+ int tableID = CDI_UNDEFID;
- tablefp = fopen(tablefile, "r");
- if ( tablefp == NULL ) return (tableID);
+ FILE *tablefp = fopen(tablefile, "r");
+ if ( tablefp == NULL ) return tableID;
- tablename = (char* )strrchr(tablefile, '/');
+ char *tablename = (char* )strrchr(tablefile, '/');
if ( tablename == 0 ) tablename = (char *) tablefile;
else tablename++;
@@ -59625,7 +59683,8 @@ int tableRead(const char *tablefile)
size_t len = strlen(line);
if ( line[len-1] == '\n' ) line[len-1] = '\0';
lnr++;
- id = CDI_UNDEFID;
+ int id = CDI_UNDEFID;
+ int ltype = CDI_UNDEFID;
name[0] = 0;
longname[0] = 0;
units[0] = 0;
@@ -59643,6 +59702,21 @@ int tableRead(const char *tablefile)
while ( isdigit((int) *pline) ) pline++;
+ if ( *pline == ';' || *pline == ':' )
+ {
+ pline++;
+ ltype = atoi(pline);
+ while ( isdigit((int) *pline) ) pline++;
+
+ if ( *pline == ';' || *pline == ':' )
+ {
+ pline++;
+ while ( isdigit((int) *pline) ) pline++;
+ }
+ }
+
+ while ( isdigit((int) *pline) ) pline++;
+
if ( strchr(pline, '|') )
err = decodeForm2(pline, name, longname, units);
else
@@ -59652,86 +59726,67 @@ int tableRead(const char *tablefile)
if ( name[0] == 0 ) sprintf(name, "var%d", id);
- tableDefEntry(tableID, id, name, longname, units);
+ tableDefEntry(tableID, id, ltype, name, longname, units);
}
- return (tableID);
+ return tableID;
}
+
static int tableFromEnv(int modelID, int tablenum)
{
- int tableID = UNDEFID;
char tablename[256] = {'\0'};
- int tablenamefound = 0;
+ size_t tablenameLen = 0;
+ int instID;
- const char *modelName;
- if ( (modelName = modelInqNamePtr(modelID)) )
- {
- strcpy(tablename, modelName);
- if ( tablenum )
- {
- size_t len = strlen(tablename);
- sprintf(tablename+len, "_%03d", tablenum);
- }
- tablenamefound = 1;
+ const char *name2Use;
+ {
+ const char *modelName, *instName;
+ if ( (modelName = modelInqNamePtr(modelID)) )
+ name2Use = modelName;
+ else if ( (instID = modelInqInstitut(modelID)) != CDI_UNDEFID
+ && (instName = institutInqNamePtr(instID)) )
+ name2Use = instName;
+ else
+ return CDI_UNDEFID;
+ }
+ tablenameLen = strlen(name2Use);
+ memcpy(tablename, name2Use, tablenameLen);
+ if ( tablenum )
+ tablenameLen
+ += (size_t)(sprintf(tablename+tablenameLen, "_%03d", tablenum));
+ size_t lenp = 0, lenf = tablenameLen;
+ if ( tablePath )
+ lenp = strlen(tablePath);
+ /* if (tablePath) printf("tablePath = %s\n", tablePath); */
+ /* if (tablename) printf("tableName = %s\n", tablename); */
+ char *tablefile = (char *) Malloc(lenp+lenf+3);
+ if ( tablePath )
+ {
+ strcpy(tablefile, tablePath);
+ strcat(tablefile, "/");
}
else
- {
- int instID = modelInqInstitut(modelID);
- if ( instID != UNDEFID )
- {
- const char *instName;
- if ( (instName = institutInqNamePtr(instID)) )
- {
- strcpy(tablename, instName);
- if ( tablenum )
- {
- size_t len = strlen(tablename);
- sprintf(tablename+len, "_%03d", tablenum);
- }
- tablenamefound = 1;
- }
- }
- }
+ tablefile[0] = '\0';
+ strcat(tablefile, tablename);
+ /* if (tablefile) printf("tableFile = %s\n", tablefile); */
- if ( tablenamefound )
+ int tableID = tableRead(tablefile);
+ if ( tableID != CDI_UNDEFID )
{
- size_t lenp = 0, lenf;
- char *tablefile = NULL;
- if ( tablePath )
- lenp = strlen(tablePath);
- lenf = strlen(tablename);
- /* if (tablePath) printf("tablePath = %s\n", tablePath); */
- /* if (tablename) printf("tableName = %s\n", tablename); */
- tablefile = (char *) Malloc(lenp+lenf+3);
- if ( tablePath )
- {
- strcpy(tablefile, tablePath);
- strcat(tablefile, "/");
- }
- else
- tablefile[0] = '\0';
- strcat(tablefile, tablename);
- /* if (tablefile) printf("tableFile = %s\n", tablefile); */
-
- tableID = tableRead(tablefile);
- if ( tableID != UNDEFID )
- {
- tableDefModelID(tableID, modelID);
- tableDefNum(tableID, tablenum);
- }
- /* printf("tableID = %d %s\n", tableID, tablefile); */
-
- Free(tablefile);
+ tableDefModelID(tableID, modelID);
+ tableDefNum(tableID, tablenum);
}
+ /* printf("tableID = %d %s\n", tableID, tablefile); */
+ Free(tablefile);
- return (tableID);
+ return tableID;
}
int tableInq(int modelID, int tablenum, const char *tablename)
{
- int tableID = UNDEFID;
- int modelID2 = UNDEFID;
+ int tableID = CDI_UNDEFID;
+ int modelID2 = CDI_UNDEFID;
char tablefile[256] = {'\0'};
if ( ! ParTableInit ) parTableInit();
@@ -59753,7 +59808,7 @@ int tableInq(int modelID, int tablenum, const char *tablename)
if ( memcmp(parTable[tableID].name, tablename, len) == 0 ) break;
}
}
- if ( tableID == MAX_TABLE ) tableID = UNDEFID;
+ if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
if ( CDI_Debug )
Message("tableID = %d tablename = %s", tableID, tablename);
}
@@ -59768,11 +59823,11 @@ int tableInq(int modelID, int tablenum, const char *tablename)
}
}
- if ( tableID == MAX_TABLE ) tableID = UNDEFID;
+ if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
- if ( tableID == UNDEFID )
+ if ( tableID == CDI_UNDEFID )
{
- if ( modelID != UNDEFID )
+ if ( modelID != CDI_UNDEFID )
{
const char *modelName;
if ( (modelName = modelInqNamePtr(modelID)) )
@@ -59784,7 +59839,7 @@ int tableInq(int modelID, int tablenum, const char *tablename)
modelID2 = modelInq(-1, 0, tablefile);
}
}
- if ( modelID2 != UNDEFID )
+ if ( modelID2 != CDI_UNDEFID )
for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
{
if ( parTable[tableID].used )
@@ -59795,9 +59850,9 @@ int tableInq(int modelID, int tablenum, const char *tablename)
}
}
- if ( tableID == MAX_TABLE ) tableID = UNDEFID;
+ if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
- if ( tableID == UNDEFID && modelID != UNDEFID )
+ if ( tableID == CDI_UNDEFID && modelID != CDI_UNDEFID )
tableID = tableFromEnv(modelID, tablenum);
if ( CDI_Debug )
@@ -59805,19 +59860,19 @@ int tableInq(int modelID, int tablenum, const char *tablename)
Message("tableID = %d tablename = %s", tableID, tablename);
}
- return (tableID);
+ return tableID;
}
int tableDef(int modelID, int tablenum, const char *tablename)
{
- int tableID = UNDEFID;
+ int tableID = CDI_UNDEFID;
if ( ! ParTableInit ) parTableInit();
/*
- if ( ! (modelID == UNDEFID && tablenum == 0) )
+ if ( ! (modelID == CDI_UNDEFID && tablenum == 0) )
tableID = tableInq(modelID, tablenum, tablename);
*/
- if ( tableID == UNDEFID )
+ if ( tableID == CDI_UNDEFID )
{
tableID = tableNewEntry();
@@ -59826,22 +59881,25 @@ int tableDef(int modelID, int tablenum, const char *tablename)
if ( tablename )
parTable[tableID].name = strdupx(tablename);
- parTable[tableID].pars = (PAR *) Malloc(MAX_PARS * sizeof(PAR));
+ parTable[tableID].pars = (param_type *) Malloc(MAX_PARS * sizeof(param_type));
}
- return (tableID);
+ return tableID;
}
-static void tableDefModelID(int tableID, int modelID)
+static
+void tableDefModelID(int tableID, int modelID)
{
parTable[tableID].modelID = modelID;
}
-static void tableDefNum(int tableID, int tablenum)
+static
+void tableDefNum(int tableID, int tablenum)
{
parTable[tableID].number = tablenum;
}
+
int tableInqNum(int tableID)
{
int number = 0;
@@ -59849,9 +59907,10 @@ int tableInqNum(int tableID)
if ( tableID >= 0 && tableID < MAX_TABLE )
number = parTable[tableID].number;
- return (number);
+ return number;
}
+
int tableInqModel(int tableID)
{
int modelID = -1;
@@ -59859,9 +59918,10 @@ int tableInqModel(int tableID)
if ( tableID >= 0 && tableID < MAX_TABLE )
modelID = parTable[tableID].modelID;
- return (modelID);
+ return modelID;
}
+
static void partabCheckID(int item)
{
if ( item < 0 || item >= parTableSize )
@@ -59871,6 +59931,7 @@ static void partabCheckID(int item)
Error("item %d name undefined!", item);
}
+
const char *tableInqNamePtr(int tableID)
{
const char *tablename = NULL;
@@ -59884,22 +59945,21 @@ const char *tableInqNamePtr(int tableID)
if ( parTable[tableID].name )
tablename = parTable[tableID].name;
- return (tablename);
+ return tablename;
}
+
void tableWrite(const char *ptfile, int tableID)
{
- int item, npars;
size_t maxname = 4, maxlname = 10, maxunits = 2;
- FILE *ptfp;
- int tablenum, modelID, instID = CDI_UNDEFID;
+ int instID = CDI_UNDEFID;
int center = 0, subcenter = 0;
const char *instnameptr = NULL, *modelnameptr = NULL;
if ( CDI_Debug )
Message("write parameter table %d to %s", tableID, ptfile);
- if ( tableID == UNDEFID )
+ if ( tableID == CDI_UNDEFID )
{
Warning("parameter table ID undefined");
return;
@@ -59907,11 +59967,11 @@ void tableWrite(const char *ptfile, int tableID)
partabCheckID(tableID);
- ptfp = fopen(ptfile, "w");
+ FILE *ptfp = fopen(ptfile, "w");
- npars = parTable[tableID].npars;
+ int npars = parTable[tableID].npars;
- for ( item = 0; item < npars; item++)
+ for ( int item = 0; item < npars; item++)
{
if ( parTable[tableID].pars[item].name )
{
@@ -59932,8 +59992,8 @@ void tableWrite(const char *ptfile, int tableID)
}
}
- tablenum = tableInqNum(tableID);
- modelID = parTable[tableID].modelID;
+ int tablenum = tableInqNum(tableID);
+ int modelID = parTable[tableID].modelID;
if ( modelID != CDI_UNDEFID )
{
modelnameptr = modelInqNamePtr(modelID);
@@ -59972,8 +60032,8 @@ void tableWrite(const char *ptfile, int tableID)
(int)maxname, "name",
(int)maxlname, "title",
(int)maxunits, "units");
-
- for ( item = 0; item < npars; item++)
+
+ for ( int item = 0; item < npars; item++)
{
const char *name = parTable[tableID].pars[item].name,
*longname = parTable[tableID].pars[item].longname,
@@ -59992,26 +60052,14 @@ void tableWrite(const char *ptfile, int tableID)
}
-void tableWriteC(const char *filename, int tableID)
-{
- FILE *ptfp = fopen(filename, "w");
- if (!ptfp)
- Error("failed to open file \"%s\"!", filename);
- if ( CDI_Debug )
- Message("write parameter table %d to %s", tableID, filename);
- tableFWriteC(ptfp, tableID);
- fclose(ptfp);
-}
-
void tableFWriteC(FILE *ptfp, int tableID)
{
const char chelp[] = "";
- int item, npars;
size_t maxname = 0, maxlname = 0, maxunits = 0;
char tablename[256];
- if ( tableID == UNDEFID )
+ if ( tableID == CDI_UNDEFID )
{
Warning("parameter table ID undefined");
return;
@@ -60019,9 +60067,9 @@ void tableFWriteC(FILE *ptfp, int tableID)
partabCheckID(tableID);
- npars = parTable[tableID].npars;
+ int npars = parTable[tableID].npars;
- for ( item = 0; item < npars; item++)
+ for ( int item = 0; item < npars; item++)
{
if ( parTable[tableID].pars[item].name )
{
@@ -60049,16 +60097,16 @@ void tableFWriteC(FILE *ptfp, int tableID)
for (size_t i = 0; i < len; i++ )
if ( tablename[i] == '.' ) tablename[i] = '_';
}
- fprintf(ptfp, "static const PAR %s[] = {\n", tablename);
+ fprintf(ptfp, "static const param_type %s[] = {\n", tablename);
- for ( item = 0; item < npars; item++ )
+ for ( int item = 0; item < npars; item++ )
{
size_t len = strlen(parTable[tableID].pars[item].name),
llen = parTable[tableID].pars[item].longname
? strlen(parTable[tableID].pars[item].longname) : 0,
ulen = parTable[tableID].pars[item].units
? strlen(parTable[tableID].pars[item].units) : 0;
- fprintf(ptfp, " {%4d, 0, \"%s\", %-*s%c%s%s, %-*s%c%s%s %-*s},\n",
+ fprintf(ptfp, " {%4d, -1, 0, \"%s\", %-*s%c%s%s, %-*s%c%s%s %-*s},\n",
parTable[tableID].pars[item].id,
parTable[tableID].pars[item].name, (int)(maxname-len), chelp,
llen?'"':' ',
@@ -60075,200 +60123,62 @@ void tableFWriteC(FILE *ptfp, int tableID)
}
-int tableInqParCode(int tableID, char *varname, int *code)
-{
- int err = 1;
-
- if ( tableID != UNDEFID && varname != NULL )
- {
- int npars = parTable[tableID].npars;
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].name
- && strcmp(parTable[tableID].pars[item].name, varname) == 0 )
- {
- *code = parTable[tableID].pars[item].id;
- err = 0;
- break;
- }
- }
- }
-
- return (err);
-}
-
-
-int tableInqParName(int tableID, int code, char *varname)
-{
- int err = 1;
-
- if ( tableID >= 0 && tableID < MAX_TABLE )
- {
- int npars = parTable[tableID].npars;
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].id == code )
- {
- if ( parTable[tableID].pars[item].name )
- strcpy(varname, parTable[tableID].pars[item].name); //FIXME: This may overrun the supplied buffer!
- err = 0;
- break;
- }
- }
- }
- else if ( tableID == UNDEFID )
- { }
- else
- Error("Invalid table ID %d", tableID);
-
- return (err);
-}
-
-
-const char *tableInqParNamePtr(int tableID, int code)
-{
- const char *name = NULL;
-
- if ( tableID != UNDEFID )
- {
- int npars = parTable[tableID].npars;
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].id == code )
- {
- name = parTable[tableID].pars[item].name;
- break;
- }
- }
- }
-
- return (name);
-}
-
-
-const char *tableInqParLongnamePtr(int tableID, int code)
-{
- const char *longname = NULL;
-
- if ( tableID != UNDEFID )
- {
- int npars = parTable[tableID].npars;
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].id == code )
- {
- longname = parTable[tableID].pars[item].longname;
- break;
- }
- }
- }
-
- return (longname);
-}
-
-
-const char *tableInqParUnitsPtr(int tableID, int code)
-{
- const char *units = NULL;
-
- if ( tableID != UNDEFID )
- {
- int npars = parTable[tableID].npars;
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].id == code )
- {
- units = parTable[tableID].pars[item].units;
- break;
- }
- }
- }
-
- return (units);
-}
-
-
-int tableInqParLongname(int tableID, int code, char *longname)
+void tableInqEntry(int tableID, int id, int ltype, char *name, char *longname, char *units)
{
- if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
+ if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == CDI_UNDEFID) ) { } else
Error("Invalid table ID %d", tableID);
- int err = 1;
-
- if ( tableID != UNDEFID )
+ if ( tableID != CDI_UNDEFID )
{
int npars = parTable[tableID].npars;
for ( int item = 0; item < npars; item++ )
{
- if ( parTable[tableID].pars[item].id == code )
+ if ( parTable[tableID].pars[item].id == id &&
+ (parTable[tableID].pars[item].ltype == -1 || ltype == -1 ||
+ parTable[tableID].pars[item].ltype == ltype) )
{
- if ( parTable[tableID].pars[item].longname )
+ if ( name && parTable[tableID].pars[item].name )
+ strcpy(name, parTable[tableID].pars[item].name);
+ if ( longname && parTable[tableID].pars[item].longname )
strcpy(longname, parTable[tableID].pars[item].longname);
- err = 0;
+ if ( units && parTable[tableID].pars[item].units )
+ strcpy(units, parTable[tableID].pars[item].units);
+
break;
}
}
}
-
- return (err);
}
-int tableInqParUnits(int tableID, int code, char *units)
+int tableInqParCode(int tableID, char *varname, int *code)
{
-
- if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
- Error("Invalid table ID %d", tableID);
-
int err = 1;
- if ( tableID != UNDEFID )
+ if ( tableID != CDI_UNDEFID && varname != NULL )
{
int npars = parTable[tableID].npars;
for ( int item = 0; item < npars; item++ )
{
- if ( parTable[tableID].pars[item].id == code )
- {
- if ( parTable[tableID].pars[item].units )
- strcpy(units, parTable[tableID].pars[item].units);
+ if ( parTable[tableID].pars[item].name
+ && strcmp(parTable[tableID].pars[item].name, varname) == 0 )
+ {
+ *code = parTable[tableID].pars[item].id;
err = 0;
- break;
- }
+ break;
+ }
}
}
- return (err);
+ return err;
}
-void tableInqPar(int tableID, int code, char *name, char *longname, char *units)
-{
-
- if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
- Error("Invalid table ID %d", tableID);
-
- int npars = parTable[tableID].npars;
-
- for ( int item = 0; item < npars; item++ )
- {
- if ( parTable[tableID].pars[item].id == code )
- {
- if ( parTable[tableID].pars[item].name )
- strcpy(name, parTable[tableID].pars[item].name);
- if ( parTable[tableID].pars[item].longname )
- strcpy(longname, parTable[tableID].pars[item].longname);
- if ( parTable[tableID].pars[item].units )
- strcpy(units, parTable[tableID].pars[item].units);
- break;
- }
- }
-}
-
int tableInqNumber(void)
{
if ( ! ParTableInit ) parTableInit();
- return (parTableNum);
+ return parTableNum;
}
/*
* Local Variables:
@@ -60283,7 +60193,7 @@ int tableInqNumber(void)
#endif
#include <stddef.h>
-#include <string.h>
+
static int DefaultTimeType = TAXIS_ABSOLUTE;
@@ -60373,24 +60283,15 @@ static int TAXIS_Debug = 0; /* If set to 1, debugging */
const char *tunitNamePtr(int unitID)
{
- const char *name;
int size = sizeof(Timeunits)/sizeof(*Timeunits);
-
- if ( unitID > 0 && unitID < size )
- name = Timeunits[unitID];
- else
- name = Timeunits[0];
-
- return (name);
+ return (unitID > 0 && unitID < size) ? Timeunits[unitID] : Timeunits[0];
}
#if 0
static
void taxis_defaults(void)
{
- char *timeunit;
-
- timeunit = getenv("TIMEUNIT");
+ char *timeunit = getenv("TIMEUNIT");
if ( timeunit )
{
if ( strcmp(timeunit, "minutes") == 0 )
@@ -60419,7 +60320,8 @@ static
void taxisDefaultValue(taxis_t* taxisptr)
{
taxisptr->self = CDI_UNDEFID;
- taxisptr->used = FALSE;
+ taxisptr->used = false;
+ taxisptr->datatype = CDI_DATATYPE_FLT64;
taxisptr->type = DefaultTimeType;
taxisptr->vdate = 0;
taxisptr->vtime = 0;
@@ -60430,8 +60332,8 @@ void taxisDefaultValue(taxis_t* taxisptr)
taxisptr->calendar = cdiDefaultCalendar;
taxisptr->unit = DefaultTimeUnit;
taxisptr->numavg = 0;
- taxisptr->climatology = FALSE;
- taxisptr->has_bounds = FALSE;
+ taxisptr->climatology = false;
+ taxisptr->has_bounds = false;
taxisptr->vdate_lb = 0;
taxisptr->vtime_lb = 0;
taxisptr->vdate_ub = 0;
@@ -60440,6 +60342,7 @@ void taxisDefaultValue(taxis_t* taxisptr)
taxisptr->fc_period = 0;
taxisptr->name = NULL;
taxisptr->longname = NULL;
+ taxisptr->units = NULL;
}
static taxis_t *
@@ -60456,33 +60359,22 @@ taxisNewEntry(cdiResH resH)
reshReplace(resH, taxisptr, &taxisOps);
}
- return (taxisptr);
+ return taxisptr;
}
static
-void taxisInit (void)
+void taxisInit(void)
{
- static int taxisInitialized = 0;
- char *env;
+ static bool taxisInitialized = false;
if ( taxisInitialized ) return;
- taxisInitialized = 1;
+ taxisInitialized = true;
- env = getenv("TAXIS_DEBUG");
+ char *env = getenv("TAXIS_DEBUG");
if ( env ) TAXIS_Debug = atoi(env);
}
-#if 0
-static
-void taxis_copy(taxis_t *taxisptr2, taxis_t *taxisptr1)
-{
- int taxisID2 = taxisptr2->self;
- memcpy(taxisptr2, taxisptr1, sizeof(taxis_t));
- taxisptr2->self = taxisID2;
-}
-#endif
-
/*
@Function taxisCreate
@Title Create a Time axis
@@ -60516,8 +60408,7 @@ taxisDefRtime(taxisID, 120000);
*/
int taxisCreate(int taxistype)
{
- if ( CDI_Debug )
- Message("taxistype: %d", taxistype);
+ if ( CDI_Debug ) Message("taxistype: %d", taxistype);
taxisInit ();
@@ -60526,16 +60417,16 @@ int taxisCreate(int taxistype)
int taxisID = taxisptr->self;
- if ( CDI_Debug )
- Message("taxisID: %d", taxisID);
+ if ( CDI_Debug ) Message("taxisID: %d", taxisID);
- return (taxisID);
+ return taxisID;
}
void taxisDestroyKernel(taxis_t *taxisptr)
{
delete_refcount_string(taxisptr->name);
delete_refcount_string(taxisptr->longname);
+ delete_refcount_string(taxisptr->units);
}
/*
@@ -60571,21 +60462,26 @@ int taxisDuplicate(int taxisID1)
int taxisID2 = taxisptr2->self;
- if ( CDI_Debug )
- Message("taxisID2: %d", taxisID2);
+ if ( CDI_Debug ) Message("taxisID2: %d", taxisID2);
ptaxisCopy(taxisptr2, taxisptr1);
- return (taxisID2);
+
+ return taxisID2;
}
void taxisDefType(int taxisID, int type)
{
- taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+ taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps);
- if (taxisptr->type != type)
+ if ( taxisptr->type != type )
{
taxisptr->type = type;
+ if ( taxisptr->units )
+ {
+ delete_refcount_string(taxisptr->units);
+ taxisptr->units = NULL;
+ }
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60661,6 +60557,12 @@ void taxisDefRdate(int taxisID, int rdate)
if (taxisptr->rdate != rdate)
{
taxisptr->rdate = rdate;
+
+ if ( taxisptr->units )
+ {
+ delete_refcount_string(taxisptr->units);
+ taxisptr->units = NULL;
+ }
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60686,6 +60588,11 @@ void taxisDefRtime(int taxisID, int rtime)
if (taxisptr->rtime != rtime)
{
taxisptr->rtime = rtime;
+ if ( taxisptr->units )
+ {
+ delete_refcount_string(taxisptr->units);
+ taxisptr->units = NULL;
+ }
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60775,6 +60682,11 @@ void taxisDefTunit(int taxisID, int unit)
if (taxisptr->unit != unit)
{
taxisptr->unit = unit;
+ if ( taxisptr->units )
+ {
+ delete_refcount_string(taxisptr->units);
+ taxisptr->units = NULL;
+ }
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60822,16 +60734,26 @@ The valid CDI time types are TAXIS_ABSOLUTE and TAXIS_RELATIVE.
int taxisInqType(int taxisID)
{
taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-
- return (taxisptr->type);
+ return taxisptr->type;
}
int taxisHasBounds(int taxisID)
{
taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+ return taxisptr->has_bounds;
+}
+
- return (taxisptr->has_bounds);
+void taxisWithBounds(int taxisID)
+{
+ taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+ if ( taxisptr->has_bounds == false )
+ {
+ taxisptr->has_bounds = true;
+ reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+ }
}
@@ -60839,9 +60761,9 @@ void taxisDeleteBounds(int taxisID)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
- if (taxisptr->has_bounds != FALSE)
+ if ( taxisptr->has_bounds )
{
- taxisptr->has_bounds = FALSE;
+ taxisptr->has_bounds = false;
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60850,7 +60772,7 @@ void taxisDeleteBounds(int taxisID)
void taxisCopyTimestep(int taxisID2, int taxisID1)
{
taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps),
- *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
+ *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
reshLock();
@@ -60897,8 +60819,7 @@ The function @func{taxisInqVdate} returns the verification date of a Time axis.
int taxisInqVdate(int taxisID)
{
taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-
- return (taxisptr->vdate);
+ return taxisptr->vdate;
}
@@ -60915,13 +60836,13 @@ void taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
- if (taxisptr->vdate_lb != vdate_lb
- || taxisptr->vdate_ub != vdate_ub
- || taxisptr->has_bounds != TRUE)
+ if ( taxisptr->vdate_lb != vdate_lb
+ || taxisptr->vdate_ub != vdate_ub
+ || taxisptr->has_bounds == false )
{
taxisptr->vdate_lb = vdate_lb;
taxisptr->vdate_ub = vdate_ub;
- taxisptr->has_bounds = TRUE;
+ taxisptr->has_bounds = true;
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -60945,8 +60866,7 @@ The function @func{taxisInqVtime} returns the verification time of a Time axis.
int taxisInqVtime(int taxisID)
{
taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-
- return (taxisptr->vtime);
+ return taxisptr->vtime;
}
@@ -60963,13 +60883,13 @@ void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
- if (taxisptr->vtime_lb != vtime_lb
- || taxisptr->vtime_ub != vtime_ub
- || taxisptr->has_bounds != TRUE)
+ if ( taxisptr->vtime_lb != vtime_lb
+ || taxisptr->vtime_ub != vtime_ub
+ || taxisptr->has_bounds == false )
{
taxisptr->vtime_lb = vtime_lb;
taxisptr->vtime_ub = vtime_ub;
- taxisptr->has_bounds = TRUE;
+ taxisptr->has_bounds = true;
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -61001,7 +60921,7 @@ int taxisInqRdate(int taxisID)
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
- return (taxisptr->rdate);
+ return taxisptr->rdate;
}
/*
@@ -61031,7 +60951,7 @@ int taxisInqRtime(int taxisID)
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
- return (taxisptr->rtime);
+ return taxisptr->rtime;
}
/*
@@ -61060,7 +60980,7 @@ int taxisInqFdate(int taxisID)
taxisptr->ftime = taxisptr->vtime;
}
- return (taxisptr->fdate);
+ return taxisptr->fdate;
}
/*
@@ -61089,7 +61009,7 @@ int taxisInqFtime(int taxisID)
taxisptr->ftime = taxisptr->vtime;
}
- return (taxisptr->ftime);
+ return taxisptr->ftime;
}
/*
@@ -61113,55 +61033,55 @@ The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEP
*/
int taxisInqCalendar(int taxisID)
{
- taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-
- return (taxisptr->calendar);
+ taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
+ return taxisptr->calendar;
}
int taxisInqTunit(int taxisID)
{
- taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-
- return (taxisptr->unit);
+ taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
+ return taxisptr->unit;
}
int taxisInqForecastTunit(int taxisID)
{
- taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-
- return (taxisptr->fc_unit);
+ taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
+ return taxisptr->fc_unit;
}
double taxisInqForecastPeriod(int taxisID)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-
- return (taxisptr->fc_period);
+ return taxisptr->fc_period;
}
int taxisInqNumavg(int taxisID)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-
- return (taxisptr->numavg);
+ return taxisptr->numavg;
}
taxis_t *taxisPtr(int taxisID)
{
taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+ return taxisptr;
+}
- return (taxisptr);
+
+void ptaxisDefDatatype(taxis_t *taxisptr, int datatype)
+{
+ taxisptr->datatype = datatype;
}
-void
-ptaxisDefName(taxis_t *taxisptr, const char *name)
+
+void ptaxisDefName(taxis_t *taxisptr, const char *name)
{
- if (name)
+ if ( name )
{
size_t len = strlen(name);
delete_refcount_string(taxisptr->name);
@@ -61170,10 +61090,10 @@ ptaxisDefName(taxis_t *taxisptr, const char *name)
}
}
-void
-ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
+
+void ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
{
- if (longname)
+ if ( longname )
{
size_t len = strlen(longname);
delete_refcount_string(taxisptr->longname);
@@ -61183,11 +61103,21 @@ ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
}
+void ptaxisDefUnits(taxis_t *taxisptr, const char *units)
+{
+ if ( units )
+ {
+ size_t len = strlen(units);
+ delete_refcount_string(taxisptr->units);
+ char *taxisunits = taxisptr->units = new_refcount_string(len);
+ strcpy(taxisunits, units);
+ }
+}
+
+
static void
cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
{
- static int lwarn = TRUE;
-
*days = 0;
*secs = 0;
@@ -61232,10 +61162,11 @@ cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
}
else
{
+ static bool lwarn = true;
if ( lwarn )
{
Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
- lwarn = FALSE;
+ lwarn = false;
}
}
}
@@ -61243,8 +61174,6 @@ cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
static
void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
{
- static int lwarn = TRUE;
-
if ( timeunit == TUNIT_SECOND )
{
*timevalue = days*86400. + secs;
@@ -61268,10 +61197,11 @@ void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
}
else
{
+ static bool lwarn = true;
if ( lwarn )
{
Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
- lwarn = FALSE;
+ lwarn = false;
}
}
}
@@ -61335,28 +61265,24 @@ void timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime)
double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
{
- int ryear, rmonth;
- int year, month, day, hour, minute, second;
- int rdate, rtime;
double value = 0;
- int timeunit;
- int timeunit0;
- int calendar;
int julday1, secofday1, julday2, secofday2, days, secs;
- timeunit = (*taxis).unit;
- calendar = (*taxis).calendar;
+ int timeunit = (*taxis).unit;
+ int calendar = (*taxis).calendar;
- rdate = (*taxis).rdate;
- rtime = (*taxis).rtime;
+ int rdate = (*taxis).rdate;
+ int rtime = (*taxis).rtime;
if ( rdate == -1 )
{
- rdate = (*taxis).vdate;
- rtime = (*taxis).vtime;
+ rdate = (*taxis).vdate;
+ rtime = (*taxis).vtime;
}
- if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return(value);
+ if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return value;
+ int ryear, rmonth;
+ int year, month, day, hour, minute, second;
cdiDecodeDate(rdate, &ryear, &rmonth, &day);
cdiDecodeTime(rtime, &hour, &minute, &second);
@@ -61365,7 +61291,7 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
cdiDecodeDate(vdate, &year, &month, &day);
cdiDecodeTime(vtime, &hour, &minute, &second);
- timeunit0 = timeunit;
+ int timeunit0 = timeunit;
if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
{
@@ -61374,17 +61300,15 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
{
- int nmonth, dpm;
-
value = (year-ryear)*12 - rmonth + month;
- nmonth = (int) value;
+ int nmonth = (int) value;
month -= nmonth;
while ( month > 12 ) { month -= 12; year++; }
while ( month < 1 ) { month += 12; year--; }
- dpm = days_per_month(calendar, year, month);
+ int dpm = days_per_month(calendar, year, month);
encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
@@ -61408,39 +61332,35 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
value /= 30;
}
- return (value);
+ return value;
}
-static void conv_timeval(double timevalue, int *rvdate, int *rvtime)
+static
+void conv_timeval(double timevalue, int *rvdate, int *rvtime)
{
- int vdate = 0, vtime = 0;
- int hour, minute, second;
int daysec;
- vdate = (int) timevalue;
+ int vdate = (int) timevalue;
if ( vdate < 0 )
daysec = (int) (-(timevalue - vdate)*86400 + 0.01);
else
daysec = (int) ( (timevalue - vdate)*86400 + 0.01);
- hour = daysec / 3600;
- minute = (daysec - hour*3600)/60;
- second = daysec - hour*3600 - minute*60;
- vtime = cdiEncodeTime(hour, minute, second);
+ int hour = daysec / 3600;
+ int minute = (daysec - hour*3600)/60;
+ int second = daysec - hour*3600 - minute*60;
+ int vtime = cdiEncodeTime(hour, minute, second);
*rvdate = vdate;
*rvtime = vtime;
}
-static void
-splitTimevalue(double timevalue, int timeunit, int *date, int *time)
+static
+void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
{
int vdate = 0, vtime = 0;
- int hour, minute, second;
- int year, month, day;
- static int lwarn = TRUE;
if ( timeunit == TUNIT_SECOND )
{
@@ -61480,16 +61400,19 @@ splitTimevalue(double timevalue, int timeunit, int *date, int *time)
}
else
{
+ static bool lwarn = true;
if ( lwarn )
{
Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
- lwarn = FALSE;
+ lwarn = false;
}
}
/* verify date and time */
+ int year, month, day;
cdiDecodeDate(vdate, &year, &month, &day);
+ int hour, minute, second;
cdiDecodeTime(vtime, &hour, &minute, &second);
if ( month > 17 || day > 31 || hour > 23 || minute > 59 || second > 59 )
@@ -61504,9 +61427,10 @@ splitTimevalue(double timevalue, int timeunit, int *date, int *time)
vdate = cdiEncodeDate(year, month, day);
vtime = cdiEncodeTime(hour, minute, second);
+ static bool lwarn = true;
if ( lwarn )
{
- lwarn = FALSE;
+ lwarn = false;
Warning("Reset wrong date/time to %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d!",
year, month, day, hour, minute, second);
}
@@ -61519,22 +61443,19 @@ splitTimevalue(double timevalue, int timeunit, int *date, int *time)
void cdiSetForecastPeriod(double timevalue, taxis_t *taxis)
{
- int year, month, day, hour, minute, second;
- int vdate, vtime;
- int timeunit;
- int calendar;
int julday, secofday, days, secs;
(*taxis).fc_period = timevalue;
- timeunit = (*taxis).fc_unit;
- calendar = (*taxis).calendar;
+ int timeunit = (*taxis).fc_unit;
+ int calendar = (*taxis).calendar;
- vdate = (*taxis).vdate;
- vtime = (*taxis).vtime;
+ int vdate = (*taxis).vdate;
+ int vtime = (*taxis).vtime;
if ( vdate == 0 && vtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
+ int year, month, day, hour, minute, second;
cdiDecodeDate(vdate, &year, &month, &day);
cdiDecodeTime(vtime, &hour, &minute, &second);
@@ -61603,27 +61524,21 @@ double cdiEncodeTimeval(int date, int time, taxis_t *taxis)
{
int year, month, day;
cdiDecodeDate(date, &year, &month, &day);
- timevalue = date/100;
- if ( day != 0 )
- {
- if ( date < 0 ) timevalue -= 0.5;
- else timevalue += 0.5;
- }
+ timevalue = date/100
+ + copysign((double)(day != 0) * 0.5, (double)date);
}
else
{
int hour, minute, second;
cdiDecodeTime(time, &hour, &minute, &second);
- if ( date < 0 )
- timevalue = -(-date + (hour*3600 + minute*60 + second)/86400.);
- else
- timevalue = date + (hour*3600 + minute*60 + second)/86400.;
+ timevalue = copysign(1.0, (double)date)
+ * (fabs((double)date) + (hour*3600 + minute*60 + second)/86400.);
}
}
else
timevalue = vtime2timeval(date, time, taxis);
- return (timevalue);
+ return timevalue;
}
@@ -61639,6 +61554,7 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
/* memcpy(dest, source, sizeof(taxis_t)); */
dest->used = source->used;
+ dest->datatype = source->datatype;
dest->type = source->type;
dest->vdate = source->vdate;
dest->vtime = source->vtime;
@@ -61661,10 +61577,13 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
dest->climatology = source->climatology;
delete_refcount_string(dest->name);
delete_refcount_string(dest->longname);
+ delete_refcount_string(dest->units);
dest->name = dup_refcount_string(source->name);
dest->longname = dup_refcount_string(source->longname);
+ dest->units = dup_refcount_string(source->units);
if (dest->self != CDI_UNDEFID)
reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
+
reshUnlock ();
}
@@ -61703,13 +61622,13 @@ taxisPrintKernel(taxis_t * taxisptr, FILE * fp)
"fc_unit = %d\n"
"fc_period = %g\n"
"\n", taxisptr->self, taxisptr->self,
- taxisptr->used, taxisptr->type,
+ (int)taxisptr->used, taxisptr->type,
taxisptr->vdate, taxisptr->vtime,
taxisptr->rdate, taxisptr->rtime,
taxisptr->fdate, taxisptr->ftime,
taxisptr->calendar, taxisptr->unit,
- taxisptr->numavg, taxisptr->climatology,
- taxisptr->has_bounds,
+ taxisptr->numavg, (int)taxisptr->climatology,
+ (int) taxisptr->has_bounds,
vdate_lb, vtime_lb, vdate_ub, vtime_ub,
taxisptr->fc_unit, taxisptr->fc_period );
}
@@ -61749,20 +61668,21 @@ taxisTxCode ( void )
return TAXIS;
}
-enum { taxisNint = 21 };
+enum { taxisNint = 22 };
static int
taxisGetPackSize(void *p, void *context)
{
taxis_t *taxisptr = (taxis_t*) p;
int packBufferSize
- = serializeGetSize(taxisNint, DATATYPE_INT, context)
- + serializeGetSize(1, DATATYPE_UINT32, context)
+ = serializeGetSize(taxisNint, CDI_DATATYPE_INT, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context)
+ (taxisptr->name ?
- serializeGetSize((int)strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
+ serializeGetSize((int)strlen(taxisptr->name), CDI_DATATYPE_TXT, context) : 0)
+ (taxisptr->longname ?
- serializeGetSize((int)strlen(taxisptr->longname), DATATYPE_TXT,
- context) : 0);
+ serializeGetSize((int)strlen(taxisptr->longname), CDI_DATATYPE_TXT, context) : 0)
+ + (taxisptr->units ?
+ serializeGetSize((int)strlen(taxisptr->units), CDI_DATATYPE_TXT, context) : 0);
return packBufferSize;
}
@@ -61776,11 +61696,11 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
int idx = 0;
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- intBuffer, taxisNint, DATATYPE_INT, context);
+ intBuffer, taxisNint, CDI_DATATYPE_INT, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
+ &d, 1, CDI_DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
+ xassert(cdiCheckSum(CDI_DATATYPE_INT, taxisNint, intBuffer) == d);
taxisInit();
@@ -61813,7 +61733,7 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
int len = intBuffer[idx];
char *name = new_refcount_string((size_t)len);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- name, len, DATATYPE_TXT, context);
+ name, len, CDI_DATATYPE_TXT, context);
name[len] = '\0';
taxisP->name = name;
}
@@ -61823,10 +61743,19 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
int len = intBuffer[idx];
char *longname = new_refcount_string((size_t)len);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- longname, len, DATATYPE_TXT, context);
+ longname, len, CDI_DATATYPE_TXT, context);
longname[len] = '\0';
taxisP->longname = longname;
}
+ if (intBuffer[idx])
+ {
+ int len = intBuffer[idx];
+ char *units = new_refcount_string((size_t)len);
+ serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+ units, len, CDI_DATATYPE_TXT, context);
+ units[len] = '\0';
+ taxisP->units = units;
+ }
reshSetStatus(taxisP->self, &taxisOps,
reshGetStatus(taxisP->self, &taxisOps) & ~RESH_SYNC_BIT);
@@ -61865,17 +61794,21 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
intBuffer[idx++] = taxisP->vtime_ub;
intBuffer[idx++] = taxisP->name ? (int)strlen(taxisP->name) : 0;
intBuffer[idx++] = taxisP->longname ? (int)strlen(taxisP->longname) : 0;
+ intBuffer[idx++] = taxisP->units ? (int)strlen(taxisP->units) : 0;
- serializePack(intBuffer, taxisNint, DATATYPE_INT,
+ serializePack(intBuffer, taxisNint, CDI_DATATYPE_INT,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_INT, taxisNint, intBuffer);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
if (taxisP->name)
- serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
+ serializePack(taxisP->name, intBuffer[15], CDI_DATATYPE_TXT,
packBuffer, packBufferSize, packBufferPos, context);
if (taxisP->longname)
- serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
+ serializePack(taxisP->longname, intBuffer[16], CDI_DATATYPE_TXT,
+ packBuffer, packBufferSize, packBufferPos, context);
+ if (taxisP->units)
+ serializePack(taxisP->units, intBuffer[16], CDI_DATATYPE_TXT,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -61906,7 +61839,7 @@ void decode_julday(int calendar,
double b = floor((a - 1867216.25)/36524.25);
double c = a + b - floor(b/4) + 1525;
- if ( calendar == CALENDAR_STANDARD )
+ if ( calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN )
if ( a < 2299161 ) c = a + 1524;
double d = floor((c - 122.1)/365.25);
@@ -61943,7 +61876,7 @@ int encode_julday(int calendar, int year, int month, int day)
else
ib = (int)(iy/400) - (int)(iy/100);
- if ( calendar == CALENDAR_STANDARD )
+ if ( calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN )
{
if ( year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15))) )
{
@@ -62274,7 +62207,7 @@ int tstepsNewEntry(stream_t *streamptr)
tstepsInitEntry(streamptr, tsID);
- streamptr->tsteps[tsID].taxis.used = TRUE;
+ streamptr->tsteps[tsID].taxis.used = true;
return (int)tsID;
}
@@ -62282,24 +62215,20 @@ int tstepsNewEntry(stream_t *streamptr)
void cdiCreateTimesteps(stream_t *streamptr)
{
- long ntsteps;
- long tsID;
-
if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
return;
- if ( streamptr->ntsteps == 0 ) ntsteps = 1; /* <<<<<-------- */
- else ntsteps = streamptr->ntsteps;
+ long ntsteps = (streamptr->ntsteps == 0) ? 1 : streamptr->ntsteps;
streamptr->tsteps = (tsteps_t *) Malloc((size_t)ntsteps*sizeof(tsteps_t));
streamptr->tstepsTableSize = (int)ntsteps;
streamptr->tstepsNextID = (int)ntsteps;
- for ( tsID = 0; tsID < ntsteps; tsID++ )
+ for ( long tsID = 0; tsID < ntsteps; tsID++ )
{
tstepsInitEntry(streamptr, (size_t)tsID);
- streamptr->tsteps[tsID].taxis.used = TRUE;
+ streamptr->tsteps[tsID].taxis.used = true;
}
}
/*
@@ -62326,47 +62255,6 @@ void cdiCreateTimesteps(stream_t *streamptr)
-void cdiPrintDatatypes(void)
-{
-#define XSTRING(x) #x
-#define STRING(x) XSTRING(x)
- fprintf (stderr, "+-------------+-------+\n"
- "| types | bytes |\n"
- "+-------------+-------+\n"
- "| void * | %3d |\n"
- "+-------------+-------+\n"
- "| char | %3d |\n"
- "+-------------+-------+\n"
- "| short | %3d |\n"
- "| int | %3d |\n"
- "| long | %3d |\n"
- "| long long | %3d |\n"
- "| size_t | %3d |\n"
- "| off_t | %3d |\n"
- "+-------------+-------+\n"
- "| float | %3d |\n"
- "| double | %3d |\n"
- "| long double | %3d |\n"
- "+-------------+-------+\n\n"
- "+-------------+-----------+\n"
- "| INT32 | %-9s |\n"
- "| INT64 | %-9s |\n"
- "| FLT32 | %-9s |\n"
- "| FLT64 | %-9s |\n"
- "+-------------+-----------+\n"
- "\n byte ordering is %s\n\n",
- (int) sizeof(void *), (int) sizeof(char),
- (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
- (int) sizeof(size_t), (int) sizeof(off_t),
- (int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
- STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
- ((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
- : ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
- : "Unhandled endianness!")));
-#undef STRING
-#undef XSTRING
-}
-
static const char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-"
"%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
@@ -62457,7 +62345,7 @@ char* cdiUnescapeSpaces(const char* string, const char** outStringEnd)
return result;
}
-#ifdef HAVE_DECL_UUID_GENERATE
+#if defined (HAVE_DECL_UUID_GENERATE) && defined (HAVE_UUID_UUID_H)
#include <sys/time.h>
#include <uuid/uuid.h>
void cdiCreateUUID(unsigned char *uuid)
@@ -62484,7 +62372,7 @@ void cdiCreateUUID(unsigned char *uuid)
uuid_generate(uuid);
setstate(caller_rand_state);
}
-#elif defined (HAVE_DECL_UUID_CREATE)
+#elif defined (HAVE_DECL_UUID_CREATE) && defined (HAVE_UUID_H)
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
@@ -62504,8 +62392,8 @@ void cdiCreateUUID(unsigned char *uuid)
void cdiCreateUUID(unsigned char *uuid)
{
static int uuid_seeded = 0;
- static char uuid_rand_state[31 * sizeof (long)];
#ifndef _SX
+ static char uuid_rand_state[31 * sizeof (long)];
char *caller_rand_state;
if (uuid_seeded)
caller_rand_state = setstate(uuid_rand_state);
@@ -62526,6 +62414,27 @@ void cdiCreateUUID(unsigned char *uuid)
for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
uuid[i] = (unsigned char)random();
#else
+ unsigned short caller_rand_state[3];
+ {
+ static unsigned short our_rand_state[3];
+ if (!uuid_seeded)
+ {
+ struct timeval tv;
+ int status = gettimeofday(&tv, NULL);
+ if (status != 0)
+ {
+ perror("failed seed generation!");
+ exit(1);
+ }
+ unsigned seed = tv.tv_sec ^ tv.tv_usec;
+ our_rand_state[0] = 0x330E;
+ our_rand_state[1] = (unsigned short)(seed & 0xFFFFU);
+ our_rand_state[2] = (unsigned short)((seed >> 16) & 0xFFFFU);
+ }
+ unsigned short *p = seed48(our_rand_state);
+ uuid_seeded = 1;
+ memcpy(caller_rand_state, p, sizeof (caller_rand_state));
+ }
for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
uuid[i] = (unsigned char)lrand48();
#endif
@@ -62535,6 +62444,8 @@ void cdiCreateUUID(unsigned char *uuid)
uuid[7] = (unsigned char)((uuid[7] & 0x0f) | (4 << 4));
#ifndef _SX
setstate(caller_rand_state);
+#else
+ seed48(caller_rand_state);
#endif
}
#endif
@@ -62551,14 +62462,8 @@ void cdiCreateUUID(unsigned char *uuid)
#if defined (HAVE_CONFIG_H)
#endif
-#include <stdbool.h>
-#include <string.h>
-#include <math.h>
-
-#undef UNDEFID
-#define UNDEFID -1
static size_t Vctsize = 0;
static double *Vct = NULL;
@@ -62590,6 +62495,7 @@ typedef struct
typedef struct
{
+ int varID;
int param;
int prec;
int tsteptype;
@@ -62613,7 +62519,7 @@ typedef struct
int comptype; // compression type
int complevel; // compression level
short timave;
- short lmissval;
+ bool lmissval;
double missval;
char *name;
char *stdname;
@@ -62635,18 +62541,18 @@ vartable_t;
static vartable_t *vartable;
static unsigned varTablesize = 0;
-static unsigned nvars = 0;
-
+static unsigned varTableUsed = 0;
-static void
-paramInitEntry(unsigned varID, int param)
+static
+void paramInitEntry(unsigned varID, int param)
{
+ vartable[varID].varID = (int)varID;
vartable[varID].param = param;
vartable[varID].prec = 0;
vartable[varID].tsteptype = TSTEP_INSTANT;
vartable[varID].timave = 0;
vartable[varID].timaccu = 0;
- vartable[varID].gridID = UNDEFID;
+ vartable[varID].gridID = CDI_UNDEFID;
vartable[varID].zaxistype = 0;
vartable[varID].ltype1 = 0;
vartable[varID].ltype2 = -1;
@@ -62656,14 +62562,14 @@ paramInitEntry(unsigned varID, int param)
vartable[varID].recordTable = NULL;
vartable[varID].nsubtypes_alloc= 0;
vartable[varID].nsubtypes = 0;
- vartable[varID].instID = UNDEFID;
- vartable[varID].modelID = UNDEFID;
- vartable[varID].tableID = UNDEFID;
- vartable[varID].typeOfGeneratingProcess = UNDEFID;
- vartable[varID].productDefinitionTemplate = UNDEFID;
- vartable[varID].comptype = COMPRESS_NONE;
+ vartable[varID].instID = CDI_UNDEFID;
+ vartable[varID].modelID = CDI_UNDEFID;
+ vartable[varID].tableID = CDI_UNDEFID;
+ vartable[varID].typeOfGeneratingProcess = CDI_UNDEFID;
+ vartable[varID].productDefinitionTemplate = CDI_UNDEFID;
+ vartable[varID].comptype = CDI_COMPRESS_NONE;
vartable[varID].complevel = 1;
- vartable[varID].lmissval = 0;
+ vartable[varID].lmissval = false;
vartable[varID].missval = 0;
vartable[varID].name = NULL;
vartable[varID].stdname = NULL;
@@ -62682,7 +62588,7 @@ varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *nam
{
/* testing for "param" implicitly checks if we are beyond the
* current vartable size: */
- if (vartable[varID].param == param)
+ if ( vartable[varID].param == param )
{
int no_of_tiles = -1;
if ( tiles ) no_of_tiles = tiles->numberOfTiles;
@@ -62697,11 +62603,11 @@ varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *nam
{
if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
{
- if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
+ if ( strcmp(name, vartable[varID].name) == 0 ) return varID;
}
else
{
- return (varID);
+ return varID;
}
}
}
@@ -62715,7 +62621,7 @@ void varFree(void)
{
if ( CDI_Debug ) Message("call to varFree");
- for ( unsigned varID = 0; varID < nvars; varID++ )
+ for ( size_t varID = 0; varID < varTableUsed; varID++ )
{
if ( vartable[varID].recordTable )
{
@@ -62749,7 +62655,7 @@ void varFree(void)
vartable = NULL;
varTablesize = 0;
- nvars = 0;
+ varTableUsed = 0;
if ( Vct )
Free(Vct);
@@ -62837,24 +62743,24 @@ static int levelNewEntry(unsigned varID, int level1, int level2, int tileID)
levelTable = (leveltable_t *) Malloc((size_t)levelTableSize
* sizeof (leveltable_t));
for ( int i = 0; i < levelTableSize; i++ )
- levelTable[i].recID = UNDEFID;
+ levelTable[i].recID = CDI_UNDEFID;
}
else
{
while( levelID < levelTableSize
- && levelTable[levelID].recID != UNDEFID )
+ && levelTable[levelID].recID != CDI_UNDEFID )
++levelID;
}
/*
If the table overflows, double its size.
*/
- if( levelID == levelTableSize )
+ if ( levelID == levelTableSize )
{
levelTable = (leveltable_t *) Realloc(levelTable,
(size_t)(levelTableSize *= 2)
* sizeof (leveltable_t));
for( int i = levelID; i < levelTableSize; i++ )
- levelTable[i].recID = UNDEFID;
+ levelTable[i].recID = CDI_UNDEFID;
}
levelTable[levelID].level1 = level1;
@@ -62865,7 +62771,7 @@ static int levelNewEntry(unsigned varID, int level1, int level2, int tileID)
vartable[varID].recordTable[tileID].levelTableSize = levelTableSize;
vartable[varID].recordTable[tileID].levelTable = levelTable;
- return (levelID);
+ return levelID;
}
#define UNDEF_PARAM -4711
@@ -62913,7 +62819,7 @@ paramNewEntry(int param)
{
vartable = (vartable_t *) Realloc(vartable, (size_t)(varTablesize *= 2)
* sizeof (vartable_t));
- for( unsigned i = varID; i < varTablesize; i++ )
+ for ( size_t i = varID; i < varTablesize; i++ )
{
vartable[i].param = UNDEF_PARAM;
vartable[i].opt_grib_kvpair = NULL;
@@ -62924,7 +62830,7 @@ paramNewEntry(int param)
paramInitEntry(varID, param);
- return (varID);
+ return varID;
}
@@ -62961,6 +62867,7 @@ int varInsertTileSubtype(vartable_t *vptr, const var_tile_t *tiles)
subtypeDestroyPtr(subtype_ptr);
return vptr->tiles->nentries - 1;
}
+
return CDI_UNDEFID;
}
@@ -62972,11 +62879,11 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
const var_tile_t *tiles, int *tile_index)
{
unsigned varID = (cdiSplitLtype105 != 1 || zaxistype != ZAXIS_HEIGHT) ?
- varGetEntry(param, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned)UNDEFID;
+ varGetEntry(param, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned) CDI_UNDEFID;
- if ( varID == (unsigned)UNDEFID )
+ if ( varID == (unsigned) CDI_UNDEFID )
{
- nvars++;
+ varTableUsed++;
varID = paramNewEntry(param);
vartable[varID].gridID = gridID;
vartable[varID].zaxistype = zaxistype;
@@ -62989,10 +62896,10 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
if ( numavg ) vartable[varID].timave = 1;
- if ( name ) if ( name[0] ) vartable[varID].name = strdup(name);
- if ( stdname ) if ( stdname[0] ) vartable[varID].stdname = strdup(stdname);
- if ( longname ) if ( longname[0] ) vartable[varID].longname = strdup(longname);
- if ( units ) if ( units[0] ) vartable[varID].units = strdup(units);
+ if ( name && name[0] ) vartable[varID].name = strdup(name);
+ if ( stdname && stdname[0] ) vartable[varID].stdname = strdup(stdname);
+ if ( longname && longname[0] ) vartable[varID].longname = strdup(longname);
+ if ( units && units[0] ) vartable[varID].units = strdup(units);
}
else
{
@@ -63017,11 +62924,12 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
int this_tile = varInsertTileSubtype(&vartable[varID], tiles);
int tileID = tileGetEntry(varID, this_tile);
if ( tile_index ) (*tile_index) = this_tile;
- if (tileID == CDI_UNDEFID) {
- tileID = tileNewEntry((int)varID);
- vartable[varID].recordTable[tileID].subtypeIndex = this_tile;
- vartable[varID].nsubtypes++;
- }
+ if ( tileID == CDI_UNDEFID )
+ {
+ tileID = tileNewEntry((int)varID);
+ vartable[varID].recordTable[tileID].subtypeIndex = this_tile;
+ vartable[varID].nsubtypes++;
+ }
/* append current level to level table info */
int levelID = levelNewEntry(varID, level1, level2, tileID);
@@ -63044,131 +62952,138 @@ int dblcmp(const void *s1, const void *s2)
if ( *((double *) s1) < *((double *) s2) ) cmp = -1;
else if ( *((double *) s1) > *((double *) s2) ) cmp = 1;
- return (cmp);
+ return cmp;
}
*/
static
int cmpLevelTable(const void* s1, const void* s2)
{
int cmp = 0;
- const leveltable_t* x = (const leveltable_t*) s1;
- const leveltable_t* y = (const leveltable_t*) s2;
+ const leveltable_t *x = (const leveltable_t*) s1;
+ const leveltable_t *y = (const leveltable_t*) s2;
/*
printf("%g %g %d %d\n", x->leve11, y->level1, x, y);
*/
if ( x->level1 < y->level1 ) cmp = -1;
else if ( x->level1 > y->level1 ) cmp = 1;
- return (cmp);
+ return cmp;
}
static
int cmpLevelTableInv(const void* s1, const void* s2)
{
int cmp = 0;
- const leveltable_t* x = (const leveltable_t*) s1;
- const leveltable_t* y = (const leveltable_t*) s2;
+ const leveltable_t *x = (const leveltable_t*) s1;
+ const leveltable_t *y = (const leveltable_t*) s2;
/*
printf("%g %g %d %d\n", x->leve11, y->level1, x, y);
*/
if ( x->level1 < y->level1 ) cmp = 1;
else if ( x->level1 > y->level1 ) cmp = -1;
- return (cmp);
+ return cmp;
}
-typedef struct
+struct paraminfo
{
- int varid;
- int param;
- int ltype;
-}
-param_t;
-
+ int varid, param, ltype;
+};
static
-int cmpparam(const void* s1, const void* s2)
+int cmp_param(const void* s1, const void* s2)
{
- const param_t* x = (const param_t*) s1;
- const param_t* y = (const param_t*) s2;
+ const struct paraminfo *x = (const struct paraminfo*) s1;
+ const struct paraminfo *y = (const struct paraminfo*) s2;
int cmp = (( x->param > y->param ) - ( x->param < y->param )) * 2
+ ( x->ltype > y->ltype ) - ( x->ltype < y->ltype );
- return (cmp);
+ return cmp;
+}
+
+struct varinfo
+{
+ int varid;
+ const char *name;
+};
+/*
+static
+int cmp_varname(const void *s1, const void *s2)
+{
+ const struct varinfo *x = (const struct varinfo *)s1,
+ *y = (const struct varinfo *)s2;
+ return strcmp(x->name, y->name);
+}
+*/
+static
+int cmp_varname(const void *s1, const void *s2)
+{
+ const vartable_t *x = (const vartable_t *)s1,
+ *y = (const vartable_t *)s2;
+ return strcmp(x->name, y->name);
}
void cdi_generate_vars(stream_t *streamptr)
{
- int gridID, zaxisID;
-
- int instID, modelID, tableID;
- int param, zaxistype, ltype1, ltype2;
- int prec;
- int tsteptype;
- int timave, timaccu;
- int lbounds;
- int comptype;
- char name[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
- double *dlevels = NULL;
- double *dlevels1 = NULL;
- double *dlevels2 = NULL;
- double level_sf = 1;
int vlistID = streamptr->vlistID;
- int *varids = (int *) Malloc(nvars*sizeof(int));
- for ( unsigned varID = 0; varID < nvars; varID++ ) varids[varID] = (int)varID;
-
- if ( streamptr->sortname )
+ int *varids = (int *) Malloc(varTableUsed*sizeof(int));
+ for ( size_t varID = 0; varID < varTableUsed; varID++ ) varids[varID] = (int)varID;
+ /*
+ if ( streamptr->sortparam )
{
- param_t *varInfo = (param_t *) Malloc((size_t)nvars * sizeof (param_t));
+ struct paraminfo *varInfo = (struct paraminfo *) Malloc((size_t)varTableUsed * sizeof(struct paraminfo));
- for ( unsigned varID = 0; varID < nvars; varID++ )
+ for ( unsigned varID = 0; varID < varTableUsed; varID++ )
{
varInfo[varID].varid = varids[varID];
varInfo[varID].param = vartable[varID].param;
varInfo[varID].ltype = vartable[varID].ltype1;
}
- qsort(varInfo, (size_t)nvars, sizeof(param_t), cmpparam);
- for ( unsigned varID = 0; varID < nvars; varID++ )
+ qsort(varInfo, (size_t)varTableUsed, sizeof(struct paraminfo), cmp_param);
+ for ( unsigned varID = 0; varID < varTableUsed; varID++ )
{
varids[varID] = varInfo[varID].varid;
}
Free(varInfo);
}
- for ( unsigned index = 0; index < nvars; index++ )
+ if ( streamptr->sortname )
+ {
+ qsort(vartable, (size_t)varTableUsed, sizeof(vartable_t), cmp_varname);
+ }
+ */
+ for ( size_t index = 0; index < varTableUsed; index++ )
{
int varid = varids[index];
- gridID = vartable[varid].gridID;
- param = vartable[varid].param;
- ltype1 = vartable[varid].ltype1;
- ltype2 = vartable[varid].ltype2;
- zaxistype = vartable[varid].zaxistype;
+ int gridID = vartable[varid].gridID;
+ int param = vartable[varid].param;
+ int ltype1 = vartable[varid].ltype1;
+ int ltype2 = vartable[varid].ltype2;
+ int zaxistype = vartable[varid].zaxistype;
if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && cdiDefaultLeveltype != -1 )
zaxistype = cdiDefaultLeveltype;
- lbounds = vartable[varid].lbounds;
- prec = vartable[varid].prec;
- instID = vartable[varid].instID;
- modelID = vartable[varid].modelID;
- tableID = vartable[varid].tableID;
- tsteptype = vartable[varid].tsteptype;
- timave = vartable[varid].timave;
- timaccu = vartable[varid].timaccu;
- comptype = vartable[varid].comptype;
-
- level_sf = 1;
+ int lbounds = vartable[varid].lbounds;
+ int prec = vartable[varid].prec;
+ int instID = vartable[varid].instID;
+ int modelID = vartable[varid].modelID;
+ int tableID = vartable[varid].tableID;
+ int tsteptype = vartable[varid].tsteptype;
+ int timave = vartable[varid].timave;
+ int timaccu = vartable[varid].timaccu;
+ int comptype = vartable[varid].comptype;
+
+ double level_sf = 1;
if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
- zaxisID = UNDEFID;
-
/* consistency check: test if all subtypes have the same levels: */
unsigned nlevels = vartable[varid].recordTable[0].nlevels;
- for (int isub=1; isub<vartable[varid].nsubtypes; isub++) {
- if (vartable[varid].recordTable[isub].nlevels != nlevels)
+ for ( int isub = 1; isub < vartable[varid].nsubtypes; isub++ ) {
+ if ( vartable[varid].recordTable[isub].nlevels != nlevels )
{
fprintf(stderr, "var \"%s\": isub = %d / %d :: "
"nlevels = %d, vartable[varid].recordTable[isub].nlevels = %d\n",
@@ -63179,7 +63094,7 @@ void cdi_generate_vars(stream_t *streamptr)
leveltable_t *t1 = vartable[varid].recordTable[isub-1].levelTable;
leveltable_t *t2 = vartable[varid].recordTable[isub ].levelTable;
- for (unsigned ilev=0; ilev<nlevels; ilev++)
+ for ( unsigned ilev = 0; ilev < nlevels; ilev++ )
if ((t1[ilev].level1 != t2[ilev].level1) ||
(t1[ilev].level2 != t2[ilev].level2) ||
(t1[ilev].lindex != t2[ilev].lindex))
@@ -63188,32 +63103,31 @@ void cdi_generate_vars(stream_t *streamptr)
"nlevels = %d, vartable[varid].recordTable[isub].nlevels = %d\n",
vartable[varid].name, varid, isub, vartable[varid].nsubtypes,
nlevels, vartable[varid].recordTable[isub].nlevels);
- Message("t1[ilev].level1=%d / t2[ilev].level1=%d",t1[ilev].level1, t2[ilev].level1);
- Message("t1[ilev].level2=%d / t2[ilev].level2=%d",t1[ilev].level2, t2[ilev].level2);
- Message("t1[ilev].lindex=%d / t2[ilev].lindex=%d",t1[ilev].lindex, t2[ilev].lindex);
+ Message("t1[ilev].level1=%d / t2[ilev].level1=%d", t1[ilev].level1, t2[ilev].level1);
+ Message("t1[ilev].level2=%d / t2[ilev].level2=%d", t1[ilev].level2, t2[ilev].level2);
+ Message("t1[ilev].lindex=%d / t2[ilev].lindex=%d", t1[ilev].lindex, t2[ilev].lindex);
Error("zaxis type must not change for same parameter!");
}
}
leveltable_t *levelTable = vartable[varid].recordTable[0].levelTable;
- if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
- levelTable[0].level1 == 0 )
+ if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 && levelTable[0].level1 == 0 )
zaxistype = ZAXIS_SURFACE;
- dlevels = (double *) Malloc(nlevels*sizeof(double));
+ double *dlevels = (double *) Malloc(nlevels*sizeof(double));
if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
- for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels[levelID] = (level_sf*levelTable[levelID].level1 +
level_sf*levelTable[levelID].level2)/2;
else
- for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels[levelID] = level_sf*levelTable[levelID].level1;
if ( nlevels > 1 )
{
bool linc = true, ldec = true, lsort = false;
- for (unsigned levelID = 1; levelID < nlevels; levelID++ )
+ for ( unsigned levelID = 1; levelID < nlevels; levelID++ )
{
/* check increasing of levels */
linc &= (dlevels[levelID] > dlevels[levelID-1]);
@@ -63225,7 +63139,7 @@ void cdi_generate_vars(stream_t *streamptr)
* levelTable[levelID1].level1 < levelTable[levelID2].level1 <=> levelID1 > levelID2
* unless already sorted in decreasing order
*/
- if ( !ldec && zaxistype == ZAXIS_PRESSURE )
+ if ( (!linc && !ldec) && zaxistype == ZAXIS_PRESSURE )
{
qsort(levelTable, nlevels, sizeof(leveltable_t), cmpLevelTableInv);
lsort = true;
@@ -63246,33 +63160,35 @@ void cdi_generate_vars(stream_t *streamptr)
if ( lsort )
{
if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
- for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels[levelID] = (level_sf*levelTable[levelID].level1 +
level_sf*levelTable[levelID].level2)/2.;
else
- for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels[levelID] = level_sf*levelTable[levelID].level1;
}
}
+ double *dlevels1 = NULL;
+ double *dlevels2 = NULL;
if ( lbounds )
{
dlevels1 = (double *) Malloc(nlevels*sizeof(double));
- for (unsigned levelID = 0; levelID < nlevels; levelID++)
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels1[levelID] = level_sf*levelTable[levelID].level1;
dlevels2 = (double *) Malloc(nlevels*sizeof(double));
- for (unsigned levelID = 0; levelID < nlevels; levelID++)
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
dlevels2[levelID] = level_sf*levelTable[levelID].level2;
}
+ const char **cvals = NULL;
const char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
- zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, lbounds, dlevels1, dlevels2,
- (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
+ int zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, cvals, 0, lbounds, dlevels1, dlevels2,
+ (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
- if ( ltype1 != ltype2 && ltype2 != -1 )
- {
- zaxisDefLtype2(zaxisID, ltype2);
- }
+ if ( CDI_cmor_mode && nlevels == 1 && zaxistype != ZAXIS_HYBRID ) zaxisDefScalar(zaxisID);
+
+ if ( ltype1 != ltype2 && ltype2 != -1 ) zaxisDefLtype2(zaxisID, ltype2);
if ( zaxisInqType(zaxisID) == ZAXIS_REFERENCE )
{
@@ -63291,18 +63207,19 @@ void cdi_generate_vars(stream_t *streamptr)
/* generate new variable */
int varID = stream_new_var(streamptr, gridID, zaxisID, tilesetID);
- varID = vlistDefVarTiles(vlistID, gridID, zaxisID, tsteptype, tilesetID);
+ varID = vlistDefVarTiles(vlistID, gridID, zaxisID, TIME_VARYING, tilesetID);
+ vlistDefVarTsteptype(vlistID, varID, tsteptype);
vlistDefVarParam(vlistID, varID, param);
vlistDefVarDatatype(vlistID, varID, prec);
vlistDefVarTimave(vlistID, varID, timave);
vlistDefVarTimaccu(vlistID, varID, timaccu);
vlistDefVarCompType(vlistID, varID, comptype);
- if ( vartable[varid].typeOfGeneratingProcess != UNDEFID )
+ if ( vartable[varid].typeOfGeneratingProcess != CDI_UNDEFID )
vlistDefVarTypeOfGeneratingProcess(vlistID, varID, vartable[varid].typeOfGeneratingProcess);
- if ( vartable[varid].productDefinitionTemplate != UNDEFID )
+ if ( vartable[varid].productDefinitionTemplate != CDI_UNDEFID )
vlistDefVarProductDefinitionTemplate(vlistID, varID, vartable[varid].productDefinitionTemplate);
if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);
@@ -63315,10 +63232,8 @@ void cdi_generate_vars(stream_t *streamptr)
vartable[varid].ensdata->ens_count,
vartable[varid].ensdata->forecast_init_type);
- int i;
- vlist_t *vlistptr;
- vlistptr = vlist_to_pointer(vlistID);
- for (i=0; i<vartable[varid].opt_grib_nentries; i++)
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
+ for ( int i = 0; i < vartable[varid].opt_grib_nentries; i++ )
{
resize_opt_grib_entries(&vlistptr->vars[varID], vlistptr->vars[varID].opt_grib_nentries+1);
vlistptr->vars[varID].opt_grib_nentries += 1;
@@ -63326,74 +63241,58 @@ void cdi_generate_vars(stream_t *streamptr)
vlistptr->vars[varID].opt_grib_kvpair[idx] = vartable[varid].opt_grib_kvpair[i];
vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = NULL;
- if (vartable[varid].opt_grib_kvpair[i].keyword)
- vlistptr->vars[varID].opt_grib_kvpair[idx].keyword =
+ if ( vartable[varid].opt_grib_kvpair[i].keyword )
+ vlistptr->vars[varID].opt_grib_kvpair[idx].keyword =
strdupx(vartable[varid].opt_grib_kvpair[i].keyword);
- vlistptr->vars[varID].opt_grib_kvpair[i].update = TRUE;
+ vlistptr->vars[varID].opt_grib_kvpair[i].update = true;
}
/* note: if the key is not defined, we do not throw an error! */
- if ( cdiDefaultTableID != UNDEFID )
+ if ( cdiDefaultTableID != CDI_UNDEFID )
{
int pdis, pcat, pnum;
cdiDecodeParam(param, &pnum, &pcat, &pdis);
- if ( tableInqParNamePtr(cdiDefaultTableID, pnum) )
+ char name[CDI_MAX_NAME]; name[0] = 0;
+ char longname[CDI_MAX_NAME]; longname[0] = 0;
+ char units[CDI_MAX_NAME]; units[0] = 0;
+ tableInqEntry(cdiDefaultTableID, pnum, -1, name, longname, units);
+ if ( name[0] )
{
- if ( tableID != UNDEFID )
+ if ( tableID != CDI_UNDEFID )
{
- strcpy(name, tableInqParNamePtr(cdiDefaultTableID, pnum));
vlistDefVarName(vlistID, varID, name);
- if ( tableInqParLongnamePtr(cdiDefaultTableID, pnum) )
- {
- strcpy(longname, tableInqParLongnamePtr(cdiDefaultTableID, pnum));
- vlistDefVarLongname(vlistID, varID, longname);
- }
- if ( tableInqParUnitsPtr(cdiDefaultTableID, pnum) )
- {
- strcpy(units, tableInqParUnitsPtr(cdiDefaultTableID, pnum));
- vlistDefVarUnits(vlistID, varID, units);
- }
- }
+ if ( longname[0] ) vlistDefVarLongname(vlistID, varID, longname);
+ if ( units[0] ) vlistDefVarUnits(vlistID, varID, units);
+ }
else
tableID = cdiDefaultTableID;
}
- if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
- if ( cdiDefaultInstID != UNDEFID ) instID = cdiDefaultInstID;
+ if ( cdiDefaultModelID != CDI_UNDEFID ) modelID = cdiDefaultModelID;
+ if ( cdiDefaultInstID != CDI_UNDEFID ) instID = cdiDefaultInstID;
}
- if ( instID != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
- if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
- if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
+ if ( instID != CDI_UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
+ if ( modelID != CDI_UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
+ if ( tableID != CDI_UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
}
- for ( unsigned index = 0; index < nvars; index++ )
+ for ( size_t index = 0; index < varTableUsed; index++ )
{
int varid = varids[index];
unsigned nlevels = vartable[varid].recordTable[0].nlevels;
- /*
- for ( levelID = 0; levelID < nlevels; levelID++ )
- {
- printf("%d %d %d %d %d\n", varid, levelID,
- vartable[varid].levelTable[levelID].lindex,
- vartable[varid].levelTable[levelID].recID,
- vartable[varid].levelTable[levelID].level1);
- }
- */
- unsigned nsub = vartable[varid].nsubtypes >= 0
- ? (unsigned)vartable[varid].nsubtypes : 0U;
- for (size_t isub=0; isub < nsub; isub++)
+ unsigned nsub = vartable[varid].nsubtypes >= 0 ? (unsigned)vartable[varid].nsubtypes : 0U;
+ for ( size_t isub = 0; isub < nsub; isub++ )
{
sleveltable_t *restrict streamRecordTable
= streamptr->vars[index].recordTable + isub;
leveltable_t *restrict vartableLevelTable
= vartable[varid].recordTable[isub].levelTable;
- for (unsigned levelID = 0; levelID < nlevels; levelID++)
+ for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
{
- streamRecordTable->recordID[levelID]
- = vartableLevelTable[levelID].recID;
+ streamRecordTable->recordID[levelID] = vartableLevelTable[levelID].recID;
unsigned lindex;
- for (lindex = 0; lindex < nlevels; lindex++ )
+ for ( lindex = 0; lindex < nlevels; lindex++ )
if ( levelID == (unsigned)vartableLevelTable[lindex].lindex )
break;
if ( lindex == nlevels )
@@ -63428,50 +63327,48 @@ void varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZ
}
-int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, const char *longname, const char *units, int ltype1)
+bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const double *levels, const char *longname, const char *units, int ltype1)
{
- int differ = 1;
- int levelID;
- int zlbounds = 0;
- int ltype_is_equal = FALSE;
+ bool differ = true;
- if ( ltype1 == zaxisInqLtype(zaxisID) ) ltype_is_equal = TRUE;
+ bool ltype_is_equal = (ltype1 == zaxisInqLtype(zaxisID));
if ( ltype_is_equal && (zaxistype == zaxisInqType(zaxisID) || zaxistype == ZAXIS_GENERIC) )
{
- if ( zaxisInqLbounds(zaxisID, NULL) > 0 ) zlbounds = 1;
+ bool zlbounds = (zaxisInqLbounds(zaxisID, NULL) > 0);
if ( nlevels == zaxisInqSize(zaxisID) && zlbounds == lbounds )
{
- const double *dlevels;
- char zlongname[CDI_MAX_NAME];
- char zunits[CDI_MAX_NAME];
-
- dlevels = zaxisInqLevelsPtr(zaxisID);
- for ( levelID = 0; levelID < nlevels; levelID++ )
- {
- if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
- break;
- }
-
- if ( levelID == nlevels ) differ = 0;
+ const double *dlevels = zaxisInqLevelsPtr(zaxisID);
+ if ( dlevels && levels )
+ {
+ int levelID;
+ for ( levelID = 0; levelID < nlevels; levelID++ )
+ {
+ if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
+ break;
+ }
+ if ( levelID == nlevels ) differ = false;
+ }
if ( ! differ )
{
- zaxisInqLongname(zaxisID, zlongname);
- zaxisInqUnits(zaxisID, zunits);
- if ( longname && zlongname[0] )
- {
- if ( strcmp(longname, zlongname) != 0 ) differ = 1;
- }
- if ( units && zunits[0] )
- {
- if ( strcmp(units, zunits) != 0 ) differ = 1;
- }
- }
+ if ( longname && longname[0] )
+ {
+ char zlongname[CDI_MAX_NAME]; zlongname[0] = 0;
+ zaxisInqLongname(zaxisID, zlongname);
+ if ( zlongname[0] && (strcmp(longname, zlongname) != 0) ) differ = true;
+ }
+ if ( units && units[0] )
+ {
+ char zunits[CDI_MAX_NAME]; zunits[0] = 0;
+ zaxisInqUnits(zaxisID, zunits);
+ if ( zunits[0] && (strcmp(units, zunits) != 0) ) differ = true;
+ }
+ }
}
}
- return (differ);
+ return differ;
}
struct varDefZAxisSearchState
@@ -63479,7 +63376,7 @@ struct varDefZAxisSearchState
int resIDValue;
int zaxistype;
int nlevels;
- int lbounds;
+ bool lbounds;
const double *levels;
const char *longname;
const char *units;
@@ -63491,9 +63388,9 @@ varDefZAxisSearch(int id, void *res, void *data)
{
struct varDefZAxisSearchState *state = (struct varDefZAxisSearchState *)data;
(void)res;
- if (zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
- state->levels, state->longname, state->units, state->ltype)
- == 0)
+ if ( zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
+ state->levels, state->longname, state->units, state->ltype)
+ == false)
{
state->resIDValue = id;
return CDI_APPLY_STOP;
@@ -63503,17 +63400,17 @@ varDefZAxisSearch(int id, void *res, void *data)
}
-int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, int lbounds,
- const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
+int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,
+ const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
const char *longname, const char *units, int prec, int mode, int ltype1)
{
/*
mode: 0 search in vlist and zaxis table
1 search in zaxis table
*/
- int zaxisdefined = 0;
- int zaxisID = UNDEFID;
- int zaxisglobdefined = 0;
+ int zaxisID = CDI_UNDEFID;
+ bool zaxisdefined = false;
+ bool zaxisglobdefined = false;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
int nzaxis = vlistptr->nzaxis;
@@ -63522,9 +63419,9 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, i
{
zaxisID = vlistptr->zaxisIDs[index];
- if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
+ if ( !zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) )
{
- zaxisdefined = 1;
+ zaxisdefined = true;
break;
}
}
@@ -63549,7 +63446,7 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, i
for (int index = 0; index < nzaxis; index++ )
if ( vlistptr->zaxisIDs[index] == zaxisID )
{
- zaxisglobdefined = FALSE;
+ zaxisglobdefined = false;
break;
}
}
@@ -63559,20 +63456,24 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, i
if ( ! zaxisglobdefined )
{
zaxisID = zaxisCreate(zaxistype, nlevels);
- zaxisDefLevels(zaxisID, levels);
+ if ( levels ) zaxisDefLevels(zaxisID, levels);
if ( lbounds )
{
zaxisDefLbounds(zaxisID, levels1);
zaxisDefUbounds(zaxisID, levels2);
}
+ if ( cvals != NULL && nlevels != 0 && clength != 0 ) zaxisDefCvals(zaxisID, cvals, (int)clength);
+
if ( (zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF) && vctsize > 0 )
zaxisDefVct(zaxisID, vctsize, vct);
- zaxisDefName(zaxisID, name);
- zaxisDefLongname(zaxisID, longname);
- zaxisDefUnits(zaxisID, units);
- zaxisDefPrec(zaxisID, prec);
+ if ( name && name[0] ) zaxisDefName(zaxisID, name);
+ if ( longname && longname[0] ) zaxisDefLongname(zaxisID, longname);
+ else zaxisDefLongname(zaxisID, "");
+ if ( units && units[0] ) zaxisDefUnits(zaxisID, units);
+ else zaxisDefUnits(zaxisID, "");
+ zaxisDefDatatype(zaxisID, prec);
zaxisDefLtype(zaxisID, ltype1);
}
@@ -63580,20 +63481,20 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, i
vlistptr->nzaxis++;
}
- return (zaxisID);
+ return zaxisID;
}
void varDefMissval(int varID, double missval)
{
- vartable[varID].lmissval = 1;
+ vartable[varID].lmissval = true;
vartable[varID].missval = missval;
}
void varDefCompType(int varID, int comptype)
{
- if ( vartable[varID].comptype == COMPRESS_NONE )
+ if ( vartable[varID].comptype == CDI_COMPRESS_NONE )
vartable[varID].comptype = comptype;
}
@@ -63606,7 +63507,7 @@ void varDefCompLevel(int varID, int complevel)
int varInqInst(int varID)
{
- return (vartable[varID].instID);
+ return vartable[varID].instID;
}
@@ -63618,7 +63519,7 @@ void varDefInst(int varID, int instID)
int varInqModel(int varID)
{
- return (vartable[varID].modelID);
+ return vartable[varID].modelID;
}
@@ -63630,7 +63531,7 @@ void varDefModel(int varID, int modelID)
int varInqTable(int varID)
{
- return (vartable[varID].tableID);
+ return vartable[varID].tableID;
}
@@ -63664,10 +63565,10 @@ void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate)
#if defined (HAVE_LIBGRIB_API)
/* Resizes and initializes opt_grib_kvpair data structure. */
-static
+static
void resize_vartable_opt_grib_entries(vartable_t *var, int nentries)
{
- if (var->opt_grib_kvpair_size >= nentries)
+ if (var->opt_grib_kvpair_size >= nentries)
{
return; /* nothing to do; array is still large enough */
}
@@ -63687,7 +63588,7 @@ void resize_vartable_opt_grib_entries(vartable_t *var, int nentries)
for (i=var->opt_grib_kvpair_size; i<new_size; i++) {
tmp[i].int_val = 0;
tmp[i].dbl_val = 0;
- tmp[i].update = FALSE;
+ tmp[i].update = false;
tmp[i].keyword = NULL;
} // for
var->opt_grib_kvpair_size = new_size;
@@ -63740,7 +63641,7 @@ void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keywor
idx = i;
}
- if (idx == -1)
+ if (idx == -1)
{
resize_vartable_opt_grib_entries(&vartable[varID], vartable[varID].opt_grib_nentries+1);
vartable[varID].opt_grib_nentries += 1;
@@ -63762,9 +63663,8 @@ void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keywor
#if defined (HAVE_LIBGRIB_API)
int varOptGribNentries(int varID)
{
- int nentries = 0;
- nentries = vartable[varID].opt_grib_nentries;
- return (nentries);
+ int nentries = vartable[varID].opt_grib_nentries;
+ return nentries;
}
#endif
@@ -63777,65 +63677,6 @@ int varOptGribNentries(int varID)
* require-trailing-newline: t
* End:
*/
-#ifndef VLIST_VAR_H
-#define VLIST_VAR_H
-
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifndef _VLIST_H
-#endif
-
-int vlistVarGetPackSize(vlist_t *p, int varID, void *context);
-void vlistVarPack(vlist_t *p, int varID,
- char * buffer, int bufferSize, int * pos, void *context);
-void vlistVarUnpack(int vlistID,
- char * buf, int size, int *position, int, void *context);
-int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB);
-void vlistDefVarIOrank ( int, int, int );
-int vlistInqVarIOrank ( int, int );
-
-void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef VLIST_ATT_H
-#define VLIST_ATT_H
-
-#ifdef HAVE_CONFIG_H
-#endif
-
-int
-vlistAttsGetSize(vlist_t *p, int varID, void *context);
-
-void
-vlistAttsPack(vlist_t *p, int varID,
- void * buf, int size, int *position, void *context);
-
-void
-vlistAttsUnpack(int vlistID, int varID,
- void * buf, int size, int *position, void *context);
-
-
-#endif
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
#if defined (HAVE_CONFIG_H)
#endif
@@ -63861,7 +63702,7 @@ static pthread_once_t _vlist_init_thread = PTHREAD_ONCE_INIT;
#else
-static int vlistIsInitialized = 0;
+static bool vlistIsInitialized = false;
# define VLIST_INIT() \
if ( !vlistIsInitialized ) vlist_initialize()
@@ -63871,8 +63712,7 @@ static int vlistIsInitialized = 0;
static int
vlist_compare(vlist_t *a, vlist_t *b)
{
- int diff;
- diff = (a->nvars != b->nvars) | (a->ngrids != b->ngrids)
+ int diff = (a->nvars != b->nvars) | (a->ngrids != b->ngrids)
| (a->nzaxis != b->nzaxis) | (a->instID != b->instID)
| (a->modelID != b->modelID) | (a->tableID != b->tableID)
| (a->ntsteps != b->ntsteps) | (a->atts.nelems != b->atts.nelems);
@@ -63881,7 +63721,7 @@ vlist_compare(vlist_t *a, vlist_t *b)
diff |= vlistVarCompare(a, varID, b, varID);
size_t natts = a->atts.nelems;
for (size_t attID = 0; attID < natts; ++attID)
- diff |= vlist_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
+ diff |= cdi_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
return diff;
}
@@ -63901,8 +63741,8 @@ const
resOps vlistOps = {
(valCompareFunc)vlist_compare,
(valDestroyFunc)vlist_delete,
- (valPrintFunc)vlistPrintKernel
- , vlistGetSizeP,
+ (valPrintFunc)vlistPrintKernel,
+ vlistGetSizeP,
vlistPackP,
vlistTxCode
};
@@ -63911,7 +63751,7 @@ resOps vlistOps = {
vlist_t *vlist_to_pointer(int vlistID)
{
VLIST_INIT();
- return (vlist_t*) reshGetVal(vlistID, &vlistOps );
+ return (vlist_t*) reshGetVal(vlistID, &vlistOps);
}
static
@@ -63933,7 +63773,7 @@ void vlist_init_entry(vlist_t *vlistptr)
vlistptr->atts.nalloc = MAX_ATTRIBUTES;
vlistptr->atts.nelems = 0;
vlistptr->nsubtypes = 0;
- for (int i=0; i<MAX_SUBTYPES_PS; i++)
+ for ( int i = 0; i < MAX_SUBTYPES_PS; i++ )
vlistptr->subtypeIDs[i] = CDI_UNDEFID;
}
@@ -63949,15 +63789,13 @@ vlist_t *vlist_new_entry(cdiResH resH)
vlistptr->self = resH;
reshReplace(resH, vlistptr, &vlistOps);
}
- return (vlistptr);
+ return vlistptr;
}
static
void vlist_delete_entry(vlist_t *vlistptr)
{
- int idx;
-
- idx = vlistptr->self;
+ int idx = vlistptr->self;
reshRemove(idx, &vlistOps );
@@ -63970,12 +63808,10 @@ void vlist_delete_entry(vlist_t *vlistptr)
static
void vlist_initialize(void)
{
- char *env;
-
- env = getenv("VLIST_DEBUG");
+ char *env = getenv("VLIST_DEBUG");
if ( env ) VLIST_Debug = atoi(env);
#ifndef HAVE_LIBPTHREAD
- vlistIsInitialized = TRUE;
+ vlistIsInitialized = true;
#endif
}
@@ -64033,7 +63869,7 @@ int vlistCreate(void)
vlist_t *vlistptr = vlist_new_entry(CDI_UNDEFID);
if ( CDI_Debug ) Message("create vlistID = %d", vlistptr->self);
- return (vlistptr->self);
+ return vlistptr->self;
}
static void
@@ -64042,7 +63878,7 @@ vlist_delete(vlist_t *vlistptr)
int vlistID = vlistptr->self;
if ( CDI_Debug ) Message("call to vlist_delete, vlistID = %d", vlistID);
- vlistDelAtts(vlistID, CDI_GLOBAL);
+ cdiDelAtts(vlistID, CDI_GLOBAL);
int nvars = vlistptr->nvars;
var_t *vars = vlistptr->vars;
@@ -64058,17 +63894,18 @@ vlist_delete(vlist_t *vlistptr)
if ( vlistptr->vars[varID].opt_grib_kvpair )
{
- for (int i=0; i<vlistptr->vars[varID].opt_grib_nentries; i++) {
- if ( vlistptr->vars[varID].opt_grib_kvpair[i].keyword )
- Free(vlistptr->vars[varID].opt_grib_kvpair[i].keyword);
- }
+ for ( int i = 0; i<vlistptr->vars[varID].opt_grib_nentries; i++ )
+ {
+ if ( vlistptr->vars[varID].opt_grib_kvpair[i].keyword )
+ Free(vlistptr->vars[varID].opt_grib_kvpair[i].keyword);
+ }
Free(vlistptr->vars[varID].opt_grib_kvpair);
}
vlistptr->vars[varID].opt_grib_nentries = 0;
vlistptr->vars[varID].opt_grib_kvpair_size = 0;
vlistptr->vars[varID].opt_grib_kvpair = NULL;
- vlistDelAtts(vlistID, varID);
+ cdiDelAtts(vlistID, varID);
}
if ( vars ) Free(vars);
@@ -64138,7 +63975,7 @@ void var_copy_entries(var_t *var2, var_t *var1)
if ( var1->opt_grib_kvpair[i].keyword != NULL ) {
var2->opt_grib_kvpair[i] = var1->opt_grib_kvpair[i];
var2->opt_grib_kvpair[i].keyword = strdupx(var1->opt_grib_kvpair[i].keyword);
- var2->opt_grib_kvpair[i].update = TRUE;
+ var2->opt_grib_kvpair[i].update = true;
if ( CDI_Debug ) Message("done.");
}
else {
@@ -64171,7 +64008,7 @@ void vlistCopy(int vlistID2, int vlistID1)
var_t *vars2 = vlistptr2->vars;
vlist_copy(vlistptr2, vlistptr1);
- vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+ cdiCopyAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
if ( vars1 )
{
@@ -64188,7 +64025,7 @@ void vlistCopy(int vlistID2, int vlistID1)
var_copy_entries(&vars2[varID], &vars1[varID]);
vlistptr2->vars[varID].atts.nelems = 0;
- vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
+ cdiCopyAtts(vlistID1, varID, vlistID2, varID);
if ( vars1[varID].levinfo )
{
@@ -64222,23 +64059,22 @@ int vlistDuplicate(int vlistID)
int vlistIDnew = vlistCreate();
vlistCopy(vlistIDnew, vlistID);
- return (vlistIDnew);
+ return vlistIDnew;
}
void vlistClearFlag(int vlistID)
{
- int varID, levID;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- for ( varID = 0; varID < vlistptr->nvars; varID++ )
+ for ( int varID = 0; varID < vlistptr->nvars; varID++ )
{
- vlistptr->vars[varID].flag = FALSE;
+ vlistptr->vars[varID].flag = false;
if ( vlistptr->vars[varID].levinfo )
{
int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
- for ( levID = 0; levID < nlevs; levID++ )
- vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+ for ( int levID = 0; levID < nlevs; levID++ )
+ vlistptr->vars[varID].levinfo[levID].flag = false;
}
}
}
@@ -64249,7 +64085,7 @@ struct vgzSearchState
int resIDValue;
int zaxistype;
int nlevels;
- int lbounds;
+ bool lbounds;
const double *levels;
};
@@ -64260,7 +64096,7 @@ vgzZAxisSearch(int id, void *res, void *data)
(void)res;
if (zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
state->levels, NULL, NULL, 0)
- == 0)
+ == false)
{
state->resIDValue = id;
return CDI_APPLY_STOP;
@@ -64269,27 +64105,27 @@ vgzZAxisSearch(int id, void *res, void *data)
return CDI_APPLY_GO_ON;
}
-
static
int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *levels,
- const double *lbounds, const double *ubounds, int vctsize, const double *vct)
+ const double *lbounds, const double *ubounds, int vctsize, const double *vct,
+ const char **cvals, size_t clen)
{
int zaxisID = CDI_UNDEFID;
- int zaxisglobdefined = 0;
- int has_bounds = FALSE;
+ bool zaxisdefined = false;
+ bool zaxisglobdefined = false;
+ bool has_bounds = false;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- int zaxisdefined = 0;
int nzaxis = vlistptr->nzaxis;
- if ( lbounds && ubounds ) has_bounds = TRUE;
+ if ( lbounds && ubounds ) has_bounds = true;
for ( int index = 0; index < nzaxis; ++index )
{
zaxisID = vlistptr->zaxisIDs[index];
- if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
+ if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == false )
{
- zaxisdefined = 1;
+ zaxisdefined = true;
break;
}
}
@@ -64314,6 +64150,10 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
{
zaxisID = zaxisCreate(zaxistype, nlevels);
zaxisDefLevels(zaxisID, levels);
+
+ if ( zaxistype == ZAXIS_CHAR )
+ zaxisDefCvals(zaxisID, cvals, (int)clen);
+
if ( has_bounds )
{
zaxisDefLbounds(zaxisID, lbounds);
@@ -64329,7 +64169,7 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
vlistptr->nzaxis++;
}
- return (zaxisID);
+ return zaxisID;
}
/*
@@ -64355,34 +64195,29 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
vlist_copy(vlistptr2, vlistptr1);
- vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+ cdiCopyAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
if ( vlistptr1->vars )
{
- int nvars = vlistptr1->nvars;
- int nvars2 = 0;
- int varID2;
-
vlistptr2->ngrids = 0;
vlistptr2->nzaxis = 0;
+ int nvars = vlistptr1->nvars;
+ int nvars2 = 0;
for ( int varID = 0; varID < nvars; varID++ )
- nvars2 += (vars1[varID].flag != 0);
+ nvars2 += vars1[varID].flag;
vlistptr2->nvars = nvars2;
vlistptr2->varsAllocated = nvars2;
- if ( nvars2 > 0 )
- vars2 = (var_t *) Malloc((size_t)nvars2*sizeof(var_t));
- else
- vars2 = NULL;
+ vars2 = (nvars2 > 0) ? (var_t *) Malloc((size_t)nvars2*sizeof(var_t)) : NULL;
vlistptr2->vars = vars2;
- varID2 = 0;
+ int varID2 = 0;
for ( int varID = 0; varID < nvars; varID++ )
if ( vars1[varID].flag )
{
- vlistptr2->vars[varID2].flag = FALSE;
+ vlistptr2->vars[varID2].flag = false;
int zaxisID = vlistptr1->vars[varID].zaxisID;
int gridID = vlistptr1->vars[varID].gridID;
int subtypeID = vlistptr1->vars[varID].subtypeID;
@@ -64397,46 +64232,80 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
var_copy_entries(&vars2[varID2], &vars1[varID]);
vlistptr2->vars[varID2].atts.nelems = 0;
- vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
+ cdiCopyAtts(vlistID1, varID, vlistID2, varID2);
int nlevs = zaxisInqSize(vars1[varID].zaxisID);
int nlevs2 = 0;
if ( vars1[varID].levinfo )
for ( int levID = 0; levID < nlevs; levID++ )
- nlevs2 += (vars1[varID].levinfo[levID].flag != 0);
+ nlevs2 += vars1[varID].levinfo[levID].flag;
vars2[varID2].levinfo = (levinfo_t *) Malloc((size_t)nlevs2 * sizeof(levinfo_t));
if ( nlevs != nlevs2 )
{
int nvct = 0;
+ double *levels = NULL;
+ char **cvals1 = NULL, **cvals2 = NULL;
+ size_t clen2 = 0;
double *lbounds = NULL, *ubounds = NULL;
const double *vct = NULL;
char ctemp[CDI_MAX_NAME];
+ if ( !vars1[varID].levinfo ) cdiVlistCreateVarLevInfo(vlistptr1, varID);
+
zaxisID = vars1[varID].zaxisID;
- double *levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
- if ( !vars1[varID].levinfo )
- cdiVlistCreateVarLevInfo(vlistptr1, varID);
+ int zaxisType = zaxisInqType(zaxisID);
- {
- int levID2 = 0;
- for ( int levID = 0; levID < nlevs; ++levID )
- if ( vars1[varID].levinfo[levID].flag )
- {
- vars1[varID].levinfo[levID].flevelID = levID2;
- vars1[varID].levinfo[levID].mlevelID = levID2;
+ int levID2 = 0;
+ for ( int levID = 0; levID < nlevs; ++levID )
+ if ( vars1[varID].levinfo[levID].flag )
+ {
+ vars1[varID].levinfo[levID].flevelID = levID2;
+ vars1[varID].levinfo[levID].mlevelID = levID2;
+ }
+
+
+ if ( zaxisInqLevels(zaxisID, NULL) )
+ {
+ levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
+
+ levID2 = 0;
+ for ( int levID = 0; levID < nlevs; ++levID )
+ if ( vars1[varID].levinfo[levID].flag )
levels[levID2++] = zaxisInqLevel(zaxisID, levID);
- }
- }
+ }
- int zaxisType = zaxisInqType(zaxisID);
+ if ( zaxisType == ZAXIS_HYBRID )
+ {
+ nvct = zaxisInqVctSize(zaxisID);
+ vct = zaxisInqVctPtr(zaxisID);
+ }
- if ( zaxisType == ZAXIS_HYBRID )
- {
- nvct = zaxisInqVctSize(zaxisID);
- vct = zaxisInqVctPtr(zaxisID);
- }
+ if ( zaxisType == ZAXIS_CHAR )
+ {
+ cvals1 = zaxisInqCValsPtr(zaxisID);
+ size_t clen1 = (size_t)zaxisInqCLen(zaxisID);
+ for ( int levID = 0; levID < nlevs; ++levID )
+ if ( vars1[varID].levinfo[levID].flag )
+ {
+ size_t testlen = clen1;
+ while ( cvals1[levID][testlen] == ' ' )
+ testlen--;
+ if ( clen2 < testlen )
+ clen2 = testlen;
+ }
+ cvals2 = (char **) Malloc((size_t)nlevs2 * sizeof (char *));
+ levID2 = 0;
+
+ for ( int levID = 0; levID < nlevs; ++levID )
+ if ( vars1[varID].levinfo[levID].flag )
+ {
+ cvals2[levID2] = Malloc((size_t)(clen2) * sizeof (char));
+ memcpy(cvals2[levID2], cvals1[levID], clen2*sizeof(char));
+ levID2++;
+ }
+ }
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
@@ -64444,12 +64313,12 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
ubounds = lbounds + nlevs2;
double *lbounds1 = (double *) Malloc(2 * (size_t)nlevs * sizeof (double)),
- *ubounds1 = lbounds1 + nlevs;
+ *ubounds1 = lbounds1 + nlevs;
zaxisInqLbounds(zaxisID, lbounds1);
zaxisInqUbounds(zaxisID, ubounds1);
- int levID2 = 0;
+ levID2 = 0;
for ( int levID = 0; levID < nlevs; ++levID )
if ( vars1[varID].levinfo[levID].flag )
{
@@ -64461,9 +64330,15 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
Free(lbounds1);
}
- int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct);
- free(levels);
- Free(lbounds);
+ int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct, (const char **)cvals2, clen2);
+ if ( levels ) Free(levels);
+ if ( lbounds ) Free(lbounds);
+ if ( cvals2 )
+ {
+ for ( int levID = 0; levID < nlevs2; ++levID )
+ Free(cvals2[levID]);
+ Free(cvals2);
+ }
zaxisInqName(zaxisID, ctemp);
zaxisDefName(zaxisID2, ctemp);
@@ -64471,6 +64346,17 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
zaxisDefLongname(zaxisID2, ctemp);
zaxisInqUnits(zaxisID, ctemp);
zaxisDefUnits(zaxisID2, ctemp);
+ zaxisDefDatatype(zaxisID2, zaxisInqDatatype(zaxisID));
+
+ if ( zaxisType == ZAXIS_CHAR )
+ {
+ char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
+ cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
+ if ( dimname[0] == 0 ) { memcpy(dimname, "area_type", 10); dimname[10] = 0; }
+ cdiZaxisDefKeyStr(zaxisID2, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
+ }
+
+ if ( zaxisType == ZAXIS_GENERIC ) zaxisDefLtype(zaxisID2, zaxisInqLtype(zaxisID));
zaxisID = zaxisID2;
vars2[varID2].zaxisID = zaxisID2;
@@ -64478,7 +64364,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
for ( int levID = 0; levID < nlevs2; levID++ )
{
- vars2[varID2].levinfo[levID].flag = FALSE;
+ vars2[varID2].levinfo[levID].flag = false;
vars2[varID2].levinfo[levID].index = -1;
}
@@ -64561,7 +64447,7 @@ void vlistCat(int vlistID2, int vlistID1)
}
vars2[varID2].atts.nelems = 0;
- vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
+ cdiCopyAtts(vlistID1, varID, vlistID2, varID2);
vlistAdd2GridIDs(vlistptr2, vars1[varID].gridID);
vlistAdd2ZaxisIDs(vlistptr2, vars1[varID].zaxisID);
@@ -64597,8 +64483,8 @@ void vlistMerge(int vlistID2, int vlistID1)
{
for ( varID = 0; varID < nvars2; varID++ )
{
- int ngp1 = gridInqSize(vars1[varID].gridID);
- int ngp2 = gridInqSize(vars2[varID].gridID);
+ size_t ngp1 = gridInqSize(vars1[varID].gridID);
+ size_t ngp2 = gridInqSize(vars2[varID].gridID);
if ( ngp1 != ngp2 ) break;
if ( vars1[varID].name && vars2[varID].name )
@@ -64645,11 +64531,11 @@ void vlistMerge(int vlistID2, int vlistID1)
vars1[varID].levinfo[levID].mlevelID = nlevs2 + levID;
}
- int *lvar = (int *) Calloc((size_t)nvars2, sizeof(int));
+ bool *lvar = (bool *) Calloc((size_t)nvars2, sizeof(bool));
for ( varID = 0; varID < nvars2; varID++ )
{
- if ( lvar[varID] == TRUE ) continue;
+ if ( lvar[varID] == true ) continue;
int zaxisID1 = vars1[varID].zaxisID;
int zaxisID2 = vars2[varID].zaxisID;
@@ -64665,30 +64551,32 @@ void vlistMerge(int vlistID2, int vlistID1)
int nlevs = nlevs1 + nlevs2;
int zaxisID = zaxisDuplicate(zaxisID2);
-
zaxisResize(zaxisID, nlevs);
- double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
+ if ( zaxisInqLevels(zaxisID1, NULL) )
+ {
+ double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
- zaxisInqLevels(zaxisID1, levels);
- /*
- for ( levID = 0; levID < nlevs1; levID++ )
- fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
- */
- for ( int levID = 0; levID < nlevs1; levID++ )
- zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
+ zaxisInqLevels(zaxisID1, levels);
+ /*
+ for ( levID = 0; levID < nlevs1; levID++ )
+ fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
+ */
+ for ( int levID = 0; levID < nlevs1; levID++ )
+ zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
- Free(levels);
+ Free(levels);
+ }
for ( int index = 0; index < vlistptr2->nzaxis; index++ )
if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
vlistptr2->zaxisIDs[index] = zaxisID;
for ( int varID2 = 0; varID2 < nvars2; varID2++ )
- if ( lvar[varID2] == FALSE && vars2[varID2].zaxisID == zaxisID2 )
+ if ( lvar[varID2] == false && vars2[varID2].zaxisID == zaxisID2 )
{
vars2[varID2].zaxisID = zaxisID;
- lvar[varID2] = TRUE;
+ lvar[varID2] = true;
}
}
@@ -64719,29 +64607,29 @@ The function @func{vlistNvars} returns the number of variables in the variable l
int vlistNvars(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->nvars);
+ return vlistptr->nvars;
}
int vlistNrecs(int vlistID)
{
- int nrecs = 0;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
+ int nrecs = 0;
for ( int varID = 0; varID < vlistptr->nvars; varID++ )
nrecs += zaxisInqSize(vlistptr->vars[varID].zaxisID);
- return (nrecs);
+ return nrecs;
}
int vlistNumber(int vlistID)
{
- int number, number2, datatype;
+ int number, number2;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- datatype = vlistptr->vars[0].datatype;
- if ( datatype== DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ int datatype = vlistptr->vars[0].datatype;
+ if ( datatype== CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
number = CDI_COMP;
else
number = CDI_REAL;
@@ -64749,7 +64637,7 @@ int vlistNumber(int vlistID)
for ( int varID = 1; varID < vlistptr->nvars; varID++ )
{
datatype = vlistptr->vars[varID].datatype;
- if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+ if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
number2 = CDI_COMP;
else
number2 = CDI_REAL;
@@ -64761,7 +64649,7 @@ int vlistNumber(int vlistID)
}
}
- return (number);
+ return number;
}
/*
@@ -64784,7 +64672,7 @@ int vlistNgrids(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->ngrids);
+ return vlistptr->ngrids;
}
/*
@@ -64807,7 +64695,7 @@ int vlistNzaxis(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->nzaxis);
+ return vlistptr->nzaxis;
}
@@ -64815,7 +64703,7 @@ int vlistNsubtypes(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->nsubtypes);
+ return vlistptr->nsubtypes;
}
@@ -64823,7 +64711,7 @@ void vlistDefNtsteps(int vlistID, int nts)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- if (vlistptr->ntsteps != nts)
+ if ( vlistptr->ntsteps != nts )
{
vlistptr->ntsteps = nts;
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -64901,7 +64789,8 @@ void vlistPrintKernel(vlist_t *vlistptr, FILE *fp)
int mlevID = li.mlevelID;
int index = li.index;
int flag = li.flag;
- double level = zaxisInqLevel(zaxisID, levID);
+
+ double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levID) : levID+1;
fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d %.9g\n",
varID, levID, fvarID, flevID, mvarID, mlevID, index,
@@ -64912,7 +64801,7 @@ void vlistPrintKernel(vlist_t *vlistptr, FILE *fp)
fputs("\n"
" varID size iorank\n", fp);
for ( int varID = 0; varID < nvars; varID++ )
- fprintf(fp, "%3d %8d %6d\n", varID,
+ fprintf(fp, "%3d %8zu %6d\n", varID,
zaxisInqSize(vlistptr->vars[varID].zaxisID)
* gridInqSize(vlistptr->vars[varID].gridID),
vlistptr->vars[varID].iorank);
@@ -64945,7 +64834,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- if (vlistptr->taxisID != taxisID)
+ if ( vlistptr->taxisID != taxisID )
{
//FIXME: This code seems to leak a taxis_t object if `vlistptr->taxisID` was valid before the call to vlistDefTaxis.
vlistptr->taxisID = taxisID;
@@ -64973,7 +64862,7 @@ int vlistInqTaxis(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->taxisID);
+ return vlistptr->taxisID;
}
@@ -64981,7 +64870,7 @@ void vlistDefTable(int vlistID, int tableID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- if (vlistptr->tableID != tableID)
+ if ( vlistptr->tableID != tableID )
{
vlistptr->tableID = tableID;
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -64993,7 +64882,7 @@ int vlistInqTable(int vlistID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->tableID);
+ return vlistptr->tableID;
}
@@ -65001,7 +64890,7 @@ void vlistDefInstitut(int vlistID, int instID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- if (vlistptr->instID != instID)
+ if ( vlistptr->instID != instID )
{
vlistptr->instID = instID;
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65028,7 +64917,7 @@ int vlistInqInstitut(int vlistID)
vlistDefInstitut(vlistID, instID);
}
- return (instID);
+ return instID;
}
@@ -65036,7 +64925,7 @@ void vlistDefModel(int vlistID, int modelID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- if (vlistptr->modelID != modelID)
+ if ( vlistptr->modelID != modelID )
{
vlistptr->modelID = modelID;
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65064,23 +64953,23 @@ int vlistInqModel(int vlistID)
vlistDefModel(vlistID, modelID);
}
- return (modelID);
+ return modelID;
}
-int vlistGridsizeMax(int vlistID)
+size_t vlistGridsizeMax(int vlistID)
{
- int gridsizemax = 0;
+ size_t gridsizemax = 0;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
for ( int index = 0 ; index < vlistptr->ngrids ; index++ )
{
int gridID = vlistptr->gridIDs[index];
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
if ( gridsize > gridsizemax ) gridsizemax = gridsize;
}
- return (gridsizemax);
+ return gridsizemax;
}
@@ -65092,7 +64981,7 @@ int vlistGrid(int vlistID, int index)
if ( index < vlistptr->ngrids && index >= 0 )
gridID = vlistptr->gridIDs[index];
- return (gridID);
+ return gridID;
}
@@ -65106,7 +64995,7 @@ int vlistGridIndex(int vlistID, int gridID)
if ( index == vlistptr->ngrids ) index = -1;
- return (index);
+ return index;
}
@@ -65160,7 +65049,7 @@ int vlistZaxis(int vlistID, int index)
if ( index < vlistptr->nzaxis && index >= 0 )
zaxisID = vlistptr->zaxisIDs[index];
- return (zaxisID);
+ return zaxisID;
}
@@ -65174,7 +65063,7 @@ int vlistZaxisIndex(int vlistID, int zaxisID)
if ( index == vlistptr->nzaxis ) index = -1;
- return (index);
+ return index;
}
@@ -65268,25 +65157,27 @@ int vlistSubtypeIndex(int vlistID, int subtypeID)
int vlistHasTime(int vlistID)
{
- int hastime = FALSE;
+ bool hastime = false;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- for ( int varID = 0; varID < vlistptr->nvars; varID++ )
- if ( vlistptr->vars[varID].tsteptype != TSTEP_CONSTANT )
- {
- hastime = TRUE;
- break;
- }
+ if ( !(CDI_reduce_dim && vlistptr->ntsteps == 1) )
+ {
+ for ( int varID = 0; varID < vlistptr->nvars; varID++ )
+ if ( vlistptr->vars[varID].timetype != TIME_CONSTANT )
+ {
+ hastime = true;
+ break;
+ }
+ }
- return (hastime);
+ return (int)hastime;
}
enum {
vlist_nints=6,
};
-static int
-vlistTxCode ( void )
+static int vlistTxCode ( void )
{
return VLIST;
}
@@ -65297,9 +65188,9 @@ int vlistGetSizeP ( void * vlistptr, void *context)
{
int txsize, varID;
vlist_t *p = (vlist_t*) vlistptr;
- txsize = serializeGetSize(vlist_nints, DATATYPE_INT, context);
- txsize += serializeGetSize(1, DATATYPE_LONG, context);
- txsize += vlistAttsGetSize(p, CDI_GLOBAL, context);
+ txsize = serializeGetSize(vlist_nints, CDI_DATATYPE_INT, context);
+ txsize += serializeGetSize(1, CDI_DATATYPE_LONG, context);
+ txsize += cdiAttsGetSize(p, CDI_GLOBAL, context);
for ( varID = 0; varID < p->nvars; varID++ )
txsize += vlistVarGetPackSize(p, varID, context);
return txsize;
@@ -65318,10 +65209,10 @@ void vlistPackP ( void * vlistptr, void * buf, int size, int *position,
tempbuf[3] = p->tableID;
tempbuf[4] = p->instID;
tempbuf[5] = p->modelID;
- serializePack(tempbuf, vlist_nints, DATATYPE_INT, buf, size, position, context);
- serializePack(&p->ntsteps, 1, DATATYPE_LONG, buf, size, position, context);
+ serializePack(tempbuf, vlist_nints, CDI_DATATYPE_INT, buf, size, position, context);
+ serializePack(&p->ntsteps, 1, CDI_DATATYPE_LONG, buf, size, position, context);
- vlistAttsPack(p, CDI_GLOBAL, buf, size, position, context);
+ cdiAttsPack(p, CDI_GLOBAL, buf, size, position, context);
for ( varID = 0; varID < p->nvars; varID++ )
{
vlistVarPack(p, varID, (char *)buf, size, position, context);
@@ -65332,7 +65223,7 @@ void vlistUnpack(char * buf, int size, int *position, int originNamespace,
void *context, int force_id)
{
int tempbuf[vlist_nints];
- serializeUnpack(buf, size, position, tempbuf, vlist_nints, DATATYPE_INT, context);
+ serializeUnpack(buf, size, position, tempbuf, vlist_nints, CDI_DATATYPE_INT, context);
int nvars = tempbuf[1];
int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
vlist_t *p = vlist_new_entry(force_id?targetID:CDI_UNDEFID);
@@ -65344,8 +65235,8 @@ void vlistUnpack(char * buf, int size, int *position, int originNamespace,
p->tableID = tempbuf[3];
p->instID = namespaceAdaptKey(tempbuf[4], originNamespace);
p->modelID = namespaceAdaptKey(tempbuf[5], originNamespace);
- serializeUnpack(buf, size, position, &p->ntsteps, 1, DATATYPE_LONG, context);
- vlistAttsUnpack(targetID, CDI_GLOBAL, buf, size, position, context);
+ serializeUnpack(buf, size, position, &p->ntsteps, 1, CDI_DATATYPE_LONG, context);
+ cdiAttsUnpack(targetID, CDI_GLOBAL, buf, size, position, context);
for (int varID = 0; varID < nvars; varID++ )
vlistVarUnpack(targetID, buf, size, position, originNamespace, context);
reshSetStatus(targetID, &vlistOps,
@@ -65355,11 +65246,10 @@ void vlistUnpack(char * buf, int size, int *position, int originNamespace,
void vlist_check_contents(int vlistID)
{
- int index, nzaxis, zaxisID;
-
- nzaxis = vlistNzaxis(vlistID);
+ int zaxisID;
+ int nzaxis = vlistNzaxis(vlistID);
- for ( index = 0; index < nzaxis; index++ )
+ for ( int index = 0; index < nzaxis; index++ )
{
zaxisID = vlistZaxis(vlistID, index);
if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
@@ -65371,7 +65261,7 @@ void vlist_check_contents(int vlistID)
/* Resizes and initializes opt_grib_kvpair data structure. */
void resize_opt_grib_entries(var_t *var, int nentries)
{
- if (var->opt_grib_kvpair_size >= nentries)
+ if (var->opt_grib_kvpair_size >= nentries)
{
if ( CDI_Debug )
Message("data structure has size %d, no resize to %d needed.", var->opt_grib_kvpair_size, nentries);
@@ -65391,7 +65281,7 @@ void resize_opt_grib_entries(var_t *var, int nentries)
for (i=var->opt_grib_kvpair_size; i<new_size; i++) {
tmp[i].int_val = 0;
tmp[i].dbl_val = 0;
- tmp[i].update = FALSE;
+ tmp[i].update = false;
tmp[i].keyword = NULL;
} // for
var->opt_grib_kvpair_size = new_size;
@@ -65419,6 +65309,7 @@ void resize_opt_grib_entries(var_t *var, int nentries)
+
static
cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
{
@@ -65434,7 +65325,7 @@ cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
attsp = &(vlistptr->vars[varID].atts);
}
- return (attsp);
+ return attsp;
}
static
@@ -65452,27 +65343,24 @@ cdi_att_t *find_att(cdi_atts_t *attsp, const char *name)
{
cdi_att_t *attp = atts + attid;
if ( attp->namesz == slen && memcmp(attp->name, name, slen) == 0 )
- return (attp); /* Normal return */
+ return attp; /* Normal return */
}
- return (NULL);
+ return NULL;
}
static
cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
{
- cdi_att_t *attp;
- size_t slen;
-
xassert(attsp != NULL);
xassert(name != NULL);
- if ( attsp->nelems == attsp->nalloc ) return (NULL);
+ if ( attsp->nelems == attsp->nalloc ) return NULL;
- attp = &(attsp->value[attsp->nelems]);
+ cdi_att_t *attp = &(attsp->value[attsp->nelems]);
attsp->nelems++;
- slen = strlen(name);
+ size_t slen = strlen(name);
if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
attp->name = (char *) Malloc(slen+1);
@@ -65480,7 +65368,7 @@ cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
attp->namesz = slen;
attp->xvalue = NULL;
- return (attp);
+ return attp;
}
static
@@ -65500,44 +65388,64 @@ void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t x
}
}
+static
+cdi_atts_t *cdi_get_attsp(int objID, int varID)
+{
+ cdi_atts_t *attsp = NULL;
+
+ if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == GRID )
+ {
+ grid_t *gridptr = grid_to_pointer(objID);
+ attsp = &gridptr->atts;
+ }
+ else if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == ZAXIS )
+ {
+ zaxis_t *zaxisptr = zaxis_to_pointer(objID);
+ attsp = &zaxisptr->atts;
+ }
+ else
+ {
+ vlist_t *vlistptr = vlist_to_pointer(objID);
+ attsp = get_attsp(vlistptr, varID);
+ }
+
+ return attsp;
+}
+
/*
- at Function vlistInqNatts
- at Title Get number of variable attributes
+ at Function cdiInqNatts
+ at Title Get number of attributes
- at Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
+ at Prototype int cdiInqNatts(int cdiID, int varID, int *nattsp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
- @Item nattsp Pointer to location for returned number of variable attributes.
+ @Item nattsp Pointer to location for returned number of attributes.
@Description
-The function @func{vlistInqNatts} gets the number of variable attributes assigned to this variable.
+The function @func{cdiInqNatts} gets the number of attributes assigned to this variable.
@EndFunction
*/
-int vlistInqNatts(int vlistID, int varID, int *nattsp)
+int cdiInqNatts(int cdiID, int varID, int *nattsp)
{
int status = CDI_NOERR;
- vlist_t *vlistptr;
- cdi_atts_t *attsp;
- vlistptr = vlist_to_pointer(vlistID);
-
- attsp = get_attsp(vlistptr, varID);
+ cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
xassert(attsp != NULL);
*nattsp = (int)attsp->nelems;
- return (status);
+ return status;
}
/*
- at Function vlistInqAtt
+ at Function cdiInqAtt
@Title Get information about an attribute
- at Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
+ at Prototype int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item attnum Attribute number (from 0 to natts-1).
@Item name Pointer to the location for the returned attribute name. The caller must allocate space for the
@@ -65547,22 +65455,20 @@ int vlistInqNatts(int vlistID, int varID, int *nattsp)
@Item lenp Pointer to location for returned attribute number.
@Description
-The function @func{vlistInqAtt} gets information about an attribute.
+The function @func{cdiInqAtt} gets information about an attribute.
@EndFunction
*/
-int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
+int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
{
int status = CDI_NOERR;
- cdi_att_t *attp = NULL;
xassert(name != NULL);
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- cdi_atts_t *attsp = get_attsp(vlistptr, varID);
+ cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
xassert(attsp != NULL);
+ cdi_att_t *attp = NULL;
if ( attnum >= 0 && attnum < (int)attsp->nelems )
attp = &(attsp->value[attnum]);
@@ -65580,102 +65486,79 @@ int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int
status = -1;
}
- return (status);
+ return status;
}
-int vlistDelAtts(int vlistID, int varID)
+int cdiDelAtts(int cdiID, int varID)
{
int status = CDI_NOERR;
- vlist_t *vlistptr;
- cdi_att_t *attp = NULL;
- cdi_atts_t *attsp;
- int attid;
-
- vlistptr = vlist_to_pointer(vlistID);
- attsp = get_attsp(vlistptr, varID);
+ cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
xassert(attsp != NULL);
- for ( attid = 0; attid < (int)attsp->nelems; attid++ )
+ for ( int attid = 0; attid < (int)attsp->nelems; attid++ )
{
- attp = &(attsp->value[attid]);
+ cdi_att_t *attp = &(attsp->value[attid]);
if ( attp->name ) Free(attp->name);
if ( attp->xvalue ) Free(attp->xvalue);
}
attsp->nelems = 0;
- return (status);
+ return status;
}
-int vlistDelAtt(int vlistID, int varID, const char *name)
+int cdiDelAtt(int cdiID, int varID, const char *name)
{
int status = CDI_NOERR;
- UNUSED(vlistID);
+ UNUSED(cdiID);
UNUSED(varID);
UNUSED(name);
- fprintf(stderr, "vlistDelAtt not implemented!\n");
+ fprintf(stderr, "cdiDelAtt not implemented!\n");
- return (status);
+ return status;
}
static
-int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
+int cdi_def_att(int indtype, int exdtype, int cdiID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
{
int status = CDI_NOERR;
- vlist_t *vlistptr;
- cdi_att_t *attp;
- cdi_atts_t *attsp;
if ( len != 0 && xp == NULL ) /* Null arg */
- {
- return (CDI_EINVAL);
- }
+ return CDI_EINVAL;
- vlistptr = vlist_to_pointer(vlistID);
-
- attsp = get_attsp(vlistptr, varID);
+ cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
xassert(attsp != NULL);
- attp = find_att(attsp, name);
- if ( attp == NULL )
- attp = new_att(attsp, name);
+ cdi_att_t *attp = find_att(attsp, name);
+ if ( attp == NULL ) attp = new_att(attsp, name);
- if ( attp != NULL )
- fill_att(attp, indtype, exdtype, len, xsz, xp);
+ if ( attp != NULL ) fill_att(attp, indtype, exdtype, len, xsz, xp);
- return (status);
+ return status;
}
static
-int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
+int cdi_inq_att(int indtype, int cdiID, int varID, const char *name, size_t mxsz, void *xp)
{
int status = CDI_NOERR;
- vlist_t *vlistptr;
- cdi_att_t *attp;
- cdi_atts_t *attsp;
- size_t xsz;
if ( mxsz != 0 && xp == NULL ) /* Null arg */
- {
- return (CDI_EINVAL);
- }
-
- vlistptr = vlist_to_pointer(vlistID);
+ return CDI_EINVAL;
- attsp = get_attsp(vlistptr, varID);
+ cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
xassert(attsp != NULL);
- attp = find_att(attsp, name);
+ cdi_att_t *attp = find_att(attsp, name);
if ( attp != NULL ) /* name in use */
{
if ( attp->indtype == indtype )
{
- xsz = attp->xsz;
+ size_t xsz = attp->xsz;
if ( mxsz < xsz ) xsz = mxsz;
if ( xsz > 0 )
memcpy(xp, attp->xvalue, xsz);
@@ -65692,184 +65575,178 @@ int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t
status = -1;
}
- return (status);
+ return status;
}
-int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
+int cdiCopyAtts(int cdiID1, int varID1, int cdiID2, int varID2)
{
int status = CDI_NOERR;
- vlist_t *vlistptr1;
- cdi_att_t *attp = NULL;
- cdi_atts_t *attsp1;
- int attid;
-
- vlistptr1 = vlist_to_pointer(vlistID1);
- attsp1 = get_attsp(vlistptr1, varID_1);
+ cdi_atts_t *attsp1 = cdi_get_attsp(cdiID1, varID1);
xassert(attsp1 != NULL);
- for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
+ for ( int attid = 0; attid < (int)attsp1->nelems; attid++ )
{
- attp = &(attsp1->value[attid]);
- vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
+ cdi_att_t *attp = &(attsp1->value[attid]);
+ cdi_def_att(attp->indtype, attp->exdtype, cdiID2, varID2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
}
- return (status);
+ return status;
}
/*
- at Function vlistDefAttInt
+ at Function cdiDefAttInt
@Title Define an integer attribute
- at Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
+ at Prototype int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
- @Item type External data type (@func{DATATYPE_INT16} or @func{DATATYPE_INT32}).
+ @Item type External data type (@func{CDI_DATATYPE_INT16} or @func{CDI_DATATYPE_INT32}).
@Item len Number of values provided for the attribute.
@Item ip Pointer to one or more integer values.
@Description
-The function @func{vlistDefAttInt} defines an integer attribute.
+The function @func{cdiDefAttInt} defines an integer attribute.
@EndFunction
*/
-int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
+int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
{
- return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (int), ip);
+ return cdi_def_att(CDI_DATATYPE_INT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(int), ip);
}
/*
- at Function vlistDefAttFlt
+ at Function cdiDefAttFlt
@Title Define a floating point attribute
- at Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
+ at Prototype int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
- @Item type External data type (@func{DATATYPE_FLT32} or @func{DATATYPE_FLT64}).
+ @Item type External data type (@func{CDI_DATATYPE_FLT32} or @func{CDI_DATATYPE_FLT64}).
@Item len Number of values provided for the attribute.
@Item dp Pointer to one or more floating point values.
@Description
-The function @func{vlistDefAttFlt} defines a floating point attribute.
+The function @func{cdiDefAttFlt} defines a floating point attribute.
@EndFunction
*/
-int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
+int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
{
- return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (double), dp);
+ return cdi_def_att(CDI_DATATYPE_FLT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(double), dp);
}
/*
- at Function vlistDefAttTxt
+ at Function cdiDefAttTxt
@Title Define a text attribute
- at Prototype int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
+ at Prototype int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
@Item len Number of values provided for the attribute.
@Item tp Pointer to one or more character values.
@Description
-The function @func{vlistDefAttTxt} defines a text attribute.
+The function @func{cdiDefAttTxt} defines a text attribute.
@EndFunction
*/
-int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
+int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
{
- return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t)len, (size_t)len, tp);
+ return cdi_def_att(CDI_DATATYPE_TXT, CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)len, (size_t)len, tp);
}
/*
- at Function vlistInqAttInt
+ at Function cdiInqAttInt
@Title Get the value(s) of an integer attribute
- at Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
+ at Prototype int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
@Item mlen Number of allocated values provided for the attribute.
@Item ip Pointer location for returned integer attribute value(s).
@Description
-The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
+The function @func{cdiInqAttInt} gets the values(s) of an integer attribute.
@EndFunction
*/
-int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
+int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
{
- return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, (size_t)mlen * sizeof (int), ip);
+ return cdi_inq_att(CDI_DATATYPE_INT, cdiID, varID, name, (size_t)mlen * sizeof(int), ip);
}
/*
- at Function vlistInqAttFlt
+ at Function cdiInqAttFlt
@Title Get the value(s) of a floating point attribute
- at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
+ at Prototype int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
@Item mlen Number of allocated values provided for the attribute.
@Item dp Pointer location for returned floating point attribute value(s).
@Description
-The function @func{vlistInqAttFlt} gets the values(s) of a floating point attribute.
+The function @func{cdiInqAttFlt} gets the values(s) of a floating point attribute.
@EndFunction
*/
-int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
+int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
{
- return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, (size_t)mlen * sizeof (double), dp);
+ return cdi_inq_att(CDI_DATATYPE_FLT, cdiID, varID, name, (size_t)mlen * sizeof(double), dp);
}
/*
- at Function vlistInqAttTxt
+ at Function cdiInqAttTxt
@Title Get the value(s) of a text attribute
- at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
+ at Prototype int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp)
@Parameter
- @Item vlistID Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+ @Item cdiID CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
@Item varID Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@Item name Attribute name.
@Item mlen Number of allocated values provided for the attribute.
@Item tp Pointer location for returned text attribute value(s).
@Description
-The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
+The function @func{cdiInqAttTxt} gets the values(s) of a text attribute.
@EndFunction
*/
-int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
+int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp)
{
- return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, (size_t)mlen * sizeof (char), tp);
+ return cdi_inq_att(CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)mlen * sizeof(char), tp);
}
enum {
- vlist_att_nints = 4, /* namesz, exdtype, indtype, nelems */
+ cdi_att_nints = 4, /* namesz, exdtype, indtype, nelems */
};
-static inline int
-vlistAttTypeLookup(cdi_att_t *attp)
+static inline
+int cdiAttTypeLookup(cdi_att_t *attp)
{
int type;
switch (attp->indtype)
{
- case DATATYPE_FLT:
- type = DATATYPE_FLT64;
+ case CDI_DATATYPE_FLT:
+ type = CDI_DATATYPE_FLT64;
break;
- case DATATYPE_INT:
- case DATATYPE_TXT:
+ case CDI_DATATYPE_INT:
+ case CDI_DATATYPE_TXT:
type = attp->indtype;
break;
default:
@@ -65880,8 +65757,7 @@ vlistAttTypeLookup(cdi_att_t *attp)
}
-int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB,
- int attnum)
+int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum)
{
cdi_atts_t *attspa = get_attsp(a, varIDA),
*attspb = get_attsp(b, varIDB);
@@ -65905,8 +65781,8 @@ int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB,
}
-static int
-vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
+static
+int cdiAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
{
cdi_atts_t *attsp;
cdi_att_t *attp;
@@ -65914,30 +65790,31 @@ vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
xassert(attsp = get_attsp(vlistptr, varID));
xassert(attnum >= 0 && attnum < (int)attsp->nelems);
attp = &(attsp->value[attnum]);
- int txsize = serializeGetSize(vlist_att_nints, DATATYPE_INT, context)
- + serializeGetSize((int)attp->namesz, DATATYPE_TXT, context);
- txsize += serializeGetSize((int)attp->nelems, vlistAttTypeLookup(attp), context);
+ int txsize = serializeGetSize(cdi_att_nints, CDI_DATATYPE_INT, context)
+ + serializeGetSize((int)attp->namesz, CDI_DATATYPE_TXT, context);
+ txsize += serializeGetSize((int)attp->nelems, cdiAttTypeLookup(attp), context);
return txsize;
}
-int
-vlistAttsGetSize(vlist_t *p, int varID, void *context)
+
+int cdiAttsGetSize(void *vp, int varID, void *context)
{
+ vlist_t *p = (vlist_t*) vp;
cdi_atts_t *attsp = get_attsp(p, varID);
- int txsize = serializeGetSize(1, DATATYPE_INT, context);
+ int txsize = serializeGetSize(1, CDI_DATATYPE_INT, context);
size_t numAtts = attsp->nelems;
for (size_t i = 0; i < numAtts; ++i)
- txsize += vlistAttGetSize(p, varID, (int)i, context);
+ txsize += cdiAttGetSize(p, varID, (int)i, context);
return txsize;
}
-static void
-vlistAttPack(vlist_t *vlistptr, int varID, int attnum,
- void * buf, int size, int *position, void *context)
+static
+void cdiAttPack(vlist_t *vlistptr, int varID, int attnum,
+ void *buf, int size, int *position, void *context)
{
cdi_atts_t *attsp;
cdi_att_t *attp;
- int tempbuf[vlist_att_nints];
+ int tempbuf[cdi_att_nints];
xassert(attsp = get_attsp(vlistptr, varID));
xassert(attnum >= 0 && attnum < (int)attsp->nelems);
@@ -65946,50 +65823,49 @@ vlistAttPack(vlist_t *vlistptr, int varID, int attnum,
tempbuf[1] = attp->exdtype;
tempbuf[2] = attp->indtype;
tempbuf[3] = (int)attp->nelems;
- serializePack(tempbuf, vlist_att_nints, DATATYPE_INT, buf, size, position, context);
- serializePack(attp->name, (int)attp->namesz, DATATYPE_TXT, buf, size, position, context);
- serializePack(attp->xvalue, (int)attp->nelems, vlistAttTypeLookup(attp),
+ serializePack(tempbuf, cdi_att_nints, CDI_DATATYPE_INT, buf, size, position, context);
+ serializePack(attp->name, (int)attp->namesz, CDI_DATATYPE_TXT, buf, size, position, context);
+ serializePack(attp->xvalue, (int)attp->nelems, cdiAttTypeLookup(attp),
buf, size, position, context);
}
-void
-vlistAttsPack(vlist_t *p, int varID,
- void * buf, int size, int *position, void *context)
+
+void cdiAttsPack(void *vp, int varID, void *buf, int size, int *position, void *context)
{
+ vlist_t *p = (vlist_t*) vp;
cdi_atts_t *attsp = get_attsp(p, varID);
size_t numAtts = attsp->nelems;
int numAttsI = (int)numAtts;
xassert(numAtts <= INT_MAX);
- serializePack(&numAttsI, 1, DATATYPE_INT, buf, size, position, context);
+ serializePack(&numAttsI, 1, CDI_DATATYPE_INT, buf, size, position, context);
for (size_t i = 0; i < numAtts; ++i)
- vlistAttPack(p, varID, (int)i, buf, size, position, context);
+ cdiAttPack(p, varID, (int)i, buf, size, position, context);
}
-static void
-vlistAttUnpack(int vlistID, int varID,
- void * buf, int size, int *position, void *context)
+static
+void cdiAttUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
{
- int tempbuf[vlist_att_nints];
+ int tempbuf[cdi_att_nints];
serializeUnpack(buf, size, position,
- tempbuf, vlist_att_nints, DATATYPE_INT, context);
+ tempbuf, cdi_att_nints, CDI_DATATYPE_INT, context);
char *attName = (char *) Malloc((size_t)tempbuf[0] + 1);
- serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
+ serializeUnpack(buf, size, position, attName, tempbuf[0], CDI_DATATYPE_TXT, context);
attName[tempbuf[0]] = '\0';
int attVDt;
size_t elemSize;
switch (tempbuf[2])
{
- case DATATYPE_FLT:
- attVDt = DATATYPE_FLT64;
+ case CDI_DATATYPE_FLT:
+ attVDt = CDI_DATATYPE_FLT64;
elemSize = sizeof(double);
break;
- case DATATYPE_INT:
- attVDt = DATATYPE_INT;
+ case CDI_DATATYPE_INT:
+ attVDt = CDI_DATATYPE_INT;
elemSize = sizeof(int);
break;
- case DATATYPE_TXT:
- attVDt = DATATYPE_TXT;
+ case CDI_DATATYPE_TXT:
+ attVDt = CDI_DATATYPE_TXT;
elemSize = 1;
break;
default:
@@ -65998,22 +65874,19 @@ vlistAttUnpack(int vlistID, int varID,
}
void *attData = (void *) Malloc(elemSize * (size_t)tempbuf[3]);
serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
- vlist_def_att(tempbuf[2], tempbuf[1], vlistID, varID, attName,
- (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
+ cdi_def_att(tempbuf[2], tempbuf[1], cdiID, varID, attName,
+ (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
Free(attName);
Free(attData);
}
-void
-vlistAttsUnpack(int vlistID, int varID,
- void * buf, int size, int *position, void *context)
+
+void cdiAttsUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
{
- int numAtts, i;
- serializeUnpack(buf, size, position, &numAtts, 1, DATATYPE_INT, context);
- for (i = 0; i < numAtts; ++i)
- {
- vlistAttUnpack(vlistID, varID, buf, size, position, context);
- }
+ int numAtts;
+ serializeUnpack(buf, size, position, &numAtts, 1, CDI_DATATYPE_INT, context);
+ for ( int i = 0; i < numAtts; ++i )
+ cdiAttUnpack(cdiID, varID, buf, size, position, context);
}
/*
@@ -66028,11 +65901,9 @@ vlistAttsUnpack(int vlistID, int varID,
#if defined (HAVE_CONFIG_H)
#endif
-#include <limits.h>
-
#if defined (HAVE_LIBGRIB_API)
-# include <grib_api.h>
+#include <grib_api.h>
#endif
@@ -66046,6 +65917,7 @@ void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].flag = 0;
vlistptr->vars[varID].param = 0;
vlistptr->vars[varID].datatype = CDI_UNDEFID;
+ vlistptr->vars[varID].timetype = CDI_UNDEFID;
vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
vlistptr->vars[varID].timave = 0;
vlistptr->vars[varID].timaccu = 0;
@@ -66059,7 +65931,7 @@ void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].instID = CDI_UNDEFID;
vlistptr->vars[varID].modelID = CDI_UNDEFID;
vlistptr->vars[varID].tableID = CDI_UNDEFID;
- vlistptr->vars[varID].missvalused = FALSE;
+ vlistptr->vars[varID].missvalused = false;
vlistptr->vars[varID].missval = cdiDefaultMissval;
vlistptr->vars[varID].addoffset = 0.0;
vlistptr->vars[varID].scalefactor = 1.0;
@@ -66069,11 +65941,11 @@ void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].units = NULL;
vlistptr->vars[varID].extra = NULL;
vlistptr->vars[varID].levinfo = NULL;
- vlistptr->vars[varID].comptype = COMPRESS_NONE;
+ vlistptr->vars[varID].comptype = CDI_COMPRESS_NONE;
vlistptr->vars[varID].complevel = 1;
vlistptr->vars[varID].atts.nalloc = MAX_ATTRIBUTES;
vlistptr->vars[varID].atts.nelems = 0;
- vlistptr->vars[varID].lvalidrange = 0;
+ vlistptr->vars[varID].lvalidrange = false;
vlistptr->vars[varID].validrange[0] = VALIDMISS;
vlistptr->vars[varID].validrange[1] = VALIDMISS;
vlistptr->vars[varID].ensdata = NULL;
@@ -66083,18 +65955,13 @@ void vlistvarInitEntry(int vlistID, int varID)
vlistptr->vars[varID].opt_grib_nentries = 0;
}
-
-
static
int vlistvarNewEntry(int vlistID)
{
int varID = 0;
- int vlistvarSize;
- var_t *vlistvar;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- vlistvarSize = vlistptr->varsAllocated;
- vlistvar = vlistptr->vars;
+ int vlistvarSize = vlistptr->varsAllocated;
+ var_t *vlistvar = vlistptr->vars;
/*
Look for a free slot in vlistvar.
(Create the table the first time through).
@@ -66103,8 +65970,8 @@ int vlistvarNewEntry(int vlistID)
{
vlistvarSize = 2;
vlistvar = (var_t *) Malloc((size_t)vlistvarSize * sizeof (var_t));
- for (int i = 0; i < vlistvarSize; i++ )
- vlistvar[i].isUsed = FALSE;
+ for ( int i = 0; i < vlistvarSize; i++ )
+ vlistvar[i].isUsed = false;
}
else
{
@@ -66119,7 +65986,7 @@ int vlistvarNewEntry(int vlistID)
vlistvar = (var_t *) Realloc(vlistvar,
(size_t)(vlistvarSize *= 2) * sizeof(var_t));
for ( int i = varID; i < vlistvarSize; i++ )
- vlistvar[i].isUsed = FALSE;
+ vlistvar[i].isUsed = false;
}
vlistptr->varsAllocated = vlistvarSize;
@@ -66127,9 +65994,9 @@ int vlistvarNewEntry(int vlistID)
vlistvarInitEntry(vlistID, varID);
- vlistptr->vars[varID].isUsed = TRUE;
+ vlistptr->vars[varID].isUsed = true;
- return (varID);
+ return varID;
}
void vlistCheckVarID(const char *caller, int vlistID, int varID)
@@ -66147,24 +66014,24 @@ void vlistCheckVarID(const char *caller, int vlistID, int varID)
}
-int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int tilesetID)
+int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tilesetID)
{
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
if ( CDI_Debug )
- Message("gridID = %d zaxisID = %d tsteptype = %d", gridID, zaxisID, tsteptype);
+ Message("gridID = %d zaxisID = %d timetype = %d", gridID, zaxisID, timetype);
int varID = vlistvarNewEntry(vlistID);
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
vlistptr->nvars++;
vlistptr->vars[varID].gridID = gridID;
vlistptr->vars[varID].zaxisID = zaxisID;
- vlistptr->vars[varID].tsteptype = tsteptype;
+ vlistptr->vars[varID].timetype = timetype;
vlistptr->vars[varID].subtypeID = tilesetID;
- if ( tsteptype < 0 )
+ if ( timetype < 0 )
{
- Message("Unexpected tstep type %d, set to TSTEP_INSTANT!", tsteptype);
- vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
+ Message("Unexpected time type %d, set to TIME_VARYING!", timetype);
+ vlistptr->vars[varID].timetype = TIME_VARYING;
}
vlistAdd2GridIDs(vlistptr, gridID);
@@ -66173,21 +66040,21 @@ int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int ti
vlistptr->vars[varID].param = cdiEncodeParam(-(varID + 1), 255, 255);
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
- return (varID);
+
+ return varID;
}
/*
@Function vlistDefVar
@Title Define a Variable
- at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+ at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
@Parameter
@Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
@Item gridID Grid ID, from a previous call to @fref{gridCreate}.
@Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
- @Item tsteptype One of the set of predefined CDI timestep types.
- The valid CDI timestep types are @func{TSTEP_CONSTANT}, @func{TSTEP_INSTANT},
- @func{TSTEP_ACCUM}, @func{TSTEP_AVG}, @func{TSTEP_MAX}, @func{TSTEP_MIN} and @func{TSTEP_SD}.
+ @Item timetype One of the set of predefined CDI timestep types.
+ The valid CDI timestep types are @func{TIME_CONSTANT} and @func{TIME_VARYING}.
@Description
The function @func{vlistDefVar} adds a new variable to vlistID.
@@ -66204,7 +66071,7 @@ and add a variable with @func{vlistDefVar}.
int vlistID, varID;
...
vlistID = vlistCreate();
-varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_INSTANT);
+varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
...
streamDefVlist(streamID, vlistID);
...
@@ -66213,10 +66080,10 @@ vlistDestroy(vlistID);
@EndSource
@EndFunction
*/
-int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
{
/* call "vlistDefVarTiles" with a trivial tile index: */
- return vlistDefVarTiles(vlistID, gridID, zaxisID, tsteptype, CDI_UNDEFID);
+ return vlistDefVarTiles(vlistID, gridID, zaxisID, timetype, CDI_UNDEFID);
}
void
@@ -66295,15 +66162,15 @@ void vlistDefVarCode(int vlistID, int varID, int code)
}
-void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype)
+void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *timetype)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
vlistCheckVarID(__func__, vlistID, varID);
- *gridID = vlistptr->vars[varID].gridID;
- *zaxisID = vlistptr->vars[varID].zaxisID;
- *tsteptype = vlistptr->vars[varID].tsteptype;
+ *gridID = vlistptr->vars[varID].gridID;
+ *zaxisID = vlistptr->vars[varID].zaxisID;
+ *timetype = vlistptr->vars[varID].timetype;
return;
}
@@ -66331,7 +66198,7 @@ int vlistInqVarGrid(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].gridID);
+ return vlistptr->vars[varID].gridID;
}
/*
@@ -66357,7 +66224,7 @@ int vlistInqVarZaxis(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].zaxisID);
+ return vlistptr->vars[varID].zaxisID;
}
@@ -66378,7 +66245,8 @@ int vlistInqVarSubtype(int vlistID, int varID)
vlist_t *vlistptr = vlist_to_pointer(vlistID);
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].subtypeID);
+
+ return vlistptr->vars[varID].subtypeID;
}
@@ -66405,7 +66273,7 @@ int vlistInqVarParam(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].param);
+ return vlistptr->vars[varID].param;
}
/*
@@ -66442,7 +66310,7 @@ int vlistInqVarCode(int vlistID, int varID)
tableInqParCode(vlistptr->vars[varID].tableID, vlistptr->vars[varID].name, &code);
}
- return (code);
+ return code;
}
@@ -66452,37 +66320,7 @@ const char *vlistInqVarNamePtr(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].name);
-}
-
-
-const char *vlistInqVarLongnamePtr(int vlistID, int varID)
-{
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- vlistCheckVarID(__func__, vlistID, varID);
-
- return (vlistptr->vars[varID].longname);
-}
-
-
-const char *vlistInqVarStdnamePtr(int vlistID, int varID)
-{
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- vlistCheckVarID(__func__, vlistID, varID);
-
- return (vlistptr->vars[varID].stdname);
-}
-
-
-const char *vlistInqVarUnitsPtr(int vlistID, int varID)
-{
- vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- vlistCheckVarID(__func__, vlistID, varID);
-
- return (vlistptr->vars[varID].units);
+ return vlistptr->vars[varID].name;
}
/*
@@ -66521,8 +66359,9 @@ void vlistInqVarName(int vlistID, int varID, char *name)
{
int code = pnum;
int tableID = vlistptr->vars[varID].tableID;
- if ( tableInqParName(tableID, code, name) != 0 )
- sprintf(name, "var%d", code);
+ name[0] = 0;
+ tableInqEntry(tableID, code, -1, name, NULL, NULL);
+ if ( !name[0] ) sprintf(name, "var%d", code);
}
else
{
@@ -66558,24 +66397,29 @@ char* vlistCopyVarName(int vlistId, int varId)
vlistCheckVarID(__func__, vlistId, varId);
//If a name is set in the variable description, use that.
- const char* name = vlistptr->vars[varId].name;
- if(name) return strdup(name);
+ {
+ const char* name = vlistptr->vars[varId].name;
+ if (name) return strdup(name);
+ }
//Otherwise we check if we should use the table of parameter descriptions.
int param = vlistptr->vars[varId].param;
int discipline, category, number;
cdiDecodeParam(param, &number, &category, &discipline);
char *result = NULL;
- if(discipline == 255)
+ if (discipline == 255)
{
int tableId = vlistptr->vars[varId].tableID;
- if(( name = tableInqParNamePtr(tableId, number) ))
+ char name[CDI_MAX_NAME]; name[0] = 0;
+ tableInqEntry(tableId, number, -1, name, NULL, NULL);
+ if ( name[0] )
result = strdup(name);
- {
- //No luck, fall back to outputting a name of the format "var<num>".
- result = (char *) Malloc(3 + 3 * sizeof (int) * CHAR_BIT / 8 + 2);
- sprintf(result, "var%d", number);
- }
+ else
+ {
+ //No luck, fall back to outputting a name of the format "var<num>".
+ result = (char *) Malloc(3 + 3 * sizeof (int) * CHAR_BIT / 8 + 2);
+ sprintf(result, "var%d", number);
+ }
}
else
{
@@ -66624,8 +66468,7 @@ void vlistInqVarLongname(int vlistID, int varID, char *longname)
{
int code = pnum;
int tableID = vlistptr->vars[varID].tableID;
- if ( tableInqParLongname(tableID, code, longname) != 0 )
- longname[0] = '\0';
+ tableInqEntry(tableID, code, -1, NULL, longname, NULL);
}
}
else
@@ -66709,8 +66552,7 @@ void vlistInqVarUnits(int vlistID, int varID, char *units)
{
int code = pnum;
int tableID = vlistptr->vars[varID].tableID;
- if ( tableInqParUnits(tableID, code, units) != 0 )
- units[0] = '\0';
+ tableInqEntry(tableID, code, -1, NULL, NULL, units);
}
}
else
@@ -66729,28 +66571,27 @@ int vlistInqVarID(int vlistID, int code)
int param = vlistptr->vars[varID].param;
int pdis, pcat, pnum;
cdiDecodeParam(param, &pnum, &pcat, &pdis);
- if ( pnum == code ) return (varID);
+ if ( pnum == code ) return varID;
}
- return (CDI_UNDEFID);
+ return CDI_UNDEFID;
}
-int vlistInqVarSize(int vlistID, int varID)
+size_t vlistInqVarSize(int vlistID, int varID)
{
vlistCheckVarID(__func__, vlistID, varID);
- int zaxisID, gridID;
- int tsteptype;
- vlistInqVar(vlistID, varID, &gridID, &zaxisID, &tsteptype);
+ int zaxisID, gridID, timetype;
+ vlistInqVar(vlistID, varID, &gridID, &zaxisID, &timetype);
- int nlevs = zaxisInqSize(zaxisID);
+ size_t nlevs = (size_t)zaxisInqSize(zaxisID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
- int size = gridsize*nlevs;
+ size_t size = gridsize*nlevs;
- return (size);
+ return size;
}
/*
@@ -66767,9 +66608,9 @@ The function @func{vlistInqVarDatatype} returns the data type of a variable.
@Result
@func{vlistInqVarDatatype} returns an identifier to the data type of the variable.
-The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16}, @func{DATATYPE_PACK24},
- at func{DATATYPE_FLT32}, @func{DATATYPE_FLT64}, @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and
- at func{DATATYPE_INT32}.
+The valid CDI data types are @func{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16}, @func{CDI_DATATYPE_PACK24},
+ at func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64}, @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and
+ at func{CDI_DATATYPE_INT32}.
@EndFunction
*/
@@ -66779,7 +66620,7 @@ int vlistInqVarDatatype(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].datatype);
+ return vlistptr->vars[varID].datatype;
}
@@ -66790,11 +66631,11 @@ int vlistInqVarNumber(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
int number = CDI_REAL;
- if ( vlistptr->vars[varID].datatype == DATATYPE_CPX32 ||
- vlistptr->vars[varID].datatype == DATATYPE_CPX64 )
+ if ( vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX32 ||
+ vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX64 )
number = CDI_COMP;
- return (number);
+ return number;
}
/*
@@ -66806,9 +66647,9 @@ int vlistInqVarNumber(int vlistID, int varID)
@Item vlistID Variable list ID, from a previous call to @fref{vlistCreate}.
@Item varID Variable identifier.
@Item datatype The data type identifier.
- The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16},
- @func{DATATYPE_PACK24}, @func{DATATYPE_FLT32}, @func{DATATYPE_FLT64},
- @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and @func{DATATYPE_INT32}.
+ The valid CDI data types are @func{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16},
+ @func{CDI_DATATYPE_PACK24}, @func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64},
+ @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and @func{CDI_DATATYPE_INT32}.
@Description
The function @func{vlistDefVarDatatype} defines the data type of a variable.
@@ -66825,15 +66666,15 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
{
vlistptr->vars[varID].datatype = datatype;
- if ( vlistptr->vars[varID].missvalused == FALSE )
+ if ( !vlistptr->vars[varID].missvalused )
switch (datatype)
{
- case DATATYPE_INT8: vlistptr->vars[varID].missval = -SCHAR_MAX; break;
- case DATATYPE_UINT8: vlistptr->vars[varID].missval = UCHAR_MAX; break;
- case DATATYPE_INT16: vlistptr->vars[varID].missval = -SHRT_MAX; break;
- case DATATYPE_UINT16: vlistptr->vars[varID].missval = USHRT_MAX; break;
- case DATATYPE_INT32: vlistptr->vars[varID].missval = -INT_MAX; break;
- case DATATYPE_UINT32: vlistptr->vars[varID].missval = UINT_MAX; break;
+ case CDI_DATATYPE_INT8: vlistptr->vars[varID].missval = -SCHAR_MAX; break;
+ case CDI_DATATYPE_UINT8: vlistptr->vars[varID].missval = UCHAR_MAX; break;
+ case CDI_DATATYPE_INT16: vlistptr->vars[varID].missval = -SHRT_MAX; break;
+ case CDI_DATATYPE_UINT16: vlistptr->vars[varID].missval = USHRT_MAX; break;
+ case CDI_DATATYPE_INT32: vlistptr->vars[varID].missval = -INT_MAX; break;
+ case CDI_DATATYPE_UINT32: vlistptr->vars[varID].missval = UINT_MAX; break;
}
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
}
@@ -66854,7 +66695,7 @@ void vlistDefVarInstitut(int vlistID, int varID, int instID)
int vlistInqVarInstitut(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].instID);
+ return vlistptr->vars[varID].instID;
}
@@ -66872,7 +66713,7 @@ void vlistDefVarModel(int vlistID, int varID, int modelID)
int vlistInqVarModel(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].modelID);
+ return vlistptr->vars[varID].modelID;
}
@@ -66898,7 +66739,7 @@ void vlistDefVarTable(int vlistID, int varID, int tableID)
int vlistInqVarTable(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].tableID);
+ return vlistptr->vars[varID].tableID;
}
/*
@@ -67060,7 +66901,7 @@ double vlistInqVarMissval(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].missval);
+ return vlistptr->vars[varID].missval;
}
/*
@@ -67085,7 +66926,7 @@ void vlistDefVarMissval(int vlistID, int varID, double missval)
vlistCheckVarID(__func__, vlistID, varID);
vlistptr->vars[varID].missval = missval;
- vlistptr->vars[varID].missvalused = TRUE;
+ vlistptr->vars[varID].missvalused = true;
}
/*
@@ -67170,7 +67011,7 @@ int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
validrange[1] = vlistptr->vars[varID].validrange[1];
}
- return (vlistptr->vars[varID].lvalidrange);
+ return (int)vlistptr->vars[varID].lvalidrange;
}
@@ -67182,7 +67023,7 @@ void vlistDefVarValidrange(int vlistID, int varID, const double *validrange)
vlistptr->vars[varID].validrange[0] = validrange[0];
vlistptr->vars[varID].validrange[1] = validrange[1];
- vlistptr->vars[varID].lvalidrange = TRUE;
+ vlistptr->vars[varID].lvalidrange = true;
reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
}
@@ -67193,7 +67034,7 @@ double vlistInqVarScalefactor(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].scalefactor);
+ return vlistptr->vars[varID].scalefactor;
}
@@ -67203,7 +67044,7 @@ double vlistInqVarAddoffset(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].addoffset);
+ return vlistptr->vars[varID].addoffset;
}
@@ -67235,6 +67076,24 @@ void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
}
+void vlistDefVarTimetype(int vlistID, int varID, int timetype)
+{
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
+ if (vlistptr->vars[varID].timetype != timetype)
+ {
+ vlistptr->vars[varID].timetype = timetype;
+ reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+ }
+}
+
+
+int vlistInqVarTimetype(int vlistID, int varID)
+{
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
+ return vlistptr->vars[varID].timetype;
+}
+
+
void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
@@ -67260,7 +67119,7 @@ The function @func{vlistInqVarTsteptype} returns the timestep type of a Variable
@Result
@func{vlistInqVarTsteptype} returns the timestep type of the Variable,
one of the set of predefined CDI timestep types.
-The valid CDI timestep types are @func{TSTEP_CONSTANT}, @func{TSTEP_INSTANT},
+The valid CDI timestep types are @func{TSTEP_INSTANT},
@func{TSTEP_ACCUM}, @func{TSTEP_AVG}, @func{TSTEP_MAX}, @func{TSTEP_MIN} and @func{TSTEP_SD}.
@EndFunction
@@ -67268,7 +67127,7 @@ The valid CDI timestep types are @func{TSTEP_CONSTANT}, @func{TSTEP_INSTANT},
int vlistInqVarTsteptype(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].tsteptype);
+ return vlistptr->vars[varID].tsteptype;
}
@@ -67286,7 +67145,7 @@ void vlistDefVarTimave(int vlistID, int varID, int timave)
int vlistInqVarTimave(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].timave);
+ return vlistptr->vars[varID].timave;
}
@@ -67304,7 +67163,7 @@ void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
int vlistInqVarTimaccu(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].timaccu);
+ return vlistptr->vars[varID].timaccu;
}
@@ -67322,7 +67181,7 @@ void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGenera
int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].typeOfGeneratingProcess);
+ return vlistptr->vars[varID].typeOfGeneratingProcess;
}
@@ -67341,8 +67200,7 @@ void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDef
int vlistInqVarProductDefinitionTemplate(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
- return (vlistptr->vars[varID].productDefinitionTemplate);
+ return vlistptr->vars[varID].productDefinitionTemplate;
}
@@ -67400,7 +67258,7 @@ void vlistDestroyVarUnits(int vlistID, int varID)
int vlistInqVarMissvalUsed(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].missvalused);
+ return (int)vlistptr->vars[varID].missvalused;
}
@@ -67439,7 +67297,7 @@ int vlistInqFlag(int vlistID, int varID, int levID)
vlist_t *vlistptr = vlist_to_pointer(vlistID);
if (vlistptr->vars[varID].levinfo)
- return (vlistptr->vars[varID].levinfo[levID].flag);
+ return vlistptr->vars[varID].levinfo[levID].flag;
else
{
levinfo_t li = DEFAULT_LEVINFO(levID);
@@ -67464,7 +67322,7 @@ int vlistFindVar(int vlistID, int fvarID)
Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
}
- return (varID);
+ return varID;
}
@@ -67491,14 +67349,14 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
}
}
- return (levelID);
+ return levelID;
}
int vlistMergedVar(int vlistID, int varID)
{
vlist_t *vlistptr = vlist_to_pointer(vlistID);
- return (vlistptr->vars[varID].mvarID);
+ return vlistptr->vars[varID].mvarID;
}
@@ -67537,7 +67395,7 @@ int vlistInqIndex(int vlistID, int varID, int levelID)
vlist_t *vlistptr = vlist_to_pointer(vlistID);
if (vlistptr->vars[varID].levinfo)
- return (vlistptr->vars[varID].levinfo[levelID].index);
+ return vlistptr->vars[varID].levinfo[levelID].index;
else
{
levinfo_t li = DEFAULT_LEVINFO(levelID);
@@ -67626,7 +67484,7 @@ int vlistInqVarCompType(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].comptype);
+ return vlistptr->vars[varID].comptype;
}
@@ -67650,7 +67508,7 @@ int vlistInqVarCompLevel(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].complevel);
+ return vlistptr->vars[varID].complevel;
}
@@ -67674,7 +67532,7 @@ int vlistInqVarChunkType(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].chunktype);
+ return vlistptr->vars[varID].chunktype;
}
static
@@ -67735,9 +67593,7 @@ void vlistDefVarXYZ(int vlistID, int varID, int xyz)
void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3])
{
- vlist_t *vlistptr;
-
- vlistptr = vlist_to_pointer(vlistID);
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
vlistCheckVarID(__func__, vlistID, varID);
@@ -67751,7 +67607,7 @@ int vlistInqVarXYZ(int vlistID, int varID)
vlistCheckVarID(__func__, vlistID, varID);
- return (vlistptr->vars[varID].xyz);
+ return vlistptr->vars[varID].xyz;
}
/* Ensemble Info Routines */
@@ -67788,7 +67644,7 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
status = 1;
}
- return (status);
+ return status;
}
@@ -67813,7 +67669,7 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
if ( idx < vlistptr->vars[varID].opt_grib_nentries )
{
vlistptr->vars[varID].opt_grib_kvpair[idx].int_val = value;
- vlistptr->vars[varID].opt_grib_kvpair[idx].update = TRUE;
+ vlistptr->vars[varID].opt_grib_kvpair[idx].update = true;
}
else
{
@@ -67822,7 +67678,7 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
idx = vlistptr->vars[varID].opt_grib_nentries -1;
vlistptr->vars[varID].opt_grib_kvpair[idx].data_type = t_int;
vlistptr->vars[varID].opt_grib_kvpair[idx].int_val = value;
- vlistptr->vars[varID].opt_grib_kvpair[idx].update = TRUE;
+ vlistptr->vars[varID].opt_grib_kvpair[idx].update = true;
if ( name )
vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = strdupx(name);
else
@@ -67876,7 +67732,7 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
if ( idx < vlistptr->vars[varID].opt_grib_nentries )
{
vlistptr->vars[varID].opt_grib_kvpair[idx].dbl_val = value;
- vlistptr->vars[varID].opt_grib_kvpair[idx].update = TRUE;
+ vlistptr->vars[varID].opt_grib_kvpair[idx].update = true;
}
else
{
@@ -67885,7 +67741,7 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
idx = vlistptr->vars[varID].opt_grib_nentries - 1;
vlistptr->vars[varID].opt_grib_kvpair[idx].data_type = t_double;
vlistptr->vars[varID].opt_grib_kvpair[idx].dbl_val = value;
- vlistptr->vars[varID].opt_grib_kvpair[idx].update = TRUE;
+ vlistptr->vars[varID].opt_grib_kvpair[idx].update = true;
if ( name )
vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = strdupx(name);
else
@@ -68018,7 +67874,7 @@ int vlistInqVarIntKey(int vlistID, int varID, const char* name)
void vlistDefVarIOrank(int vlistID, int varID, int iorank)
{
- vlist_t *vlistptr = vlist_to_pointer(vlistID );
+ vlist_t *vlistptr = vlist_to_pointer(vlistID);
vlistCheckVarID ( __func__, vlistID, varID );
@@ -68052,7 +67908,7 @@ int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
#define FCMP2(f) (namespaceResHDecode(pva->f).idx \
!= namespaceResHDecode(pvb->f).idx)
int diff = FCMP(fvarID) | FCMP(mvarID) | FCMP(flag) | FCMP(param)
- | FCMP(datatype) | FCMP(tsteptype) | FCMP(timave) | FCMP(timaccu)
+ | FCMP(datatype) | FCMP(timetype) | FCMP(tsteptype) | FCMP(timave) | FCMP(timaccu)
| FCMP(chunktype) | FCMP(xyz) | FCMP2(gridID) | FCMP2(zaxisID)
| FCMP2(instID) | FCMP2(modelID) | FCMP2(tableID) | FCMP(missvalused)
| FCMPFLT(missval) | FCMPFLT(addoffset) | FCMPFLT(scalefactor) | FCMPSTR(name)
@@ -68078,7 +67934,7 @@ int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
if (natts != b->vars[varIDB].atts.nelems)
return 1;
for (size_t attID = 0; attID < natts; ++attID)
- diff |= vlist_att_compare(a, varIDA, b, varIDB, (int)attID);
+ diff |= cdi_att_compare(a, varIDA, b, varIDB, (int)attID);
if ((diff |= ((pva->ensdata == NULL) ^ (pvb->ensdata == NULL))))
return 1;
if (pva->ensdata)
@@ -68096,21 +67952,21 @@ enum {
int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
{
var_t *var = p->vars + varID;
- int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
- + serializeGetSize(vlistvar_ndbls, DATATYPE_FLT64, context);
+ int varsize = serializeGetSize(vlistvar_nints, CDI_DATATYPE_INT, context)
+ + serializeGetSize(vlistvar_ndbls, CDI_DATATYPE_FLT64, context);
if (var->name)
- varsize += serializeGetSize((int)strlen(var->name), DATATYPE_TXT, context);
+ varsize += serializeGetSize((int)strlen(var->name), CDI_DATATYPE_TXT, context);
if (var->longname)
- varsize += serializeGetSize((int)strlen(var->longname), DATATYPE_TXT, context);
+ varsize += serializeGetSize((int)strlen(var->longname), CDI_DATATYPE_TXT, context);
if (var->stdname)
- varsize += serializeGetSize((int)strlen(var->stdname), DATATYPE_TXT, context);
+ varsize += serializeGetSize((int)strlen(var->stdname), CDI_DATATYPE_TXT, context);
if (var->units)
- varsize += serializeGetSize((int)strlen(var->units), DATATYPE_TXT, context);
+ varsize += serializeGetSize((int)strlen(var->units), CDI_DATATYPE_TXT, context);
if (var->extra)
- varsize += serializeGetSize((int)strlen(var->extra), DATATYPE_TXT, context);
+ varsize += serializeGetSize((int)strlen(var->extra), CDI_DATATYPE_TXT, context);
varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
- DATATYPE_INT, context);
- varsize += vlistAttsGetSize(p, varID, context);
+ CDI_DATATYPE_INT, context);
+ varsize += cdiAttsGetSize(p, varID, context);
return varsize;
}
@@ -68125,7 +67981,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
tempbuf[0] = var->flag;
tempbuf[1] = var->gridID;
tempbuf[2] = var->zaxisID;
- tempbuf[3] = var->tsteptype;
+ tempbuf[3] = var->timetype;
tempbuf[4] = namesz = var->name?(int)strlen(var->name):0;
tempbuf[5] = longnamesz = var->longname?(int)strlen(var->longname):0;
tempbuf[6] = stdnamesz = var->stdname?(int)strlen(var->stdname):0;
@@ -68137,7 +67993,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
tempbuf[12] = var->tableID;
tempbuf[13] = var->timave;
tempbuf[14] = var->timaccu;
- tempbuf[15] = var->missvalused;
+ tempbuf[15] = (int)var->missvalused;
tempbuf[16] = var->comptype;
tempbuf[17] = var->complevel;
int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
@@ -68147,23 +68003,23 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
dtempbuf[0] = var->missval;
dtempbuf[1] = var->scalefactor;
dtempbuf[2] = var->addoffset;
- serializePack(tempbuf, vlistvar_nints, DATATYPE_INT,
+ serializePack(tempbuf, vlistvar_nints, CDI_DATATYPE_INT,
buf, size, position, context);
- serializePack(dtempbuf, vlistvar_ndbls, DATATYPE_FLT64,
+ serializePack(dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64,
buf, size, position, context);
if (namesz)
- serializePack(var->name, namesz, DATATYPE_TXT, buf, size, position, context);
+ serializePack(var->name, namesz, CDI_DATATYPE_TXT, buf, size, position, context);
if (longnamesz)
- serializePack(var->longname, longnamesz, DATATYPE_TXT,
+ serializePack(var->longname, longnamesz, CDI_DATATYPE_TXT,
buf, size, position, context);
if (stdnamesz)
- serializePack(var->stdname, stdnamesz, DATATYPE_TXT,
+ serializePack(var->stdname, stdnamesz, CDI_DATATYPE_TXT,
buf, size, position, context);
if (unitssz)
- serializePack(var->units, unitssz, DATATYPE_TXT,
+ serializePack(var->units, unitssz, CDI_DATATYPE_TXT,
buf, size, position, context);
if (extralen)
- serializePack(var->extra, extralen, DATATYPE_TXT,
+ serializePack(var->extra, extralen, CDI_DATATYPE_TXT,
buf, size, position, context);
if (nlevs)
{
@@ -68175,10 +68031,10 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
levbuf[levID][2] = var->levinfo[levID].mlevelID;
levbuf[levID][3] = var->levinfo[levID].flevelID;
}
- serializePack(levbuf, nlevs * 4, DATATYPE_INT,
+ serializePack(levbuf, nlevs * 4, CDI_DATATYPE_INT,
buf, size, position, context);
}
- vlistAttsPack(p, varID, buf, size, position, context);
+ cdiAttsPack(p, varID, buf, size, position, context);
}
static inline int
@@ -68196,9 +68052,9 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
char *varname = NULL;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
serializeUnpack(buf, size, position,
- tempbuf, vlistvar_nints, DATATYPE_INT, context);
+ tempbuf, vlistvar_nints, CDI_DATATYPE_INT, context);
serializeUnpack(buf, size, position,
- dtempbuf, vlistvar_ndbls, DATATYPE_FLT64, context);
+ dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64, context);
/* ------------------------------------------- */
/* NOTE: Tile sets currently not supported!!! */
@@ -68216,35 +68072,35 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
if (tempbuf[4])
{
serializeUnpack(buf, size, position,
- varname, tempbuf[4], DATATYPE_TXT, context);
+ varname, tempbuf[4], CDI_DATATYPE_TXT, context);
varname[tempbuf[4]] = '\0';
vlistDefVarName(vlistID, newvar, varname);
}
if (tempbuf[5])
{
serializeUnpack(buf, size, position,
- varname, tempbuf[5], DATATYPE_TXT, context);
+ varname, tempbuf[5], CDI_DATATYPE_TXT, context);
varname[tempbuf[5]] = '\0';
vlistDefVarLongname(vlistID, newvar, varname);
}
if (tempbuf[6])
{
serializeUnpack(buf, size, position,
- varname, tempbuf[6], DATATYPE_TXT, context);
+ varname, tempbuf[6], CDI_DATATYPE_TXT, context);
varname[tempbuf[6]] = '\0';
vlistDefVarStdname(vlistID, newvar, varname);
}
if (tempbuf[7])
{
serializeUnpack(buf, size, position,
- varname, tempbuf[7], DATATYPE_TXT, context);
+ varname, tempbuf[7], CDI_DATATYPE_TXT, context);
varname[tempbuf[7]] = '\0';
vlistDefVarUnits(vlistID, newvar, varname);
}
if (tempbuf[20])
{
serializeUnpack(buf, size, position,
- varname, tempbuf[20], DATATYPE_TXT, context);
+ varname, tempbuf[20], CDI_DATATYPE_TXT, context);
varname[tempbuf[20]] = '\0';
vlistDefVarExtra(vlistID, newvar, varname);
}
@@ -68273,7 +68129,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
int i, flagSetLev = 0;
cdiVlistCreateVarLevInfo(vlistptr, newvar);
serializeUnpack(buf, size, position,
- levbuf, nlevs * 4, DATATYPE_INT, context);
+ levbuf, nlevs * 4, CDI_DATATYPE_INT, context);
for (i = 0; i < nlevs; ++i)
{
vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
@@ -68287,7 +68143,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
}
vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
- vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
+ cdiAttsUnpack(vlistID, newvar, buf, size, position, context);
}
@@ -68322,10 +68178,10 @@ static const struct {
}
ZaxistypeEntry[] = {
{ /* 0 */ 0, "sfc", "surface", "", ""},
- { /* 1 */ 0, "lev", "generic", "", "level"},
+ { /* 1 */ 0, "lev", "generic", "", ""},
{ /* 2 */ 2, "lev", "hybrid", "", "level"},
{ /* 3 */ 2, "lev", "hybrid_half", "", "level"},
- { /* 4 */ 2, "lev", "pressure", "air_pressure", "Pa"},
+ { /* 4 */ 2, "plev", "pressure", "air_pressure", "Pa"},
{ /* 5 */ 1, "height", "height", "height", "m"},
{ /* 6 */ 2, "depth", "depth_below_sea", "depth", "m"},
{ /* 7 */ 2, "depth", "depth_below_land", "", "cm"},
@@ -68347,6 +68203,7 @@ ZaxistypeEntry[] = {
{ /* 23 */ 0, "sedimentbottomtw", "sediment_bottom_tw", "", ""},
{ /* 24 */ 0, "mixlayer", "mix_layer", "", ""},
{ /* 25 */ 0, "height", "generalized_height", "height", ""},
+ { /* 26 */ 0, "character", "area_type", "", ""},
};
enum {
@@ -68354,35 +68211,6 @@ enum {
};
-typedef struct {
- char dimname[CDI_MAX_NAME];
- char vdimname[CDI_MAX_NAME];
- char name[CDI_MAX_NAME];
- char longname[CDI_MAX_NAME];
- char stdname[CDI_MAX_NAME];
- char units[CDI_MAX_NAME];
- char psname[CDI_MAX_NAME];
- double *vals;
- double *lbounds;
- double *ubounds;
- double *weights;
- int self;
- int prec;
- int scalar;
- int type;
- int ltype; /* GRIB level type */
- int ltype2;
- int size;
- int direction;
- int vctsize;
- unsigned positive;
- double *vct;
- int number; /* Reference number to a generalized Z-axis */
- int nhlev;
- unsigned char uuid[CDI_UUID_SIZE];
-}
-zaxis_t;
-
static int zaxisCompareP (zaxis_t *z1, zaxis_t *z2);
static void zaxisDestroyP ( void * zaxisptr );
static void zaxisPrintP ( void * zaxisptr, FILE * fp );
@@ -68406,65 +68234,75 @@ const resOps *getZaxisOps(void)
static int ZAXIS_Debug = 0; /* If set to 1, debugging */
-void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit)
+void zaxisGetTypeDescription(int zaxisType, int *outPositive, const char **outName, const char **outLongName, const char **outStdName, const char **outUnit)
{
- if(zaxisType < 0 || zaxisType >= CDI_NumZaxistype)
+ if ( zaxisType < 0 || zaxisType >= CDI_NumZaxistype )
{
- if(outPositive) *outPositive = 0;
- if(outName) *outName = NULL;
- if(outLongName) *outLongName = NULL;
- if(outStdName) *outStdName = NULL;
- if(outUnit) *outUnit = NULL;
+ if (outPositive) *outPositive = 0;
+ if (outName) *outName = NULL;
+ if (outLongName) *outLongName = NULL;
+ if (outStdName) *outStdName = NULL;
+ if (outUnit) *outUnit = NULL;
}
else
{
- if(outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
- if(outName) *outName = ZaxistypeEntry[zaxisType].name;
- if(outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
- if(outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
- if(outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
+ if (outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
+ if (outName) *outName = ZaxistypeEntry[zaxisType].name;
+ if (outLongName && zaxisType != ZAXIS_GENERIC) *outLongName = ZaxistypeEntry[zaxisType].longname;
+ if (outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
+ if (outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
}
}
+
+zaxis_t *zaxis_to_pointer(int id)
+{
+ return (zaxis_t *)reshGetVal(id, &zaxisOps);
+}
+
static
-void zaxisDefaultValue(zaxis_t *zaxisptr)
-{
- zaxisptr->self = CDI_UNDEFID;
- zaxisptr->name[0] = 0;
- zaxisptr->longname[0] = 0;
- zaxisptr->stdname[0] = 0;
- zaxisptr->dimname[0] = 0;
- zaxisptr->vdimname[0] = 0;
- zaxisptr->units[0] = 0;
- zaxisptr->psname[0] = 0;
- zaxisptr->vals = NULL;
- zaxisptr->ubounds = NULL;
- zaxisptr->lbounds = NULL;
- zaxisptr->weights = NULL;
- zaxisptr->type = CDI_UNDEFID;
- zaxisptr->ltype = 0;
- zaxisptr->ltype2 = -1;
- zaxisptr->positive = 0;
- zaxisptr->scalar = 0;
- zaxisptr->direction = 0;
- zaxisptr->prec = 0;
- zaxisptr->size = 0;
- zaxisptr->vctsize = 0;
- zaxisptr->vct = NULL;
- zaxisptr->number = 0;
- zaxisptr->nhlev = 0;
+void zaxis_init(zaxis_t *zaxisptr)
+{
+ zaxisptr->self = CDI_UNDEFID;
+ zaxisptr->name[0] = 0;
+ zaxisptr->longname[0] = 0;
+ zaxisptr->stdname[0] = 0;
+ zaxisptr->dimname[0] = 0;
+ zaxisptr->vdimname[0] = 0;
+ zaxisptr->units[0] = 0;
+ zaxisptr->psname[0] = 0;
+ zaxisptr->p0name[0] = 0;
+ zaxisptr->p0value.defined = false;
+ zaxisptr->vals = NULL;
+ zaxisptr->cvals = NULL;
+ zaxisptr->clength = 0;
+ zaxisptr->ubounds = NULL;
+ zaxisptr->lbounds = NULL;
+ zaxisptr->weights = NULL;
+ zaxisptr->type = CDI_UNDEFID;
+ zaxisptr->ltype = 0;
+ zaxisptr->ltype2 = -1;
+ zaxisptr->positive = 0;
+ zaxisptr->scalar = 0;
+ zaxisptr->direction = 0;
+ zaxisptr->datatype = 0;
+ zaxisptr->size = 0;
+ zaxisptr->vctsize = 0;
+ zaxisptr->vct = NULL;
+ zaxisptr->number = 0;
+ zaxisptr->nhlev = 0;
memset(zaxisptr->uuid, 0, CDI_UUID_SIZE);
+ zaxisptr->atts.nalloc = MAX_ATTRIBUTES;
+ zaxisptr->atts.nelems = 0;
}
-
static
zaxis_t *zaxisNewEntry(int id)
{
zaxis_t *zaxisptr = (zaxis_t *) Malloc(sizeof(zaxis_t));
+ zaxis_init(zaxisptr);
- zaxisDefaultValue ( zaxisptr );
-
- if (id == CDI_UNDEFID)
+ if ( id == CDI_UNDEFID )
zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
else
{
@@ -68472,27 +68310,17 @@ zaxis_t *zaxisNewEntry(int id)
reshReplace(id, zaxisptr, &zaxisOps);
}
- return (zaxisptr);
+ return zaxisptr;
}
-static inline zaxis_t *
-zaxisID2Ptr(int id)
-{
- return (zaxis_t *)reshGetVal(id, &zaxisOps);
-}
-
-
static
void zaxisInit(void)
{
- static int zaxisInitialized = 0;
- char *env;
-
+ static bool zaxisInitialized = false;
if ( zaxisInitialized ) return;
+ zaxisInitialized = true;
- zaxisInitialized = 1;
-
- env = getenv("ZAXIS_DEBUG");
+ const char *env = getenv("ZAXIS_DEBUG");
if ( env ) ZAXIS_Debug = atoi(env);
}
@@ -68504,14 +68332,14 @@ void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
zaxisptr2->self = zaxisID2;
}
+
unsigned cdiZaxisCount(void)
{
return reshCountType(&zaxisOps);
}
-
-static int
-zaxisCreate_(int zaxistype, int size, int id)
+static
+int zaxisCreate_(int zaxistype, int size, int id)
{
zaxis_t *zaxisptr = zaxisNewEntry(id);
@@ -68524,7 +68352,7 @@ zaxisCreate_(int zaxistype, int size, int id)
int zaxisID = zaxisptr->self;
zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
- zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
+ if ( zaxistype != ZAXIS_GENERIC ) zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
if ( *ZaxistypeEntry[zaxistype].stdname )
@@ -68532,16 +68360,9 @@ zaxisCreate_(int zaxistype, int size, int id)
zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
- double *vals = zaxisptr->vals
- = (double *) Malloc((size_t)size * sizeof(double));
-
- for ( int ilev = 0; ilev < size; ilev++ )
- vals[ilev] = 0.0;
-
return zaxisID;
}
-
/*
@Function zaxisCreate
@Title Create a vertical Z-axis
@@ -68583,21 +68404,27 @@ zaxisDefLevels(zaxisID, levs);
*/
int zaxisCreate(int zaxistype, int size)
{
- if ( CDI_Debug )
- Message("zaxistype: %d size: %d ", zaxistype, size);
+ if ( CDI_Debug ) Message("zaxistype: %d size: %d ", zaxistype, size);
+
+ zaxisInit();
- zaxisInit ();
return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
}
-
-static void zaxisDestroyKernel( zaxis_t * zaxisptr )
+static
+void zaxisDestroyKernel( zaxis_t * zaxisptr )
{
xassert ( zaxisptr );
int id = zaxisptr->self;
if ( zaxisptr->vals ) Free( zaxisptr->vals );
+ if ( zaxisptr->cvals )
+ {
+ for ( int i=0; i<zaxisptr->size; i++)
+ Free(zaxisptr->cvals[i]);
+ Free( zaxisptr->cvals );
+ }
if ( zaxisptr->lbounds ) Free( zaxisptr->lbounds );
if ( zaxisptr->ubounds ) Free( zaxisptr->ubounds );
if ( zaxisptr->weights ) Free( zaxisptr->weights );
@@ -68620,16 +68447,15 @@ static void zaxisDestroyKernel( zaxis_t * zaxisptr )
*/
void zaxisDestroy(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- zaxisDestroyKernel ( zaxisptr );
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ zaxisDestroyKernel(zaxisptr);
}
static
-void zaxisDestroyP ( void * zaxisptr )
+void zaxisDestroyP(void *zaxisptr)
{
- zaxisDestroyKernel (( zaxis_t * ) zaxisptr );
+ zaxisDestroyKernel((zaxis_t *) zaxisptr);
}
@@ -68638,7 +68464,7 @@ const char *zaxisNamePtr(int zaxistype)
const char *name = (zaxistype >= 0 && zaxistype < CDI_NumZaxistype)
? ZaxistypeEntry[zaxistype].longname
: ZaxistypeEntry[ZAXIS_GENERIC].longname;
- return (name);
+ return name;
}
@@ -68652,36 +68478,44 @@ void zaxisSetString(char *zaxisstrname, const char *name, size_t len)
{
if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
strncpy(zaxisstrname, name, len);
- zaxisstrname[len - 1] = 0;
+ zaxisstrname[len-1] = 0;
}
static inline
void zaxisGetString(char *name, const char *zaxisstrname, size_t len)
{
- if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
- strncpy(name, zaxisstrname, len);
- name[len - 1] = 0;
+ size_t slen = strlen(zaxisstrname)+1;
+ if ( slen > len ) slen = len;
+ if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
+ strncpy(name, zaxisstrname, slen);
+ name[slen-1] = 0;
}
static
-char *zaxis_key_to_string(zaxis_t *zaxisptr, int key)
+void *zaxis_key_to_ptr(zaxis_t *zaxisptr, int key)
{
- char *zaxisstring = NULL;
+ void *keyptr = NULL;
switch (key)
{
- case CDI_ZAXIS_DIMNAME: zaxisstring = zaxisptr->dimname; break;
- case CDI_ZAXIS_VDIMNAME: zaxisstring = zaxisptr->vdimname; break;
+ case CDI_KEY_NAME: keyptr = (void*)zaxisptr->name; break;
+ case CDI_KEY_LONGNAME: keyptr = (void*)zaxisptr->longname; break;
+ case CDI_KEY_UNITS: keyptr = (void*)zaxisptr->units; break;
+ case CDI_KEY_DIMNAME: keyptr = (void*)zaxisptr->dimname; break;
+ case CDI_KEY_VDIMNAME: keyptr = (void*)zaxisptr->vdimname; break;
+ case CDI_KEY_PSNAME: keyptr = (void*)zaxisptr->psname; break;
+ case CDI_KEY_P0NAME: keyptr = (void*)zaxisptr->p0name; break;
+ case CDI_KEY_P0VALUE: keyptr = (void*)&zaxisptr->p0value; break;
}
- return zaxisstring;
+ return keyptr;
}
/*
- at Function cdiZaxisDefString
+ at Function cdiZaxisDefKeyStr
@Title Define a CDI Z-axis string value from a key
- at Prototype int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg)
+ at Prototype int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
@Parameter
@Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
@Item key The key to be searched
@@ -68689,37 +68523,37 @@ char *zaxis_key_to_string(zaxis_t *zaxisptr, int key)
@Item mesg The address of a string where the data will be read
@Description
-The function @func{cdiZaxisDefString} defines a CDI Z-axis string value from a key.
+The function @func{cdiZaxisDefKeyStr} defines a CDI Z-axis string value from a key.
@Result
- at func{cdiZaxisDefString} returns 0 if OK and integer value on error.
+ at func{cdiZaxisDefKeyStr} returns 0 if OK and integer value on error.
@EndFunction
*/
-int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg)
+int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
{
- if ( size <= 0 || mesg == NULL || *mesg == 0 ) return -1;
+ if ( size < 1 || mesg == NULL ) return -1;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- char *zaxisstring = zaxis_key_to_string(zaxisptr, key);
- if ( zaxisstring == NULL)
+ char *keyptr = (char*)zaxis_key_to_ptr(zaxisptr, key);
+ if ( keyptr == NULL)
{
Warning("CDI zaxis string key %d not supported!", key);
return -1;
}
- zaxisSetString(zaxisstring, mesg, (size_t)size);
+ zaxisSetString(keyptr, mesg, (size_t)size);
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
return 0;
}
/*
- at Function cdiZaxisInqString
+ at Function cdiZaxisInqKeyStr
@Title Get a CDI Z-axis string value from a key
- at Prototype int cdiZaxisInqString(int zaxisID, int key, int size, char *mesg)
+ at Prototype int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
@Parameter
@Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
@Item key The key to be searched.
@@ -68730,26 +68564,99 @@ int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg)
is given by the predefined constant @func{CDI_MAX_NAME}.
@Description
-The function @func{cdiZaxisInqString} return a CDI Z-axis string value from a key.
+The function @func{cdiZaxisInqKeyStr} return a CDI Z-axis string value from a key.
@Result
- at func{cdiZaxisInqString} returns 0 if OK and integer value on error.
+ at func{cdiZaxisInqKeyStr} returns 0 if OK and integer value on error.
@EndFunction
*/
-int cdiZaxisInqString(int zaxisID, int key, int size, char *mesg)
+int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
{
- if ( size <= 0 || mesg == NULL ) return -1;
+ if ( size < 1 || mesg == NULL ) return -1;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- const char *zaxisstring = zaxis_key_to_string(zaxisptr, key);
- if ( zaxisstring == NULL)
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ const char *keyptr = (const char*)zaxis_key_to_ptr(zaxisptr, key);
+ if ( keyptr == NULL)
{
Warning("CDI zaxis string key %d not supported!", key);
return -1;
}
- zaxisGetString(mesg, zaxisstring, (size_t)size);
+ zaxisGetString(mesg, keyptr, (size_t)size);
+
+ return 0;
+}
+
+
+/*
+ at Function cdiZaxisDefKeyFlt
+ at Title Define a CDI Z-axis floating point value from a key
+
+ at Prototype int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
+ at Parameter
+ @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
+ @Item key The key to be searched
+ @Item value A double where the data will be read
+
+ at Description
+The function @func{cdiZaxisDefKeyFlt} defines a CDI Z-axis double value from a key.
+
+ at Result
+ at func{cdiZaxisDefKeyFlt} returns 0 if OK and integer value on error.
+
+ at EndFunction
+*/
+int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
+{
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+
+ zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
+ if ( keyptr == NULL)
+ {
+ Warning("CDI zaxis double key %d not supported!", key);
+ return -1;
+ }
+
+ keyptr->value = value;
+ keyptr->defined = true;
+
+ reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+
+ return 0;
+}
+
+/*
+ at Function cdiZaxisInqKeyFlt
+ at Title Get a CDI Z-axis floating point value from a key
+
+ at Prototype int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
+ at Parameter
+ @Item zaxisID Z-axis ID, from a previous call to @fref{zaxisCreate}.
+ @Item key The key to be searched.
+ @Item value The address of a double where the data will be retrieved.
+
+ at Description
+The function @func{cdiZaxisInqKeyFlt} return a CDI Z-axis double value from a key.
+
+ at Result
+ at func{cdiZaxisInqKeyFlt} returns 0 if OK and integer value on error.
+
+ at EndFunction
+*/
+int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
+{
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
+ if ( keyptr == NULL)
+ {
+ Warning("CDI zaxis double key %d not supported!", key);
+ return -1;
+ }
+
+ if ( !keyptr->defined ) return 1;
+
+ *value = keyptr->value;
return 0;
}
@@ -68770,14 +68677,7 @@ The function @func{zaxisDefName} defines the name of a Z-axis.
*/
void zaxisDefName(int zaxisID, const char *name)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- if ( name )
- {
- strncpy(zaxisptr->name, name, CDI_MAX_NAME - 1);
- zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
- reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
- }
+ (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
}
/*
@@ -68796,14 +68696,7 @@ The function @func{zaxisDefLongname} defines the longname of a Z-axis.
*/
void zaxisDefLongname(int zaxisID, const char *longname)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- if ( longname )
- {
- strncpy(zaxisptr->longname, longname, CDI_MAX_NAME - 1);
- zaxisptr->longname[CDI_MAX_NAME - 1] = '\0';
- reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
- }
+ (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
}
/*
@@ -68822,27 +68715,7 @@ The function @func{zaxisDefUnits} defines the units of a Z-axis.
*/
void zaxisDefUnits(int zaxisID, const char *units)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- if ( units )
- {
- strncpy(zaxisptr->units, units, CDI_MAX_NAME - 1);
- zaxisptr->units[CDI_MAX_NAME - 1] = '\0';
- reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
- }
-}
-
-
-void zaxisDefPsName(int zaxisID, const char *psname)
-{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- if ( psname )
- {
- strncpy(zaxisptr->psname, psname, CDI_MAX_NAME - 1);
- zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
- reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
- }
+ (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
}
/*
@@ -68866,13 +68739,12 @@ The function @func{zaxisInqName} returns the name of a Z-axis.
*/
void zaxisInqName(int zaxisID, char *name)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- strcpy(name, zaxisptr->name);
+ (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
}
const char *zaxisInqNamePtr(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->name;
}
@@ -68897,8 +68769,7 @@ The function @func{zaxisInqLongname} returns the longname of a Z-axis.
*/
void zaxisInqLongname(int zaxisID, char *longname)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- strcpy(longname, zaxisptr->longname);
+ (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
}
/*
@@ -68922,51 +68793,43 @@ The function @func{zaxisInqUnits} returns the units of a Z-axis.
*/
void zaxisInqUnits(int zaxisID, char *units)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- strcpy(units, zaxisptr->units);
+ (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
}
void zaxisInqStdname(int zaxisID, char *stdname)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
strcpy(stdname, zaxisptr->stdname);
}
-void zaxisInqPsName(int zaxisID, char *psname)
-{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- strcpy(psname, zaxisptr->psname);
-}
-
-
-void zaxisDefPrec(int zaxisID, int prec)
+void zaxisDefDatatype(int zaxisID, int datatype)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if (zaxisptr->prec != prec)
+ if ( zaxisptr->datatype != datatype )
{
- zaxisptr->prec = prec;
+ zaxisptr->datatype = datatype;
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
}
-int zaxisInqPrec(int zaxisID)
+int zaxisInqDatatype(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- return (zaxisptr->prec);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ return zaxisptr->datatype;
}
void zaxisDefPositive(int zaxisID, int positive)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if (zaxisptr->positive != (unsigned)(positive != 0))
+ if ( zaxisptr->positive != (unsigned)positive )
{
- zaxisptr->positive = (unsigned)(positive != 0);
+ zaxisptr->positive = (unsigned)positive;
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
}
@@ -68974,14 +68837,14 @@ void zaxisDefPositive(int zaxisID, int positive)
int zaxisInqPositive(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return (int)zaxisptr->positive;
}
void zaxisDefScalar(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
zaxisptr->scalar = 1;
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
@@ -68989,14 +68852,14 @@ void zaxisDefScalar(int zaxisID)
int zaxisInqScalar(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->scalar;
}
void zaxisDefLtype(int zaxisID, int ltype)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if (zaxisptr->ltype != ltype)
{
@@ -69008,16 +68871,16 @@ void zaxisDefLtype(int zaxisID, int ltype)
int zaxisInqLtype(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->ltype;
}
void zaxisDefLtype2(int zaxisID, int ltype2)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if (zaxisptr->ltype2 != ltype2)
+ if ( zaxisptr->ltype2 != ltype2 )
{
zaxisptr->ltype2 = ltype2;
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
@@ -69027,7 +68890,7 @@ void zaxisDefLtype2(int zaxisID, int ltype2)
int zaxisInqLtype2(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->ltype2;
}
@@ -69047,15 +68910,41 @@ The function @func{zaxisDefLevels} defines the levels of a Z-axis.
*/
void zaxisDefLevels(int zaxisID, const double *levels)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ size_t size = (size_t)zaxisptr->size;
+
+ if ( levels )
+ {
+ if ( zaxisptr->vals == NULL )
+ zaxisptr->vals = (double*) Malloc(size*sizeof(double));
+
+ double *vals = zaxisptr->vals;
+
+ for ( size_t ilev = 0; ilev < size; ++ilev )
+ vals[ilev] = levels[ilev];
+
+ reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+ }
+}
+
+void zaxisDefCvals(int zaxisID, const char **cvals, int clen)
+{
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
int size = zaxisptr->size;
- double *vals = zaxisptr->vals;
+ if ( cvals && clen )
+ {
+ zaxisptr->clength = clen;
+ zaxisptr->cvals = (char**) Malloc((size_t)size*sizeof(char *));
- for (int ilev = 0; ilev < size; ilev++ )
- vals[ilev] = levels[ilev];
- reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+ for ( int ilev = 0; ilev < size; ++ilev )
+ {
+ zaxisptr->cvals[ilev] = Malloc((size_t)clen*sizeof(char));
+ memcpy(zaxisptr->cvals[ilev],cvals[ilev], (size_t)clen*sizeof(char));
+ }
+ reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+ }
}
/*
@@ -69075,16 +68964,22 @@ The function @func{zaxisDefLevel} defines one level of a Z-axis.
*/
void zaxisDefLevel(int zaxisID, int levelID, double level)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- if ( levelID >= 0 && levelID < zaxisptr->size )
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ int size = zaxisptr->size;
+
+ if ( zaxisptr->vals == NULL )
+ zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));
+
+ if ( levelID >= 0 && levelID < size )
zaxisptr->vals[levelID] = level;
+
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
void zaxisDefNlevRef(int zaxisID, const int nhlev)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if (zaxisptr->nhlev != nhlev)
{
zaxisptr->nhlev = nhlev;
@@ -69095,7 +68990,7 @@ void zaxisDefNlevRef(int zaxisID, const int nhlev)
int zaxisInqNlevRef(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->nhlev;
}
@@ -69115,7 +69010,7 @@ The function @func{zaxisDefNumber} defines the reference number for a generalize
*/
void zaxisDefNumber(int zaxisID, const int number)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if (zaxisptr->number != number)
{
zaxisptr->number = number;
@@ -69140,7 +69035,7 @@ The function @func{zaxisInqNumber} returns the reference number to a generalized
*/
int zaxisInqNumber(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->number;
}
@@ -69160,7 +69055,7 @@ The function @func{zaxisDefUUID} defines the UUID for a generalized Z-axis.
*/
void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
memcpy(zaxisptr->uuid, uuid, CDI_UUID_SIZE);
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
@@ -69183,7 +69078,7 @@ The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
*/
void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
memcpy(uuid, zaxisptr->uuid, CDI_UUID_SIZE);
}
@@ -69206,43 +69101,54 @@ The function @func{zaxisInqLevel} returns one level of a Z-axis.
double zaxisInqLevel(int zaxisID, int levelID)
{
double level = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if ( levelID >= 0 && levelID < zaxisptr->size )
+ if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
level = zaxisptr->vals[levelID];
return level;
}
-double zaxisInqLbound(int zaxisID, int index)
+
+double zaxisInqLbound(int zaxisID, int levelID)
{
double level = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if ( zaxisptr->lbounds && ( index >= 0 && index < zaxisptr->size ) )
- level = zaxisptr->lbounds[index];
+ if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
+ level = zaxisptr->lbounds[levelID];
return level;
}
-double zaxisInqUbound(int zaxisID, int index)
+double zaxisInqUbound(int zaxisID, int levelID)
{
double level = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+
+ if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
+ level = zaxisptr->ubounds[levelID];
- if ( zaxisptr->ubounds && ( index >= 0 && index < zaxisptr->size ) )
- level = zaxisptr->ubounds[index];
return level;
}
const double *zaxisInqLevelsPtr(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
return zaxisptr->vals;
}
+
+char **zaxisInqCValsPtr(int zaxisID)
+{
+ char **cvals = NULL;
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ cvals = zaxisptr->cvals;
+ return cvals;
+}
+
/*
@Function zaxisInqLevels
@Title Get all levels of a Z-axis
@@ -69260,55 +69166,98 @@ The function @func{zaxisInqLevels} returns all levels of a Z-axis.
@func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
@EndFunction
*/
-void zaxisInqLevels(int zaxisID, double *levels)
+int zaxisInqLevels(int zaxisID, double *levels)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- int size = zaxisptr->size;
- for (int i = 0; i < size; i++ )
- levels[i] = zaxisptr->vals[i];
+ int size = 0;
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+
+ if ( zaxisptr->vals )
+ {
+ size = zaxisptr->size;
+
+ if ( levels )
+ for ( int i = 0; i < size; i++ )
+ levels[i] = zaxisptr->vals[i];
+ }
+
+ return size;
+}
+
+int zaxisInqCLen(int zaxisID)
+{
+ int size = 0;
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+
+ if ( zaxisptr->cvals && zaxisptr->clength)
+ size = zaxisptr->clength;
+ return size;
+}
+
+int zaxisInqCVals(int zaxisID, char ***clevels)
+{
+ int size = 0;
+ size_t clen = 0;
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+
+ if ( zaxisptr->cvals )
+ {
+ size = zaxisptr->size;
+ clen = zaxisptr->clength;
+ if ( size && clen )
+ {
+ (*clevels) = Malloc(size*sizeof(char*));
+ for ( int i = 0; i < size; i++ )
+ {
+ (*clevels)[i] = Malloc(clen*sizeof(char));
+ memcpy((*clevels)[i], zaxisptr->cvals[i], clen*sizeof(char));
+ }
+ }
+ }
+
+ return size;
}
int zaxisInqLbounds(int zaxisID, double *lbounds)
{
int size = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if ( zaxisptr->lbounds )
{
size = zaxisptr->size;
if ( lbounds )
- for (int i = 0; i < size; i++ )
- lbounds[i] = zaxisptr->lbounds[i];
+ for ( int i = 0; i < size; i++ )
+ lbounds[i] = zaxisptr->lbounds[i];
}
- return (size);
+ return size;
}
int zaxisInqUbounds(int zaxisID, double *ubounds)
{
int size = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if ( zaxisptr->ubounds )
{
size = zaxisptr->size;
if ( ubounds )
- for (int i = 0; i < size; i++ )
- ubounds[i] = zaxisptr->ubounds[i];
+ for ( int i = 0; i < size; i++ )
+ ubounds[i] = zaxisptr->ubounds[i];
}
- return (size);
+ return size;
}
int zaxisInqWeights(int zaxisID, double *weights)
{
int size = 0;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if ( zaxisptr->weights )
{
@@ -69316,25 +69265,29 @@ int zaxisInqWeights(int zaxisID, double *weights)
if ( weights )
for ( int i = 0; i < size; i++ )
- weights[i] = zaxisptr->weights[i];
+ weights[i] = zaxisptr->weights[i];
}
- return (size);
+ return size;
}
int zaxisInqLevelID(int zaxisID, double level)
{
int levelID = CDI_UNDEFID;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- int size = zaxisptr->size;
- for ( int i = 0; i < size; i++ )
- if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
- {
- levelID = i;
- break;
- }
+ if ( zaxisptr->vals )
+ {
+ int size = zaxisptr->size;
+
+ for ( int i = 0; i < size; i++ )
+ if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
+ {
+ levelID = i;
+ break;
+ }
+ }
return levelID;
}
@@ -69366,8 +69319,8 @@ The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
*/
int zaxisInqType(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- return (zaxisptr->type);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ return zaxisptr->type;
}
/*
@@ -69388,16 +69341,16 @@ The function @func{zaxisInqSize} returns the size of a Z-axis.
*/
int zaxisInqSize(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- return (zaxisptr->size);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ return zaxisptr->size;
}
void cdiCheckZaxis(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
+ if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC && zaxisptr->vals )
{
int size = zaxisptr->size;
if ( size > 1 )
@@ -69431,7 +69384,7 @@ void cdiCheckZaxis(int zaxisID)
void zaxisDefVct(int zaxisID, int size, const double *vct)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
if ( zaxisptr->vct == 0 || zaxisptr->vctsize != size )
{
@@ -69446,28 +69399,28 @@ void zaxisDefVct(int zaxisID, int size, const double *vct)
void zaxisInqVct(int zaxisID, double *vct)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
memcpy(vct, zaxisptr->vct, (size_t)zaxisptr->vctsize * sizeof (double));
}
int zaxisInqVctSize(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- return (zaxisptr->vctsize);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ return zaxisptr->vctsize;
}
const double *zaxisInqVctPtr(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
- return (zaxisptr->vct);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ return zaxisptr->vct;
}
void zaxisDefLbounds(int zaxisID, const double *lbounds)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
size_t size = (size_t)zaxisptr->size;
@@ -69485,7 +69438,7 @@ void zaxisDefLbounds(int zaxisID, const double *lbounds)
void zaxisDefUbounds(int zaxisID, const double *ubounds)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
size_t size = (size_t)zaxisptr->size;
@@ -69503,7 +69456,7 @@ void zaxisDefUbounds(int zaxisID, const double *ubounds)
void zaxisDefWeights(int zaxisID, const double *weights)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
size_t size = (size_t)zaxisptr->size;
@@ -69521,34 +69474,33 @@ void zaxisDefWeights(int zaxisID, const double *weights)
void zaxisChangeType(int zaxisID, int zaxistype)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
zaxisptr->type = zaxistype;
}
void zaxisResize(int zaxisID, int size)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
xassert(size >= 0);
zaxisptr->size = size;
if ( zaxisptr->vals )
- zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size * sizeof(double));
+ zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size*sizeof(double));
}
int zaxisDuplicate(int zaxisID)
{
- int zaxisIDnew;
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
int zaxistype = zaxisInqType(zaxisID);
int zaxissize = zaxisInqSize(zaxisID);
- zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
- zaxis_t *zaxisptrnew = zaxisID2Ptr(zaxisIDnew);
+ int zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
+ zaxis_t *zaxisptrnew = zaxis_to_pointer(zaxisIDnew);
zaxis_copy(zaxisptrnew, zaxisptr);
@@ -69556,10 +69508,9 @@ int zaxisDuplicate(int zaxisID)
strcpy(zaxisptrnew->longname, zaxisptr->longname);
strcpy(zaxisptrnew->units, zaxisptr->units);
- if ( zaxisptr->vals != NULL )
+ if ( zaxisptr->vals )
{
size_t size = (size_t)zaxissize;
-
zaxisptrnew->vals = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
}
@@ -69567,7 +69518,6 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->lbounds )
{
size_t size = (size_t)zaxissize;
-
zaxisptrnew->lbounds = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
}
@@ -69575,15 +69525,13 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->ubounds )
{
size_t size = (size_t)zaxissize;
-
zaxisptrnew->ubounds = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
}
- if ( zaxisptr->vct != NULL )
+ if ( zaxisptr->vct )
{
size_t size = (size_t)zaxisptr->vctsize;
-
if ( size )
{
zaxisptrnew->vctsize = (int)size;
@@ -69592,55 +69540,71 @@ int zaxisDuplicate(int zaxisID)
}
}
- return (zaxisIDnew);
+ return zaxisIDnew;
}
-
-static void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
+static
+void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
{
- unsigned char uuid[CDI_UUID_SIZE];
- int levelID;
- int nbyte;
-
- xassert ( zaxisptr );
+ xassert(zaxisptr);
int zaxisID = zaxisptr->self;
-
int type = zaxisptr->type;
int nlevels = zaxisptr->size;
- int prec = zaxisptr->prec;
+ int datatype = zaxisptr->datatype;
- int dig = (prec == DATATYPE_FLT64) ? 15 : 7;
+ int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
+ int nbyte;
int nbyte0 = 0;
- fprintf(fp, "#\n");
- fprintf(fp, "# zaxisID %d\n", index);
- fprintf(fp, "#\n");
fprintf(fp, "zaxistype = %s\n", zaxisNamePtr(type));
fprintf(fp, "size = %d\n", nlevels);
+ if ( nlevels == 1 )
+ {
+ bool zscalar = (bool)zaxisptr->scalar;
+ if ( zscalar ) fprintf(fp, "scalar = true\n");
+ }
if ( zaxisptr->name[0] ) fprintf(fp, "name = %s\n", zaxisptr->name);
if ( zaxisptr->longname[0] ) fprintf(fp, "longname = %s\n", zaxisptr->longname);
if ( zaxisptr->units[0] ) fprintf(fp, "units = %s\n", zaxisptr->units);
- nbyte0 = fprintf(fp, "levels = ");
- nbyte = nbyte0;
- for ( levelID = 0; levelID < nlevels; levelID++ )
+ if ( zaxisptr->vals )
{
- if ( nbyte > 80 )
- {
- fprintf(fp, "\n");
- fprintf(fp, "%*s", nbyte0, "");
- nbyte = nbyte0;
- }
- nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
+ nbyte0 = fprintf(fp, "levels = ");
+ nbyte = nbyte0;
+ for ( int levelID = 0; levelID < nlevels; levelID++ )
+ {
+ if ( nbyte > 80 )
+ {
+ fprintf(fp, "\n");
+ fprintf(fp, "%*s", nbyte0, "");
+ nbyte = nbyte0;
+ }
+ nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
+ }
+ fprintf(fp, "\n");
+ }
+
+ if ( zaxisptr->cvals )
+ {
+ dig = datatype;
+ nbyte0 = fprintf(fp, "types = ");
+ nbyte = nbyte0;
+ for ( int levelID = 0; levelID < nlevels; levelID++ )
+ {
+ fprintf(fp, "\n");
+ fprintf(fp, "%*s", nbyte0, "");
+ nbyte = nbyte0;
+ nbyte += fprintf(fp, "%.*s [%d]", dig, zaxisptr->cvals[levelID], levelID+1);
+ }
+ fprintf(fp, "\n");
}
- fprintf(fp, "\n");
if ( zaxisptr->lbounds && zaxisptr->ubounds )
{
nbyte0 = fprintf(fp, "lbounds = ");
nbyte = nbyte0;
- for ( levelID = 0; levelID < nlevels; levelID++ )
+ for ( int levelID = 0; levelID < nlevels; levelID++ )
{
if ( nbyte > 80 )
{
@@ -69654,7 +69618,7 @@ static void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
nbyte0 = fprintf(fp, "ubounds = ");
nbyte = nbyte0;
- for ( levelID = 0; levelID < nlevels; levelID++ )
+ for ( int levelID = 0; levelID < nlevels; levelID++ )
{
if ( nbyte > 80 )
{
@@ -69705,6 +69669,7 @@ static void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
if ( type == ZAXIS_REFERENCE )
{
+ unsigned char uuid[CDI_UUID_SIZE];
zaxisInqUUID(zaxisID, uuid);
if ( *uuid )
{
@@ -69717,44 +69682,41 @@ static void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
}
-void zaxisPrint ( int zaxisID, int index )
+void zaxisPrint(int zaxisID)
{
- zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
-
- zaxisPrintKernel ( zaxisptr, index, stdout );
+ zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+ zaxisPrintKernel(zaxisptr, stdout);
}
static
-void zaxisPrintP ( void * voidptr, FILE * fp )
+void zaxisPrintP(void * voidptr, FILE * fp)
{
zaxis_t *zaxisptr = ( zaxis_t * ) voidptr;
xassert ( zaxisptr );
- zaxisPrintKernel(zaxisptr, zaxisptr->self, fp);
+ zaxisPrintKernel(zaxisptr, fp);
}
-static int
-zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
+static
+int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
{
- enum {
- differ = 1,
- };
+ enum { differ = 1 };
int diff = 0;
xassert(z1 && z2);
diff |= (z1->type != z2->type)
| (z1->ltype != z2->ltype)
| (z1->direction != z2->direction)
- | (z1->prec != z2->prec)
+ | (z1->datatype != z2->datatype)
| (z1->size != z2->size)
| (z1->vctsize != z2->vctsize)
| (z1->positive != z2->positive);
- if (diff)
- return differ;
+ if ( diff ) return differ;
+
int size = z1->size;
int anyPresent = 0;
int present = (z1->vals != NULL);
@@ -69763,7 +69725,7 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
if (!diff && present)
{
const double *p = z1->vals, *q = z2->vals;
- for (int i = 0; i < size; i++)
+ for ( int i = 0; i < size; i++ )
diff |= IS_NOT_EQUAL(p[i], q[i]);
}
@@ -69773,7 +69735,7 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
if (!diff && present)
{
const double *p = z1->lbounds, *q = z2->lbounds;
- for (int i = 0; i < size; i++)
+ for ( int i = 0; i < size; i++ )
diff |= IS_NOT_EQUAL(p[i], q[i]);
}
@@ -69783,7 +69745,7 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
if (!diff && present)
{
const double *p = z1->ubounds, *q = z2->ubounds;
- for (int i = 0; i < size; ++i)
+ for ( int i = 0; i < size; ++i )
diff |= IS_NOT_EQUAL(p[i], q[i]);
}
@@ -69793,7 +69755,7 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
if (!diff && present)
{
const double *p = z1->weights, *q = z2->weights;
- for (int i = 0; i < size; ++i)
+ for ( int i = 0; i < size; ++i )
diff |= IS_NOT_EQUAL(p[i], q[i]);
}
@@ -69804,7 +69766,7 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
int vctsize = z1->vctsize;
xassert(vctsize);
const double *p = z1->vct, *q = z2->vct;
- for (int i = 0; i < vctsize; ++i)
+ for ( int i = 0; i < vctsize; ++i )
diff |= IS_NOT_EQUAL(p[i], q[i]);
}
@@ -69820,8 +69782,8 @@ zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
}
-static int
-zaxisTxCode ( void )
+static
+int zaxisTxCode(void)
{
return ZAXIS;
}
@@ -69836,10 +69798,10 @@ enum { zaxisNint = 8,
};
#define ZAXIS_STR_SERIALIZE { zaxisP->name, zaxisP->longname, \
- zaxisP->stdname, zaxisP->units }
+ zaxisP->stdname, zaxisP->units }
static
-int zaxisGetMemberMask ( zaxis_t * zaxisP )
+int zaxisGetMemberMask( zaxis_t * zaxisP )
{
int memberMask = 0;
@@ -69856,33 +69818,33 @@ static int
zaxisGetPackSize(void * voidP, void *context)
{
zaxis_t * zaxisP = ( zaxis_t * ) voidP;
- int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ int packBufferSize = serializeGetSize(zaxisNint, CDI_DATATYPE_INT, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
xassert(zaxisP->size);
if ( zaxisP->vals )
- packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
if ( zaxisP->lbounds )
- packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
if ( zaxisP->ubounds )
- packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
if ( zaxisP->weights )
- packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
if ( zaxisP->vct )
{
xassert ( zaxisP->vctsize );
- packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
- + serializeGetSize(1, DATATYPE_UINT32, context);
+ packBufferSize += serializeGetSize(zaxisP->vctsize, CDI_DATATYPE_FLT64, context)
+ + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
}
{
@@ -69892,10 +69854,10 @@ zaxisGetPackSize(void * voidP, void *context)
+= serializeStrTabGetPackSize(strTab, (int)numStr, context);
}
- packBufferSize += serializeGetSize(1, DATATYPE_UCHAR, context);
+ packBufferSize += serializeGetSize(1, CDI_DATATYPE_UCHAR, context);
if (!cdiUUIDIsNull(zaxisP->uuid))
- packBufferSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+ packBufferSize += serializeGetSize(CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
return packBufferSize;
}
@@ -69910,11 +69872,11 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
uint32_t d;
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- intBuffer, zaxisNint, DATATYPE_INT, context);
+ intBuffer, zaxisNint, CDI_DATATYPE_INT, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
+ &d, 1, CDI_DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
+ xassert(cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer) == d);
zaxisInit();
@@ -69922,7 +69884,7 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
= zaxisNewEntry(force_id ? namespaceAdaptKey(intBuffer[0], originNamespace)
: CDI_UNDEFID);
- zaxisP->prec = intBuffer[1];
+ zaxisP->datatype = intBuffer[1];
zaxisP->type = intBuffer[2];
zaxisP->ltype = intBuffer[3];
zaxisP->size = intBuffer[4];
@@ -69937,10 +69899,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
zaxisP->vals = (double *) Malloc((size_t)size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->vals, size, DATATYPE_FLT64, context);
+ zaxisP->vals, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->vals) == d);
}
if (memberMask & lbounds)
@@ -69950,10 +69912,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
zaxisP->lbounds = (double *) Malloc((size_t)size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->lbounds, size, DATATYPE_FLT64, context);
+ zaxisP->lbounds, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->lbounds) == d);
}
if (memberMask & ubounds)
@@ -69963,10 +69925,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
zaxisP->ubounds = (double *) Malloc((size_t)size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->ubounds, size, DATATYPE_FLT64, context);
+ zaxisP->ubounds, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->ubounds) == d);
}
if (memberMask & weights)
@@ -69976,10 +69938,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
zaxisP->weights = (double *) Malloc((size_t)size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->weights, size, DATATYPE_FLT64, context);
+ zaxisP->weights, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->weights) == d);
}
if ( memberMask & vct )
@@ -69989,10 +69951,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
zaxisP->vct = (double *) Malloc((size_t)size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->vct, size, DATATYPE_FLT64, context);
+ zaxisP->vct, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &d, 1, DATATYPE_UINT32, context);
- xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
+ &d, 1, CDI_DATATYPE_UINT32, context);
+ xassert(cdiCheckSum(CDI_DATATYPE_FLT64, size, zaxisP->vct) == d);
}
{
@@ -70003,11 +69965,11 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
}
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- &zaxisP->positive, 1, DATATYPE_UCHAR, context);
+ &zaxisP->positive, 1, CDI_DATATYPE_UCHAR, context);
if (memberMask & zaxisHasUUIDFlag)
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
- zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+ zaxisP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
reshSetStatus(zaxisP->self, &zaxisOps,
reshGetStatus(zaxisP->self, &zaxisOps) & ~RESH_SYNC_BIT);
@@ -70023,7 +69985,7 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
uint32_t d;
intBuffer[0] = zaxisP->self;
- intBuffer[1] = zaxisP->prec;
+ intBuffer[1] = zaxisP->datatype;
intBuffer[2] = zaxisP->type;
intBuffer[3] = zaxisP->ltype;
intBuffer[4] = zaxisP->size;
@@ -70031,30 +69993,30 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
intBuffer[6] = zaxisP->vctsize;
intBuffer[7] = memberMask = zaxisGetMemberMask ( zaxisP );
- serializePack(intBuffer, zaxisNint, DATATYPE_INT,
+ serializePack(intBuffer, zaxisNint, CDI_DATATYPE_INT,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
if ( memberMask & vals )
{
xassert(zaxisP->size);
- serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
+ serializePack(zaxisP->vals, zaxisP->size, CDI_DATATYPE_FLT64,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->vals );
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
}
if (memberMask & lbounds)
{
xassert(zaxisP->size);
- serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
+ serializePack(zaxisP->lbounds, zaxisP->size, CDI_DATATYPE_FLT64,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -70062,10 +70024,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
{
xassert(zaxisP->size);
- serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
+ serializePack(zaxisP->ubounds, zaxisP->size, CDI_DATATYPE_FLT64,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -70073,10 +70035,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
{
xassert(zaxisP->size);
- serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
+ serializePack(zaxisP->weights, zaxisP->size, CDI_DATATYPE_FLT64,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->weights);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -70084,10 +70046,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
{
xassert(zaxisP->vctsize);
- serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
+ serializePack(zaxisP->vct, zaxisP->vctsize, CDI_DATATYPE_FLT64,
packBuffer, packBufferSize, packBufferPos, context);
- d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
- serializePack(&d, 1, DATATYPE_UINT32,
+ d = cdiCheckSum(CDI_DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
+ serializePack(&d, 1, CDI_DATATYPE_UINT32,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -70098,11 +70060,11 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
packBuffer, packBufferSize, packBufferPos, context);
}
- serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
+ serializePack(&zaxisP->positive, 1, CDI_DATATYPE_UCHAR,
packBuffer, packBufferSize, packBufferPos, context);
if (memberMask & zaxisHasUUIDFlag)
- serializePack(zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
+ serializePack(zaxisP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR,
packBuffer, packBufferSize, packBufferPos, context);
}
@@ -70124,7 +70086,7 @@ void cdiZaxisGetIndexList(unsigned nzaxis, int *zaxisResHs)
* require-trailing-newline: t
* End:
*/
- static const char cdi_libvers[] = "1.7.2" " of " "Jun 7 2016"" " "20:09:57";
+ static const char cdi_libvers[] = "1.9.2" " of " "Nov 6 2017"" " "11:55:15";
const char *cdiLibraryVersion(void)
{
return (cdi_libvers);
@@ -70728,7 +70690,7 @@ if (e>s) { /* Need this to handle NULL string.*/
} return s; }
#ifndef __CF__KnR
-static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term);
+static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term);
#endif
/* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally
points to the terminating '\0' of s, but may actually point to anywhere in s.
@@ -70745,8 +70707,7 @@ else if (e>s) { /* Watch out for neg. length string.*/
while (e>s && *--e==t){;} /* Don't follow t's past beginning. */
e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
}
-if (0) /* to prevent not used warnings in gcc (added by TJ) */
- num_elem("", 0, '\0', 1);
+(void)num_elem; /* to prevent not used warnings in gcc (added by TJ) */
return s; }
@@ -70796,7 +70757,7 @@ typedef DSC$DESCRIPTOR_A(1) fstringvector;
#define NUM_ELEM_ARG(B) *_2(A,B),_NUM_ELEM_ARG
#define TERM_CHARS(A,B) A,B
#ifndef __CF__KnR
-static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term)
+static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term)
#else
static int num_elem( strv, elem_len, term_char, num_term)
char *strv; unsigned elem_len; int term_char; int num_term;
@@ -70815,10 +70776,10 @@ for (num=0; ; num++) {
if (i==(unsigned)num_term) break;
else strv += elem_len-i;
}
-if (0) { /* to prevent not used warnings in gcc (added by ROOT) */
- c2fstrv(0, 0, 0, 0); f2cstrv(0, 0, 0, 0); kill_trailing(0, 0);
- vkill_trailing(0, 0, 0, 0); num_elem(0, 0, 0, 0);
-}
+/* to prevent not used warnings in gcc (added by ROOT, changed by TJ
+ * because of unreachable warnings from clang) */
+(void)c2fstrv; (void)f2cstrv; (void)kill_trailing;
+(void)vkill_trailing; (void)num_elem;
return (int)num;
}
/* #endif removed 2/10/98 (CFITSIO) */
@@ -72708,10 +72669,32 @@ string. */
#if defined (HAVE_CF_INTERFACE)
+#include <limits.h>
+#include <assert.h>
+
#if ! defined (__CFORTRAN_LOADED)
+# if defined __clang__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wreserved-id-macro"
+# endif
# include "cfortran.h"
+# if defined __clang__
+# pragma GCC diagnostic pop
+# endif
+#endif
+/* These functions are meant to be called from Fortran and don't
+ * need an interface declaration in a C header. */
+#if defined __clang__
+# pragma GCC diagnostic ignored "-Wmissing-prototypes"
#endif
+static
+int size_t_c2f(size_t value_size_t)
+{
+ assert(value_size_t < INT_MAX);
+ return (int) value_size_t;
+}
+
/* Byte order */
@@ -72830,28 +72813,105 @@ FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT,
FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
+static int streamNvals_fwrap(int streamID)
+{
+ size_t v;
+ v = streamNvals(streamID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, streamNvals_fwrap, STREAMNVALS, streamnvals, INT)
FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
-/* STREAM var I/O routines */
+/* STREAM var I/O routines (random access) */
-FCALLSCSUB4 (streamWriteVar, STREAMWRITEVAR, streamwritevar, INT, INT, DOUBLEV, INT)
-FCALLSCSUB4 (streamWriteVarF, STREAMWRITEVARF, streamwritevarf, INT, INT, FLOATV, INT)
-FCALLSCSUB4 (streamReadVar, STREAMREADVAR, streamreadvar, INT, INT, DOUBLEV, PINT)
-FCALLSCSUB4 (streamReadVarF, STREAMREADVARF, streamreadvarf, INT, INT, FLOATV, PINT)
-FCALLSCSUB5 (streamWriteVarSlice, STREAMWRITEVARSLICE, streamwritevarslice, INT, INT, INT, DOUBLEV, INT)
-FCALLSCSUB5 (streamWriteVarSliceF, STREAMWRITEVARSLICEF, streamwritevarslicef, INT, INT, INT, FLOATV, INT)
-FCALLSCSUB5 (streamReadVarSlice, STREAMREADVARSLICE, streamreadvarslice, INT, INT, INT, DOUBLEV, PINT)
-FCALLSCSUB5 (streamReadVarSliceF, STREAMREADVARSLICEF, streamreadvarslicef, INT, INT, INT, FLOATV, PINT)
-FCALLSCSUB5 (streamWriteVarChunk, STREAMWRITEVARCHUNK, streamwritevarchunk, INT, INT, INTVV, DOUBLEV, INT)
+static void streamWriteVar_fwrap(int streamID, int varID, const double data[], int nmiss)
+{
+ streamWriteVar(streamID, varID, data, (size_t)nmiss);
+}
+FCALLSCSUB4 (streamWriteVar_fwrap, STREAMWRITEVAR, streamwritevar, INT, INT, DOUBLEV, INT)
+static void streamWriteVarF_fwrap(int streamID, int varID, const float data[], int nmiss)
+{
+ streamWriteVarF(streamID, varID, data, (size_t)nmiss);
+}
+FCALLSCSUB4 (streamWriteVarF_fwrap, STREAMWRITEVARF, streamwritevarf, INT, INT, FLOATV, INT)
+static void streamReadVar_fwrap(int streamID, int varID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVar(streamID, varID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB4 (streamReadVar_fwrap, STREAMREADVAR, streamreadvar, INT, INT, DOUBLEV, PINT)
+static void streamReadVarF_fwrap(int streamID, int varID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarF(streamID, varID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB4 (streamReadVarF_fwrap, STREAMREADVARF, streamreadvarf, INT, INT, FLOATV, PINT)
+static void streamWriteVarSlice_fwrap(int streamID, int varID, int levelID, const double data[], int nmiss)
+{
+ streamWriteVarSlice(streamID, varID, levelID, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarSlice_fwrap, STREAMWRITEVARSLICE, streamwritevarslice, INT, INT, INT, DOUBLEV, INT)
+static void streamWriteVarSliceF_fwrap(int streamID, int varID, int levelID, const float data[], int nmiss)
+{
+ streamWriteVarSliceF(streamID, varID, levelID, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarSliceF_fwrap, STREAMWRITEVARSLICEF, streamwritevarslicef, INT, INT, INT, FLOATV, INT)
+static void streamReadVarSlice_fwrap(int streamID, int varID, int levelID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarSlice(streamID, varID, levelID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB5 (streamReadVarSlice_fwrap, STREAMREADVARSLICE, streamreadvarslice, INT, INT, INT, DOUBLEV, PINT)
+static void streamReadVarSliceF_fwrap(int streamID, int varID, int levelID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadVarSliceF(streamID, varID, levelID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB5 (streamReadVarSliceF_fwrap, STREAMREADVARSLICEF, streamreadvarslicef, INT, INT, INT, FLOATV, PINT)
+static void streamWriteVarChunk_fwrap(int streamID, int varID, const int rect[3][2], const double data[], int nmiss)
+{
+ streamWriteVarChunk(streamID, varID, rect, data, (size_t)nmiss);
+}
+FCALLSCSUB5 (streamWriteVarChunk_fwrap, STREAMWRITEVARCHUNK, streamwritevarchunk, INT, INT, INTVV, DOUBLEV, INT)
-/* STREAM record I/O routines */
+/* STREAM record I/O routines (sequential access) */
FCALLSCSUB3 (streamDefRecord, STREAMDEFRECORD, streamdefrecord, INT, INT, INT)
FCALLSCSUB3 (streamInqRecord, STREAMINQRECORD, streaminqrecord, INT, PINT, PINT)
-FCALLSCSUB3 (streamWriteRecord, STREAMWRITERECORD, streamwriterecord, INT, DOUBLEV, INT)
-FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, FLOATV, INT)
-FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, DOUBLEV, PINT)
-FCALLSCSUB3 (streamReadRecordF, STREAMREADRECORDF, streamreadrecordf, INT, FLOATV, PINT)
+static void streamWriteRecord_fwrap(int streamID, const double data[], int nmiss)
+{
+ streamWriteRecord(streamID, data, (size_t)nmiss);
+}
+FCALLSCSUB3 (streamWriteRecord_fwrap, STREAMWRITERECORD, streamwriterecord, INT, DOUBLEV, INT)
+static void streamWriteRecordF_fwrap(int streamID, const float data[], int nmiss)
+{
+ streamWriteRecordF(streamID, data, (size_t)nmiss);
+}
+FCALLSCSUB3 (streamWriteRecordF_fwrap, STREAMWRITERECORDF, streamwriterecordf, INT, FLOATV, INT)
+static void streamReadRecord_fwrap(int streamID, double data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadRecord(streamID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB3 (streamReadRecord_fwrap, STREAMREADRECORD, streamreadrecord, INT, DOUBLEV, PINT)
+static void streamReadRecordF_fwrap(int streamID, float data[], int *nmiss)
+{
+ size_t nmiss_size_t;
+ streamReadRecordF(streamID, data, &nmiss_size_t);
+ assert(nmiss_size_t < INT_MAX);
+ *nmiss = nmiss_size_t;
+}
+FCALLSCSUB3 (streamReadRecordF_fwrap, STREAMREADRECORDF, streamreadrecordf, INT, FLOATV, PINT)
FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
/* File driven I/O (may yield better performance than using the streamXXX functions) */
@@ -72875,7 +72935,13 @@ FCALLSCFUN1 (INT, vlistNzaxis, VLISTNZAXIS, vlistnzaxis, INT)
FCALLSCFUN1 (INT, vlistNsubtypes, VLISTNSUBTYPES, vlistnsubtypes, INT)
FCALLSCSUB2 (vlistDefNtsteps, VLISTDEFNTSTEPS, vlistdefntsteps, INT, INT)
FCALLSCFUN1 (INT, vlistNtsteps, VLISTNTSTEPS, vlistntsteps, INT)
-FCALLSCFUN1 (INT, vlistGridsizeMax, VLISTGRIDSIZEMAX, vlistgridsizemax, INT)
+static int vlistGridsizeMax_fwrap(int vlistID)
+{
+ size_t v;
+ v = vlistGridsizeMax(vlistID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, vlistGridsizeMax_fwrap, VLISTGRIDSIZEMAX, vlistgridsizemax, INT)
FCALLSCFUN2 (INT, vlistGrid, VLISTGRID, vlistgrid, INT, INT)
FCALLSCFUN2 (INT, vlistGridIndex, VLISTGRIDINDEX, vlistgridindex, INT, INT)
FCALLSCSUB3 (vlistChangeGridIndex, VLISTCHANGEGRIDINDEX, vlistchangegridindex, INT, INT, INT)
@@ -72909,6 +72975,8 @@ FCALLSCFUN2 (INT, vlistInqVarZaxis, VLISTINQVARZAXIS, vlistinqvarzaxis, INT, INT
/* used in MPIOM */
FCALLSCFUN2 (INT, vlistInqVarID, VLISTINQVARID, vlistinqvarid, INT, INT)
+FCALLSCSUB3 (vlistDefVarTimetype, VLISTDEFVARTIMETYPE, vlistdefvartimetype, INT, INT, INT)
+FCALLSCFUN2 (INT, vlistInqVarTimetype, VLISTINQVARTIMETYPE, vlistinqvartimetype, INT, INT)
FCALLSCSUB3 (vlistDefVarTsteptype, VLISTDEFVARTSTEPTYPE, vlistdefvartsteptype, INT, INT, INT)
FCALLSCFUN2 (INT, vlistInqVarTsteptype, VLISTINQVARTSTEPTYPE, vlistinqvartsteptype, INT, INT)
FCALLSCSUB3 (vlistDefVarCompType, VLISTDEFVARCOMPTYPE, vlistdefvarcomptype, INT, INT, INT)
@@ -72957,7 +73025,13 @@ FCALLSCSUB3 (vlistDefVarTypeOfGeneratingProcess, VLISTDEFVARTYPEOFGENERATINGPROC
FCALLSCFUN2 (INT, vlistInqVarTypeOfGeneratingProcess, VLISTINQVARTYPEOFGENERATINGPROCESS, vlistinqvartypeofgeneratingprocess, INT, INT)
FCALLSCSUB3 (vlistDefVarProductDefinitionTemplate, VLISTDEFVARPRODUCTDEFINITIONTEMPLATE, vlistdefvarproductdefinitiontemplate, INT, INT, INT)
FCALLSCFUN2 (INT, vlistInqVarProductDefinitionTemplate, VLISTINQVARPRODUCTDEFINITIONTEMPLATE, vlistinqvarproductdefinitiontemplate, INT, INT)
-FCALLSCFUN2 (INT, vlistInqVarSize, VLISTINQVARSIZE, vlistinqvarsize, INT, INT)
+static int vlistInqVarSize_fwrap(int vlistID, int varID)
+{
+ size_t v;
+ v = vlistInqVarSize(vlistID, varID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, vlistInqVarSize_fwrap, VLISTINQVARSIZE, vlistinqvarsize, INT, INT)
FCALLSCSUB4 (vlistDefIndex, VLISTDEFINDEX, vlistdefindex, INT, INT, INT, INT)
FCALLSCFUN3 (INT, vlistInqIndex, VLISTINQINDEX, vlistinqindex, INT, INT, INT)
FCALLSCSUB4 (vlistDefFlag, VLISTDEFFLAG, vlistdefflag, INT, INT, INT, INT)
@@ -72979,23 +73053,18 @@ FCALLSCFUN3 (INT, vlistHasVarKey, VLISTHASVARKEY, vlisthasvarkey, INT, INT, STRI
FCALLSCFUN3 (DOUBLE, vlistInqVarDblKey, VLISTINQVARDBLKEY, vlistinqvardblkey, INT, INT, STRING)
FCALLSCFUN3 (INT, vlistInqVarIntKey, VLISTINQVARINTKEY, vlistinqvarintkey, INT, INT, STRING)
-/* needed only for CDO operator after */
-
-FCALLSCFUN2 (STRING, vlistInqVarNamePtr, VLISTINQVARNAMEPTR, vlistinqvarnameptr, INT, INT)
-FCALLSCFUN2 (STRING, vlistInqVarLongnamePtr, VLISTINQVARLONGNAMEPTR, vlistinqvarlongnameptr, INT, INT)
-FCALLSCFUN2 (STRING, vlistInqVarUnitsPtr, VLISTINQVARUNITSPTR, vlistinqvarunitsptr, INT, INT)
-
-/* VLIST attributes */
+/* CDI attributes */
-FCALLSCFUN3 (INT, vlistInqNatts, VLISTINQNATTS, vlistinqnatts, INT, INT, PINT)
-FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING, PINT, PINT)
-FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
-FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, INTV)
-FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, DOUBLEV)
-FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, PPSTRING)
-FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, INTV)
-FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, DOUBLEV)
-FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PPSTRING)
+FCALLSCFUN3 (INT, cdiInqNatts, CDIINQNATTS, cdiinqnatts, INT, INT, PINT)
+FCALLSCFUN6 (INT, cdiInqAtt, CDIINQATT, cdiinqatt, INT, INT, INT, PSTRING, PINT, PINT)
+FCALLSCFUN3 (INT, cdiDelAtt, CDIDELATT, cdidelatt, INT, INT, STRING)
+FCALLSCFUN4 (INT, cdiCopyAtts, CDICOPYATTS, cdicopyatts, INT, INT, INT, INT)
+FCALLSCFUN6 (INT, cdiDefAttInt, CDIDEFATTINT, cdidefattint, INT, INT, STRING, INT, INT, INTV)
+FCALLSCFUN6 (INT, cdiDefAttFlt, CDIDEFATTFLT, cdidefattflt, INT, INT, STRING, INT, INT, DOUBLEV)
+FCALLSCFUN5 (INT, cdiDefAttTxt, CDIDEFATTTXT, cdidefatttxt, INT, INT, STRING, INT, PPSTRING)
+FCALLSCFUN5 (INT, cdiInqAttInt, CDIINQATTINT, cdiinqattint, INT, INT, STRING, INT, INTV)
+FCALLSCFUN5 (INT, cdiInqAttFlt, CDIINQATTFLT, cdiinqattflt, INT, INT, STRING, INT, DOUBLEV)
+FCALLSCFUN5 (INT, cdiInqAttTxt, CDIINQATTTXT, cdiinqatttxt, INT, INT, STRING, INT, PPSTRING)
/* GRID routines */
@@ -73006,27 +73075,81 @@ FCALLSCSUB2 (gridDefMaskGME, GRIDDEFMASKGME, griddefmaskgme, INT, INTV)
FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, INTV)
FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, INTV)
FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, INTV)
-FCALLSCSUB3 (gridPrint, GRIDPRINT, gridprint, INT, INT, INT)
-FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
+FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
+static int gridCreate_fwrap(int gridtype, int size)
+{
+ int v;
+ v = gridCreate(gridtype, (size_t)size);
+ return v;
+}
+FCALLSCFUN2 (INT, gridCreate_fwrap, GRIDCREATE, gridcreate, INT, INT)
FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
+FCALLSCSUB2 (gridDefProj, GRIDDEFPROJ, griddefproj, INT, INT)
+FCALLSCFUN1 (INT, gridInqProj, GRIDINQPROJ, gridinqproj, INT)
+FCALLSCFUN1 (INT, gridInqProjType, GRIDINQPROJTYPE, gridinqprojtype, INT)
FCALLSCFUN1 (INT, gridInqType, GRIDINQTYPE, gridinqtype, INT)
-FCALLSCFUN1 (INT, gridInqSize, GRIDINQSIZE, gridinqsize, INT)
-FCALLSCSUB2 (gridDefXsize, GRIDDEFXSIZE, griddefxsize, INT, INT)
-FCALLSCFUN1 (INT, gridInqXsize, GRIDINQXSIZE, gridinqxsize, INT)
-FCALLSCSUB2 (gridDefYsize, GRIDDEFYSIZE, griddefysize, INT, INT)
-FCALLSCFUN1 (INT, gridInqYsize, GRIDINQYSIZE, gridinqysize, INT)
+static int gridInqSize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqSize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqSize_fwrap, GRIDINQSIZE, gridinqsize, INT)
+static void gridDefXsize_fwrap(int gridID, int xsize)
+{
+ gridDefXsize(gridID, (size_t)xsize);
+}
+FCALLSCSUB2 (gridDefXsize_fwrap, GRIDDEFXSIZE, griddefxsize, INT, INT)
+static int gridInqXsize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqXsize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqXsize_fwrap, GRIDINQXSIZE, gridinqxsize, INT)
+static void gridDefYsize_fwrap(int gridID, int ysize)
+{
+ gridDefYsize(gridID, (size_t)ysize);
+}
+FCALLSCSUB2 (gridDefYsize_fwrap, GRIDDEFYSIZE, griddefysize, INT, INT)
+static int gridInqYsize_fwrap(int gridID)
+{
+ size_t v;
+ v = gridInqYsize(gridID);
+ return size_t_c2f(v);
+}
+FCALLSCFUN1 (INT, gridInqYsize_fwrap, GRIDINQYSIZE, gridinqysize, INT)
FCALLSCSUB2 (gridDefNP, GRIDDEFNP, griddefnp, INT, INT)
FCALLSCFUN1 (INT, gridInqNP, GRIDINQNP, gridinqnp, INT)
FCALLSCSUB2 (gridDefXvals, GRIDDEFXVALS, griddefxvals, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqXvals, GRIDINQXVALS, gridinqxvals, INT, DOUBLEV)
+static int gridInqXvals_fwrap(int gridID, double xvals[])
+{
+ size_t v;
+ v = gridInqXvals(gridID, xvals);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqXvals_fwrap, GRIDINQXVALS, gridinqxvals, INT, DOUBLEV)
+FCALLSCFUN1 (INT, gridInqXIsc, GRIDINQXISC, gridinqxisc, INT)
FCALLSCSUB2 (gridDefYvals, GRIDDEFYVALS, griddefyvals, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqYvals, GRIDINQYVALS, gridinqyvals, INT, DOUBLEV)
+static int gridInqYvals_fwrap(int gridID, double yvals[])
+{
+ size_t v;
+ v = gridInqYvals(gridID, yvals);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqYvals_fwrap, GRIDINQYVALS, gridinqyvals, INT, DOUBLEV)
+FCALLSCFUN1 (INT, gridInqYIsc, GRIDINQYISC, gridinqyisc, INT)
/* CDI grid string key values */
-FCALLSCFUN4 (INT, cdiGridDefString, CDIGRIDDEFSTRING, cdigriddefstring, INT, INT, INT, STRING)
-FCALLSCFUN4 (INT, cdiGridInqString, CDIGRIDINQSTRING, cdigridinqstring, INT, INT, INT, PSTRING)
+
+/* CDI zaxis string key values */
+
+FCALLSCFUN4 (INT, cdiGridDefKeyStr, CDIGRIDDEFKEYSTR, cdigriddefkeystr, INT, INT, INT, STRING)
+FCALLSCFUN4 (INT, cdiGridInqKeyStr, CDIGRIDINQKEYSTR, cdigridinqkeystr, INT, INT, INT, PSTRING)
+FCALLSCFUN3 (INT, cdiZaxisDefKeyFlt, CDIZAXISDEFKEYFLT, cdizaxisdefkeyflt, INT, INT, DOUBLE)
+FCALLSCFUN3 (INT, cdiZaxisInqKeyFlt, CDIZAXISINQKEYFLT, cdizaxisinqkeyflt, INT, INT, PDOUBLE)
FCALLSCSUB2 (gridDefXname, GRIDDEFXNAME, griddefxname, INT, STRING)
FCALLSCSUB2 (gridInqXname, GRIDINQXNAME, gridinqxname, INT, PSTRING)
FCALLSCSUB2 (gridDefXlongname, GRIDDEFXLONGNAME, griddefxlongname, INT, STRING)
@@ -73041,34 +73164,28 @@ FCALLSCSUB2 (gridDefYunits, GRIDDEFYUNITS, griddefyunits, INT, STRING)
FCALLSCSUB2 (gridInqYunits, GRIDINQYUNITS, gridinqyunits, INT, PSTRING)
FCALLSCSUB2 (gridInqXstdname, GRIDINQXSTDNAME, gridinqxstdname, INT, PSTRING)
FCALLSCSUB2 (gridInqYstdname, GRIDINQYSTDNAME, gridinqystdname, INT, PSTRING)
-FCALLSCSUB2 (gridDefPrec, GRIDDEFPREC, griddefprec, INT, INT)
-FCALLSCFUN1 (INT, gridInqPrec, GRIDINQPREC, gridinqprec, INT)
-FCALLSCFUN2 (DOUBLE, gridInqXval, GRIDINQXVAL, gridinqxval, INT, INT)
-FCALLSCFUN2 (DOUBLE, gridInqYval, GRIDINQYVAL, gridinqyval, INT, INT)
+FCALLSCSUB2 (gridDefDatatype, GRIDDEFDATATYPE, griddefdatatype, INT, INT)
+FCALLSCFUN1 (INT, gridInqDatatype, GRIDINQDATATYPE, gridinqdatatype, INT)
+static double gridInqXval_fwrap(int gridID, int index)
+{
+ double v;
+ v = gridInqXval(gridID, (size_t)index);
+ return v;
+}
+FCALLSCFUN2 (DOUBLE, gridInqXval_fwrap, GRIDINQXVAL, gridinqxval, INT, INT)
+static double gridInqYval_fwrap(int gridID, int index)
+{
+ double v;
+ v = gridInqYval(gridID, (size_t)index);
+ return v;
+}
+FCALLSCFUN2 (DOUBLE, gridInqYval_fwrap, GRIDINQYVAL, gridinqyval, INT, INT)
FCALLSCFUN1 (DOUBLE, gridInqXinc, GRIDINQXINC, gridinqxinc, INT)
FCALLSCFUN1 (DOUBLE, gridInqYinc, GRIDINQYINC, gridinqyinc, INT)
FCALLSCFUN1 (INT, gridIsCircular, GRIDISCIRCULAR, gridiscircular, INT)
-FCALLSCFUN1 (INT, gridIsRotated, GRIDISROTATED, gridisrotated, INT)
-FCALLSCSUB2 (gridDefXpole, GRIDDEFXPOLE, griddefxpole, INT, DOUBLE)
-FCALLSCFUN1 (DOUBLE, gridInqXpole, GRIDINQXPOLE, gridinqxpole, INT)
-FCALLSCSUB2 (gridDefYpole, GRIDDEFYPOLE, griddefypole, INT, DOUBLE)
-FCALLSCFUN1 (DOUBLE, gridInqYpole, GRIDINQYPOLE, gridinqypole, INT)
-FCALLSCSUB2 (gridDefAngle, GRIDDEFANGLE, griddefangle, INT, DOUBLE)
-FCALLSCFUN1 (DOUBLE, gridInqAngle, GRIDINQANGLE, gridinqangle, INT)
FCALLSCFUN1 (INT, gridInqTrunc, GRIDINQTRUNC, gridinqtrunc, INT)
FCALLSCSUB2 (gridDefTrunc, GRIDDEFTRUNC, griddeftrunc, INT, INT)
-/* Hexagonal GME grid */
-
-FCALLSCSUB2 (gridDefGMEnd, GRIDDEFGMEND, griddefgmend, INT, INT)
-FCALLSCFUN1 (INT, gridInqGMEnd, GRIDINQGMEND, gridinqgmend, INT)
-FCALLSCSUB2 (gridDefGMEni, GRIDDEFGMENI, griddefgmeni, INT, INT)
-FCALLSCFUN1 (INT, gridInqGMEni, GRIDINQGMENI, gridinqgmeni, INT)
-FCALLSCSUB2 (gridDefGMEni2, GRIDDEFGMENI2, griddefgmeni2, INT, INT)
-FCALLSCFUN1 (INT, gridInqGMEni2, GRIDINQGMENI2, gridinqgmeni2, INT)
-FCALLSCSUB2 (gridDefGMEni3, GRIDDEFGMENI3, griddefgmeni3, INT, INT)
-FCALLSCFUN1 (INT, gridInqGMEni3, GRIDINQGMENI3, gridinqgmeni3, INT)
-
/* Reference of an unstructured grid */
FCALLSCSUB2 (gridDefNumber, GRIDDEFNUMBER, griddefnumber, INT, INT)
@@ -73080,47 +73197,64 @@ FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PST
FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, PVOID)
FCALLSCSUB2 (gridInqUUID, GRIDINQUUID, gridinquuid, INT, PVOID)
-/* Lambert Conformal Conic grid (GRIB version) */
+/* Rotated Lon/Lat grid */
-FCALLSCSUB10 (gridDefLCC, GRIDDEFLCC, griddeflcc, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, INT)
-FCALLSCSUB10 (gridInqLCC, GRIDINQLCC, gridinqlcc, INT, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PINT, PINT)
+FCALLSCSUB4 (gridDefParamRLL, GRIDDEFPARAMRLL, griddefparamrll, INT, DOUBLE, DOUBLE, DOUBLE)
+FCALLSCSUB4 (gridInqParamRLL, GRIDINQPARAMRLL, gridinqparamrll, INT, PDOUBLE, PDOUBLE, PDOUBLE)
-/* Lambert Conformal Conic 2 grid (PROJ version) */
+/* Hexagonal GME grid */
-FCALLSCSUB6 (gridDefLcc2, GRIDDEFLCC2, griddeflcc2, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE)
-FCALLSCSUB6 (gridInqLcc2, GRIDINQLCC2, gridinqlcc2, INT, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE)
+FCALLSCSUB5 (gridDefParamGME, GRIDDEFPARAMGME, griddefparamgme, INT, INT, INT, INT, INT)
+FCALLSCSUB5 (gridInqParamGME, GRIDINQPARAMGME, gridinqparamgme, INT, PINT, PINT, PINT, PINT)
-/* Lambert Azimuthal Equal Area grid */
+/* Lambert Conformal Conic grid (GRIB version) */
-FCALLSCSUB4 (gridDefLaea, GRIDDEFLAEA, griddeflaea, INT, DOUBLE, DOUBLE, DOUBLE)
-FCALLSCSUB4 (gridInqLaea, GRIDINQLAEA, gridinqlaea, INT, PDOUBLE, PDOUBLE, PDOUBLE)
+FCALLSCSUB12 (gridDefParamLCC, GRIDDEFPARAMLCC, griddefparamlcc, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE)
+FCALLSCFUN12 (INT, gridInqParamLCC, GRIDINQPARAMLCC, gridinqparamlcc, INT, DOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE)
FCALLSCSUB2 (gridDefArea, GRIDDEFAREA, griddefarea, INT, DOUBLEV)
FCALLSCSUB2 (gridInqArea, GRIDINQAREA, gridinqarea, INT, DOUBLEV)
FCALLSCFUN1 (INT, gridHasArea, GRIDHASAREA, gridhasarea, INT)
FCALLSCSUB2 (gridDefNvertex, GRIDDEFNVERTEX, griddefnvertex, INT, INT)
FCALLSCFUN1 (INT, gridInqNvertex, GRIDINQNVERTEX, gridinqnvertex, INT)
FCALLSCSUB2 (gridDefXbounds, GRIDDEFXBOUNDS, griddefxbounds, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqXbounds, GRIDINQXBOUNDS, gridinqxbounds, INT, DOUBLEV)
+static int gridInqXbounds_fwrap(int gridID, double xbounds[])
+{
+ size_t v;
+ v = gridInqXbounds(gridID, xbounds);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqXbounds_fwrap, GRIDINQXBOUNDS, gridinqxbounds, INT, DOUBLEV)
FCALLSCSUB2 (gridDefYbounds, GRIDDEFYBOUNDS, griddefybounds, INT, DOUBLEV)
-FCALLSCFUN2 (INT, gridInqYbounds, GRIDINQYBOUNDS, gridinqybounds, INT, DOUBLEV)
+static int gridInqYbounds_fwrap(int gridID, double ybounds[])
+{
+ size_t v;
+ v = gridInqYbounds(gridID, ybounds);
+ return size_t_c2f(v);
+}
+FCALLSCFUN2 (INT, gridInqYbounds_fwrap, GRIDINQYBOUNDS, gridinqybounds, INT, DOUBLEV)
FCALLSCSUB3 (gridDefRowlon, GRIDDEFROWLON, griddefrowlon, INT, INT, INTV)
FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, INTV)
FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
FCALLSCSUB2 (gridDefComplexPacking, GRIDDEFCOMPLEXPACKING, griddefcomplexpacking, INT, INT)
FCALLSCFUN1 (INT, gridInqComplexPacking, GRIDINQCOMPLEXPACKING, gridinqcomplexpacking, INT)
+FCALLSCSUB2 (gridDefUvRelativeToGrid, GRIDDEFUVRELATIVETOGRID, griddefuvrelativetogrid, INT, INT)
+FCALLSCFUN1 (INT, gridInqUvRelativeToGrid, GRIDINQUVRELATIVETOGRID, gridinquvrelativetogrid, INT)
+FCALLSCSUB2 (gridDefScanningMode, GRIDDEFSCANNINGMODE, griddefscanningmode, INT, INT)
+FCALLSCFUN1 (INT, gridInqScanningMode, GRIDINQSCANNINGMODE, gridinqscanningmode, INT)
/* ZAXIS routines */
FCALLSCSUB2 (zaxisName, ZAXISNAME, zaxisname, INT, PSTRING)
+FCALLSCFUN1 (STRING, zaxisNamePtr, ZAXISNAMEPTR, zaxisnameptr, INT)
FCALLSCFUN2 (INT, zaxisCreate, ZAXISCREATE, zaxiscreate, INT, INT)
FCALLSCSUB1 (zaxisDestroy, ZAXISDESTROY, zaxisdestroy, INT)
FCALLSCFUN1 (INT, zaxisInqType, ZAXISINQTYPE, zaxisinqtype, INT)
FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
-FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
-FCALLSCSUB2 (zaxisPrint, ZAXISPRINT, zaxisprint, INT, INT)
+FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, DOUBLEV)
-FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, DOUBLEV)
+FCALLSCFUN2 (INT, zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, DOUBLEV)
+FCALLSCFUN1 (INT, zaxisInqCLen, ZAXISINQCLEN, zaxisinqclen, INT)
FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
FCALLSCFUN2 (DOUBLE, zaxisInqLevel, ZAXISINQLEVEL, zaxisinqlevel, INT, INT)
FCALLSCSUB2 (zaxisDefNlevRef, ZAXISDEFNLEVREF, zaxisdefnlevref, INT, INT)
@@ -73129,11 +73263,8 @@ FCALLSCSUB2 (zaxisDefNumber, ZAXISDEFNUMBER, zaxisdefnumber, INT, INT)
FCALLSCFUN1 (INT, zaxisInqNumber, ZAXISINQNUMBER, zaxisinqnumber, INT)
FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, PVOID)
FCALLSCSUB2 (zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PVOID)
-
-/* CDI zaxis string key values */
-
-FCALLSCFUN4 (INT, cdiZaxisDefString, CDIZAXISDEFSTRING, cdizaxisdefstring, INT, INT, INT, STRING)
-FCALLSCFUN4 (INT, cdiZaxisInqString, CDIZAXISINQSTRING, cdizaxisinqstring, INT, INT, INT, PSTRING)
+FCALLSCFUN4 (INT, cdiZaxisDefKeyStr, CDIZAXISDEFKEYSTR, cdizaxisdefkeystr, INT, INT, INT, STRING)
+FCALLSCFUN4 (INT, cdiZaxisInqKeyStr, CDIZAXISINQKEYSTR, cdizaxisinqkeystr, INT, INT, INT, PSTRING)
FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
FCALLSCSUB2 (zaxisInqName, ZAXISINQNAME, zaxisinqname, INT, PSTRING)
FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
@@ -73141,10 +73272,8 @@ FCALLSCSUB2 (zaxisInqLongname, ZAXISINQLONGNAME, zaxisinqlongname, INT, PSTRING)
FCALLSCSUB2 (zaxisDefUnits, ZAXISDEFUNITS, zaxisdefunits, INT, STRING)
FCALLSCSUB2 (zaxisInqUnits, ZAXISINQUNITS, zaxisinqunits, INT, PSTRING)
FCALLSCSUB2 (zaxisInqStdname, ZAXISINQSTDNAME, zaxisinqstdname, INT, PSTRING)
-FCALLSCSUB2 (zaxisDefPsName, ZAXISDEFPSNAME, zaxisdefpsname, INT, STRING)
-FCALLSCSUB2 (zaxisInqPsName, ZAXISINQPSNAME, zaxisinqpsname, INT, PSTRING)
-FCALLSCSUB2 (zaxisDefPrec, ZAXISDEFPREC, zaxisdefprec, INT, INT)
-FCALLSCFUN1 (INT, zaxisInqPrec, ZAXISINQPREC, zaxisinqprec, INT)
+FCALLSCSUB2 (zaxisDefDatatype, ZAXISDEFDATATYPE, zaxisdefdatatype, INT, INT)
+FCALLSCFUN1 (INT, zaxisInqDatatype, ZAXISINQDATATYPE, zaxisinqdatatype, INT)
FCALLSCSUB2 (zaxisDefPositive, ZAXISDEFPOSITIVE, zaxisdefpositive, INT, INT)
FCALLSCFUN1 (INT, zaxisInqPositive, ZAXISINQPOSITIVE, zaxisinqpositive, INT)
FCALLSCSUB1 (zaxisDefScalar, ZAXISDEFSCALAR, zaxisdefscalar, INT)
@@ -73184,6 +73313,7 @@ FCALLSCSUB2 (taxisDefFtime, TAXISDEFFTIME, taxisdefftime, INT, INT)
FCALLSCFUN1 (INT, taxisInqFdate, TAXISINQFDATE, taxisinqfdate, INT)
FCALLSCFUN1 (INT, taxisInqFtime, TAXISINQFTIME, taxisinqftime, INT)
FCALLSCFUN1 (INT, taxisHasBounds, TAXISHASBOUNDS, taxishasbounds, INT)
+FCALLSCSUB1 (taxisWithBounds, TAXISWITHBOUNDS, taxiswithbounds, INT)
FCALLSCSUB1 (taxisDeleteBounds, TAXISDELETEBOUNDS, taxisdeletebounds, INT)
FCALLSCSUB3 (taxisDefVdateBounds, TAXISDEFVDATEBOUNDS, taxisdefvdatebounds, INT, INT, INT)
FCALLSCSUB3 (taxisDefVtimeBounds, TAXISDEFVTIMEBOUNDS, taxisdefvtimebounds, INT, INT, INT)
@@ -73222,27 +73352,15 @@ FCALLSCFUN1 (STRING, modelInqNamePtr, MODELINQNAMEPTR, modelinqnameptr, INT)
/* Table routines */
-FCALLSCSUB2 (tableWriteC, TABLEWRITEC, tablewritec, STRING, INT)
FCALLSCSUB2 (tableWrite, TABLEWRITE, tablewrite, STRING, INT)
FCALLSCFUN1 (INT, tableRead, TABLEREAD, tableread, STRING)
FCALLSCFUN3 (INT, tableDef, TABLEDEF, tabledef, INT, INT, STRING)
FCALLSCFUN1 (STRING, tableInqNamePtr, TABLEINQNAMEPTR, tableinqnameptr, INT)
-FCALLSCSUB5 (tableDefEntry, TABLEDEFENTRY, tabledefentry, INT, INT, STRING, STRING, STRING)
FCALLSCFUN3 (INT, tableInq, TABLEINQ, tableinq, INT, INT, STRING)
FCALLSCFUN0 (INT, tableInqNumber, TABLEINQNUMBER, tableinqnumber)
FCALLSCFUN1 (INT, tableInqNum, TABLEINQNUM, tableinqnum, INT)
FCALLSCFUN1 (INT, tableInqModel, TABLEINQMODEL, tableinqmodel, INT)
-FCALLSCSUB5 (tableInqPar, TABLEINQPAR, tableinqpar, INT, INT, PSTRING, PSTRING, PSTRING)
-FCALLSCFUN3 (INT, tableInqParCode, TABLEINQPARCODE, tableinqparcode, INT, PSTRING, PINT)
-FCALLSCFUN3 (INT, tableInqParName, TABLEINQPARNAME, tableinqparname, INT, INT, PSTRING)
-FCALLSCFUN3 (INT, tableInqParLongname, TABLEINQPARLONGNAME, tableinqparlongname, INT, INT, PSTRING)
-FCALLSCFUN3 (INT, tableInqParUnits, TABLEINQPARUNITS, tableinqparunits, INT, INT, PSTRING)
-
-/* needed only for CDO operator after */
-
-FCALLSCFUN2 (STRING, tableInqParNamePtr, TABLEINQPARNAMEPTR, tableinqparnameptr, INT, INT)
-FCALLSCFUN2 (STRING, tableInqParLongnamePtr, TABLEINQPARLONGNAMEPTR, tableinqparlongnameptr, INT, INT)
-FCALLSCFUN2 (STRING, tableInqParUnitsPtr, TABLEINQPARUNITSPTR, tableinqparunitsptr, INT, INT)
+FCALLSCSUB6 (tableInqEntry, TABLEINQENTRY, tableinqentry, INT, INT, INT, PSTRING, PSTRING, PSTRING)
/* History routines */
@@ -73276,4 +73394,7 @@ FCALLSCFUN4 (INT, subtypeInqAttribute, SUBTYPEINQATTRIBUTE, subtypeinqattribute,
FCALLSCFUN2 (INT, vlistInqVarSubtype, VLISTINQVARSUBTYPE, vlistinqvarsubtype, INT, INT)
FCALLSCSUB3 (gribapiLibraryVersion, GRIBAPILIBRARYVERSION, gribapilibraryversion, PINT, PINT, PINT)
+#if defined __clang__
+# pragma GCC diagnostic pop
+#endif
#endif
diff --git a/libcdi/src/cdipio.h b/libcdi/src/cdipio.h
index 4ff825a..d5df933 100644
--- a/libcdi/src/cdipio.h
+++ b/libcdi/src/cdipio.h
@@ -49,12 +49,12 @@ void pioWriteTimestep(void);
void cdiPioRDMAProgress(void);
void streamWriteVarPart (int streamID, int varID,
- const void *data, int nmiss,
+ const void *data, size_t nmiss,
Xt_idxlist partDesc);
void streamWriteScatteredVarPart(int streamID, int varID, const void *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc);
+ size_t nmiss, Xt_idxlist partDesc);
/* cdiPioCSRLastN: return role codes appropriate to use the last
\textit{nProcsIO} tasks as I/O servers */
int cdiPioCSRLastN(MPI_Comm commSuper, int IOMode, int nProcsIO);
diff --git a/libcdi/src/cdipioFortran.c b/libcdi/src/cdipioFortran.c
index b076ece..e51c477 100644
--- a/libcdi/src/cdipioFortran.c
+++ b/libcdi/src/cdipioFortran.c
@@ -55,12 +55,12 @@ static int cdiPioInit_fwrap(int commSuper, int confResH, int *pioNamespace)
FCALLSCFUN3 (INT, cdiPioInit_fwrap, CDIPIOINIT, cdipioinit, INT, INT, PINT)
FCALLSCSUB0 (pioWriteTimestep, PIOWRITETIMESTEP, piowritetimestep)
FCALLSCSUB0 (cdiPioRDMAProgress, CDIPIORDMAPROGRESS, cdipiordmaprogress)
-static void streamWriteVarPart_fwrap(int streamID, int varID, const void *data, int nmiss, void *partDesc)
+static void streamWriteVarPart_fwrap(int streamID, int varID, const void *data, size_t nmiss, void *partDesc)
{
streamWriteVarPart(streamID, varID, data, nmiss, (*(Xt_idxlist *)partDesc));
}
FCALLSCSUB5 (streamWriteVarPart_fwrap, STREAMWRITEVARPART, streamwritevarpart, INT, INT, PVOID, INT, PVOID)
-static void streamWriteScatteredVarPart_fwrap(int streamID, int varID, const void *data, int numBlocks, const int blocklengths[], const int displacements[], int nmiss, void *partDesc)
+static void streamWriteScatteredVarPart_fwrap(int streamID, int varID, const void *data, int numBlocks, const int blocklengths[], const int displacements[], size_t nmiss, void *partDesc)
{
streamWriteScatteredVarPart(streamID, varID, data, numBlocks, blocklengths, displacements, nmiss, (*(Xt_idxlist *)partDesc));
}
diff --git a/libcdi/src/config.h.in b/libcdi/src/config.h.in
index 3110e95..1293cb9 100644
--- a/libcdi/src/config.h.in
+++ b/libcdi/src/config.h.in
@@ -267,6 +267,11 @@
# endif
#endif
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
diff --git a/libcdi/src/grb_read.c b/libcdi/src/grb_read.c
index 787dd65..ee5f3d2 100644
--- a/libcdi/src/grb_read.c
+++ b/libcdi/src/grb_read.c
@@ -16,8 +16,8 @@
static
-int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *data, size_t datasize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID)
+int grbDecode(int filetype, int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID)
{
int status = 0;
@@ -29,7 +29,7 @@ int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *d
if ( cdiNAdditionalGRIBKeys > 0 )
Error("CGRIBEX decode does not support reading of additional GRIB keys!");
#endif
- status = cgribexDecode(memtype, gribbuffer, gribsize, data, (long) datasize, unreduced, nmiss, missval);
+ status = cgribexDecode(memtype, gribbuffer, gribsize, data, datasize, unreduced, nmiss, missval);
}
else
#endif
@@ -39,7 +39,7 @@ int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *d
if ( memtype == MEMTYPE_FLOAT )
datap = Malloc(datasize*sizeof(double));
- status = gribapiDecode(gribbuffer, gribsize, datap, (long) datasize, unreduced, nmiss, missval, vlistID, varID);
+ status = gribapiDecode(gribbuffer, gribsize, datap, datasize, unreduced, nmiss, missval, vlistID, varID);
if ( memtype == MEMTYPE_FLOAT )
{
@@ -111,7 +111,7 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
}
-void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
+void grb_read_record(stream_t * streamptr, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -127,7 +127,7 @@ void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
int varID = streamptr->tsteps[tsID].records[recID].varID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
streamptr->numvals += gridsize;
@@ -140,11 +140,11 @@ void grb_read_record(stream_t * streamptr, int memtype, void *data, int *nmiss)
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, data, (size_t)gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+ grbDecode(filetype, memtype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
}
-void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int *nmiss)
+void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -155,14 +155,14 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
int tsID = streamptr->curTsID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
off_t currentfilepos = fileGetPos(fileID);
int isub = subtypeInqActiveIndex(streamptr->vars[varID].subtypeID);
int nlevs = streamptr->vars[varID].recordTable[0].nlevs;
if ( CDI_Debug )
- Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+ Message("nlevs = %d gridID = %d gridsize = %zu", nlevs, gridID, gridsize);
*nmiss = 0;
for (int levelID = 0; levelID < nlevs; levelID++ )
{
@@ -176,7 +176,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
double missval = vlistInqVarMissval(vlistID, varID);
- int imiss;
+ size_t imiss;
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
@@ -186,7 +186,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
else
datap = (double*)data + levelID*gridsize;
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, datap, (size_t)gridsize,
+ grbDecode(filetype, memtype, gribbuffer, recsize, datap, gridsize,
streamptr->unreduced, &imiss, missval, vlistID, varID);
*nmiss += imiss;
@@ -196,7 +196,7 @@ void grb_read_var(stream_t * streamptr, int varID, int memtype, void *data, int
}
-void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss)
+void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss)
{
int filetype = streamptr->filetype;
@@ -204,11 +204,11 @@ void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
int vlistID = streamptr->vlistID;
int gridID = vlistInqVarGrid(vlistID, varID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
int tsID = streamptr->curTsID;
if ( CDI_Debug )
- Message("gridID = %d gridsize = %d", gridID, gridsize);
+ Message("gridID = %d gridsize = %zu", gridID, gridsize);
int fileID = streamptr->fileID;
@@ -230,7 +230,7 @@ void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
double missval = vlistInqVarMissval(vlistID, varID);
- grbDecode(filetype, memtype, gribbuffer, (int)recsize, data, (size_t)gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+ grbDecode(filetype, memtype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
fileSetPos(fileID, currentfilepos, SEEK_SET);
}
diff --git a/libcdi/src/grb_write.c b/libcdi/src/grb_write.c
index c868ac6..d1c689f 100644
--- a/libcdi/src/grb_write.c
+++ b/libcdi/src/grb_write.c
@@ -19,7 +19,7 @@
static
size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int date, int time, int tsteptype, int numavg,
- size_t datasize, const void *data, int nmiss, void **gribbuffer,
+ size_t datasize, const void *data, size_t nmiss, void **gribbuffer,
int comptype, void *gribContainer)
{
size_t nbytes = 0;
@@ -32,7 +32,7 @@ size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID,
nbytes = cgribexEncode(memtype, varID, levelID, vlistID, gridID, zaxisID,
date, time, tsteptype, numavg,
- (long) datasize, data, nmiss, *gribbuffer, gribbuffersize);
+ datasize, data, nmiss, *gribbuffer, gribbuffersize);
}
else
#endif
@@ -152,23 +152,19 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
if (scanModeIN != cdiGribDataScanningMode.value)
{
- int gridID;
- int varID, levelID;
- int vlistID;
//int zip;
- int gridsize, nmiss = 0;
+ size_t nmiss = 0;
- vlistID = streamptr1->vlistID;
- varID = streamptr1->tsteps[tsID].records[recID].varID;
- levelID = streamptr1->tsteps[tsID].records[recID].levelID;
+ int vlistID = streamptr1->vlistID;
+ int varID = streamptr1->tsteps[tsID].records[recID].varID;
+ int levelID = streamptr1->tsteps[tsID].records[recID].levelID;
//gribbuffer = (unsigned char *) streamptr->record->buffer;
// allocate above ..
- gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = gridInqSize(gridID);
+ int gridID = vlistInqVarGrid(vlistID, varID);
- gridsize = vlistGridsizeMax(vlistID);
+ size_t gridsize = vlistGridsizeMax(vlistID);
if ( vlistNumber(vlistID) != CDI_REAL ) gridsize *= 2;
- double * data = (double *) malloc(gridsize*sizeof(double));
+ double *data = (double *) malloc(gridsize*sizeof(double));
//int missval = vlistInqVarMissval(vlistID, varID);
//streamptr->numvals += gridsize;
@@ -176,7 +172,7 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
// memtype: MEMTYPE_FLOAT or MEMTYPE_DOUBLE
//int statusDC = grbDecode(filetype, MEMTYPE_DOUBLE, gribbuffer, recsize, data, gridsize, streamptr1->unreduced, &nmiss, missval, vlistID, varID);
//int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *data, size_t datasize,
- // int unreduced, int *nmiss, double missval, int vlistID, int varID);
+ // int unreduced, size_t *nmiss, double missval, int vlistID, int varID);
//streamptr1->tsteps[tsID].records[recID].zip = zip;
//gribapiSetScanningMode(gh, cdoGribDataScanningMode); // T.B.D. this will be done by grbDecode..
@@ -190,7 +186,7 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
//grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
//grb_write_var(streamptr2, varID, MEMTYPE_DOUBLE, data, nmiss);
- //grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
+ //grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
//grb_write_var_slice(streamptr2, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
free(data);
@@ -221,7 +217,7 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
}
-void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
+void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
void *gribbuffer = NULL;
void *gc = NULL;
@@ -241,7 +237,7 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
if ( CDI_Debug )
Message("gridID = %d zaxisID = %d", gridID, zaxisID);
- size_t datasize = (size_t)gridInqSize(gridID);
+ size_t datasize = gridInqSize(gridID);
#ifdef HAVE_LIBCGRIBEX
if ( filetype == CDI_FILETYPE_GRB )
@@ -289,22 +285,22 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
}
-void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss)
{
int vlistID = streamptr->vlistID,
gridID = vlistInqVarGrid(vlistID, varID),
- gridsize = gridInqSize(gridID),
zaxisID = vlistInqVarZaxis(vlistID, varID),
nlevs = zaxisInqSize(zaxisID);
+ size_t gridsize = gridInqSize(gridID);
double missval = vlistInqVarMissval(vlistID, varID);
- size_t chunkLen = (size_t)gridsize;
+ size_t chunkLen = gridsize;
if ( memtype == MEMTYPE_FLOAT )
for ( int levelID = 0; levelID < nlevs; levelID++ )
{
const float *restrict fdata = ((const float *)data)+levelID*gridsize;
- int nmiss_slice = 0;
+ size_t nmiss_slice = 0;
if ( nmiss )
for ( size_t i = 0; i < chunkLen; ++i )
nmiss_slice += DBL_IS_EQUAL(fdata[i], missval);
@@ -316,7 +312,7 @@ void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data
{
const double *restrict ddata = ((const double *)data)+levelID*gridsize;
- int nmiss_slice = 0;
+ size_t nmiss_slice = 0;
if ( nmiss )
for ( size_t i = 0; i < chunkLen; ++i )
nmiss_slice += DBL_IS_EQUAL(ddata[i], missval);
@@ -326,7 +322,7 @@ void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data
}
-void grb_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+void grb_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss)
{
int varID = streamptr->record->varID;
int levelID = streamptr->record->levelID;
diff --git a/libcdi/src/gribapi_utilities.c b/libcdi/src/gribapi_utilities.c
index 5e88cd9..dd583c2 100644
--- a/libcdi/src/gribapi_utilities.c
+++ b/libcdi/src/gribapi_utilities.c
@@ -527,16 +527,17 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
size_t datasize;
FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
- long numberOfPoints;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
-
long lpar;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &lpar);
+ size_t numberOfPoints = (size_t) lpar;
+
if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
{
- long nlon, nlat;
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &nlon);
- FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &nlat);
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &lpar);
+ size_t nlon = (size_t) lpar;
+ FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+ size_t nlat = (size_t) lpar;
if ( gridtype == GRID_GAUSSIAN )
{
@@ -545,11 +546,11 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
}
if ( numberOfPoints != nlon*nlat )
- Error("numberOfPoints (%ld) and gridSize (%ld) differ!", numberOfPoints, nlon*nlat);
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", numberOfPoints, nlon*nlat);
- grid->size = (int)numberOfPoints;
- grid->x.size = (int)nlon;
- grid->y.size = (int)nlat;
+ grid->size = numberOfPoints;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
grid->x.inc = 0;
grid->y.inc = 0;
grid->x.flag = 0;
@@ -611,7 +612,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
int nlat = (int)lpar;
- grid->size = (int)numberOfPoints;
+ grid->size = numberOfPoints;
grid->nrowlon = nlat;
grid->rowlon = (int *) Malloc((size_t)nlat * sizeof (int));
@@ -621,7 +622,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
for ( int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
Free(pl);
- grid->y.size = nlat;
+ grid->y.size = (size_t)nlat;
grid->x.inc = 0;
grid->y.inc = 0;
grid->x.flag = 0;
@@ -670,14 +671,14 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
else if ( projtype == CDI_PROJ_LCC )
{
FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
- int nlon = (int)lpar;
+ size_t nlon = (size_t)lpar;
FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
- int nlat = (int)lpar;
+ size_t nlat = (size_t)lpar;
if ( numberOfPoints != nlon*nlat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", numberOfPoints, nlon*nlat);
- grid->size = (int)numberOfPoints;
+ grid->size = numberOfPoints;
grid->x.size = nlon;
grid->y.size = nlat;
@@ -702,14 +703,14 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
grid->lcomplex = 0;
if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
- grid->size = (int)datasize;
+ grid->size = datasize;
FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
grid->trunc = (int)lpar;
}
else if ( gridtype == GRID_GME )
{
- grid->size = (int)numberOfPoints;
+ grid->size = numberOfPoints;
if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->gme.nd = (int)lpar;
if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->gme.ni = (int)lpar;
if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->gme.ni2 = (int)lpar;
@@ -723,7 +724,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
size_t len = sizeof(reference_link);
reference_link[0] = 0;
*/
- grid->size = (int)numberOfPoints;
+ grid->size = numberOfPoints;
if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
{
@@ -746,11 +747,11 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
}
else if ( gridtype == GRID_GENERIC )
{
- int nlon = 0, nlat = 0;
- if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
- if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+ size_t nlon = 0, nlat = 0;
+ if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (size_t)lpar;
+ if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (size_t)lpar;
- grid->size = (int)numberOfPoints;
+ grid->size = numberOfPoints;
if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
{
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index d87ccd6..405e095 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -4,8 +4,6 @@
#include <assert.h>
#include <string.h>
-#include <float.h> /* FLT_EPSILON */
-#include <limits.h> /* INT_MAX */
#include "dmemory.h"
#include "cdi.h"
@@ -290,7 +288,7 @@ void gridSetName(char *gridstrname, const char *name)
}
-void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
+void cdiGridTypeInit(grid_t *gridptr, int gridtype, size_t size)
{
gridptr->type = gridtype;
gridptr->size = size;
@@ -379,18 +377,18 @@ void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *r
}
static
-void calc_gaussgrid(double *restrict yvals, int ysize, double yfirst, double ylast)
+void calc_gaussgrid(double *restrict yvals, size_t ysize, double yfirst, double ylast)
{
- double *restrict yw = (double *) Malloc((size_t)ysize * sizeof(double));
- gaussaw(yvals, yw, (size_t)ysize);
+ double *restrict yw = (double *) Malloc(ysize * sizeof(double));
+ gaussaw(yvals, yw, ysize);
Free(yw);
- for (int i = 0; i < ysize; i++ )
+ for (size_t i = 0; i < ysize; i++ )
yvals[i] = asin(yvals[i])/M_PI*180.0;
if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
{
- int yhsize = ysize/2;
- for (int i = 0; i < yhsize; i++ )
+ size_t yhsize = ysize/2;
+ for (size_t i = 0; i < yhsize; i++ )
{
double ytmp = yvals[i];
yvals[i] = yvals[ysize-i-1];
@@ -414,7 +412,8 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
{
double *restrict ytmp = NULL;
- int nstart, lfound = 0;
+ int nstart;
+ bool lfound = false;
int ny = (int) (180./(fabs(ylast-yfirst)/(ysize-1)) + 0.5);
ny -= ny%2;
if ( ny > ysize && ny < 4096 )
@@ -494,7 +493,7 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
@Function gridCreate
@Title Create a horizontal Grid
- at Prototype int gridCreate(int gridtype, int size)
+ at Prototype int gridCreate(int gridtype, size_t size)
@Parameter
@Item gridtype The type of the grid, one of the set of predefined CDI grid types.
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
@@ -530,11 +529,9 @@ gridDefYvals(gridID, lats);
@EndSource
@EndFunction
*/
-int gridCreate(int gridtype, int size)
+int gridCreate(int gridtype, size_t size)
{
- if ( CDI_Debug ) Message("gridtype=%s size=%d", gridNamePtr(gridtype), size);
-
- if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
+ if ( CDI_Debug ) Message("gridtype=%s size=%zu", gridNamePtr(gridtype), size);
gridInit();
@@ -1082,7 +1079,7 @@ int gridInqType(int gridID)
@Function gridInqSize
@Title Get the size of a Grid
- at Prototype int gridInqSize(int gridID)
+ at Prototype size_t gridInqSize(int gridID)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@@ -1094,21 +1091,18 @@ The function @func{gridInqSize} returns the size of a Grid.
@EndFunction
*/
-int gridInqSize(int gridID)
+size_t gridInqSize(int gridID)
{
grid_t *gridptr = grid_to_pointer(gridID);
- int size = gridptr->size;
+ size_t size = gridptr->size;
if ( size == 0 )
{
- int xsize = gridptr->x.size;
- int ysize = gridptr->y.size;
+ size_t xsize = gridptr->x.size;
+ size_t ysize = gridptr->y.size;
- if ( ysize )
- size = xsize * ysize;
- else
- size = xsize;
+ size = ysize ? xsize * ysize : xsize;
gridptr->size = size;
}
@@ -1163,7 +1157,7 @@ void gridDefTrunc(int gridID, int trunc)
@Function gridDefXsize
@Title Define the number of values of a X-axis
- at Prototype void gridDefXsize(int gridID, int xsize)
+ at Prototype void gridDefXsize(int gridID, size_t xsize)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate}.
@Item xsize Number of values of a X-axis.
@@ -1173,17 +1167,17 @@ The function @func{gridDefXsize} defines the number of values of a X-axis.
@EndFunction
*/
-void gridDefXsize(int gridID, int xsize)
+void gridDefXsize(int gridID, size_t xsize)
{
grid_t *gridptr = grid_to_pointer(gridID);
- int gridSize = gridInqSize(gridID);
+ size_t gridSize = gridInqSize(gridID);
if ( xsize > gridSize )
- Error("xsize %d is greater then gridsize %d", xsize, gridSize);
+ Error("xsize %zu is greater then gridsize %zu", xsize, gridSize);
int gridType = gridInqType(gridID);
if ( gridType == GRID_UNSTRUCTURED && xsize != gridSize )
- Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
+ Error("xsize %zu must be equal to gridsize %zu for gridtype: UNSTRUCTURED", xsize, gridSize);
if ( gridptr->x.size != xsize )
{
@@ -1193,9 +1187,9 @@ void gridDefXsize(int gridID, int xsize)
if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
{
- long axisproduct = gridptr->x.size*gridptr->y.size;
+ size_t axisproduct = gridptr->x.size*gridptr->y.size;
if ( axisproduct > 0 && axisproduct != gridSize )
- Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
+ Error("Inconsistent grid declaration! (xsize=%zu ysize=%zu gridsize=%zu)",
gridptr->x.size, gridptr->y.size, gridSize);
}
}
@@ -1241,7 +1235,7 @@ int gridInqDatatype(int gridID)
@Function gridInqXsize
@Title Get the number of values of a X-axis
- at Prototype int gridInqXsize(int gridID)
+ at Prototype size_t gridInqXsize(int gridID)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@@ -1253,7 +1247,7 @@ The function @func{gridInqXsize} returns the number of values of a X-axis.
@EndFunction
*/
-int gridInqXsize(int gridID)
+size_t gridInqXsize(int gridID)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->x.size;
@@ -1263,7 +1257,7 @@ int gridInqXsize(int gridID)
@Function gridDefYsize
@Title Define the number of values of a Y-axis
- at Prototype void gridDefYsize(int gridID, int ysize)
+ at Prototype void gridDefYsize(int gridID, size_t ysize)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate}.
@Item ysize Number of values of a Y-axis.
@@ -1273,18 +1267,18 @@ The function @func{gridDefYsize} defines the number of values of a Y-axis.
@EndFunction
*/
-void gridDefYsize(int gridID, int ysize)
+void gridDefYsize(int gridID, size_t ysize)
{
grid_t *gridptr = grid_to_pointer(gridID);
- int gridSize = gridInqSize(gridID);
+ size_t gridSize = gridInqSize(gridID);
if ( ysize > gridSize )
- Error("ysize %d is greater then gridsize %d", ysize, gridSize);
+ Error("ysize %zu is greater then gridsize %zu", ysize, gridSize);
int gridType = gridInqType(gridID);
if ( gridType == GRID_UNSTRUCTURED && ysize != gridSize )
- Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridSize);
+ Error("ysize %zu must be equal gridsize %zu for gridtype: UNSTRUCTURED", ysize, gridSize);
if ( gridptr->y.size != ysize )
{
@@ -1294,9 +1288,9 @@ void gridDefYsize(int gridID, int ysize)
if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
{
- long axisproduct = gridptr->x.size*gridptr->y.size;
+ size_t axisproduct = gridptr->x.size*gridptr->y.size;
if ( axisproduct > 0 && axisproduct != gridSize )
- Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
+ Error("Inconsistent grid declaration! (xsize=%zu ysize=%zu gridsize=%zu)",
gridptr->x.size, gridptr->y.size, gridSize);
}
}
@@ -1305,7 +1299,7 @@ void gridDefYsize(int gridID, int ysize)
@Function gridInqYsize
@Title Get the number of values of a Y-axis
- at Prototype int gridInqYsize(int gridID)
+ at Prototype size_t gridInqYsize(int gridID)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@@ -1317,7 +1311,7 @@ The function @func{gridInqYsize} returns the number of values of a Y-axis.
@EndFunction
*/
-int gridInqYsize(int gridID)
+size_t gridInqYsize(int gridID)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->y.size;
@@ -1411,11 +1405,11 @@ void gridInqRowlon(int gridID, int *rowlon)
memcpy(rowlon, gridptr->rowlon, (size_t)gridptr->nrowlon * sizeof(int));
}
-static int
+static size_t
gridInqMaskSerialGeneric(grid_t *gridptr, mask_t **internalMask,
int *restrict mask)
{
- long size = gridptr->size;
+ size_t size = gridptr->size;
if ( CDI_Debug && size == 0 )
Warning("Size undefined for gridID = %d", gridptr->self);
@@ -1424,16 +1418,16 @@ gridInqMaskSerialGeneric(grid_t *gridptr, mask_t **internalMask,
if ( mask_src )
{
if (mask && size > 0)
- for (size_t i = 0; i < (size_t)size; ++i)
+ for (size_t i = 0; i < size; ++i)
mask[i] = (int)mask_src[i];
}
else
size = 0;
- return (int)size;
+ return size;
}
-static int
+static size_t
gridInqMaskSerial(grid_t *gridptr, int *mask)
{
return gridInqMaskSerialGeneric(gridptr, &gridptr->mask, mask);
@@ -1449,7 +1443,7 @@ int gridInqMask(int gridID, int *mask)
static void
gridDefMaskSerial(grid_t *gridptr, const int *mask)
{
- long size = gridptr->size;
+ size_t size = gridptr->size;
if ( size == 0 )
Error("Size undefined for gridID = %d", gridptr->self);
@@ -1465,11 +1459,11 @@ gridDefMaskSerial(grid_t *gridptr, const int *mask)
else
{
if ( gridptr->mask == NULL )
- gridptr->mask = (mask_t *) Malloc((size_t)size*sizeof(mask_t));
+ gridptr->mask = (mask_t *) Malloc(size*sizeof(mask_t));
else if ( CDI_Debug )
Warning("grid mask already defined!");
- for (long i = 0; i < size; ++i )
+ for (size_t i = 0; i < size; ++i )
gridptr->mask[i] = (mask_t)(mask[i] != 0);
}
}
@@ -1496,17 +1490,17 @@ int gridInqMaskGME(int gridID, int *mask)
static void
gridDefMaskGMESerial(grid_t *gridptr, const int *mask)
{
- long size = gridptr->size;
+ size_t size = gridptr->size;
if ( size == 0 )
Error("Size undefined for gridID = %d", gridptr->self);
if ( gridptr->mask_gme == NULL )
- gridptr->mask_gme = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
+ gridptr->mask_gme = (mask_t *) Malloc(size * sizeof (mask_t));
else if ( CDI_Debug )
Warning("mask already defined!");
- for (long i = 0; i < size; ++i)
+ for (size_t i = 0; i < size; ++i)
gridptr->mask_gme[i] = (mask_t)(mask[i] != 0);
}
@@ -1518,9 +1512,9 @@ void gridDefMaskGME(int gridID, const int *mask)
}
static
-int gridInqXValsSerial(grid_t *gridptr, double *xvals)
+size_t gridInqXValsSerial(grid_t *gridptr, double *xvals)
{
- long size;
+ size_t size;
if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
size = gridptr->size;
else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
@@ -1536,30 +1530,30 @@ int gridInqXValsSerial(grid_t *gridptr, double *xvals)
if ( size && xvals )
{
const double *gridptr_xvals = gridptr->vtable->inqXValsPtr(gridptr);
- memcpy(xvals, gridptr_xvals, (size_t)size * sizeof (double));
+ memcpy(xvals, gridptr_xvals, size * sizeof (double));
}
}
else
size = 0;
- return (int)size;
+ return size;
}
static
-int gridInqXCvalsSerial(grid_t *gridptr, char **xcvals)
+size_t gridInqXCvalsSerial(grid_t *gridptr, char **xcvals)
{
if ( gridptr->type != GRID_CHARXY )
Error("Function only valid for grid type 'GRID_CHARXY'.");
- int size = gridptr->x.size;
- int maxclength = 0;
+ size_t size = gridptr->x.size;
+ size_t maxclength = 0;
const char **gridptr_xcvals = gridptr->vtable->inqXCvalsPtr(gridptr);
if ( gridptr_xcvals && size && xcvals )
{
maxclength = gridptr->x.clength;
- for ( int i = 0; i < size; i++ )
- memcpy(xcvals[i], gridptr_xcvals[i], (size_t)maxclength*sizeof(char));
+ for ( size_t i = 0; i < size; i++ )
+ memcpy(xcvals[i], gridptr_xcvals[i], maxclength*sizeof(char));
}
return maxclength;
@@ -1580,7 +1574,7 @@ int gridInqXIscSerial(grid_t *gridptr)
@Function gridInqXvals
@Title Get all values of a X-axis
- at Prototype int gridInqXvals(int gridID, double *xvals)
+ at Prototype size_t gridInqXvals(int gridID, double *xvals)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@Item xvals Pointer to the location into which the X-values are read.
@@ -1596,14 +1590,14 @@ Otherwise, 0 is returned and @func{xvals} is empty.
@EndFunction
*/
-int gridInqXvals(int gridID, double *xvals)
+size_t gridInqXvals(int gridID, double *xvals)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqXVals(gridptr, xvals);
}
-int gridInqXCvals(int gridID, char **xcvals)
+size_t gridInqXCvals(int gridID, char **xcvals)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqXCvals(gridptr, xcvals);
@@ -1621,7 +1615,7 @@ void gridDefXValsSerial(grid_t *gridptr, const double *xvals)
{
int gridtype = gridptr->type;
- long size;
+ size_t size;
if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
size = gridptr->size;
else if ( gridtype == GRID_GAUSSIAN_REDUCED )
@@ -1635,25 +1629,25 @@ void gridDefXValsSerial(grid_t *gridptr, const double *xvals)
if (gridptr->x.vals && CDI_Debug)
Warning("values already defined!");
gridptr->x.vals = (double *)Realloc(gridptr->x.vals,
- (size_t)size * sizeof(double));
- memcpy(gridptr->x.vals, xvals, (size_t)size * sizeof (double));
+ size * sizeof(double));
+ memcpy(gridptr->x.vals, xvals, size * sizeof (double));
}
static
-int gridInqYCvalsSerial(grid_t *gridptr, char **ycvals)
+size_t gridInqYCvalsSerial(grid_t *gridptr, char **ycvals)
{
if ( gridptr->type != GRID_CHARXY )
Error("Function only valid for grid type 'GRID_CHARXY'.");
- int size = gridptr->y.size;
- int maxclength = 0;
+ size_t size = gridptr->y.size;
+ size_t maxclength = 0;
const char **gridptr_ycvals = gridptr->vtable->inqYCvalsPtr(gridptr);
if ( gridptr_ycvals && size && ycvals )
{
maxclength = gridptr->y.clength;
- for ( int i = 0; i < size; i++ )
- memcpy(ycvals[i], gridptr_ycvals[i], (size_t)maxclength*sizeof(char));
+ for ( size_t i = 0; i < size; i++ )
+ memcpy(ycvals[i], gridptr_ycvals[i], maxclength*sizeof(char));
}
return maxclength;
@@ -1692,10 +1686,10 @@ void gridDefXvals(int gridID, const double *xvals)
}
static
-int gridInqYValsSerial(grid_t *gridptr, double *yvals)
+size_t gridInqYValsSerial(grid_t *gridptr, double *yvals)
{
int gridtype = gridptr->type;
- long size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+ size_t size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
? gridptr->size : gridptr->y.size;
if ( CDI_Debug && size == 0 )
@@ -1706,20 +1700,20 @@ int gridInqYValsSerial(grid_t *gridptr, double *yvals)
if ( size && yvals )
{
const double *gridptr_yvals = gridptr->vtable->inqYValsPtr(gridptr);
- memcpy(yvals, gridptr_yvals, (size_t)size * sizeof (double));
+ memcpy(yvals, gridptr_yvals, size * sizeof (double));
}
}
else
size = 0;
- return (int)size;
+ return size;
}
/*
@Function gridInqYvals
@Title Get all values of a Y-axis
- at Prototype int gridInqYvals(int gridID, double *yvals)
+ at Prototype size_t gridInqYvals(int gridID, double *yvals)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@Item yvals Pointer to the location into which the Y-values are read.
@@ -1735,14 +1729,14 @@ Otherwise, 0 is returned and @func{yvals} is empty.
@EndFunction
*/
-int gridInqYvals(int gridID, double *yvals)
+size_t gridInqYvals(int gridID, double *yvals)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqYVals(gridptr, yvals);
}
-int gridInqYCvals(int gridID, char **ycvals)
+size_t gridInqYCvals(int gridID, char **ycvals)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqYCvals(gridptr, ycvals);
@@ -1759,7 +1753,7 @@ static
void gridDefYValsSerial(grid_t *gridptr, const double *yvals)
{
int gridtype = gridptr->type;
- long size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+ size_t size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
? gridptr->size : gridptr->y.size;
if ( size == 0 )
@@ -1768,8 +1762,8 @@ void gridDefYValsSerial(grid_t *gridptr, const double *yvals)
if ( gridptr->y.vals && CDI_Debug )
Warning("Values already defined!");
- gridptr->y.vals = (double *)Realloc(gridptr->y.vals, (size_t)size * sizeof (double));
- memcpy(gridptr->y.vals, yvals, (size_t)size * sizeof (double));
+ gridptr->y.vals = (double *)Realloc(gridptr->y.vals, size * sizeof (double));
+ memcpy(gridptr->y.vals, yvals, size * sizeof (double));
}
@@ -1795,21 +1789,21 @@ void gridDefYvals(int gridID, const double *yvals)
}
static double
-gridInqXValSerial(grid_t *gridptr, int index)
+gridInqXValSerial(grid_t *gridptr, size_t index)
{
double xval = gridptr->x.vals ? gridptr->x.vals[index] : 0;
return xval;
}
-double gridInqXval(int gridID, int index)
+double gridInqXval(int gridID, size_t index)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqXVal(gridptr, index);
}
static double
-gridInqYValSerial(grid_t *gridptr, int index)
+gridInqYValSerial(grid_t *gridptr, size_t index)
{
double yval = gridptr->y.vals ? gridptr->y.vals[index] : 0;
return yval;
@@ -1825,7 +1819,7 @@ gridInqYValSerial(grid_t *gridptr, int index)
@EndFunction
*/
-double gridInqYval(int gridID, int index)
+double gridInqYval(int gridID, size_t index)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqYVal(gridptr, index);
@@ -1849,11 +1843,11 @@ double gridInqXinc(int gridID)
if ( (! (fabs(xinc) > 0)) && xvals )
{
- int xsize = gridptr->x.size;
+ size_t xsize = gridptr->x.size;
if ( xsize > 1 )
{
xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
- for ( int i = 2; i < xsize; i++ )
+ for ( size_t i = 2; i < xsize; i++ )
if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc )
{
xinc = 0;
@@ -1885,12 +1879,12 @@ double gridInqYinc(int gridID)
if ( (! (fabs(yinc) > 0)) && yvals )
{
- int ysize = gridptr->y.size;
+ size_t ysize = gridptr->y.size;
if ( ysize > 1 )
{
yinc = yvals[1] - yvals[0];
double abs_yinc = fabs(yinc);
- for ( size_t i = 2; i < (size_t)ysize; i++ )
+ for ( size_t i = 2; i < ysize; i++ )
if ( fabs(fabs(yvals[i] - yvals[i-1]) - abs_yinc) > (0.01*abs_yinc) )
{
yinc = 0;
@@ -2047,8 +2041,8 @@ void grid_check_cyclic(grid_t *gridptr)
{
gridptr->isCyclic = 0;
enum { numVertices = 4 };
- size_t xsize = gridptr->x.size >= 0 ? (size_t)gridptr->x.size : 0,
- ysize = gridptr->y.size >= 0 ? (size_t)gridptr->y.size : 0;
+ size_t xsize = gridptr->x.size,
+ ysize = gridptr->y.size;
const double *xvals = gridptr->vtable->inqXValsPtr(gridptr),
*yvals = gridptr->vtable->inqYValsPtr(gridptr),
(*xbounds)[numVertices]
@@ -2162,13 +2156,13 @@ bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
{
bool differ = false;
- int xsizeTest = gridTest->x.size, ysizeTest = gridTest->y.size;
+ size_t xsizeTest = gridTest->x.size, ysizeTest = gridTest->y.size;
if ( !differ && xsizeTest > 0 && xsizeTest == gridRef->vtable->inqXVals(gridRef, NULL) )
{
const double *restrict xvalsRef = gridRef->vtable->inqXValsPtr(gridRef),
*restrict xvalsTest = gridTest->vtable->inqXValsPtr(gridTest);
- for ( size_t i = 0; i < (size_t)xsizeTest; ++i )
+ for ( size_t i = 0; i < xsizeTest; ++i )
if ( fabs(xvalsTest[i] - xvalsRef[i]) > 1.e-10 )
{
differ = true;
@@ -2180,7 +2174,7 @@ bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
{
const double *restrict yvalsRef = gridRef->vtable->inqYValsPtr(gridRef),
*restrict yvalsTest = gridTest->vtable->inqYValsPtr(gridTest);
- for ( size_t i = 0; i < (size_t)ysizeTest; ++i )
+ for ( size_t i = 0; i < ysizeTest; ++i )
if ( fabs(yvalsTest[i] - yvalsRef[i]) > 1.e-10 )
{
differ = true;
@@ -2194,11 +2188,11 @@ bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
static
bool compareXYvals2(grid_t *gridRef, grid_t *gridTest)
{
- int gridsize = gridTest->size;
+ size_t gridsize = gridTest->size;
bool differ = ((gridTest->x.vals == NULL) ^ (gridRef->x.vals == NULL))
|| ((gridTest->y.vals == NULL) ^ (gridRef->y.vals == NULL));
- typedef double (*inqVal)(grid_t *grid, int index);
+ typedef double (*inqVal)(grid_t *grid, size_t index);
inqVal inqXValRef = gridRef->vtable->inqXVal,
inqYValRef = gridRef->vtable->inqYVal,
inqXValTest = gridTest->vtable->inqXVal,
@@ -2232,8 +2226,8 @@ bool gridCompare(int gridID, const grid_t *grid, bool coord_compare)
printf("gridID %d\n", gridID);
printf("grid.xdef %d\n", grid->x.flag);
printf("grid.ydef %d\n", grid->y.flag);
- printf("grid.xsize %d\n", grid->x.size);
- printf("grid.ysize %d\n", grid->y.size);
+ printf("grid.xsize %zu\n", grid->x.size);
+ printf("grid.ysize %zu\n", grid->y.size);
printf("grid.xfirst %f\n", grid->x.first);
printf("grid.yfirst %f\n", grid->y.first);
printf("grid.xfirst %f\n", gridInqXval(gridID, 0));
@@ -2399,7 +2393,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
grid_t *g2 = ( grid_t * ) gridptr2;
enum { equal = 0,
differ = -1 };
- int i, size;
+ size_t i, size;
xassert ( g1 );
xassert ( g2 );
@@ -2545,7 +2539,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
{
xassert ( g1->size );
if ( !g2->mask ) return differ;
- if ( memcmp ( g1->mask, g2->mask, (size_t)g1->size * sizeof(mask_t)) ) return differ;
+ if ( memcmp ( g1->mask, g2->mask, g1->size * sizeof(mask_t)) ) return differ;
}
else if ( g2->mask )
return differ;
@@ -2554,7 +2548,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
{
xassert ( g1->size );
if ( !g2->mask_gme ) return differ;
- if ( memcmp ( g1->mask_gme, g2->mask_gme, (size_t)g1->size * sizeof(mask_t)) ) return differ;
+ if ( memcmp ( g1->mask_gme, g2->mask_gme, g1->size * sizeof(mask_t)) ) return differ;
}
else if ( g2->mask_gme )
return differ;
@@ -2593,7 +2587,7 @@ void gridComplete(grid_t *grid)
if ( grid->x.flag == 2 )
{
assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
- double *xvals = (double *) Malloc((size_t)grid->x.size * sizeof (double));
+ double *xvals = (double *) Malloc(grid->x.size * sizeof (double));
gridGenXvals(grid->x.size, grid->x.first, grid->x.last, grid->x.inc, xvals);
grid->x.vals = xvals;
// gridDefXinc(gridID, grid->x.inc);
@@ -2602,7 +2596,7 @@ void gridComplete(grid_t *grid)
if ( grid->y.flag == 2 )
{
assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
- double *yvals = (double *) Malloc((size_t)grid->y.size * sizeof (double));
+ double *yvals = (double *) Malloc(grid->y.size * sizeof (double));
gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
grid->y.vals = yvals;
// gridDefYinc(gridID, grid->y.inc);
@@ -2642,7 +2636,7 @@ void gridComplete(grid_t *grid)
if ( grid->y.flag == 2 )
{
- double *yvals = (double *) Malloc((size_t)grid->y.size * sizeof (double));
+ double *yvals = (double *) Malloc(grid->y.size * sizeof (double));
gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
grid->y.vals = yvals;
/*
@@ -2779,7 +2773,7 @@ static void
grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
{
size_t nrowlon = (size_t)gridptrOrig->nrowlon;
- size_t gridsize = (size_t)gridptrOrig->size;
+ size_t gridsize = gridptrOrig->size;
int gridtype = gridptrOrig->type;
int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
if ( nrowlon )
@@ -2790,7 +2784,7 @@ grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
if ( gridptrOrig->x.vals != NULL )
{
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->x.size;
+ size_t size = irregular ? gridsize : gridptrOrig->x.size;
gridptrDup->x.vals = (double *)Malloc(size * sizeof (double));
memcpy(gridptrDup->x.vals, gridptrOrig->x.vals, size * sizeof (double));
@@ -2798,7 +2792,7 @@ grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
if ( gridptrOrig->y.vals != NULL )
{
- size_t size = irregular ? gridsize : (size_t)gridptrOrig->y.size;
+ size_t size = irregular ? gridsize : gridptrOrig->y.size;
gridptrDup->y.vals = (double *)Malloc(size * sizeof (double));
memcpy(gridptrDup->y.vals, gridptrOrig->y.vals, size * sizeof (double));
@@ -2806,8 +2800,8 @@ grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
if ( gridptrOrig->x.bounds != NULL )
{
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->x.size)
- * (size_t)gridptrOrig->nvertex;
+ size_t size = (irregular ? gridsize : gridptrOrig->x.size)
+ * gridptrOrig->nvertex;
gridptrDup->x.bounds = (double *)Malloc(size * sizeof (double));
memcpy(gridptrDup->x.bounds, gridptrOrig->x.bounds, size * sizeof (double));
@@ -2815,8 +2809,8 @@ grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
if ( gridptrOrig->y.bounds != NULL )
{
- size_t size = (irregular ? gridsize : (size_t)gridptrOrig->y.size)
- * (size_t)gridptrOrig->nvertex;
+ size_t size = (irregular ? gridsize : gridptrOrig->y.size)
+ * gridptrOrig->nvertex;
gridptrDup->y.bounds = (double *)Malloc(size * sizeof (double));
memcpy(gridptrDup->y.bounds, gridptrOrig->y.bounds, size * sizeof (double));
@@ -2887,7 +2881,7 @@ void gridCompress(int gridID)
{
if ( gridptr->mask_gme != NULL )
{
- size_t gridsize = (size_t)gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
size_t nv = (size_t)gridptr->nvertex;
double *restrict area
= (double *)gridptr->vtable->inqAreaPtr(gridptr),
@@ -2951,7 +2945,7 @@ void gridCompress(int gridID)
static void
gridDefAreaSerial(grid_t *gridptr, const double *area)
{
- size_t size = (size_t)gridptr->size;
+ size_t size = gridptr->size;
if ( size == 0 )
Error("size undefined for gridID = %d", gridptr->self);
@@ -2976,7 +2970,7 @@ static void
gridInqAreaSerial(grid_t *gridptr, double *area)
{
if (gridptr->area)
- memcpy(area, gridptr->area, (size_t)gridptr->size * sizeof (double));
+ memcpy(area, gridptr->area, gridptr->size * sizeof (double));
}
@@ -3030,7 +3024,7 @@ int gridInqNvertex(int gridID)
}
static void
-gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, int regularSize,
+gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, size_t regularSize,
double **field)
{
int irregular = gridptr->type == GRID_CURVILINEAR
@@ -3042,7 +3036,7 @@ gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, int regularSize,
gridptr->self);
return;
}
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : regularSize);
+ size_t size = nvertex * (irregular ? gridptr->size : regularSize);
if ( size == 0 )
Error("size undefined for gridID = %d", gridptr->self);
@@ -3082,14 +3076,14 @@ void gridDefXbounds(int gridID, const double *xbounds)
gridMark4Update(gridID);
}
-static int
+static size_t
gridInqXBoundsSerial(grid_t *gridptr, double *xbounds)
{
size_t nvertex = (size_t)gridptr->nvertex;
int irregular = gridptr->type == GRID_CURVILINEAR
|| gridptr->type == GRID_UNSTRUCTURED;
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->x.size);
+ size_t size = nvertex * (irregular ? gridptr->size : gridptr->x.size);
const double *gridptr_xbounds = gridptr->vtable->inqXBoundsPtr(gridptr);
if ( gridptr_xbounds )
@@ -3100,14 +3094,14 @@ gridInqXBoundsSerial(grid_t *gridptr, double *xbounds)
else
size = 0;
- return (int)size;
+ return size;
}
/*
@Function gridInqXbounds
@Title Get the bounds of a X-axis
- at Prototype int gridInqXbounds(int gridID, double *xbounds)
+ at Prototype size_t gridInqXbounds(int gridID, double *xbounds)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@Item xbounds Pointer to the location into which the X-bounds are read.
@@ -3123,7 +3117,7 @@ Otherwise, 0 is returned and @func{xbounds} is empty.
@EndFunction
*/
-int gridInqXbounds(int gridID, double *xbounds)
+size_t gridInqXbounds(int gridID, double *xbounds)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqXBounds(gridptr, xbounds);
@@ -3169,14 +3163,14 @@ void gridDefYbounds(int gridID, const double *ybounds)
gridMark4Update(gridID);
}
-static int
+static size_t
gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
{
size_t nvertex = (size_t)gridptr->nvertex;
int irregular = gridptr->type == GRID_CURVILINEAR
|| gridptr->type == GRID_UNSTRUCTURED;
- size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->y.size);
+ size_t size = nvertex * (irregular ? gridptr->size : gridptr->y.size);
const double *gridptr_ybounds = gridptr->vtable->inqYBoundsPtr(gridptr);
if ( gridptr_ybounds )
@@ -3187,7 +3181,7 @@ gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
else
size = 0;
- return (int)size;
+ return size;
}
@@ -3195,7 +3189,7 @@ gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
@Function gridInqYbounds
@Title Get the bounds of a Y-axis
- at Prototype int gridInqYbounds(int gridID, double *ybounds)
+ at Prototype size_t gridInqYbounds(int gridID, double *ybounds)
@Parameter
@Item gridID Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
@Item ybounds Pointer to the location into which the Y-bounds are read.
@@ -3211,7 +3205,7 @@ Otherwise, 0 is returned and @func{ybounds} is empty.
@EndFunction
*/
-int gridInqYbounds(int gridID, double *ybounds)
+size_t gridInqYbounds(int gridID, double *ybounds)
{
grid_t *gridptr = grid_to_pointer(gridID);
return gridptr->vtable->inqYBounds(gridptr, ybounds);
@@ -3275,7 +3269,7 @@ printBounds(FILE *fp, int dig, const char prefix[], size_t nbyte0,
{
for ( size_t iv = 0; iv < nvertex; iv++ )
fprintf(fp, "%.*g ", dig, bounds[iv]);
- for ( size_t i = 1; i < (size_t)n; i++ )
+ for ( size_t i = 1; i < n; i++ )
{
fprintf(fp, "\n%*s", (int)nbyte0, "");
for ( size_t iv = 0; iv < nvertex; iv++ )
@@ -3382,15 +3376,15 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
unsigned char uuidOfHGrid[CDI_UUID_SIZE];
const char **xcvals = gridInqXCvalsPtr(gridID);
const char **ycvals = gridInqYCvalsPtr(gridID);
- size_t nxvals = (size_t) gridInqXvals(gridID, NULL);
- size_t nyvals = (size_t) gridInqYvals(gridID, NULL);
- size_t nxbounds = (size_t) gridInqXbounds(gridID, NULL);
- size_t nybounds = (size_t) gridInqYbounds(gridID, NULL);
+ size_t nxvals = gridInqXvals(gridID, NULL);
+ size_t nyvals = gridInqYvals(gridID, NULL);
+ size_t nxbounds = gridInqXbounds(gridID, NULL);
+ size_t nybounds = gridInqYbounds(gridID, NULL);
int type = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ size_t gridsize = gridInqSize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
int xstrlen = gridInqXIsc(gridID);
int ystrlen = gridInqYIsc(gridID);
int nvertex = gridInqNvertex(gridID);
@@ -3398,14 +3392,14 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
- fprintf(fp, "gridtype = %s\n" "gridsize = %d\n", gridNamePtr(type), gridsize);
+ fprintf(fp, "gridtype = %s\n" "gridsize = %zu\n", gridNamePtr(type), gridsize);
if ( type != GRID_GME )
{
if ( type != GRID_UNSTRUCTURED && type != GRID_SPECTRAL && type != GRID_FOURIER )
{
- if ( xsize > 0 ) fprintf(fp, "xsize = %d\n", xsize);
- if ( ysize > 0 ) fprintf(fp, "ysize = %d\n", ysize);
+ if ( xsize > 0 ) fprintf(fp, "xsize = %zu\n", xsize);
+ if ( ysize > 0 ) fprintf(fp, "ysize = %zu\n", ysize);
}
if ( nxvals > 0 || xcvals )
@@ -3457,18 +3451,18 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
{
- xdimLen = (size_t)gridsize;
- ydimLen = (size_t)gridsize;
+ xdimLen = gridsize;
+ ydimLen = gridsize;
}
else if ( type == GRID_GAUSSIAN_REDUCED )
{
xdimLen = 2;
- ydimLen = (size_t)ysize;
+ ydimLen = ysize;
}
else
{
- xdimLen = (size_t)xsize;
- ydimLen = (size_t)ysize;
+ xdimLen = xsize;
+ ydimLen = ysize;
}
if ( type == GRID_UNSTRUCTURED )
@@ -3529,7 +3523,7 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
fprintf(fp, "x%ss = %.*s\n", attstr, xstrlen, xcvals[0]);
else
fprintf(fp, "xstrings = %.*s\n", xstrlen, xcvals[0]);
- for ( int i = 1; i < xsize; i++ )
+ for ( size_t i = 1; i < xsize; i++ )
fprintf(fp, " = %.*s\n", xstrlen, xcvals[i]);
}
@@ -3575,7 +3569,7 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
fprintf(fp, "x%ss = %.*s\n", attstr, ystrlen, ycvals[0]);
else
fprintf(fp, "ystrings = %.*s\n", ystrlen, ycvals[0]);
- for ( int i = 1; i < ysize; i++ )
+ for ( size_t i = 1; i < ysize; i++ )
fprintf(fp, " = %.*s\n", ystrlen, ycvals[i]);
}
@@ -3590,20 +3584,20 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
if ( gridHasArea(gridID) )
{
- double *area = (double*) Malloc((size_t)gridsize*sizeof(double));
+ double *area = (double*) Malloc(gridsize*sizeof(double));
gridInqArea(gridID, area);
static const char prefix[] = "area = ";
- printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, (size_t)gridsize, area);
+ printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, gridsize, area);
Free(area);
}
if ( type == GRID_GAUSSIAN_REDUCED )
{
static const char prefix[] = "rowlon = ";
- int *rowlon = (int *)Malloc((size_t)ysize*sizeof(int));
+ int *rowlon = (int *)Malloc(ysize*sizeof(int));
gridInqRowlon(gridID, rowlon);
printIntsPrefixAutoBrk(fp, prefix, sizeof(prefix)-1,
- (size_t)(ysize > 0 ? ysize : 0), rowlon);
+ (ysize > 0 ? ysize : 0), rowlon);
Free(rowlon);
}
@@ -3647,11 +3641,11 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
if ( gridInqMask(gridID, NULL) )
{
- int *mask = (gridsize>0) ? (int*) Malloc((size_t)gridsize*sizeof(int)) : NULL;
+ int *mask = (gridsize>0) ? (int*) Malloc(gridsize*sizeof(int)) : NULL;
gridInqMask(gridID, mask);
static const char prefix[] = "mask = ";
printMask(fp, prefix, sizeof(prefix)-1,
- (size_t)(gridsize > 0 ? gridsize : 0), mask);
+ (gridsize > 0 ? gridsize : 0), mask);
if ( mask ) Free(mask);
}
}
@@ -3697,12 +3691,12 @@ void gridPrintP(void *voidptr, FILE *fp)
if ( gridInqMaskGME(gridID, NULL) )
{
- int gridsize = gridptr->size;
- int *mask = (gridsize>0) ? (int*) Malloc((size_t)gridsize*sizeof(int)) : NULL;
+ size_t gridsize = gridptr->size;
+ int *mask = (gridsize>0) ? (int*) Malloc(gridsize*sizeof(int)) : NULL;
gridInqMaskGME(gridID, mask);
static const char prefix[] = "mask_gme = ";
printMask(fp, prefix, sizeof(prefix)-1,
- (size_t)(gridptr->size > 0 ? gridptr->size : 0), mask);
+ (gridptr->size > 0 ? gridptr->size : 0), mask);
if ( mask ) Free(mask);
}
}
@@ -4475,13 +4469,13 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
gridP->y.inc = doubleBuffer[GRID_PACK_DBL_IDX_Y_INC];
}
- int irregular = gridP->type == GRID_UNSTRUCTURED
+ bool irregular = gridP->type == GRID_UNSTRUCTURED
|| gridP->type == GRID_CURVILINEAR;
if (memberMask & gridHasXValsFlag)
{
size = irregular ? gridP->size : gridP->x.size;
- gridP->x.vals = (double *) Malloc((size_t)size * sizeof (double));
+ gridP->x.vals = (double *) Malloc(size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->x.vals, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4493,7 +4487,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
{
size = irregular ? gridP->size : gridP->y.size;
- gridP->y.vals = (double *) Malloc((size_t)size * sizeof (double));
+ gridP->y.vals = (double *) Malloc(size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->y.vals, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4505,7 +4499,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
{
size = gridP->size;
xassert(size);
- gridP->area = (double *) Malloc((size_t)size * sizeof (double));
+ gridP->area = (double *) Malloc(size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->area, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4518,7 +4512,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
size = gridP->nvertex * (irregular ? gridP->size : gridP->x.size);
xassert(size);
- gridP->x.bounds = (double *) Malloc((size_t)size * sizeof (double));
+ gridP->x.bounds = (double *) Malloc(size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->x.bounds, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4531,7 +4525,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
size = gridP->nvertex * (irregular ? gridP->size : gridP->y.size);
xassert(size);
- gridP->y.bounds = (double *) Malloc((size_t)size * sizeof (double));
+ gridP->y.bounds = (double *) Malloc(size * sizeof (double));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->y.bounds, size, CDI_DATATYPE_FLT64, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4551,7 +4545,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
int referenceSize;
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
&referenceSize, 1, CDI_DATATYPE_INT, context);
- gridP->reference = (char *) Malloc((size_t)referenceSize);
+ gridP->reference = (char *) Malloc(referenceSize);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->reference, referenceSize, CDI_DATATYPE_TXT, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4562,7 +4556,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
if (memberMask & gridHasMaskFlag)
{
xassert((size = gridP->size));
- gridP->mask = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
+ gridP->mask = (mask_t *) Malloc(size * sizeof (mask_t));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->mask, gridP->size, CDI_DATATYPE_UCHAR, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
@@ -4573,7 +4567,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
if (memberMask & gridHasGMEMaskFlag)
{
xassert((size = gridP->size));
- gridP->mask_gme = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
+ gridP->mask_gme = (mask_t *) Malloc(size * sizeof (mask_t));
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
gridP->mask_gme, gridP->size, CDI_DATATYPE_UCHAR, context);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
diff --git a/libcdi/src/grid.h b/libcdi/src/grid.h
index 65618ee..770cd5e 100644
--- a/libcdi/src/grid.h
+++ b/libcdi/src/grid.h
@@ -27,13 +27,13 @@ struct gridVirtTable
void (*defXBounds)(grid_t *gridptr, const double *xbounds);
void (*defYBounds)(grid_t *gridptr, const double *ybounds);
void (*defArea)(grid_t *gridptr, const double *area);
- double (*inqXVal)(grid_t *gridptr, int index);
- double (*inqYVal)(grid_t *gridptr, int index);
- int (*inqXVals)(grid_t *gridptr, double *xvals);
- int (*inqXCvals)(grid_t *gridptr, char **xcvals);
+ double (*inqXVal)(grid_t *gridptr, size_t index);
+ double (*inqYVal)(grid_t *gridptr, size_t index);
+ size_t (*inqXVals)(grid_t *gridptr, double *xvals);
+ size_t (*inqXCvals)(grid_t *gridptr, char **xcvals);
int (*inqXIsc)(grid_t *gridptr);
- int (*inqYVals)(grid_t *gridptr, double *yvals);
- int (*inqYCvals)(grid_t *gridptr, char **ycvals);
+ size_t (*inqYVals)(grid_t *gridptr, double *yvals);
+ size_t (*inqYCvals)(grid_t *gridptr, char **ycvals);
int (*inqYIsc)(grid_t *gridptr);
const double *(*inqXValsPtr)(grid_t *gridptr);
const char **(*inqXCvalsPtr)(grid_t *gridptr);
@@ -47,10 +47,10 @@ struct gridVirtTable
void (*inqArea)(grid_t *gridptr, double *area);
const double *(*inqAreaPtr)(grid_t *gridptr);
int (*hasArea)(grid_t *gridptr);
- int (*inqMask)(grid_t *gridptr, int *mask);
+ size_t (*inqMask)(grid_t *gridptr, int *mask);
int (*inqMaskGME)(grid_t *gridptr, int *mask_gme);
- int (*inqXBounds)(grid_t *gridptr, double *xbounds);
- int (*inqYBounds)(grid_t *gridptr, double *ybounds);
+ size_t (*inqXBounds)(grid_t *gridptr, double *xbounds);
+ size_t (*inqYBounds)(grid_t *gridptr, double *ybounds);
const double *(*inqXBoundsPtr)(grid_t *gridptr);
const double *(*inqYBoundsPtr)(grid_t *gridptr);
};
@@ -61,7 +61,7 @@ struct gridaxis_t {
char units[CDI_MAX_NAME];
char dimname[CDI_MAX_NAME];
const char *stdname;
- int size; // number of values
+ size_t size; // number of values
short flag; // 0: undefined 1:vals 2:first+inc
double first, last, inc;
double *vals;
@@ -81,7 +81,7 @@ struct grid_t {
char mapping[CDI_MAX_NAME];
char *name;
int self;
- int size;
+ size_t size;
int type; /* grid type */
int datatype; /* grid data type */
int proj; /* grid projection */
@@ -122,7 +122,7 @@ struct grid_t {
void grid_init(grid_t *gridptr);
-void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size);
+void cdiGridTypeInit(grid_t *gridptr, int gridtype, size_t size);
void grid_free(grid_t *gridptr);
grid_t *grid_to_pointer(int gridID);
extern const struct gridVirtTable cdiGridVtable;
diff --git a/libcdi/src/iterator_fallback.c b/libcdi/src/iterator_fallback.c
index 03749a3..6ee0167 100644
--- a/libcdi/src/iterator_fallback.c
+++ b/libcdi/src/iterator_fallback.c
@@ -378,7 +378,7 @@ char *cdiFallbackIterator_copyVariableName(CdiIterator *super)
void cdiFallbackIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
{
CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int missingValues = 0;
+ size_t missingValues = 0;
streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
if(nmiss) *nmiss = (size_t)missingValues;
}
@@ -386,7 +386,7 @@ void cdiFallbackIterator_readField(CdiIterator *super, double *buffer, size_t *n
void cdiFallbackIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
{
CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
- int missingValues = 0;
+ size_t missingValues = 0;
streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
if(nmiss) *nmiss = (size_t)missingValues;
}
diff --git a/libcdi/src/mo_cdi.f90 b/libcdi/src/mo_cdi.f90
index c126d09..5993554 100644
--- a/libcdi/src/mo_cdi.f90
+++ b/libcdi/src/mo_cdi.f90
@@ -1,6 +1,6 @@
! >>> Warning: This is a generated file. If you modify it, you get what you deserve. <<<
!
-! Generated by "../../../../libcdi/interfaces/f2003/bindGen.rb" from input file "../../../../libcdi/src/cdi.h".
+! Generated by "../../../interfaces/f2003/bindGen.rb" from input file "../../../src/cdi.h".
module mo_cdi
use iso_c_binding
@@ -49,10 +49,9 @@ module mo_cdi
integer(c_int), public, parameter :: CDI_FILETYPE_NC2 = 4
integer(c_int), public, parameter :: CDI_FILETYPE_NC4 = 5
integer(c_int), public, parameter :: CDI_FILETYPE_NC4C = 6
- integer(c_int), public, parameter :: CDI_FILETYPE_NC5 = 7
- integer(c_int), public, parameter :: CDI_FILETYPE_SRV = 8
- integer(c_int), public, parameter :: CDI_FILETYPE_EXT = 9
- integer(c_int), public, parameter :: CDI_FILETYPE_IEG = 10
+ integer(c_int), public, parameter :: CDI_FILETYPE_SRV = 7
+ integer(c_int), public, parameter :: CDI_FILETYPE_EXT = 8
+ integer(c_int), public, parameter :: CDI_FILETYPE_IEG = 9
integer(c_int), public, parameter :: FILETYPE_GRB = 1
integer(c_int), public, parameter :: FILETYPE_GRB2 = 2
integer(c_int), public, parameter :: FILETYPE_NC = 3
@@ -179,8 +178,8 @@ module mo_cdi
integer(c_int), public, parameter :: ZAXIS_CHAR = 26
integer(c_int), public, parameter :: MAX_KV_PAIRS_MATCH = 10
integer(c_int), public, parameter :: TIME_CONSTANT = 0
- integer(c_int), public, parameter :: TIME_VARYING = 1
integer(c_int), public, parameter :: TIME_VARIABLE = 1
+ integer(c_int), public, parameter :: TSTEP_CONSTANT = 0
integer(c_int), public, parameter :: TSTEP_INSTANT = 1
integer(c_int), public, parameter :: TSTEP_AVG = 2
integer(c_int), public, parameter :: TSTEP_ACCUM = 3
@@ -273,6 +272,7 @@ module mo_cdi
public :: streamInqCurTimestepID
public :: streamFilename
public :: streamFilesuffix
+ public :: streamNvals
public :: streamInqNvars
public :: streamWriteVar
public :: streamWriteVarF
@@ -372,8 +372,6 @@ module mo_cdi
public :: vlistInqVarGrid
public :: vlistInqVarZaxis
public :: vlistInqVarID
- public :: vlistDefVarTimetype
- public :: vlistInqVarTimetype
public :: vlistDefVarTsteptype
public :: vlistInqVarTsteptype
public :: vlistDefVarCompType
@@ -622,7 +620,6 @@ module mo_cdi
public :: taxisInqFdate
public :: taxisInqFtime
public :: taxisHasBounds
- public :: taxisWithBounds
public :: taxisDeleteBounds
public :: taxisDefVdateBounds
public :: taxisDefVtimeBounds
@@ -877,6 +874,13 @@ module mo_cdi
integer(c_int) :: f_result
end function streamInqCurTimestepID
+ function streamNvals(streamID_dummy) bind(c, name = 'streamNvals')&
+ & result(f_result)
+ import c_int, c_size_t
+ integer(c_int), value :: streamID_dummy
+ integer(c_size_t) :: f_result
+ end function streamNvals
+
function streamInqNvars(streamID_dummy) bind(c, name = 'streamInqNvars')&
& result(f_result)
import c_int
@@ -886,88 +890,88 @@ module mo_cdi
subroutine streamWriteVar(streamID_dummy, varID_dummy, data_dummy,&
& nmiss_dummy) bind(c, name = 'streamWriteVar')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
real(c_double), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteVar
subroutine streamWriteVarF(streamID_dummy, varID_dummy, data_dummy,&
& nmiss_dummy) bind(c, name = 'streamWriteVarF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
real(c_float), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteVarF
subroutine streamReadVar(streamID_dummy, varID_dummy, data_dummy,&
& nmiss_dummy) bind(c, name = 'streamReadVar')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
real(c_double), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadVar
subroutine streamReadVarF(streamID_dummy, varID_dummy, data_dummy,&
& nmiss_dummy) bind(c, name = 'streamReadVarF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
real(c_float), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadVarF
subroutine streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy,&
& data_dummy, nmiss_dummy) bind(c, name = 'streamWriteVarSlice')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), value :: levelID_dummy
real(c_double), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteVarSlice
subroutine streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy,&
& data_dummy, nmiss_dummy) bind(c, name = 'streamWriteVarSliceF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), value :: levelID_dummy
real(c_float), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteVarSliceF
subroutine streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy,&
& data_dummy, nmiss_dummy) bind(c, name = 'streamReadVarSlice')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), value :: levelID_dummy
real(c_double), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadVarSlice
subroutine streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy,&
& data_dummy, nmiss_dummy) bind(c, name = 'streamReadVarSliceF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), value :: levelID_dummy
real(c_float), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadVarSliceF
subroutine streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy,&
& data_dummy, nmiss_dummy) bind(c, name = 'streamWriteVarChunk')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), intent(in) :: rect_dummy(2, 3)
real(c_double), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteVarChunk
subroutine streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy)&
@@ -988,34 +992,34 @@ module mo_cdi
subroutine streamWriteRecord(streamID_dummy, data_dummy, nmiss_dummy)&
& bind(c, name = 'streamWriteRecord')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
real(c_double), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteRecord
subroutine streamWriteRecordF(streamID_dummy, data_dummy, nmiss_dummy)&
& bind(c, name = 'streamWriteRecordF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
real(c_float), intent(in) :: data_dummy(*)
- integer(c_int), value :: nmiss_dummy
+ integer(c_size_t), value :: nmiss_dummy
end subroutine streamWriteRecordF
subroutine streamReadRecord(streamID_dummy, data_dummy, nmiss_dummy)&
& bind(c, name = 'streamReadRecord')
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: streamID_dummy
real(c_double), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadRecord
subroutine streamReadRecordF(streamID_dummy, data_dummy, nmiss_dummy)&
& bind(c, name = 'streamReadRecordF')
- import c_float, c_int
+ import c_float, c_int, c_size_t
integer(c_int), value :: streamID_dummy
real(c_float), intent(inout) :: data_dummy(*)
- integer(c_int), intent(inout) :: nmiss_dummy
+ integer(c_size_t), intent(inout) :: nmiss_dummy
end subroutine streamReadRecordF
subroutine streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy) bind(c,&
@@ -1131,9 +1135,9 @@ module mo_cdi
function vlistGridsizeMax(vlistID_dummy) bind(c, name = 'vlistGridsizeMax')&
& result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: vlistID_dummy
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function vlistGridsizeMax
function vlistGrid(vlistID_dummy, index_dummy) bind(c, name = 'vlistGrid')&
@@ -1280,24 +1284,24 @@ module mo_cdi
end function vlistInqModel
function vlistDefVarTiles(vlistID_dummy, gridID_dummy, zaxisID_dummy,&
- & timetype_dummy, tilesetID_dummy) bind(c, name = 'vlistDefVarTiles')&
+ & tsteptype_dummy, tilesetID_dummy) bind(c, name = 'vlistDefVarTiles')&
& result(f_result)
import c_int
integer(c_int), value :: vlistID_dummy
integer(c_int), value :: gridID_dummy
integer(c_int), value :: zaxisID_dummy
- integer(c_int), value :: timetype_dummy
+ integer(c_int), value :: tsteptype_dummy
integer(c_int), value :: tilesetID_dummy
integer(c_int) :: f_result
end function vlistDefVarTiles
function vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy,&
- & timetype_dummy) bind(c, name = 'vlistDefVar') result(f_result)
+ & tsteptype_dummy) bind(c, name = 'vlistDefVar') result(f_result)
import c_int
integer(c_int), value :: vlistID_dummy
integer(c_int), value :: gridID_dummy
integer(c_int), value :: zaxisID_dummy
- integer(c_int), value :: timetype_dummy
+ integer(c_int), value :: tsteptype_dummy
integer(c_int) :: f_result
end function vlistDefVar
@@ -1318,13 +1322,13 @@ module mo_cdi
end subroutine vlistChangeVarZaxis
subroutine vlistInqVar(vlistID_dummy, varID_dummy, gridID_dummy,&
- & zaxisID_dummy, timetype_dummy) bind(c, name = 'vlistInqVar')
+ & zaxisID_dummy, tsteptype_dummy) bind(c, name = 'vlistInqVar')
import c_int
integer(c_int), value :: vlistID_dummy
integer(c_int), value :: varID_dummy
integer(c_int), intent(inout) :: gridID_dummy
integer(c_int), intent(inout) :: zaxisID_dummy
- integer(c_int), intent(inout) :: timetype_dummy
+ integer(c_int), intent(inout) :: tsteptype_dummy
end subroutine vlistInqVar
function vlistInqVarGrid(vlistID_dummy, varID_dummy) bind(c, name =&
@@ -1351,22 +1355,6 @@ module mo_cdi
integer(c_int) :: f_result
end function vlistInqVarID
- subroutine vlistDefVarTimetype(vlistID_dummy, varID_dummy, timetype_dummy)&
- & bind(c, name = 'vlistDefVarTimetype')
- import c_int
- integer(c_int), value :: vlistID_dummy
- integer(c_int), value :: varID_dummy
- integer(c_int), value :: timetype_dummy
- end subroutine vlistDefVarTimetype
-
- function vlistInqVarTimetype(vlistID_dummy, varID_dummy) bind(c, name =&
- & 'vlistInqVarTimetype') result(f_result)
- import c_int
- integer(c_int), value :: vlistID_dummy
- integer(c_int), value :: varID_dummy
- integer(c_int) :: f_result
- end function vlistInqVarTimetype
-
subroutine vlistDefVarTsteptype(vlistID_dummy, varID_dummy,&
& tsteptype_dummy) bind(c, name = 'vlistDefVarTsteptype')
import c_int
@@ -1667,10 +1655,10 @@ module mo_cdi
function vlistInqVarSize(vlistID_dummy, varID_dummy) bind(c, name =&
& 'vlistInqVarSize') result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: vlistID_dummy
integer(c_int), value :: varID_dummy
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function vlistInqVarSize
subroutine vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy,&
@@ -1832,9 +1820,9 @@ module mo_cdi
function gridCreate(gridtype_dummy, size_dummy) bind(c, name =&
& 'gridCreate') result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridtype_dummy
- integer(c_int), value :: size_dummy
+ integer(c_size_t), value :: size_dummy
integer(c_int) :: f_result
end function gridCreate
@@ -1880,37 +1868,37 @@ module mo_cdi
function gridInqSize(gridID_dummy) bind(c, name = 'gridInqSize')&
& result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqSize
subroutine gridDefXsize(gridID_dummy, xsize_dummy) bind(c, name =&
& 'gridDefXsize')
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int), value :: xsize_dummy
+ integer(c_size_t), value :: xsize_dummy
end subroutine gridDefXsize
function gridInqXsize(gridID_dummy) bind(c, name = 'gridInqXsize')&
& result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqXsize
subroutine gridDefYsize(gridID_dummy, ysize_dummy) bind(c, name =&
& 'gridDefYsize')
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int), value :: ysize_dummy
+ integer(c_size_t), value :: ysize_dummy
end subroutine gridDefYsize
function gridInqYsize(gridID_dummy) bind(c, name = 'gridInqYsize')&
& result(f_result)
- import c_int
+ import c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqYsize
subroutine gridDefNP(gridID_dummy, np_dummy) bind(c, name = 'gridDefNP')
@@ -1935,10 +1923,10 @@ module mo_cdi
function gridInqXvals(gridID_dummy, xvals_dummy) bind(c, name =&
& 'gridInqXvals') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
real(c_double), intent(inout) :: xvals_dummy(*)
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqXvals
function gridInqXIsc(gridID_dummy) bind(c, name = 'gridInqXIsc')&
@@ -1957,10 +1945,10 @@ module mo_cdi
function gridInqYvals(gridID_dummy, yvals_dummy) bind(c, name =&
& 'gridInqYvals') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
real(c_double), intent(inout) :: yvals_dummy(*)
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqYvals
function gridInqYIsc(gridID_dummy) bind(c, name = 'gridInqYIsc')&
@@ -2004,17 +1992,17 @@ module mo_cdi
function gridInqXval(gridID_dummy, index_dummy) bind(c, name =&
& 'gridInqXval') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int), value :: index_dummy
+ integer(c_size_t), value :: index_dummy
real(c_double) :: f_result
end function gridInqXval
function gridInqYval(gridID_dummy, index_dummy) bind(c, name =&
& 'gridInqYval') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
- integer(c_int), value :: index_dummy
+ integer(c_size_t), value :: index_dummy
real(c_double) :: f_result
end function gridInqYval
@@ -2215,10 +2203,10 @@ module mo_cdi
function gridInqXbounds(gridID_dummy, xbounds_dummy) bind(c, name =&
& 'gridInqXbounds') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
real(c_double), intent(inout) :: xbounds_dummy(*)
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqXbounds
subroutine gridDefYbounds(gridID_dummy, ybounds_dummy) bind(c, name =&
@@ -2230,10 +2218,10 @@ module mo_cdi
function gridInqYbounds(gridID_dummy, ybounds_dummy) bind(c, name =&
& 'gridInqYbounds') result(f_result)
- import c_double, c_int
+ import c_double, c_int, c_size_t
integer(c_int), value :: gridID_dummy
real(c_double), intent(inout) :: ybounds_dummy(*)
- integer(c_int) :: f_result
+ integer(c_size_t) :: f_result
end function gridInqYbounds
subroutine gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_dummy) bind(c,&
@@ -2670,11 +2658,6 @@ module mo_cdi
integer(c_int) :: f_result
end function taxisHasBounds
- subroutine taxisWithBounds(taxisID_dummy) bind(c, name = 'taxisWithBounds')
- import c_int
- integer(c_int), value :: taxisID_dummy
- end subroutine taxisWithBounds
-
subroutine taxisDeleteBounds(taxisID_dummy) bind(c, name =&
& 'taxisDeleteBounds')
import c_int
diff --git a/libcdi/src/pio_client.c b/libcdi/src/pio_client.c
index 7c2ee99..319ac36 100644
--- a/libcdi/src/pio_client.c
+++ b/libcdi/src/pio_client.c
@@ -129,12 +129,12 @@ cdiPioClientStreamDefVlist_(int streamID, int vlistID)
static void
cdiPioClientStreamWriteVar_(int streamID, int varID, int memtype,
- const void *data, int nmiss)
+ const void *data, size_t nmiss)
__attribute__((noreturn));
static void
cdiPioClientStreamWriteVar_(int streamID, int varID, int memtype,
- const void *data, int nmiss)
+ const void *data, size_t nmiss)
{
(void)streamID; (void)varID; (void)memtype; (void)data; (void)nmiss;
xabort("parallel writing requires explicit partition information,"
@@ -144,7 +144,7 @@ cdiPioClientStreamWriteVar_(int streamID, int varID, int memtype,
static void
cdiPioClientStreamWriteVarChunk_(int streamID, int varID, int memtype,
const int rect[][2],
- const void *data, int nmiss)
+ const void *data, size_t nmiss)
{
/* todo: handle transmission of float data */
if (memtype != MEMTYPE_DOUBLE)
@@ -170,7 +170,7 @@ cdiPioClientStreamWriteVarChunk_(int streamID, int varID, int memtype,
static void
cdiPioClientStreamWriteVarPart(int streamID, int varID, const void *data,
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
pioBufferPartData(streamID, varID, data, nmiss, partDesc);
}
@@ -180,7 +180,7 @@ cdiPioClientStreamWriteScatteredVarPart(int streamID, int varID,
const void *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
cdiPioBufferPartDataGather(streamID, varID, data, numBlocks,
blocklengths, displacements, nmiss, partDesc);
diff --git a/libcdi/src/pio_interface.c b/libcdi/src/pio_interface.c
index da371c6..eefe499 100644
--- a/libcdi/src/pio_interface.c
+++ b/libcdi/src/pio_interface.c
@@ -286,7 +286,7 @@ cdiPioRDMAProgress(void)
static void
pioBufferPartData_(int streamID, int varID,
const void *packData, valPackFunc packDataFunc,
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
size_t streamIdx = indexOfID(&openStreams, streamID);
xassert(streamIdx != SIZE_MAX);
@@ -309,7 +309,7 @@ pioBufferPartData_(int streamID, int varID,
void
pioBufferPartData(int streamID, int varID, const double *data,
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
int chunk = xt_idxlist_get_num_indices(partDesc);
xassert(chunk <= INT_MAX);
@@ -368,7 +368,7 @@ void
cdiPioBufferPartDataGather(int streamID, int varID, const double *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
xassert(numBlocks >= 0);
pioBufferPartData_(streamID, varID,
@@ -684,7 +684,7 @@ void pioWriteTimestep(void)
void
streamWriteVarPart(int streamID, int varID, const void *data,
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
@@ -692,7 +692,7 @@ streamWriteVarPart(int streamID, int varID, const void *data,
xassert(chunk == 0 || data);
void (*myStreamWriteVarPart)(int streamID, int varID, const void *data,
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
= (void (*)(int, int, const void *, int, Xt_idxlist))
namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_PART_).func;
@@ -706,7 +706,7 @@ void
streamWriteScatteredVarPart(int streamID, int varID, const void *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
@@ -717,7 +717,7 @@ streamWriteScatteredVarPart(int streamID, int varID, const void *data,
const void *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc)
+ size_t nmiss, Xt_idxlist partDesc)
= (void (*)(int, int, const void *, int, const int[], const int[], int,
Xt_idxlist))
namespaceSwitchGet(NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_).func;
diff --git a/libcdi/src/pio_interface.h b/libcdi/src/pio_interface.h
index 8a3b1cf..1e8be5b 100644
--- a/libcdi/src/pio_interface.h
+++ b/libcdi/src/pio_interface.h
@@ -13,12 +13,12 @@
void
pioBufferPartData(int streamID, int varID, const double *data,
- int nmiss, Xt_idxlist partDesc);
+ size_t nmiss, Xt_idxlist partDesc);
void
cdiPioBufferPartDataGather(int streamID, int varID, const double *data,
int numBlocks, const int blocklengths[],
const int displacements[],
- int nmiss, Xt_idxlist partDesc);
+ size_t nmiss, Xt_idxlist partDesc);
void pioBufferFuncCall(int streamID,
struct winHeaderEntry header,
diff --git a/libcdi/src/pio_server.c b/libcdi/src/pio_server.c
index 5774a78..d18e583 100644
--- a/libcdi/src/pio_server.c
+++ b/libcdi/src/pio_server.c
@@ -303,7 +303,7 @@ countVarChunkMissingVals(int vlistID, int varID,
struct streamMapping *mapping,
int chunkLen, const double *restrict data)
{
- int nmiss = 0;
+ size_t nmiss = 0;
if (mapping->hasMissing[varID])
{
double missval = vlistInqVarMissval(vlistID, varID);
@@ -450,7 +450,7 @@ writeNetCDFStream(size_t streamIdx,
xt_idxlist_delete(preWriteChunk);
}
/* count missing values if appropriate */
- int nmiss
+ size_t nmiss
= countVarChunkMissingVals(vlistID, varID, mapping,
PPM_extents_size(3, varChunk),
data);
@@ -553,7 +553,7 @@ writeNetCDFStream(size_t streamIdx,
gatherArray(headerIdx, streamIdx, data, dstList, conf);
if (writerRank == collRank)
{
- int nmiss = countVarChunkMissingVals(vlistID, varID,
+ size_t nmiss = countVarChunkMissingVals(vlistID, varID,
mapping, varSize, data);
streamWriteVar(streamID, varID, data, nmiss);
}
@@ -1053,7 +1053,7 @@ writeGribStream(size_t streamIdx,
varIdx += varID != prevVarID;
size_t recordSize = writtenRecords[recordIdx].dataSize;
size_t nvals = recordSize / sizeof (double);
- int nmiss
+ size_t nmiss
= countVarChunkMissingVals(vlistID, varID, mapping, (int)nvals,
data + recordDataOfs);
streamWriteVarSlice(streamID, varID, level, data + recordDataOfs, nmiss);
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index ad1c3eb..bb6b382 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -1381,9 +1381,9 @@ void streamWriteContents(int streamID, char *cname)
{
int gridID = vlistGrid(vlistID, i);
int gridtype = gridInqType(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
- fprintf(cnp, "%4d:%4d:%4d:%4d\n", i+1, gridtype, xsize, ysize);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
+ fprintf(cnp, "%4d:%4d:%4zu:%4zu\n", i+1, gridtype, xsize, ysize);
}
fputs("#\nvarID:code:gridID:zaxisID:tsteptype:datatype\n", cnp);
@@ -1446,7 +1446,7 @@ void streamWriteContents(int streamID, char *cname)
#endif
// This function is used in CDO!
-off_t streamNvals(int streamID)
+size_t streamNvals(int streamID)
{
stream_t *streamptr = stream_to_pointer(streamID);
return streamptr->numvals;
diff --git a/libcdi/src/stream_cdf.h b/libcdi/src/stream_cdf.h
index 8056b6e..3fc162a 100644
--- a/libcdi/src/stream_cdf.h
+++ b/libcdi/src/stream_cdf.h
@@ -18,17 +18,17 @@ void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID);
-void cdf_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss);
-void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
+void cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss);
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss);
-void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss);
-void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
+void cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss);
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss);
-void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss);
-void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss);
+void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss);
void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss);
+ const int rect[][2], const void *data, size_t nmiss);
void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level);
void cdfDefTime(stream_t* streamptr);
diff --git a/libcdi/src/stream_cdf_i.c b/libcdi/src/stream_cdf_i.c
index 2c7fe11..3e7758c 100644
--- a/libcdi/src/stream_cdf_i.c
+++ b/libcdi/src/stream_cdf_i.c
@@ -89,7 +89,7 @@ typedef struct {
int ndims;
int dimids[8];
int dimtype[8];
- int chunks[8];
+ size_t chunks[8];
int chunked;
int chunktype;
int natts;
@@ -1099,11 +1099,11 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
if ( storage_in == NC_CHUNKED )
{
ncvars[ncvarid].chunked = 1;
- for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = (int)chunks[i];
+ for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = chunks[i];
if ( CDI_Debug )
{
fprintf(stderr, "%s: chunking %d %d %d chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED);
- for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
+ for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%zu ", chunks[i]);
fprintf(stderr, "\n");
}
{
@@ -1114,8 +1114,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
pos += sizeof (prefix) - 1;
for ( int i = nvdims-1; i >= 0; --i )
{
- pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i],
- i > 0 ? "x" : ""));
+ pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i], i > 0 ? "x" : ""));
}
buf[pos] = ' '; buf[pos + 1] = 0;
}
@@ -1324,6 +1323,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
char *varname = pstring;
while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
if ( *pstring == 0 ) lstop = true;
+ if ( *(pstring-1) == ',' ) *(pstring-1) = 0;
*pstring++ = 0;
int dimvarid;
@@ -1346,7 +1346,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
if ( k == nchecked_vars )
{
if ( nchecked_vars < max_check_vars ) checked_vars[nchecked_vars++] = strdup(varname);
- Warning("%s - %s", nc_strerror(status), varname);
+ Warning("%s - >%s<", nc_strerror(status), varname);
}
}
@@ -2122,7 +2122,7 @@ void cdf_check_gridtype(int *gridtype, bool islon, bool islat, size_t xsize, siz
if ( islat && (islon || xsize == 0) )
{
double yinc = 0;
- if ( islon && (int) ysize > 1 )
+ if ( islon && ysize > 1 )
{
yinc = fabs(grid->y.vals[0] - grid->y.vals[1]);
for ( size_t i = 2; i < ysize; i++ )
@@ -2250,8 +2250,8 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
}
else if ( (ndims - ntdims) == 1 )
{
- if ( (int) *ysize == 0 ) size = xsize;
- else size = *ysize;
+ if ( *ysize == 0 ) size = xsize;
+ else size = *ysize;
int dimid = axisvar->dimids[ndims-1];
size_t dimsize = ncdims[dimid].len;
@@ -2370,8 +2370,8 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
xsize, &ysize, ntdims, start, count, &islat) )
return true;
- if ( (int) ysize == 0 ) size = xsize;
- else if ( (int) xsize == 0 ) size = ysize;
+ if ( ysize == 0 ) size = xsize;
+ else if ( xsize == 0 ) size = ysize;
else if ( ncvar->gridtype == GRID_UNSTRUCTURED ) size = xsize;
else size = xsize*ysize;
@@ -2401,9 +2401,9 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
case GRID_CURVILINEAR:
case GRID_PROJECTION:
{
- grid->size = (int)size;
- grid->x.size = (int)xsize;
- grid->y.size = (int)ysize;
+ grid->size = size;
+ grid->x.size = xsize;
+ grid->y.size = ysize;
if ( xvarid != CDI_UNDEFID )
{
grid->x.flag = 1;
@@ -2445,14 +2445,14 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
}
case GRID_SPECTRAL:
{
- grid->size = (int)size;
+ grid->size = size;
grid->lcomplex = 1;
grid->trunc = ncvar->truncation;
break;
}
case GRID_FOURIER:
{
- grid->size = (int)size;
+ grid->size = size;
grid->trunc = ncvar->truncation;
break;
}
@@ -2463,9 +2463,9 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
}
case GRID_CHARXY:
{
- grid->size = (int)size;
- grid->x.size = (int)xsize;
- grid->y.size = (int)ysize;
+ grid->size = size;
+ grid->x.size = xsize;
+ grid->y.size = ysize;
break;
}
}
@@ -2664,17 +2664,6 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva
}
}
- if ( xsize > INT_MAX )
- {
- Warning("Size limit exceeded for x-axis dimension (limit=%d)!", INT_MAX);
- return CDI_EDIMSIZE;
- }
- if ( ysize > INT_MAX )
- {
- Warning("Size limit exceeded for y-axis dimension (limit=%d)!", INT_MAX);
- return CDI_EDIMSIZE;
- }
-
int gmapvarid = ncvar->gmapid;
bool lproj = gmapvarid != CDI_UNDEFID;
@@ -2733,10 +2722,10 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva
if ( CDI_Debug )
{
- Message("grid: type = %d, size = %d, nx = %d, ny %d",
+ Message("grid: type = %d, size = %zu, nx = %zu, ny = %zu",
grid->type, grid->size, grid->x.size, grid->y.size);
if ( proj )
- Message("proj: type = %d, size = %d, nx = %d, ny %d",
+ Message("proj: type = %d, size = %zu, nx = %zu, ny = %zu",
proj->type, proj->size, proj->x.size, proj->y.size);
}
@@ -2912,7 +2901,7 @@ int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int
int nbdims = ncvars[ncvars[zvarid].bounds].ndims;
if ( nbdims == 2 || is_scalar )
{
- size_t nlevel = is_scalar ? 1 : (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
+ size_t nlevel = is_scalar ? 1 : ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
int nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1-is_scalar]].len;
if ( nlevel == zsize && nvertex == 2 )
{
diff --git a/libcdi/src/stream_cdf_o.c b/libcdi/src/stream_cdf_o.c
index e0268ad..ce70f9e 100644
--- a/libcdi/src/stream_cdf_o.c
+++ b/libcdi/src/stream_cdf_o.c
@@ -1,5 +1,5 @@
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+#include "config.h"
#endif
#ifdef HAVE_LIBNETCDF
@@ -29,14 +29,13 @@ void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
int ivarID = streamptr1->tsteps[tsID].records[recID].varID;
int gridID = vlistInqVarGrid(vlistID1, ivarID);
- int datasize = gridInqSize(gridID);
+ size_t datasize = gridInqSize(gridID);
int datatype = vlistInqVarDatatype(vlistID1, ivarID);
int memtype = datatype != CDI_DATATYPE_FLT32 ? MEMTYPE_DOUBLE : MEMTYPE_FLOAT;
- void *data = Malloc((size_t)datasize
- * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
+ void *data = Malloc(datasize * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
- int nmiss;
+ size_t nmiss;
cdf_read_record(streamptr1, memtype, data, &nmiss);
cdf_write_record(streamptr2, memtype, data, nmiss);
@@ -144,7 +143,7 @@ struct idSearch
static inline struct idSearch
cdfSearchIDBySize(size_t startIdx, size_t numIDs, const ncgrid_t ncgrid[numIDs],
int ncIDType, int searchType, int searchSize,
- int (*typeInq)(int id), int (*sizeInq)(int id))
+ int (*typeInq)(int id), size_t (*sizeInq)(int id))
{
int numNonMatching = 0,
foundID = CDI_UNDEFID;
@@ -172,7 +171,7 @@ cdfSearchIDBySize(size_t startIdx, size_t numIDs, const ncgrid_t ncgrid[numIDs],
.foundID = foundID, .foundIdx = foundIdx };
}
-static int
+static size_t
cdfGridInqHalfSize(int gridID)
{
return gridInqSize(gridID)/2;
@@ -185,7 +184,7 @@ cdfDefSPorFC(stream_t *streamptr, int gridID, int gridindex,
{
ncgrid_t *ncgrid = streamptr->ncgrid;
- size_t dimlen = (size_t)(gridInqSize(gridID))/2;
+ size_t dimlen = gridInqSize(gridID)/2;
int iz;
int dimID;
@@ -235,13 +234,13 @@ void cdfDefFC(stream_t *streamptr, int gridID, int gridindex)
}
static const struct cdfDefGridAxisInqs {
- int (*axisSize)(int gridID);
+ size_t (*axisSize)(int gridID);
int (*axisDimname)(int cdiID, int key, int size, char *mesg);
int (*axisName)(int cdiID, int key, int size, char *mesg);
int (*axisLongname)(int cdiID, int key, int size, char *mesg);
int (*axisUnits)(int cdiID, int key, int size, char *mesg);
void (*axisStdname)(int cdiID, char *dimstdname);
- double (*axisVal)(int gridID, int index);
+ double (*axisVal)(int gridID, size_t index);
const double *(*axisValsPtr)(int gridID);
const double *(*axisBoundsPtr)(int gridID);
} gridInqsX = {
@@ -300,7 +299,7 @@ cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex,
nc_type xtype = (gridInqDatatype(gridID) == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
ncgrid_t *ncgrid = streamptr->ncgrid;
- int dimlen = inqs->axisSize(gridID);
+ size_t dimlen = inqs->axisSize(gridID);
if ( dimlen != 1 )
Error("%c size isn't 1 for %s grid!", dimtype, gridNamePtr(gridInqType(gridID)));
@@ -452,7 +451,7 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
int nvdimID = CDI_UNDEFID;
int fileID = streamptr->fileID;
- size_t dimlen = (size_t)gridAxisInq->axisSize(gridID);
+ size_t dimlen = gridAxisInq->axisSize(gridID);
nc_type xtype = (nc_type)cdfDefDatatype(gridInqDatatype(gridID), streamptr->filetype);
ncgrid_t *ncgrid = streamptr->ncgrid;
@@ -472,15 +471,15 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
gridtype0 == GRID_CURVILINEAR ||
gridtype0 == GRID_GENERIC )
{
- size_t dimlen0 = (size_t)gridAxisInq->axisSize(gridID0);
+ size_t dimlen0 = gridAxisInq->axisSize(gridID0);
char dimname0[CDI_MAX_NAME]; dimname0[0] = 0;
if ( dimname[0] ) cdiGridInqKeyStr(gridID0, dimKey, CDI_MAX_NAME, dimname0);
bool lname = dimname0[0] ? strcmp(dimname, dimname0) == 0 : true;
if ( dimlen == dimlen0 && lname )
{
- double (*inqVal)(int gridID, int index) = gridAxisInq->axisVal;
+ double (*inqVal)(int gridID, size_t index) = gridAxisInq->axisVal;
if ( IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) &&
- IS_EQUAL(inqVal(gridID0, (int)dimlen-1), inqVal(gridID, (int)dimlen-1)) )
+ IS_EQUAL(inqVal(gridID0, dimlen-1), inqVal(gridID, dimlen-1)) )
{
dimID = ncgrid[index].ncIDs[dimKey == CDI_KEY_XDIMNAME
? CDF_DIMID_X : CDF_DIMID_Y];
@@ -605,7 +604,7 @@ void cdfDefYaxis(stream_t *streamptr, int gridID, int gridindex, int ndims)
}
static
-void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
+void cdfGridCompress(int fileID, int ncvarid, size_t gridsize, int filetype, int comptype)
{
#if defined (HAVE_NETCDF4)
if ( gridsize > 1 && comptype == CDI_COMPRESS_ZIP && (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C) )
@@ -727,7 +726,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xaxisname);
checkGridName(xaxisname, fileID);
cdf_def_var(fileID, xaxisname, xtype, ndims-1, dimIDs, &ncxvarid);
- cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ cdfGridCompress(fileID, ncxvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
cdfPutGridStdAtts(fileID, ncxvarid, gridID, 'X', &gridInqsX);
@@ -741,7 +740,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
xaxisname[xaxisnameLen] = '_';
memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
cdf_def_var(fileID, xaxisname, xtype, ndims, dimIDs, &ncbxvarid);
- cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ cdfGridCompress(fileID, ncbxvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
}
@@ -756,7 +755,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
checkGridName(yaxisname, fileID);
cdf_def_var(fileID, yaxisname, xtype, ndims - 1, dimIDs, &ncyvarid);
- cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ cdfGridCompress(fileID, ncyvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
cdfPutGridStdAtts(fileID, ncyvarid, gridID, 'Y', &gridInqsY);
@@ -770,7 +769,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
yaxisname[yaxisnameLen] = '_';
memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
cdf_def_var(fileID, yaxisname, xtype, ndims, dimIDs, &ncbyvarid);
- cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+ cdfGridCompress(fileID, ncbyvarid, xdimlen*ydimlen, streamptr->filetype, streamptr->comptype);
cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
}
@@ -811,9 +810,9 @@ void cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex)
{
ncgrid_t *ncgrid = streamptr->ncgrid;
- size_t dimlen = (size_t)gridInqSize(gridID);
- size_t xdimlen = (size_t)gridInqXsize(gridID);
- size_t ydimlen = (size_t)gridInqYsize(gridID);
+ size_t dimlen = gridInqSize(gridID);
+ size_t xdimlen = gridInqXsize(gridID);
+ size_t ydimlen = gridInqYsize(gridID);
int xdimID = CDI_UNDEFID, ydimID = CDI_UNDEFID;
int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
@@ -829,11 +828,11 @@ void cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex)
{
int gridID0 = ncgrid[index].gridID;
if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0))
- && IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1),
- gridInqXval(gridID, (int)dimlen-1))
+ && IS_EQUAL(gridInqXval(gridID0, dimlen-1),
+ gridInqXval(gridID, dimlen-1))
&& IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0))
- && IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1),
- gridInqYval(gridID, (int)dimlen-1)) )
+ && IS_EQUAL(gridInqYval(gridID0, dimlen-1),
+ gridInqYval(gridID, dimlen-1)) )
{
xdimID = ncgrid[index].ncIDs[CDF_DIMID_X];
ydimID = ncgrid[index].ncIDs[CDF_DIMID_Y];
@@ -876,7 +875,7 @@ void cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex)
{
ncgrid_t *ncgrid = streamptr->ncgrid;
- size_t dimlen = (size_t)gridInqSize(gridID);
+ size_t dimlen = gridInqSize(gridID);
int dimID = CDI_UNDEFID;
int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
@@ -893,11 +892,11 @@ void cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex)
int gridID0 = ncgrid[index].gridID;
if ( gridInqNvertex(gridID0) == gridInqNvertex(gridID) &&
IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
- IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1),
- gridInqXval(gridID, (int)dimlen-1)) &&
+ IS_EQUAL(gridInqXval(gridID0, dimlen-1),
+ gridInqXval(gridID, dimlen-1)) &&
IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
- IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1),
- gridInqYval(gridID, (int)dimlen-1)) )
+ IS_EQUAL(gridInqYval(gridID0, dimlen-1),
+ gridInqYval(gridID, dimlen-1)) )
{
dimID = ncgrid[index].ncIDs[CDF_DIMID_X];
ncxvarid = ncgrid[index].ncIDs[CDF_VARID_X];
@@ -1663,7 +1662,7 @@ void cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int xory, i
{
if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
- int dimlen = ( xory == 0 ) ? gridInqXsize(gridID) : gridInqYsize(gridID);
+ size_t dimlen = ( xory == 0 ) ? gridInqXsize(gridID) : gridInqYsize(gridID);
int dimID, strlenID;
ncgrid_t *ncgrid = streamptr->ncgrid;
@@ -1714,7 +1713,7 @@ void cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int xory, i
char axisname[CDI_MAX_NAME]; axisname[0] = 0;
char **cvals = (char **) Malloc(dimlen * sizeof(char *));
- for ( int i = 0; i < dimlen; i++ )
+ for ( size_t i = 0; i < dimlen; i++ )
cvals[i] = Malloc(strlen * sizeof(char) );
int ncaxisid;
if ( xory == 0 )
@@ -1746,7 +1745,7 @@ void cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int xory, i
start[1] = 0;
count[0] = 1;
count[1] = strlen;
- for (int i = 0; i < dimlen; i++)
+ for (size_t i = 0; i < dimlen; i++)
{
start[0] = i;
status = nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]);
@@ -1771,7 +1770,7 @@ void cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex)
{
ncgrid_t *ncgrid = streamptr->ncgrid;
- size_t dimlen = (size_t)gridInqSize(gridID);
+ size_t dimlen = gridInqSize(gridID);
int iz;
int dimID;
@@ -1818,7 +1817,7 @@ void cdfDefGdim(stream_t *streamptr, int gridID, int gridindex)
int iz = 0;
int dimID = CDI_UNDEFID;
- size_t dimlen = (size_t)gridInqSize(gridID);
+ size_t dimlen = gridInqSize(gridID);
if ( gridInqYsize(gridID) == 0 )
{
@@ -1866,10 +1865,10 @@ void cdfDefGrid(stream_t *streamptr, int gridID, int gridindex)
if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
int gridtype = gridInqType(gridID);
- int size = gridInqSize(gridID);
+ size_t size = gridInqSize(gridID);
if ( CDI_Debug )
- Message("gridtype = %d size = %d", gridtype, size);
+ Message("gridtype = %d size = %zu", gridtype, size);
if ( CDI_reduce_dim && size == 1 )
{
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index c5a0c6c..75e4642 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -165,14 +165,18 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
{
bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
-
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
- if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
- grid->size = ISEC4_NumValues;
- grid->x.size = ISEC2_NumLon;
- grid->y.size = ISEC2_NumLat;
+ size_t nvalues = (size_t) ISEC4_NumValues;
+ size_t nlon = (size_t) ISEC2_NumLon;
+ size_t nlat = (size_t) ISEC2_NumLat;
+ if ( nvalues != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon*nlat);
+
+ grid->size = nvalues;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
+
if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
grid->x.inc = 0;
grid->y.inc = 0;
@@ -241,10 +245,10 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
grid->np = ISEC2_NumPar;
- grid->size = ISEC4_NumValues;
+ grid->size = (size_t)ISEC4_NumValues;
grid->rowlon = ISEC2_RowLonPtr;
- grid->nrowlon = ISEC2_NumLat;
- grid->y.size = ISEC2_NumLat;
+ grid->nrowlon = (size_t)ISEC2_NumLat;
+ grid->y.size = (size_t)ISEC2_NumLat;
grid->x.inc = 0;
grid->y.inc = 0;
grid->x.flag = 0;
@@ -283,12 +287,15 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
- if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
- Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
+ size_t nvalues = (size_t) ISEC4_NumValues;
+ size_t nlon = (size_t) ISEC2_NumLon;
+ size_t nlat = (size_t) ISEC2_NumLat;
+ if ( nvalues != nlon*nlat )
+ Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon*nlat);
- grid->size = ISEC4_NumValues;
- grid->x.size = ISEC2_NumLon;
- grid->y.size = ISEC2_NumLat;
+ grid->size = nvalues;
+ grid->x.size = nlon;
+ grid->y.size = nlat;
grid->x.first = 0;
grid->x.last = 0;
@@ -301,16 +308,13 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
}
else if ( gridtype == GRID_SPECTRAL )
{
- grid->size = ISEC4_NumValues;
+ grid->size = (size_t) ISEC4_NumValues;
grid->trunc = ISEC2_PentaJ;
- if ( ISEC2_RepMode == 2 )
- grid->lcomplex = 1;
- else
- grid->lcomplex = 0;
- }
+ grid->lcomplex = (ISEC2_RepMode == 2) ? 1 : 0;
+ }
else if ( gridtype == GRID_GME )
{
- grid->size = ISEC4_NumValues;
+ grid->size = (size_t) ISEC4_NumValues;
grid->gme.nd = ISEC2_GME_ND;
grid->gme.ni = ISEC2_GME_NI;
grid->gme.ni2 = ISEC2_GME_NI2;
@@ -318,7 +322,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
}
else if ( gridtype == GRID_GENERIC )
{
- grid->size = ISEC4_NumValues;
+ grid->size = (size_t) ISEC4_NumValues;
grid->x.size = 0;
grid->y.size = 0;
}
@@ -1322,8 +1326,8 @@ int cgribexScanTimestep(stream_t * streamptr)
#endif
#if defined (HAVE_LIBCGRIBEX)
-int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long datasize,
- int unreduced, int *nmiss, double missval)
+int cgribexDecode(int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval)
{
int status = 0;
int iret = 0, iword = 0;
@@ -1339,10 +1343,10 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
if ( memtype == MEMTYPE_FLOAT )
gribExSP(isec0, isec1, isec2, fsec2f, isec3, fsec3f, isec4, (float*) data,
- (int) datasize, (int*) gribbuffer, gribsize, &iword, hoper, &iret);
+ (int) datasize, (int*) gribbuffer, (int)gribsize, &iword, hoper, &iret);
else
gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, (double*) data,
- (int) datasize, (int*) gribbuffer, gribsize, &iword, hoper, &iret);
+ (int) datasize, (int*) gribbuffer, (int)gribsize, &iword, hoper, &iret);
*nmiss = (ISEC1_Sec2Or3Flag & 64) ? ISEC4_NumValues - ISEC4_NumNonMissValues : 0;
@@ -1355,7 +1359,7 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
if ( memtype == MEMTYPE_FLOAT )
{
float *restrict dataf = (float*) data;
- for ( long i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
if ( (fabs(dataf[i]-undef_pds) < undef_eps) || IS_EQUAL(dataf[i],FSEC3_MissVal) ) {
dataf[i] = (float)missval;
(*nmiss)++;
@@ -1364,7 +1368,7 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
else
{
double *restrict datad = (double*) data;
- for ( long i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
if ( (fabs(datad[i]-undef_pds) < undef_eps) || IS_EQUAL(datad[i],FSEC3_MissVal) ) {
datad[i] = missval;
(*nmiss)++;
@@ -1610,9 +1614,9 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
if ( gridtype == GRID_GENERIC )
{
- int gridsize = gridInqSize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int gridsize = (int)gridInqSize(gridID);
+ int xsize = (int)gridInqXsize(gridID);
+ int ysize = (int)gridInqYsize(gridID);
if ( (ysize == 32 || ysize == 48 || ysize == 64 ||
ysize == 96 || ysize == 160 || ysize == 192 ||
@@ -1688,8 +1692,8 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
else
ISEC2_GridType = GRIB1_GTYPE_LATLON;
- int nlon = gridInqXsize(gridID);
- int nlat = gridInqYsize(gridID);
+ int nlon = (int)gridInqXsize(gridID);
+ int nlat = (int)gridInqYsize(gridID);
if ( gridtype == GRID_GAUSSIAN_REDUCED )
{
@@ -1773,8 +1777,8 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
}
case GRID_LCC:
{
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int xsize = (int)gridInqXsize(gridID);
+ int ysize = (int)gridInqYsize(gridID);
double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
@@ -2079,7 +2083,7 @@ void cgribexDefEnsembleVar(int *isec1, int vlistID, int varID)
#if defined (HAVE_LIBCGRIBEX)
size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const void *data, int nmiss, void *gribbuffer, size_t gribbuffersize)
+ size_t datasize, const void *data, size_t nmiss, void *gribbuffer, size_t gribbuffersize)
{
int iret = 0, iword = 0;
int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
@@ -2109,7 +2113,9 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
cgribexDefEnsembleVar(isec1, vlistID, varID);
- ISEC4_NumValues = gridInqSize(gridID);
+ cdi_check_gridsize_int_limit("GRIB1", datasize);
+
+ ISEC4_NumValues = (int) datasize;
ISEC4_NumBits = grbBitsPerValue(datatype);
if ( nmiss > 0 )
diff --git a/libcdi/src/stream_cgribex.h b/libcdi/src/stream_cgribex.h
index 34f8f33..15490d6 100644
--- a/libcdi/src/stream_cgribex.h
+++ b/libcdi/src/stream_cgribex.h
@@ -1,23 +1,23 @@
-#ifndef _STREAM_CGRIBEX_H
-#define _STREAM_CGRIBEX_H
+#ifndef STREAM_CGRIBEX_H
+#define STREAM_CGRIBEX_H
int cgribexScanTimestep1(stream_t * streamptr);
int cgribexScanTimestep2(stream_t * streamptr);
int cgribexScanTimestep(stream_t * streamptr);
-int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long datasize,
- int unreduced, int *nmiss, double missval);
+int cgribexDecode(int memtype, void *gribbuffer, size_t gribsize, void *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval);
size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const void *data, int nmiss, void *gribbuffer, size_t gribbuffersize);
+ size_t datasize, const void *data, size_t nmiss, void *gribbuffer, size_t gribbuffersize);
void *cgribex_handle_new_from_meassage(void *gribbuffer, size_t recsize);
void cgribex_handle_delete(void *gh);
void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev);
-#endif /* _STREAM_CGRIBEX_H */
+#endif /* STREAM_CGRIBEX_H */
/*
* Local Variables:
* c-file-style: "Java"
diff --git a/libcdi/src/stream_ext.c b/libcdi/src/stream_ext.c
index f5456ce..c50dff9 100644
--- a/libcdi/src/stream_ext.c
+++ b/libcdi/src/stream_ext.c
@@ -2,10 +2,6 @@
# include "config.h"
#endif
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
#include "dmemory.h"
#include "error.h"
@@ -90,7 +86,7 @@ int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
}
*/
-void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void extReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
@@ -112,14 +108,14 @@ void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
double missval = vlistInqVarMissval(vlistID, varID);
int gridID = vlistInqVarGrid(vlistID, varID);
- int size = gridInqSize(gridID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
{
- for ( int i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -128,7 +124,7 @@ void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
}
else
{
- for ( int i = 0; i < 2*size; i+=2 )
+ for ( size_t i = 0; i < 2*size; i+=2 )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -154,7 +150,8 @@ void extDefRecord(stream_t *streamptr)
header[1] = pnum;
header[2] = streamptr->record->level;
int gridID = streamptr->record->gridID;
- header[3] = gridInqSize(gridID);
+ cdi_check_gridsize_int_limit("EXTRA", gridInqSize(gridID));
+ header[3] = (int) gridInqSize(gridID);
extrec_t *extp = (extrec_t*) streamptr->record->exsep;
extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
@@ -172,7 +169,7 @@ void extWriteRecord(stream_t *streamptr, const double *data)
}
static
-void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
+void extAddRecord(stream_t *streamptr, int param, int level, size_t xysize,
size_t recsize, off_t position, int prec, int number)
{
int vlistID = streamptr->vlistID;
@@ -638,7 +635,7 @@ int extInqTimestep(stream_t *streamptr, int tsID)
}
-void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
@@ -648,7 +645,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
double missval = vlistInqVarMissval(vlistID, varID);
- int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
int tsid = streamptr->curTsID;
off_t currentfilepos = fileGetPos(fileID);
@@ -667,7 +664,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
*nmiss = 0;
if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -676,7 +673,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
else
{
- for ( int i = 0; i < 2*gridsize; i+=2 )
+ for ( size_t i = 0; i < 2*gridsize; i+=2 )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -686,12 +683,12 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
for ( size_t levID = 0; levID < nlevs; levID++)
@@ -714,7 +711,9 @@ void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
header[0] = streamptr->tsteps[tsID].taxis.vdate;
header[1] = pnum;
header[2] = (int)(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID));
- header[3] = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ int gridID = vlistInqVarGrid(vlistID, varID);
+ cdi_check_gridsize_int_limit("EXTRA", gridInqSize(gridID));
+ header[3] = (int) gridInqSize(gridID);
extrec_t *extp = (extrec_t*) streamptr->record->exsep;
extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
@@ -730,7 +729,7 @@ void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
for ( size_t levID = 0; levID < nlevs; levID++ )
diff --git a/libcdi/src/stream_ext.h b/libcdi/src/stream_ext.h
index 89c8e2e..6080695 100644
--- a/libcdi/src/stream_ext.h
+++ b/libcdi/src/stream_ext.h
@@ -11,13 +11,13 @@ int extInqTimestep(stream_t *streamptr, int tsID);
int extInqRecord(stream_t *streamptr, int *varID, int *levelID);
void extDefRecord(stream_t *streamptr);
void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void extReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void extReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
void extWriteRecord(stream_t *streamptr, const double *data);
-void extReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
+void extReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
void extWriteVarDP(stream_t *streamptr, int varID, const double *data);
-void extReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+void extReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
void extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
#endif /* _STREAM_EXT_H */
diff --git a/libcdi/src/stream_grb.c b/libcdi/src/stream_grb.c
index c4c5c3b..0daecdd 100644
--- a/libcdi/src/stream_grb.c
+++ b/libcdi/src/stream_grb.c
@@ -279,9 +279,7 @@ int grbScanTimestep2(stream_t * streamptr)
int filetype = streamptr->filetype;
if ( filetype == CDI_FILETYPE_GRB )
- {
- status = cgribexScanTimestep2(streamptr);
- }
+ status = cgribexScanTimestep2(streamptr);
#endif
#if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
else
@@ -297,9 +295,10 @@ static
int grbScanTimestep(stream_t * streamptr)
{
int status = CDI_EUFTYPE;
- int filetype = streamptr->filetype;
#if defined (HAVE_LIBCGRIBEX)
+ int filetype = streamptr->filetype;
+
if ( filetype == CDI_FILETYPE_GRB )
status = cgribexScanTimestep(streamptr);
else
diff --git a/libcdi/src/stream_grb.h b/libcdi/src/stream_grb.h
index 78eb8c5..e98c3ec 100644
--- a/libcdi/src/stream_grb.h
+++ b/libcdi/src/stream_grb.h
@@ -12,15 +12,15 @@ int grbInqTimestep(stream_t *streamptr, int tsID);
int grbInqRecord(stream_t *streamptr, int *varID, int *levelID);
void grbDefRecord(stream_t *streamptr);
-void grb_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss);
-void grb_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
+void grb_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss);
+void grb_write_record(stream_t *streamptr, int memtype, const void *data, size_t nmiss);
void grbCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, int *nmiss);
-void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
+void grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss);
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, size_t nmiss);
-void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, int *nmiss);
-void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss);
+void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, size_t nmiss);
int grib1ltypeToZaxisType(int grib_ltype);
int grib2ltypeToZaxisType(int grib_ltype);
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index 88f40d8..368c724 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -1,11 +1,8 @@
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+#include "config.h"
#endif
#ifdef HAVE_LIBGRIB_API
-#include <limits.h>
-#include <stdio.h>
-
#include "dmemory.h"
#include "cdi.h"
#include "cdi_int.h"
@@ -1468,8 +1465,8 @@ int gribapiScanTimestep(stream_t * streamptr)
#undef gribWarning
#endif
-int gribapiDecode(void *gribbuffer, int gribsize, double *data, long gridsize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID)
+int gribapiDecode(void *gribbuffer, size_t gribsize, double *data, size_t gridsize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID)
{
int status = 0;
long lpar;
@@ -1500,8 +1497,8 @@ int gribapiDecode(void *gribbuffer, int gribsize, double *data, long gridsize,
// printf("values_size = %d numberOfPoints = %ld\n", datasize, numberOfPoints);
- if ( gridsize != (long) datasize )
- Error("Internal problem: gridsize(%ld) != datasize(%zu)!", gridsize, datasize);
+ if ( gridsize != datasize )
+ Error("Internal problem: gridsize(%zu) != datasize(%zu)!", gridsize, datasize);
size_t dummy = datasize;
GRIB_CHECK(grib_get_double_array(gh, "values", data, &dummy), 0);
@@ -1868,7 +1865,7 @@ struct gribApiMsg {
};
static struct gribApiMsg
-getGribApiCompTypeMsg(int comptype, int gridsize)
+getGribApiCompTypeMsg(int comptype, size_t gridsize)
{
const char *mesg;
size_t len;
@@ -1897,14 +1894,14 @@ getGribApiCompTypeMsg(int comptype, int gridsize)
static
-void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, bool lieee, int datatype, int nmiss, int gcinit)
+void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, bool lieee, int datatype, size_t nmiss, int gcinit)
{
UNUSED(nmiss);
bool lrotated = false;
bool lcurvi = false;
int gridtype = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
if ( editionNumber <= 1 )
if ( gridtype == GRID_GME || gridtype == GRID_UNSTRUCTURED )
@@ -1912,8 +1909,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
if ( gridtype == GRID_GENERIC )
{
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int xsize = (int) gridInqXsize(gridID);
+ int ysize = (int) gridInqYsize(gridID);
if ( (ysize == 32 || ysize == 48 || ysize == 64 ||
ysize == 96 || ysize == 160 || ysize == 192 ||
@@ -2022,8 +2019,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
}
GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
- int nlon = gridInqXsize(gridID);
- int nlat = gridInqYsize(gridID);
+ int nlon = (int) gridInqXsize(gridID);
+ int nlat = (int) gridInqYsize(gridID);
if ( gridtype == GRID_GAUSSIAN_REDUCED )
{
@@ -2129,8 +2126,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
}
case GRID_LCC:
{
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ int xsize = (int) gridInqXsize(gridID);
+ int ysize = (int) gridInqYsize(gridID);
double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
@@ -2185,19 +2182,19 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
for (size_t i = 0; i < numTruncAtt; ++i)
GRIB_CHECK(my_grib_set_long(gh, truncAttNames[i], trunc), 0);
}
- // GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridsize), 0);
+ // GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", (long)gridsize), 0);
/*
if ( lieee )
{
printf("spectral_ieee\n");
- if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize, 0);
+ if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", (long)gridsize, 0);
static const char mesg[] = "spectral_ieee";
size_t len = sizeof (mesg) -1;
GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
}
else */ if ( gridInqComplexPacking(gridID) )
{
- if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize), 0);
+ if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", (long)gridsize), 0);
static const char mesg[] = "spectral_complex";
size_t len = sizeof (mesg) -1;
GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
@@ -2229,8 +2226,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
GRIB_CHECK(my_grib_set_long(gh, "latitudeOfThePolePoint", 90000000), 0);
GRIB_CHECK(my_grib_set_long(gh, "longitudeOfThePolePoint", 0), 0);
- GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridsize), 0);
- GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", gridsize), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", (long)gridsize), 0);
+ GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", (long)gridsize), 0);
if ( comptype == CDI_COMPRESS_SZIP )
{
@@ -2756,10 +2753,10 @@ verticallyFlipGridDefinitionWhenScanningModeChanged(grib_handle *gh, double yfir
static void
convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
- int gridsize, int iDim, int jDim)
+ size_t gridsize, size_t iDim, size_t jDim)
{
- int i,j;
- int idxIN, idxOUT;
+ size_t i,j;
+ size_t idxIN, idxOUT;
// 127: reserved for testing; it will generate test data in 64 scanning mode
if (scanModeOUT== 127) // fill with testdata ...
@@ -2768,7 +2765,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
if (cdiDebugExt>=30) printf("convertDataScanningMode(): Generating test data in 64 scanning mode..\n");
for (j=0; j<jDim; j++)
{
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
{
idxIN = i + jXiDim;
@@ -2779,17 +2776,17 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
if ( (iDim*jDim)!= gridsize)
{
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): ERROR: (iDim*jDim)!= gridsize; (%d * %d) != %d\n", iDim,jDim, gridsize);
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): ERROR: (iDim*jDim)!= gridsize; (%zu * %zu) != %zu\n", iDim,jDim, gridsize);
return;
}
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): scanModeIN=%02d => scanModeOUT=%02d ; where: (iDim * jDim == gridsize) (%d*%d == %d)\n",scanModeIN, scanModeOUT, iDim,jDim, gridsize);
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): scanModeIN=%02d => scanModeOUT=%02d ; where: (iDim * jDim == gridsize) (%zu*%zu == %zu)\n",scanModeIN, scanModeOUT, iDim,jDim, gridsize);
if (cdiDebugExt>=100)
{
printf("convertDataScanningMode(): data IN:\n");
for (j=0; j<jDim; j++)
{
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
{
idxIN = i + jXiDim;
@@ -2815,9 +2812,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
return;
}
}
- double *dataCopy = NULL;
- dataCopy = (double *) malloc(gridsize*sizeof(double));
-
+ double *dataCopy = (double *) malloc(gridsize*sizeof(double));
memcpy((void*)dataCopy,(void*) data, gridsize*sizeof(double));
if (scanModeIN==64) // Scanning Mode (00 dec) +i, -j; i direction consecutive (row-major order West->East & South->North )
@@ -2846,7 +2841,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
{
for (j=0; j<jDim; j++)
{
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
idxIN = i + jXiDim;
//data[idxIN] = (double) (100.0*j +i); // just some testdata ..
idxOUT = iDim - i -1 + jXiDim;
@@ -2860,10 +2855,10 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
if (scanModeOUT==96)
{ // transpose the data
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): transpose data rows=>columns nr. (%04d : %04d) => (%04d : %04d);\n", 0, iDim-1, 0, jDim-1);
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): transpose data rows=>columns nr. (%04d : %04zu) => (%04d : %04zu);\n", 0, iDim-1, 0, jDim-1);
for (j=0; j<jDim; j++)
{
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
{
idxIN = i + jXiDim;
@@ -2884,7 +2879,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
idxIN= 0; idxOUT= (jDim-1)*iDim;
for (j=0; j<jDim; j++)
{
- if (cdiDebugExt>=25) printf("convertDataScanningMode(): copying row nr. %04d; [idxIN=%08d] => [idxOUT=%08d]\n",j, idxIN, idxOUT);
+ if (cdiDebugExt>=25) printf("convertDataScanningMode(): copying row nr. %04zu; [idxIN=%08zu] => [idxOUT=%08zu]\n",j, idxIN, idxOUT);
memcpy((void*)&data[idxOUT], (void*)&dataCopy[idxIN], iDim*sizeof(double));
idxIN += iDim; idxOUT -= iDim;
}
@@ -2892,10 +2887,10 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
if (scanModeOUT==96)
{ // transpose the data
- int jInv;
+ size_t jInv;
for (j=0; j<jDim; j++)
{
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04d;\n", j);
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
jInv = (jDim-1) -j;
for (i=0; i<iDim; i++)
data[j + i*jDim] = dataCopy[i + jInv*iDim]; // source data has -j
@@ -2910,8 +2905,8 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
{ // transpose the data
for (j=0; j<jDim; j++)
{
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04d;\n", j);
- int jXiDim = j*iDim;
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
//data[j + i*jDim] = dataCopy[i + j*iDim];
data[i + jXiDim] = dataCopy[j + i*jDim];
@@ -2921,12 +2916,12 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
if (scanModeOUT==00)
{ // transpose the data
idxIN= 0; idxOUT= 0;
- int jInv;
+ size_t jInv;
for (j=0; j<jDim; j++)
{
- if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04d;\n", j);
+ if (cdiDebugExt>=30) printf("convertDataScanningMode(): processing row nr. %04zu;\n", j);
jInv = (jDim-1) -j;
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
//data[jInv + iXjDim] = dataCopy[i + jXiDim]; // target data has -j
data[i + jXiDim] = dataCopy[jInv + i*jDim]; // target data has -j
@@ -2939,7 +2934,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
printf("convertDataScanningMode(): data OUT (new scanning mode):\n");
for (j=0; j<jDim; j++)
{
- int jXiDim = j*iDim;
+ size_t jXiDim = j*iDim;
for (i=0; i<iDim; i++)
{
idxIN = i + jXiDim;
@@ -2954,7 +2949,7 @@ convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
#endif //HIRLAM_EXTENSIONS
static
-void gribapiSetExtMode(grib_handle *gh, int gridID, long datasize, const double *data)
+void gribapiSetExtMode(grib_handle *gh, int gridID, size_t datasize, const double *data)
{
/*
Nj = 550;
@@ -2977,14 +2972,14 @@ void gribapiSetExtMode(grib_handle *gh, int gridID, long datasize, const double
if (cdiDebugExt>=100)
{
- int gridsize = gridInqSize(gridID);
- Message("(scanModeIN=%d; gridsize=%d", scanModeIN, gridsize);
+ size_t gridsize = gridInqSize(gridID);
+ Message("(scanModeIN=%d; gridsize=%zu", scanModeIN, gridsize);
}
if ( cdiGribDataScanningMode.active ) // allowed modes: <0, 64, 96>; Default is 64
{
- int iDim = gridInqXsize(gridID);
- int jDim = gridInqYsize(gridID);
+ size_t iDim = gridInqXsize(gridID);
+ size_t jDim = gridInqYsize(gridID);
double yfirst = gridInqYval(gridID, 0);
double ylast = gridInqYval(gridID, jDim-1);
@@ -3026,7 +3021,7 @@ void gribapiSetExtMode(grib_handle *gh, int gridID, long datasize, const double
size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const double *data, int nmiss, void **gribbuffer, size_t *gribbuffersize,
+ size_t datasize, const double *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize,
int comptype, void *gribContainer)
{
size_t recsize = 0;
@@ -3041,6 +3036,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
char stdname[256];
// extern unsigned char _grib_template_GRIB2[];
+ cdi_check_gridsize_int_limit("GRIB", datasize);
int param = vlistInqVarParam(vlistID, varID);
int datatype = vlistInqVarDatatype(vlistID, varID);
@@ -3144,7 +3140,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
gribapiSetExtMode(gh, gridID, datasize, data);
- GRIB_CHECK(grib_set_double_array(gh, "values", data, (size_t)datasize), 0);
+ GRIB_CHECK(grib_set_double_array(gh, "values", data, datasize), 0);
/* get the size of coded message */
GRIB_CHECK(grib_get_message(gh, (const void **)&dummy, &recsize), 0);
diff --git a/libcdi/src/stream_gribapi.h b/libcdi/src/stream_gribapi.h
index 9b4e980..5da3bba 100644
--- a/libcdi/src/stream_gribapi.h
+++ b/libcdi/src/stream_gribapi.h
@@ -1,5 +1,5 @@
-#ifndef _STREAM_GRIBAPI_H
-#define _STREAM_GRIBAPI_H
+#ifndef STREAM_GRIBAPI_H
+#define STREAM_GRIBAPI_H
#ifdef HAVE_LIBGRIB_API
@@ -9,12 +9,12 @@ int gribapiScanTimestep1(stream_t * streamptr);
int gribapiScanTimestep2(stream_t * streamptr);
int gribapiScanTimestep(stream_t * streamptr);
-int gribapiDecode(void *gribbuffer, int gribsize, double *data, long datasize,
- int unreduced, int *nmiss, double missval, int vlistID, int varID);
+int gribapiDecode(void *gribbuffer, size_t gribsize, double *data, size_t datasize,
+ int unreduced, size_t *nmiss, double missval, int vlistID, int varID);
size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
int vdate, int vtime, int tsteptype, int numavg,
- long datasize, const double *data, int nmiss, void **gribbuffer, size_t *gribbuffersize,
+ size_t datasize, const double *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize,
int ljpeg, void *gribContainer);
int gribapiGetScanningMode(grib_handle *gh);
diff --git a/libcdi/src/stream_ieg.c b/libcdi/src/stream_ieg.c
index 8850336..f6ad8c3 100644
--- a/libcdi/src/stream_ieg.c
+++ b/libcdi/src/stream_ieg.c
@@ -2,13 +2,7 @@
# include "config.h"
#endif
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <float.h>
-#include <math.h>
#include "dmemory.h"
@@ -87,7 +81,7 @@ int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
}
*/
-void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void iegReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
@@ -108,12 +102,12 @@ void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
double missval = vlistInqVarMissval(vlistID, varID);
int gridID = vlistInqVarGrid(vlistID, varID);
- int size = gridInqSize(gridID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
- for ( int i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -249,8 +243,10 @@ void iegDefGrid(int *gdb, int gridID)
int projtype = CDI_UNDEFID;
if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL ) projtype = CDI_PROJ_RLL;
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
+
+ cdi_check_gridsize_int_limit("IEG", xsize*ysize);
if ( gridtype == GRID_GENERIC )
{
@@ -313,8 +309,8 @@ void iegDefGrid(int *gdb, int gridID)
IEG_G_ResFac(gdb) = iresfac;
- IEG_G_NumLon(gdb) = xsize;
- IEG_G_NumLat(gdb) = ysize;
+ IEG_G_NumLon(gdb) = (int)xsize;
+ IEG_G_NumLat(gdb) = (int)ysize;
IEG_G_FirstLat(gdb) = (int)lround(yfirst*resfac);
IEG_G_LastLat(gdb) = (int)lround(ylast*resfac);
IEG_G_FirstLon(gdb) = (int)lround(xfirst*resfac);
@@ -324,7 +320,7 @@ void iegDefGrid(int *gdb, int gridID)
IEG_G_LonIncr(gdb) = 0;
if ( gridtype == GRID_GAUSSIAN )
- IEG_G_LatIncr(gdb) = ysize/2;
+ IEG_G_LatIncr(gdb) = (int)ysize/2;
else
{
IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
@@ -535,10 +531,10 @@ void iegWriteRecord(stream_t *streamptr, const double *data)
iegrec_t *iegp = (iegrec_t*) record->exsep;
int fileID = streamptr->fileID;
- int gridsize = gridInqSize(record->gridID);
+ size_t gridsize = gridInqSize(record->gridID);
double refval = data[0];
- for ( int i = 1; i < gridsize; i++ )
+ for ( size_t i = 1; i < gridsize; i++ )
if ( data[i] < refval ) refval = data[i];
iegp->refval = refval;
@@ -583,8 +579,8 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
grid_init(grid);
cdiGridTypeInit(grid, gridtype, IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb));
- int xsize = IEG_G_NumLon(gdb);
- int ysize = IEG_G_NumLat(gdb);
+ size_t xsize = (size_t)IEG_G_NumLon(gdb);
+ size_t ysize = (size_t)IEG_G_NumLat(gdb);
grid->x.size = xsize;
grid->y.size = ysize;
grid->x.inc = 0;
@@ -683,7 +679,7 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
#if 0
static
void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
- int level, int xsize, int ysize)
+ int level, size_t xsize, size_t ysize)
{
int varID = 0;
int levelID = 0;
@@ -1164,7 +1160,7 @@ int iegInqTimestep(stream_t *streamptr, int tsID)
}
-void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
@@ -1174,7 +1170,7 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
double missval = vlistInqVarMissval(vlistID, varID);
- int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
int tsid = streamptr->curTsID;
off_t currentfilepos = fileGetPos(fileID);
@@ -1189,7 +1185,7 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
fileSetPos(fileID, currentfilepos, SEEK_SET);
*nmiss = 0;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -1198,12 +1194,12 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
for ( size_t levID = 0; levID < nlevs; levID++)
@@ -1239,10 +1235,10 @@ void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
iegp->dprec = iegDefDatatype(vlistInqVarDatatype(vlistID, varID));
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
double refval = data[0];
- for ( int i = 1; i < gridsize; i++ )
+ for ( size_t i = 1; i < gridsize; i++ )
if ( data[i] < refval ) refval = data[i];
iegp->refval = refval;
@@ -1257,7 +1253,7 @@ void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
for ( size_t levID = 0; levID < nlevs; levID++ )
diff --git a/libcdi/src/stream_ieg.h b/libcdi/src/stream_ieg.h
index 2012792..d50ee04 100644
--- a/libcdi/src/stream_ieg.h
+++ b/libcdi/src/stream_ieg.h
@@ -11,13 +11,13 @@ int iegInqTimestep(stream_t *streamptr, int tsID);
int iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
void iegDefRecord(stream_t *streamptr);
void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void iegReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
void iegWriteRecord(stream_t *streamptr, const double *data);
-void iegReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
+void iegReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
void iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
-void iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+void iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
#endif /* _STREAM_IEG_H */
diff --git a/libcdi/src/stream_read.c b/libcdi/src/stream_read.c
index 031ef34..2f82c32 100644
--- a/libcdi/src/stream_read.c
+++ b/libcdi/src/stream_read.c
@@ -15,7 +15,7 @@
/* the single image implementation */
static
-int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmiss)
+int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, size_t *nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -90,7 +90,7 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
@Function streamReadVar
@Title Read a variable
- at Prototype void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+ at Prototype void streamReadVar(int streamID, int varID, double *data, size_t *nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
@Item varID Variable identifier.
@@ -103,7 +103,7 @@ The function streamReadVar reads all the values of one time step of a variable
from an open dataset.
@EndFunction
*/
-void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+void streamReadVar(int streamID, int varID, double *data, size_t *nmiss)
{
cdiStreamReadVar(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
}
@@ -112,7 +112,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
@Function streamReadVarF
@Title Read a variable
- at Prototype void streamReadVar(int streamID, int varID, float *data, int *nmiss)
+ at Prototype void streamReadVar(int streamID, int varID, float *data, size_t *nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
@Item varID Variable identifier.
@@ -125,13 +125,13 @@ The function streamReadVar reads all the values of one time step of a variable
from an open dataset.
@EndFunction
*/
-void streamReadVarF(int streamID, int varID, float *data, int *nmiss)
+void streamReadVarF(int streamID, int varID, float *data, size_t *nmiss)
{
if ( cdiStreamReadVar(streamID, varID, MEMTYPE_FLOAT, data, nmiss) )
{
// In case the file format does not support single precision reading,
// we fall back to double precision reading, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(streamInqVlist(streamID), varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
streamReadVar(streamID, varID, conversionBuffer, nmiss);
@@ -142,7 +142,7 @@ void streamReadVarF(int streamID, int varID, float *data, int *nmiss)
static
-int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, int *nmiss)
+int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, size_t *nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -218,7 +218,7 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
@Function streamReadVarSlice
@Title Read a horizontal slice of a variable
- at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
+ at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, size_t *nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
@Item varID Variable identifier.
@@ -232,12 +232,12 @@ The function streamReadVarSlice reads all the values of a horizontal slice of a
from an open dataset.
@EndFunction
*/
-void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
+void streamReadVarSlice(int streamID, int varID, int levelID, double *data, size_t *nmiss)
{
if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss) )
{
Warning("Unexpected error returned from cdiStreamReadVarSlice()!");
- size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
memset(data, 0, elementCount * sizeof(*data));
}
}
@@ -246,7 +246,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
@Function streamReadVarSliceF
@Title Read a horizontal slice of a variable
- at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
+ at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, size_t *nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead}.
@Item varID Variable identifier.
@@ -260,13 +260,13 @@ The function streamReadVarSliceF reads all the values of a horizontal slice of a
from an open dataset.
@EndFunction
*/
-void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
+void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, size_t *nmiss)
{
if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss) )
{
// In case the file format does not support single precision reading,
// we fall back to double precision reading, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
streamReadVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
@@ -275,7 +275,7 @@ void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int
}
static
-int stream_read_record(int streamID, int memtype, void *data, int *nmiss)
+int stream_read_record(int streamID, int memtype, void *data, size_t *nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -334,13 +334,13 @@ int stream_read_record(int streamID, int memtype, void *data, int *nmiss)
}
-void streamReadRecord(int streamID, double *data, int *nmiss)
+void streamReadRecord(int streamID, double *data, size_t *nmiss)
{
stream_read_record(streamID, MEMTYPE_DOUBLE, (void *) data, nmiss);
}
-void streamReadRecordF(int streamID, float *data, int *nmiss)
+void streamReadRecordF(int streamID, float *data, size_t *nmiss)
{
if ( stream_read_record(streamID, MEMTYPE_FLOAT, (void *) data, nmiss) )
{
@@ -351,7 +351,7 @@ void streamReadRecordF(int streamID, float *data, int *nmiss)
int vrecID = streamptr->tsteps[tsID].curRecID;
int recID = streamptr->tsteps[tsID].recIDs[vrecID];
int varID = streamptr->tsteps[tsID].records[recID].varID;
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
streamReadRecord(streamID, conversionBuffer, nmiss);
for ( size_t i = elementCount; i--; ) data[i] = (float) conversionBuffer[i];
diff --git a/libcdi/src/stream_srv.c b/libcdi/src/stream_srv.c
index cae8a90..2e824d8 100644
--- a/libcdi/src/stream_srv.c
+++ b/libcdi/src/stream_srv.c
@@ -2,11 +2,6 @@
# include "config.h"
#endif
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "dmemory.h"
#include "error.h"
@@ -84,7 +79,7 @@ int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
}
*/
-void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
+void srvReadRecord(stream_t *streamptr, double *data, size_t *nmiss)
{
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
@@ -107,12 +102,12 @@ void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
double missval = vlistInqVarMissval(vlistID, varID);
int gridID = vlistInqVarGrid(vlistID, varID);
- int size = gridInqSize(gridID);
+ size_t size = gridInqSize(gridID);
streamptr->numvals += size;
*nmiss = 0;
- for ( int i = 0; i < size; i++ )
+ for ( size_t i = 0; i < size; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -142,8 +137,8 @@ void srvDefRecord(stream_t *streamptr)
header[3] = record->time;
int gridID = record->gridID;
- int xsize = gridInqXsize(gridID),
- ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID),
+ ysize = gridInqYsize(gridID);
if ( xsize == 0 || ysize == 0 )
{
xsize = gridInqSize(gridID);
@@ -153,8 +148,10 @@ void srvDefRecord(stream_t *streamptr)
if ( gridInqSize(gridID) != xsize*ysize )
Error("Internal problem with gridsize!");
- header[4] = xsize;
- header[5] = ysize;
+ cdi_check_gridsize_int_limit("SERVICE", gridInqSize(gridID));
+
+ header[4] = (int)xsize;
+ header[5] = (int)ysize;
header[6] = 0;
header[7] = 0;
@@ -175,7 +172,7 @@ void srvWriteRecord(stream_t *streamptr, const double *data)
}
static
-void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
+void srv_add_record(stream_t *streamptr, int param, int level, size_t xsize, size_t ysize,
size_t recsize, off_t position, int prec)
{
int vlistID = streamptr->vlistID;
@@ -636,7 +633,7 @@ int srvInqTimestep(stream_t *streamptr, int tsID)
}
-void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d levID = %d", streamptr->self, varID, levID);
@@ -646,7 +643,7 @@ void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
int fileID = streamptr->fileID;
/* NOTE: tiles are not supported here! */
double missval = vlistInqVarMissval(vlistID, varID);
- int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
int tsid = streamptr->curTsID;
off_t currentfilepos = fileGetPos(fileID);
@@ -663,7 +660,7 @@ void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
fileSetPos(fileID, currentfilepos, SEEK_SET);
*nmiss = 0;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
{
data[i] = missval;
@@ -672,12 +669,12 @@ void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
}
-void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, size_t *nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
for ( size_t levID = 0; levID < nlevs; levID++)
@@ -703,8 +700,8 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
header[2] = streamptr->tsteps[tsID].taxis.vdate;
header[3] = streamptr->tsteps[tsID].taxis.vtime;
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
if ( xsize == 0 || ysize == 0 )
{
xsize = gridInqSize(gridID);
@@ -714,6 +711,8 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
if ( gridInqSize(gridID) != xsize*ysize )
Error("Internal problem with gridsize!");
+ cdi_check_gridsize_int_limit("SERVICE", gridInqSize(gridID));
+
header[4] = xsize;
header[5] = ysize;
header[6] = 0;
@@ -735,7 +734,7 @@ void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
- size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
size_t nlevs = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
for ( size_t levID = 0; levID < nlevs; levID++ )
diff --git a/libcdi/src/stream_srv.h b/libcdi/src/stream_srv.h
index 3d776ba..0cc2665 100644
--- a/libcdi/src/stream_srv.h
+++ b/libcdi/src/stream_srv.h
@@ -11,13 +11,13 @@ int srvInqTimestep(stream_t *streamptr, int tsID);
int srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
void srvDefRecord(stream_t *streamptr);
void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void srvReadRecord(stream_t *streamptr, double *data, size_t *nmiss);
void srvWriteRecord(stream_t *streamptr, const double *data);
-void srvReadVarDP (stream_t *streamptr, int varID, double *data, int *nmiss);
+void srvReadVarDP (stream_t *streamptr, int varID, double *data, size_t *nmiss);
void srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
-void srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+void srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss);
void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
#endif /* _STREAM_SRV_H */
diff --git a/libcdi/src/stream_write.c b/libcdi/src/stream_write.c
index dd8cf2e..bf186d5 100644
--- a/libcdi/src/stream_write.c
+++ b/libcdi/src/stream_write.c
@@ -14,7 +14,7 @@
/* the single image implementation */
-int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss)
+int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, size_t nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -92,7 +92,7 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
@Function streamWriteVar
@Title Write a variable
- at Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
+ at Prototype void streamWriteVar(int streamID, int varID, const double *data, size_t nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
@Item varID Variable identifier.
@@ -104,10 +104,10 @@ The function streamWriteVar writes the values of one time step of a variable to
The values are converted to the external data type of the variable, if necessary.
@EndFunction
*/
-void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
+void streamWriteVar(int streamID, int varID, const double *data, size_t nmiss)
{
- void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, int nmiss)
- = (void (*)(int, int, int, const void *, int))
+ void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, size_t nmiss)
+ = (void (*)(int, int, int, const void *, size_t))
namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
@@ -117,7 +117,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
@Function streamWriteVarF
@Title Write a variable
- at Prototype void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+ at Prototype void streamWriteVarF(int streamID, int varID, const float *data, size_t nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
@Item varID Variable identifier.
@@ -129,10 +129,10 @@ The function streamWriteVarF writes the values of one time step of a variable to
The values are converted to the external data type of the variable, if necessary.
@EndFunction
*/
-void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+void streamWriteVarF(int streamID, int varID, const float *data, size_t nmiss)
{
- int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, int nmiss)
- = (int (*)(int, int, int, const void *, int))
+ int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, size_t nmiss)
+ = (int (*)(int, int, int, const void *, size_t))
namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
if ( myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
@@ -141,7 +141,7 @@ void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
// we fall back to double precision writing, converting the data
// on the fly.
int vlistID = streamInqVlist(streamID);
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(vlistID, varID));
elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
@@ -151,7 +151,7 @@ void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
}
static
-int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
+int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, size_t nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -227,7 +227,7 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
@Function streamWriteVarSlice
@Title Write a horizontal slice of a variable
- at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+ at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, size_t nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
@Item varID Variable identifier.
@@ -240,7 +240,7 @@ The function streamWriteVarSlice writes the values of a horizontal slice of a va
The values are converted to the external data type of the variable, if necessary.
@EndFunction
*/
-void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, size_t nmiss)
{
cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
}
@@ -249,7 +249,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
@Function streamWriteVarSliceF
@Title Write a horizontal slice of a variable
- at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
+ at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, size_t nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
@Item varID Variable identifier.
@@ -262,13 +262,13 @@ The function streamWriteVarSliceF writes the values of a horizontal slice of a v
The values are converted to the external data type of the variable, if necessary.
@EndFunction
*/
-void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
+void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, size_t nmiss)
{
if ( cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
{
// In case the file format does not support single precision writing,
// we fall back to double precision writing, converting the data on the fly.
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
streamWriteVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
@@ -278,18 +278,18 @@ void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *dat
void streamWriteVarChunk(int streamID, int varID,
- const int rect[][2], const double *data, int nmiss)
+ const int rect[][2], const double *data, size_t nmiss)
{
void (*myCdiStreamWriteVarChunk_)(int streamID, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss)
- = (void (*)(int, int, int, const int [][2], const void *, int))
+ const int rect[][2], const void *data, size_t nmiss)
+ = (void (*)(int, int, int, const int [][2], const void *, size_t))
namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_CHUNK_).func;
myCdiStreamWriteVarChunk_(streamID, varID, MEMTYPE_DOUBLE, rect, data, nmiss);
}
/* single image implementation */
void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
- const int rect[][2], const void *data, int nmiss)
+ const int rect[][2], const void *data, size_t nmiss)
{
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
@@ -336,7 +336,7 @@ void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
}
static
-int stream_write_record(int streamID, int memtype, const void *data, int nmiss)
+int stream_write_record(int streamID, int memtype, const void *data, size_t nmiss)
{
// May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision writing.
// A value > 0 is returned in this case, otherwise it returns zero.
@@ -397,7 +397,7 @@ int stream_write_record(int streamID, int memtype, const void *data, int nmiss)
@Function streamWriteRecord
@Title Write a horizontal slice of a variable
- at Prototype void streamWriteRecord(int streamID, const double *data, int nmiss)
+ at Prototype void streamWriteRecord(int streamID, const double *data, size_t nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
@Item data Pointer to a block of double precision floating point data values to be written.
@@ -408,13 +408,13 @@ The function streamWriteRecord writes the values of a horizontal slice (record)
The values are converted to the external data type of the variable, if necessary.
@EndFunction
*/
-void streamWriteRecord(int streamID, const double *data, int nmiss)
+void streamWriteRecord(int streamID, const double *data, size_t nmiss)
{
stream_write_record(streamID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
}
-void streamWriteRecordF(int streamID, const float *data, int nmiss)
+void streamWriteRecordF(int streamID, const float *data, size_t nmiss)
{
if ( stream_write_record(streamID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
{
@@ -422,7 +422,7 @@ void streamWriteRecordF(int streamID, const float *data, int nmiss)
// we fall back to double precision writing, converting the data on the fly.
stream_t *streamptr = stream_to_pointer(streamID);
int varID = streamptr->record->varID;
- size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+ size_t elementCount = gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
streamWriteRecord(streamID, conversionBuffer, nmiss);
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index 98328a3..130cde2 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -1013,7 +1013,7 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
zaxisDefUbounds(zaxisID, levels2);
}
- if ( cvals != NULL && nlevels != 0 && clength != 0 ) zaxisDefCvals(zaxisID, cvals, clength);
+ if ( cvals != NULL && nlevels != 0 && clength != 0 ) zaxisDefCvals(zaxisID, cvals, (int)clength);
if ( (zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF) && vctsize > 0 )
zaxisDefVct(zaxisID, vctsize, vct);
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index ab654e0..5dc859d 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -488,7 +488,7 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
zaxisDefLevels(zaxisID, levels);
if ( zaxistype == ZAXIS_CHAR )
- zaxisDefCvals(zaxisID, cvals, clen);
+ zaxisDefCvals(zaxisID, cvals, (int)clen);
if ( has_bounds )
{
@@ -819,8 +819,8 @@ void vlistMerge(int vlistID2, int vlistID1)
{
for ( varID = 0; varID < nvars2; varID++ )
{
- int ngp1 = gridInqSize(vars1[varID].gridID);
- int ngp2 = gridInqSize(vars2[varID].gridID);
+ size_t ngp1 = gridInqSize(vars1[varID].gridID);
+ size_t ngp2 = gridInqSize(vars2[varID].gridID);
if ( ngp1 != ngp2 ) break;
if ( vars1[varID].name && vars2[varID].name )
@@ -1137,7 +1137,7 @@ void vlistPrintKernel(vlist_t *vlistptr, FILE *fp)
fputs("\n"
" varID size iorank\n", fp);
for ( int varID = 0; varID < nvars; varID++ )
- fprintf(fp, "%3d %8d %6d\n", varID,
+ fprintf(fp, "%3d %8zu %6d\n", varID,
zaxisInqSize(vlistptr->vars[varID].zaxisID)
* gridInqSize(vlistptr->vars[varID].gridID),
vlistptr->vars[varID].iorank);
@@ -1293,15 +1293,15 @@ int vlistInqModel(int vlistID)
}
-int vlistGridsizeMax(int vlistID)
+size_t vlistGridsizeMax(int vlistID)
{
- int gridsizemax = 0;
+ size_t gridsizemax = 0;
vlist_t *vlistptr = vlist_to_pointer(vlistID);
for ( int index = 0 ; index < vlistptr->ngrids ; index++ )
{
int gridID = vlistptr->gridIDs[index];
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
if ( gridsize > gridsizemax ) gridsizemax = gridsize;
}
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index 9990cf7..92e1efc 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -1,9 +1,7 @@
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+#include "config.h"
#endif
-#include <limits.h>
-
#include "dmemory.h"
#include "cdi.h"
#include "cdi_int.h"
@@ -17,8 +15,8 @@
#include "error.h"
#if defined (HAVE_LIBGRIB_API)
-# include "file.h"
-# include <grib_api.h>
+#include "file.h"
+#include <grib_api.h>
#endif
@@ -694,18 +692,18 @@ int vlistInqVarID(int vlistID, int code)
}
-int vlistInqVarSize(int vlistID, int varID)
+size_t vlistInqVarSize(int vlistID, int varID)
{
vlistCheckVarID(__func__, vlistID, varID);
int zaxisID, gridID, timetype;
vlistInqVar(vlistID, varID, &gridID, &zaxisID, &timetype);
- int nlevs = zaxisInqSize(zaxisID);
+ size_t nlevs = (size_t)zaxisInqSize(zaxisID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
- int size = gridsize*nlevs;
+ size_t size = gridsize*nlevs;
return size;
}
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index 108714f..59600ca 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -783,20 +783,20 @@ void zaxisDefLevels(int zaxisID, const double *levels)
}
-void zaxisDefCvals(int zaxisID, const char **cvals, size_t clen)
+void zaxisDefCvals(int zaxisID, const char **cvals, int clen)
{
zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
- size_t size = (size_t)zaxisptr->size;
+ int size = zaxisptr->size;
if ( cvals && clen )
{
zaxisptr->clength = clen;
- zaxisptr->cvals = (char**) Malloc(size*sizeof(char *));
+ zaxisptr->cvals = (char**) Malloc((size_t)size*sizeof(char *));
- for ( size_t ilev = 0; ilev < size; ++ilev )
+ for ( int ilev = 0; ilev < size; ++ilev )
{
- zaxisptr->cvals[ilev] = Malloc(clen*sizeof(char));
- memcpy(zaxisptr->cvals[ilev],cvals[ilev], clen*sizeof(char));
+ zaxisptr->cvals[ilev] = Malloc((size_t)clen*sizeof(char));
+ memcpy(zaxisptr->cvals[ilev],cvals[ilev], (size_t)clen*sizeof(char));
}
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
diff --git a/libcdi/tests/Makefile.in b/libcdi/tests/Makefile.in
index 4f0df77..ba1d819 100644
--- a/libcdi/tests/Makefile.in
+++ b/libcdi/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -95,23 +105,6 @@ check_PROGRAMS = cksum_verify$(EXEEXT) test_grib$(EXEEXT) \
@USE_MPI_TRUE at am__append_2 = test_resource_copy_mpi_run
@USE_MPI_TRUE at am__append_3 = test_resource_copy_mpi
subdir = tests
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs \
- $(srcdir)/test_cksum_grib.in $(srcdir)/test_cksum_nc.in \
- $(srcdir)/test_cksum_nc2.in $(srcdir)/test_cksum_nc4.in \
- $(srcdir)/test_cksum_extra.in $(srcdir)/test_cksum_service.in \
- $(srcdir)/test_cksum_ieg.in $(srcdir)/test_chunk_cksum.in \
- $(srcdir)/test_f2003.in $(srcdir)/pio_write_run.in \
- $(srcdir)/pio_write_deco2d_run.in \
- $(srcdir)/pio_cksum_mpinonb.in \
- $(srcdir)/pio_cksum_mpi_fw_ordered.in \
- $(srcdir)/pio_cksum_mpi_fw_at_all.in \
- $(srcdir)/pio_cksum_mpi_fw_at_reblock.in \
- $(srcdir)/pio_cksum_fpguard.in $(srcdir)/pio_cksum_asynch.in \
- $(srcdir)/pio_cksum_writer.in $(srcdir)/pio_cksum_cdf.in \
- $(srcdir)/test_resource_copy_mpi_run.in \
- $(srcdir)/test_cdf_transformation.in \
- $(srcdir)/test_cdf_const.in $(top_srcdir)/config/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = \
$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -143,6 +136,7 @@ am__aclocal_m4_deps = \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES = test_cksum_grib test_cksum_nc test_cksum_nc2 \
@@ -325,6 +319,23 @@ am__tty_colors = { \
std='[m'; \
fi; \
}
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pio_cksum_asynch.in \
+ $(srcdir)/pio_cksum_cdf.in $(srcdir)/pio_cksum_fpguard.in \
+ $(srcdir)/pio_cksum_mpi_fw_at_all.in \
+ $(srcdir)/pio_cksum_mpi_fw_at_reblock.in \
+ $(srcdir)/pio_cksum_mpi_fw_ordered.in \
+ $(srcdir)/pio_cksum_mpinonb.in $(srcdir)/pio_cksum_writer.in \
+ $(srcdir)/pio_write_deco2d_run.in $(srcdir)/pio_write_run.in \
+ $(srcdir)/test_cdf_const.in \
+ $(srcdir)/test_cdf_transformation.in \
+ $(srcdir)/test_chunk_cksum.in $(srcdir)/test_cksum_extra.in \
+ $(srcdir)/test_cksum_grib.in $(srcdir)/test_cksum_ieg.in \
+ $(srcdir)/test_cksum_nc.in $(srcdir)/test_cksum_nc2.in \
+ $(srcdir)/test_cksum_nc4.in $(srcdir)/test_cksum_service.in \
+ $(srcdir)/test_f2003.in \
+ $(srcdir)/test_resource_copy_mpi_run.in \
+ $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -571,7 +582,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign tests/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -1060,6 +1070,8 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
#
clean-local: clean-local-dirs
.PHONY: clean-local-dirs
diff --git a/libcdi/tests/stream_cksum.c b/libcdi/tests/stream_cksum.c
index 4f8e458..fa6eb53 100644
--- a/libcdi/tests/stream_cksum.c
+++ b/libcdi/tests/stream_cksum.c
@@ -159,7 +159,7 @@ cksum_stream(const char *fname, size_t *table_len)
// Read var1 and var2
for (int varIdx = 0; varIdx < nvars; ++varIdx)
{
- int nmiss;
+ size_t nmiss;
streamReadVar(streamID, varIdx, buf, &nmiss);
memcrc_r(checksum_state + varIdx, (const unsigned char *)vdatetime,
sizeof (vdatetime));
diff --git a/libcdi/tests/test_cdf_read.c b/libcdi/tests/test_cdf_read.c
index a3e2c60..2a8de8b 100644
--- a/libcdi/tests/test_cdf_read.c
+++ b/libcdi/tests/test_cdf_read.c
@@ -41,7 +41,7 @@ int main(int argc, const char **argv)
{
size_t memSize = (size_t)vlistInqVarSize(vlistID, (int)varID)
* sizeof (double);
- int nmiss;
+ size_t nmiss;
if (memSize > bufSize)
{
double *temp = (double *)realloc(buf, memSize);
@@ -53,7 +53,7 @@ int main(int argc, const char **argv)
buf = temp;
}
streamReadVar(streamID, (int)varID, buf, &nmiss);
- allNmissSum += (size_t)nmiss;
+ allNmissSum += nmiss;
}
}
if (countMissingValues)
diff --git a/libcdi/tests/test_grib.c b/libcdi/tests/test_grib.c
index f420278..5645c0f 100644
--- a/libcdi/tests/test_grib.c
+++ b/libcdi/tests/test_grib.c
@@ -26,7 +26,7 @@ int main()
int tsID;
int levelID;
int vlistID, taxisID;
- int nmiss;
+ size_t nmiss;
size_t datasize = (size_t)nlon * (size_t)nlat;
diff --git a/m4/acx_cfortran_flags.m4 b/m4/acx_cfortran_flags.m4
new file mode 100644
index 0000000..35fe2cd
--- /dev/null
+++ b/m4/acx_cfortran_flags.m4
@@ -0,0 +1,171 @@
+dnl acx_fc_c_link.m4 --- transform library c flags into version
+dnl that suits the fortran compiler
+dnl
+dnl Copyright (C) 2011 Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords:
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl ACX_FC_XLF_QEXTNAME_ADD_APPENDUS
+dnl Test if compiler is xlf and if -qextname is in use.
+dnl Add -Dappendus to CPPFLAGS if the above applies.
+dnl
+AC_DEFUN([ACX_XLF_QEXTNAME_ADD_APPENDUS],
+ [AS_CASE([$host],
+ [*-ibm-aix*],
+ [AC_MSG_CHECKING([if -Dappendus needs to be added to CPPFLAGS for cfortran.h])
+ AS_IF([$CC -qversion 2>&1 | grep '^IBM XL C' >/dev/null],
+ [acx_temp_qextname_f77flags=`echo "$FFLAGS" | sed -n '/-qextname/{ s/^\(.* \)*-qextname\( .*\)*$/-qextname/;p;}'`
+ acx_temp_qextname_fcflags=`echo "$FCFLAGS" | sed -n '/-qextname/{ s/^\(.* \)*-qextname\( .*\)*$/-qextname/;p;}'`
+ dnl pretend the same option as for FC was used if F77 isn't used at all
+ dnl also in case a non-xl compiler is used it will append an underscore
+ AC_PROVIDE_IFELSE([AC_PROG_F77],,
+ [AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [acx_temp_qextname_f77flags=$acx_temp_qextname_fcflags],
+ [m4_fatal([AC_PROG_F77 or AC_PROG_FC must have been invoked prior to ACX_XLF_QEXTNAME_ADD_APPENDUS])])])
+ dnl and vice versa for FC
+ AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [AS_IF([$FC -qversion 2>&1 | grep '^IBM XL Fortran' >/dev/null],,
+ [acx_temp_qextname_fcflags=-qextname])],
+ [AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [acx_temp_qextname_fcflags=$acx_temp_qextname_f77flags])])
+ AS_CASE([x"$acx_temp_qextname_fcflags$acx_temp_qextname_f77flags"],
+ [x-qextname],
+ [AC_MSG_ERROR([Option -qextname must be provided consistently to F77 and FC])],
+ [x-qextname-qextname],
+ [AC_MSG_RESULT([yes])
+ CPPFLAGS="${CPPFLAGS+$CPPFLAGS }-Dappendus"],
+ [AC_MSG_RESULT([no])])
+ ],[AC_MSG_RESULT([no])])])])
+dnl
+dnl automate flag elicitation for cfortran.h
+AC_DEFUN([_ACX_FIND_CFORTRAN_DEF],
+ [AC_REQUIRE([AC_CANONICAL_HOST])
+ _AC_FORTRAN_ASSERT
+ AC_LANG_CASE([Fortran],[save_FC=$FC ; acx_FC=$FC],
+ [Fortran 77],[save_F77=$F77 ; acx_FC=$F77])
+ AS_CASE([$host],
+ [x86_64-*-linux-*|i*86-*-linux-*|*-apple-darwin*|ia64-*-linux-*|x86_64-*-freebsd*|i*86-*-freebsd*],
+ [acx_temp=`$acx_FC -V 2>&1`
+ AS_IF([echo "$acx_temp" | grep '^Copyright.*\(The Portland Group\|NVIDIA CORPORATION\)' >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-DgFortran])],
+ [echo "$acx_temp" | grep '^NAG Fortran Compiler Release' >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-DNAGf90Fortran])],
+ [echo "$acx_temp" | grep '^Intel(R) Fortran.*Compiler' >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-DgFortran])],
+ [echo "$acx_temp" | grep '^Cray Fortran' >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-DgFortran])],
+ [acx_temp=`$acx_FC --version 2>&1` \
+ && echo $acx_temp | grep '^GNU Fortran' >/dev/null],
+ [AS_IF([echo $acx_temp | grep g77 >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-Dg77Fortran])],
+ [dnl assume gfortran
+dnl check if compiling with f2c bindings or with default bindings
+ AS_IF([echo "]AC_LANG_CASE([Fortran],[$FCFLAGS],
+ [Fortran 77],[$FFLAGS])[" | grep '^\(.* \)*-ff2c\( .*\)*$' >/dev/null],
+ [AS_VAR_SET([acx_cf_flag],[-Df2cFortran])],
+ [AS_VAR_SET([acx_cf_flag],[-DgFortran])])])],
+ [acx_temp=`$acx_FC -v 2>&1` \
+ && echo $acx_temp | grep '^f2c'],
+ [AS_VAR_SET([acx_cf_flag],[-Df2cFortran])])],
+ [*-ibm-aix*],
+ [dnl xlc set _IBMR2 so nothing needs to be done
+ AS_IF([$CC -qversion 2>&1 | grep '^IBM XL C' >/dev/null],,
+ [dnl but for other compilers set IBMR2Fortran
+ AS_VAR_SET([acx_cf_flag],[-DIBMR2Fortran])])
+ ],
+ [*-*-hpux*],
+ [AS_VAR_SET([acx_cf_flag],[-DhpuxFortran])],
+ [sx*-*-*|es*-*-*],
+ [dnl fixme: make sure user is actually using sxf90
+dnl but currently there is no alternative I know of
+ AS_VAR_SET([acx_cf_flag],[-DSXFortran])])])
+
+AC_DEFUN([ACX_FIND_CFORTRAN_DEF],
+ [AC_CACHE_CHECK([C preprocessor flags for Fortran calling convention cfortran.h],
+ [acx_cv_cf_flag],
+ [acx_cv_cf_flag=''
+dnl test if user already provided a flag
+ AS_FOR([MACRO],[macro],[pgiFortran NAGf90Fortran f2cFortran hpuxFortran apolloFortran sunFortran IBMR2Fortran CRAYFortran PATHSCALE_COMPILER gFortran mipsFortran DECFortran vmsFortran CONVEXFortran PowerStationFortran AbsoftUNIXFortran AbsoftProFortran SXFortran],
+ [acx_temp=`echo "$CPPFLAGS $CFLAGS" | sed -n 's/^\(.* \)*-D\('"MACRO"'\)\( .*\)*$/\2/;t print
+b
+: print
+p'`
+ AS_IF([test x"$acx_temp" != x],
+ [AS_IF([test x"$acx_cv_cf_flag" = x],
+ [acx_cv_cf_flag="$acx_temp (user-specified)"],
+ [echo ; echo '"'"$acx_cv_cf_flag $acx_temp"'"'
+ AC_MSG_ERROR([Multiple specification of cfortran.h flags])])])])
+dnl find automatically from machine/compiler
+ AS_IF([test x"$acx_cv_cf_flag" = x],
+ [AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [AS_IF([test -n "$FC" -a X"$FC" != Xno],
+ [AC_LANG_PUSH([Fortran])
+ AS_VAR_PUSHDEF([acx_cf_flag],[acx_cv_]_AC_LANG_ABBREV[_cf_flag])
+ _ACX_FIND_CFORTRAN_DEF
+ AS_VAR_POPDEF([acx_cf_flag])
+ AC_LANG_POP([Fortran])])])
+ AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [AS_IF([test -n "$F77" -a X"$F77" != Xno],
+ [AC_LANG_PUSH([Fortran 77])
+ AS_VAR_PUSHDEF([acx_cf_flag],[acx_cv_]_AC_LANG_ABBREV[_cf_flag])
+ _ACX_FIND_CFORTRAN_DEF
+ AS_VAR_POPDEF([acx_cf_flag])
+ AC_LANG_POP([Fortran 77])])])
+dnl check f77 flag matches fc flag
+ AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [dnl both FC and F77 are configured
+ AS_IF([test -z "$F77" -o X"$F77" = Xno],
+ [acx_cv_cf_flag="$acx_cv_fc_cf_flag (probed)"],
+ [test -z "$FC" -o X"$FC" = Xno],
+ [acx_cv_cf_flag="$acx_cv_f77_cf_flag (probed)"],
+ [AS_IF([test x"$acx_cv_f77_cf_flag" = x"$acx_cv_fc_cf_flag"],
+ [acx_cv_cf_flag="$acx_cv_f77_cf_flag (probed)"],
+ [AC_MSG_ERROR([cfortran.h flag for $F77 does not match the flag for $FC.
+Have you configured compatible compilers?])])])
+ ],
+ [acx_cv_cf_flag="$acx_cv_f77_cf_flag (probed)"])],
+ [acx_cv_cf_flag="$acx_cv_fc_cf_flag (probed)"])
+ ])
+ ])
+dnl now that flag is established, add (probed) defines to CPPFLAGS
+ AS_IF([echo "$acx_cv_cf_flag" | grep ' (probed)$' >/dev/null],
+ [CPPFLAGS="${CPPFLAGS+$CPPFLAGS }`echo "$acx_cv_cf_flag" | sed 's/ (probed)$//'`"])
+ ])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/m4/acx_check_cfortran.m4 b/m4/acx_check_cfortran.m4
new file mode 100644
index 0000000..c69ebd0
--- /dev/null
+++ b/m4/acx_check_cfortran.m4
@@ -0,0 +1,275 @@
+dnl acx_check_cfortran.m4 --- test if a program compiled from
+dnl a main Fortran program and
+dnl C functions gives expected results
+dnl
+dnl Copyright (C) 2013 Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords:
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl helper function to emit Fortran test code
+AC_DEFUN([_ACX_CHECK_CFORTRAN_FC],
+ [AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+[ MODULE conftest_data
+ IMPLICIT NONE
+ PRIVATE
+ REAL :: ri
+ PUBLIC :: ri
+ END MODULE conftest_data
+
+ FUNCTION cftstf(v) RESULT(r)
+ USE conftest_data, ONLY: ri
+ REAL, INTENT(in) :: v
+ REAL :: r
+ r = v * 100.0
+ ri = 1.0 / v
+ END FUNCTION cftstf])],
+ [_AC_RUN_LOG([mv "conftest.$ac_objext" "conftest_f.$ac_objext"],
+ [_AS_ECHO_LOG([Renaming Fortran object file.])])
+ save_LIBS=$LIBS
+ LIBS="conftest_c.$ac_objext conftest_f.$ac_objext $LIBS"
+ AC_RUN_IFELSE([AC_LANG_PROGRAM(,
+[ USE conftest_data, ONLY: ri
+ IMPLICIT NONE
+ INTERFACE
+ FUNCTION cftstc(i, v, p, q) RESULT(f)
+ INTEGER, INTENT(in) :: i
+ REAL, INTENT(in) :: v
+ INTEGER, INTENT(out) :: p
+ REAL, INTENT(out) :: q
+ REAL :: f
+ END FUNCTION cftstc
+ FUNCTION chtst() result(s)
+ CHARACTER(99) :: s
+ END FUNCTION chtst
+ END INTERFACE
+ REAL, PARAMETER :: eps = 10e-6
+ REAL :: foo, boo, too
+ INTEGER :: bar, baz, i
+ CHARACTER(99) :: aaaaaa
+ bar = 5
+ foo = 0.3
+ too = cftstc(bar, foo, baz, boo)
+ IF (ABS(baz - NINT(bar * foo)) /= 0) THEN
+ WRITE (0, '(2(a,i0))') "error checking, when baz, baz=", baz, &
+ ", NINT(bar * foo) =", NINT(bar * foo)
+ FLUSH(0)
+ CALL err_exit
+ END IF
+ IF (ABS((ri - 1.0 / (bar * foo)) / ABS(ri)) > eps) THEN
+ WRITE (0, '(2(a,g24.15))') "error checking ri, ri=", ri, ", 1.0 / &
+ &(bar * foo) = ", 1.0 / (bar * foo)
+ FLUSH(0)
+ CALL err_exit
+ END IF
+ IF (ABS((boo - (bar * foo * 100.0))/ABS(boo)) > eps) THEN
+ WRITE (0, '(2(a,g24.15))') "error checking boo, boo=", boo, &
+ ", bar * foo * 100.0 = ", bar * foo * 100.0
+ FLUSH(0)
+ CALL err_exit
+ END IF
+ IF (too /= boo) THEN
+ WRITE (0, '(2(a,g24.15))') "error checking too vs. boo, too=", too, &
+ ", boo = ", boo
+ FLUSH(0)
+ CALL err_exit
+ END IF
+ aaaaaa = chtst()
+ DO i = 1, 99
+ IF (aaaaaa(i:i) /= 'A') THEN
+ WRITE (0, '(a,i0,a)') "error checking aaaaaa(", i, ")=", &
+ aaaaaa(i:i)
+ FLUSH(0)
+ CALL err_exit
+ END IF
+ END DO])],
+ [acx_cv_cfortran_works=yes],
+ [acx_cv_cfortran_works="error"],
+ [AC_MSG_NOTICE([Skipping run test for cfortran.h in cross-compilation mode,])
+ AC_MSG_NOTICE([link test succeeded.])
+ acx_cv_cfortran_works=yes])
+ LIBS=$save_LIBS],
+ [acx_cv_cfortran_works="error compiling Fortran subroutine"])
+ AC_LANG_POP([Fortran])])
+
+dnl helper function to emit Fortran 77 test code
+AC_DEFUN([_ACX_CHECK_CFORTRAN_F77],
+ [AC_LANG_PUSH([Fortran 77])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+[ REAL FUNCTION CFTSTF(v)
+ REAL RI
+ COMMON /CFTSTD/ RI
+ REAL V
+ REAL R
+ CFTSTF = V * 100.0
+ RI = 1.0 / V
+ END FUNCTION CFTSTF])],
+ [_AC_RUN_LOG([mv "conftest.$ac_objext" "conftest_f.$ac_objext"],
+ [_AS_ECHO_LOG([Renaming Fortran object file.])])
+ save_LIBS=$LIBS
+ LIBS="conftest_c.$ac_objext conftest_f.$ac_objext $LIBS"
+ AC_RUN_IFELSE([AC_LANG_PROGRAM(,
+[ REAL RI
+ COMMON /CFTSTD/ RI
+ REAL EPS
+ PARAMETER(EPS=10E-6)
+ REAL FOO, BOO, TOO
+ INTEGER BAR, BAZ, I
+ CHARACTER(99) AAAAAA
+ EXTERNAL CFTSTC, CFTSTF, CHTST, ERR_EXIT
+ REAL CFTSTC, CFTSTF
+ CHARACTER(99) CHTST
+ BAR = 5
+ FOO = 0.3
+ TOO = CFTSTC(BAR, FOO, BAZ, BOO)
+ IF (ABS(BAZ - NINT(BAR * FOO)) /= 0) THEN
+ WRITE (0, '(2(A,I0))') "ERROR CHECKING, WHEN BAZ, BAZ=", BAZ,
+ & ", NINT(BAR * FOO) =", NINT(BAR * FOO)
+ CALL ERR_EXIT
+ END IF
+ IF (ABS((RI - 1.0 / (BAR * FOO)) / ABS(RI)) > EPS) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING RI, RI=", RI, ",
+ & 1.0 / (BAR * FOO) = ", 1.0 / (BAR * FOO)
+ CALL err_exit
+ END IF
+ IF (ABS((BOO - (BAR * FOO * 100.0))/ABS(BOO)) > EPS) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING BOO, BOO=", BOO,
+ & ", BAR * FOO * 100.0 = ", BAR * FOO * 100.0
+ CALL ERR_EXIT
+ END IF
+ IF (TOO /= BOO) THEN
+ WRITE (0, '(2(A,F24.15))') "ERROR CHECKING TOO VS. BOO, TOO=",
+ & TOO, ", BOO = ", BOO
+ CALL ERR_EXIT
+ END IF
+ AAAAAA = CHTST()
+ DO i = 1, 99
+ IF (AAAAAA(I:I) /= 'A') THEN
+ WRITE (0, '(A,I0,2A)') "ERROR CHECKING AAAAAA(", I, ")=",
+ & AAAAAA(I:I)
+ CALL ERR_EXIT
+ END IF
+ END DO])],
+ [acx_cv_cfortran_works=yes],
+ [acx_cv_cfortran_works="error"],
+ [AC_MSG_NOTICE([Skipping run test for cfortran.h in cross-compilation mode,])
+ AC_MSG_NOTICE([link test succeeded.])
+ acx_cv_cfortran_works=yes])
+ LIBS=$save_LIBS],
+ [acx_cv_cfortran_works="error compiling Fortran subroutine"])
+ AC_LANG_POP([Fortran 77])])
+
+dnl ACX_CHECK_CFORTRAN([OPTIONAL-CFORTRAN-INC-DIR],[ACTION-IF-SUCCESS],
+dnl [ACTION-IF-FAILED])
+dnl Test if C compiler can produce objects that link fine to Fortran programs
+dnl when using cfortran.h.
+dnl
+AC_DEFUN([ACX_CHECK_CFORTRAN],
+ [AC_CACHE_CHECK([if C externals constructed with cfortran.h work],
+ [acx_cv_cfortran_works],
+ [acx_cv_cfortran_works=no
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="-I]m4_ifval([$1],[$1],[$srcdir/include])[ $CPPFLAGS"
+dnl build C function
+ AC_LANG_PUSH([C])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([@%:@include "cfortran.h"
+@%:@include <math.h>
+@%:@include <stdio.h>
+@%:@include <stdlib.h>
+
+PROTOCCALLSFFUN1(FLOAT,CFTSTF,cftstf,FLOAT)
+#define conftest_F(v) \
+ CCALLSFFUN1(CFTSTF,cftstf,FLOAT,(v));
+
+static float
+cftstC(int i, float v, int *p, float *q)
+{
+ float f;
+ *p = (int)roundf(v * i);
+ *q = f = conftest_F(v * i);
+ return f;
+}
+
+FCALLSCFUN4(FLOAT,cftstC,CFTSTC,cftstc,INT,FLOAT,PINT,PFLOAT)
+
+/* test string returns */
+static const char *
+conftest_str_C(void)
+{
+ static const char msg@<:@100@:>@ = "AAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ return msg;
+}
+
+FCALLSCFUN0(STRING,conftest_str_C,CHTST,chtst)
+
+/* This function is required simply because some Fortran compilers
+ * won't stop with exit code n when encountering STOP n */
+static void
+errExit(void)
+{
+ exit(1);
+}
+
+FCALLSCSUB0(errExit,ERR_EXIT,err_exit)
+
+])],
+ [_AC_RUN_LOG([mv "conftest.$ac_objext" "conftest_c.$ac_objext"],
+ [_AS_ECHO_LOG([Renaming C object file.])])
+ AC_PROVIDE_IFELSE([AC_PROG_FC],[_ACX_CHECK_CFORTRAN_FC])
+ AC_PROVIDE_IFELSE([AC_PROG_F77],[_ACX_CHECK_CFORTRAN_F77])
+ ],
+ [acx_cv_cfortran_works="compiling with cfortran.h failed"])
+ AC_LANG_POP([C])
+ CPPFLAGS=$save_CPPFLAGS
+ ])
+ m4_ifval([$3],
+ [AS_IF([test x"$acx_cv_cfortran_works" = xyes],[$2],[$3])],
+ [AS_CASE([x"$acx_cv_cfortran_works"],
+ [x"error"],
+ [AC_MSG_FAILURE([Linking/Running with C EXTERNAL built with cfortran.h does not work!])],
+ [x"compiling with cfortran.h failed"],
+ [AC_MSG_FAILURE([Compilation with cfortran.h is not working!])],
+ [x"error compiling Fortran subroutine"],
+ [AC_MSG_FAILURE([compilation of simple Fortran source failed!])],
+ [xyes],[$2],
+ [AC_MSG_FAILURE([Unexpected error when linking C and Fortran via cfortran.h!])])])
+ ])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/src/Adisit.cc b/src/Adisit.cc
index aa4d6c8..f309515 100644
--- a/src/Adisit.cc
+++ b/src/Adisit.cc
@@ -160,7 +160,7 @@ void *Adisit(void *argument)
int varID, levelID;
int offset;
int i;
- int nmiss;
+ size_t nmiss;
int thoID = -1, saoID = -1;
char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
double pin = -1;
diff --git a/src/Afterburner.cc b/src/Afterburner.cc
index 3feb434..530c145 100644
--- a/src/Afterburner.cc
+++ b/src/Afterburner.cc
@@ -391,7 +391,7 @@ static
void *after_readTimestep(void *arg)
{
int varID, gridID, zaxisID, levelID, timeID;
- int nmiss;
+ size_t nmiss;
RARG *rarg = (RARG *) arg;
int nrecs = rarg->nrecs;
@@ -1707,7 +1707,7 @@ void after_postcntl(struct Control *globs, struct Variable *vars)
gridID = vars[code].igridID;
zaxisID = vars[code].izaxisID;
zaxisName(zaxisInqType(zaxisID), zaxistypename);
- fprintf(stderr," Detected Code %3d grid %-8s size %5d level %2d %-8s\n",
+ fprintf(stderr," Detected Code %3d grid %-8s size %5zu level %2d %-8s\n",
code, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID),
zaxisInqSize(zaxisID), zaxistypename);
}
@@ -1812,7 +1812,7 @@ void after_postcntl(struct Control *globs, struct Variable *vars)
gridID = vars[code].ogridID;
zaxisID = vars[code].ozaxisID;
zaxisName(zaxisInqType(zaxisID), zaxistypename);
- fprintf(stderr," Selected Code %3d grid %-8s size %5d level %2d %-8s\n",
+ fprintf(stderr," Selected Code %3d grid %-8s size %5zu level %2d %-8s\n",
code, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID),
zaxisInqSize(zaxisID), zaxistypename);
}
diff --git a/src/Arith.cc b/src/Arith.cc
index 7e26534..d4256e1 100644
--- a/src/Arith.cc
+++ b/src/Arith.cc
@@ -37,13 +37,13 @@ void *Arith(void *argument)
{
enum {FILL_NONE, FILL_TS, FILL_VAR, FILL_VARTS, FILL_FILE};
int filltype = FILL_NONE;
- int nmiss;
+ size_t nmiss;
int nrecs, nvars = 0;
int nlevels2 = 1;
int varID, levelID;
int levelID2;
- int *varnmiss2 = NULL;
- int **varnmiss = NULL;
+ size_t *varnmiss2 = NULL;
+ size_t **varnmiss = NULL;
double *vardata2 = NULL;
double **vardata = NULL;
@@ -152,7 +152,7 @@ void *Arith(void *argument)
if ( filltype == FILL_VAR || filltype == FILL_VARTS )
{
vardata2 = (double*) Malloc(gridsize*nlevels2*sizeof(double));
- varnmiss2 = (int*) Malloc(nlevels2*sizeof(int));
+ varnmiss2 = (size_t*) Malloc(nlevels2*sizeof(size_t));
}
if ( cdoVerbose ) cdoPrint("Number of timesteps: file1 %d, file2 %d", ntsteps1, ntsteps2);
@@ -181,13 +181,13 @@ void *Arith(void *argument)
{
nvars = vlistNvars(vlistIDx2);
vardata = (double **) Malloc(nvars*sizeof(double *));
- varnmiss = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
int gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
int nlev = zaxisInqSize(vlistInqVarZaxis(vlistIDx2, varID));
vardata[varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss[varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
}
}
@@ -250,7 +250,7 @@ void *Arith(void *argument)
{
pstreamInqRecord(streamIDx1, &varID, &levelID);
pstreamReadRecord(streamIDx1, fieldx1->ptr, &nmiss);
- fieldx1->nmiss = (size_t) nmiss;
+ fieldx1->nmiss = nmiss;
int varID2 = varID;
if ( tsID == 0 || filltype == FILL_NONE || filltype == FILL_FILE || filltype == FILL_VARTS )
@@ -261,7 +261,7 @@ void *Arith(void *argument)
{
pstreamInqRecord(streamIDx2, &varID2, &levelID2);
pstreamReadRecord(streamIDx2, fieldx2->ptr, &nmiss);
- fieldx2->nmiss = (size_t) nmiss;
+ fieldx2->nmiss = nmiss;
if ( varID != varID2 ) cdoAbort("Internal error, varIDs of input streams differ!");
if ( levelID != levelID2 ) cdoAbort("Internal error, levelIDs of input streams differ!");
}
@@ -311,7 +311,7 @@ void *Arith(void *argument)
farfun(&field1, field2, operfunc);
pstreamDefRecord(streamID3, varID, levelID);
- pstreamWriteRecord(streamID3, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID3, field1.ptr, field1.nmiss);
}
tsID++;
diff --git a/src/Arithc.cc b/src/Arithc.cc
index bc0f2e7..2187b63 100644
--- a/src/Arithc.cc
+++ b/src/Arithc.cc
@@ -72,7 +72,7 @@ int *fill_vars(int vlistID)
void *Arithc(void *argument)
{
- int nmiss;
+ size_t nmiss;
int nrecs;
int varID, levelID;
@@ -125,7 +125,7 @@ void *Arithc(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t) nmiss;
+ field.nmiss = nmiss;
if ( vars[varID] )
{
@@ -141,7 +141,7 @@ void *Arithc(void *argument)
if ( DBL_IS_EQUAL(field.ptr[i], field.missval) ) field.nmiss++;
}
- nmiss = (int) field.nmiss;
+ nmiss = field.nmiss;
pstreamDefRecord(streamID2, varID, levelID);
pstreamWriteRecord(streamID2, field.ptr, nmiss);
}
diff --git a/src/Arithdays.cc b/src/Arithdays.cc
index ad411a6..e580be1 100644
--- a/src/Arithdays.cc
+++ b/src/Arithdays.cc
@@ -73,7 +73,7 @@ void *Arithdays(void *argument)
int nrecs;
int varID, levelID;
int year, month, day;
- int nmiss;
+ size_t nmiss;
double rconst;
cdoInitialize(argument);
@@ -143,14 +143,14 @@ void *Arithdays(void *argument)
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = vlistInqVarGrid(vlistID1, varID);
field.missval = vlistInqVarMissval(vlistID1, varID);
farcfun(&field, rconst, operfunc);
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, field.ptr, (int)field.nmiss);
+ pstreamWriteRecord(streamID2, field.ptr, field.nmiss);
}
tsID++;
}
diff --git a/src/Arithlat.cc b/src/Arithlat.cc
index 79cb79c..0c73f08 100644
--- a/src/Arithlat.cc
+++ b/src/Arithlat.cc
@@ -36,7 +36,7 @@ void *Arithlat(void *argument)
int gridID0 = -1;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
long i;
char units[CDI_MAX_NAME];
double *scale = NULL;
diff --git a/src/CDIread.cc b/src/CDIread.cc
index fabeed1..e020ce4 100644
--- a/src/CDIread.cc
+++ b/src/CDIread.cc
@@ -83,7 +83,7 @@ void *CDIread(void *argument)
{
int memtype = CDO_Memtype;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nrecs;
int filetype = -1, datatype = -1;
int nruns = 1;
diff --git a/src/CDItest.cc b/src/CDItest.cc
index d893016..d0e008c 100644
--- a/src/CDItest.cc
+++ b/src/CDItest.cc
@@ -30,7 +30,7 @@ void *CDItest(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int max_copy = 3;
double s_utime, s_stime;
double e_utime, e_stime;
diff --git a/src/CMOR.cc b/src/CMOR.cc
index 68da1e4..86c919c 100644
--- a/src/CMOR.cc
+++ b/src/CMOR.cc
@@ -941,7 +941,8 @@ static void addcharvar(keyValues_t *charvars, int vlistID, const char *key, stru
{
while ( nrecs-- )
{
- int varIDrw, levelIDrw, nmiss;
+ int varIDrw, levelIDrw;
+ size_t nmiss;
pstreamInqRecord(streamID2, &varIDrw, &levelIDrw);
for ( int i = 0; i < charvars->nvalues; i++ )
if ( varIDrw == varIDs[i] )
@@ -1256,7 +1257,7 @@ static int check_mem(list_t *kvl, char *project_id)
char workchar[CMOR_MAX_STRING];
int realization, initialization_method, physics_version, forcing;
int ipos=0, ppos=0;
-
+*/
/* Test for the right member, else abort or warn */
/*
@@ -1286,6 +1287,7 @@ static int check_mem(list_t *kvl, char *project_id)
for ( int i = 0; i < 3; i++ )
kv_insert_a_val(kvl, ripchar[i], (char *)"-1", 1);
}
+*/
/* Now abort or warn */
/*
if (strcmp(project_id, "CMIP5") == 0 || strcmp(project_id, "CORDEX") == 0)
@@ -1833,7 +1835,7 @@ static void setup_dataset(list_t *kvl, int streamID, int *calendar)
#elif ( CMOR_VERSION_MAJOR == 3 )
{
/***/
-/* Could not give CMOR all attributes separately because some are required to be in a json file (outpath,...). /
+/* Could not give CMOR all attributes separately because some are required to be in a json file (outpath,...). */
/* Better collect them in this file. */
/* todo this **/
/* If a Json file is denoted, read this file and check attributes */
@@ -3680,7 +3682,7 @@ static void read_record(int streamID, struct mapping vars[], int vlistID)
int latdim = gridInqYsize(gridID);
int levdim = zaxisInqSize(zaxisID);
int chardim = gridsize/latdim;
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID, buffer, &nmiss);
for ( size_t i = 0; i < gridsize; i++ )
{
@@ -4366,7 +4368,7 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
/***/
/* However, if the mapping table contains a keyvalue pair for name or code with more than one value, */
/* the corresponding variable has a character coordinate and requires special treatment */
-/* This is tested once before mapping. If the special variable equals the variable which is to map,
+/* This is tested once before mapping. If the special variable equals the variable which is to map, */
/* the special treatment begins with fct addcharvar */
/***/
/* Different CMOR variables are built with one model variable. */
diff --git a/src/CMOR_lite.cc b/src/CMOR_lite.cc
index ae778ea..d1397d0 100644
--- a/src/CMOR_lite.cc
+++ b/src/CMOR_lite.cc
@@ -364,7 +364,7 @@ void *CMOR_lite(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
bool delvars = false;
double missval;
diff --git a/src/Cat.cc b/src/Cat.cc
index 5868b88..2061194 100644
--- a/src/Cat.cc
+++ b/src/Cat.cc
@@ -36,7 +36,7 @@ void *Cat(void *argument)
int streamID2 = CDI_UNDEFID;
int vlistID2 = CDI_UNDEFID;
int taxisID2 = CDI_UNDEFID;
- int nmiss;
+ size_t nmiss;
double tw0 = 0, tw = 0;
double *array = NULL;
diff --git a/src/Change.cc b/src/Change.cc
index 0a2f6db..5197c01 100644
--- a/src/Change.cc
+++ b/src/Change.cc
@@ -48,7 +48,7 @@ void *Change(void *argument)
int chcode = 0;
int param;
int code, tabnum, i;
- int nmiss;
+ size_t nmiss;
int nfound;
int nzaxis, zaxisID1, zaxisID2, k, nlevs, index;
double chlevels[MAXARG];
diff --git a/src/Change_e5slm.cc b/src/Change_e5slm.cc
index a3d31b6..dbbe0e1 100644
--- a/src/Change_e5slm.cc
+++ b/src/Change_e5slm.cc
@@ -32,7 +32,7 @@ void *Change_e5slm(void *argument)
char name[CDI_MAX_NAME];
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
@@ -60,7 +60,7 @@ void *Change_e5slm(void *argument)
int vlistIDslm = pstreamInqVlist(streamIDslm);
- long gridsize = gridInqSize(vlistInqVarGrid(vlistIDslm, 0));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistIDslm, 0));
double *array = (double*) Malloc(gridsize*sizeof(double));
double *cland = (double*) Malloc(gridsize*sizeof(double));
@@ -80,7 +80,7 @@ void *Change_e5slm(void *argument)
pstreamClose(streamIDslm);
- for ( long i = 0; i < gridsize; ++i ) lsea[i] = !(cland[i] > 0);
+ for ( size_t i = 0; i < gridsize; ++i ) lsea[i] = !(cland[i] > 0);
int nvars = vlistNvars(vlistID1);
diff --git a/src/Cloudlayer.cc b/src/Cloudlayer.cc
index 7cb8fdd..359e14f 100644
--- a/src/Cloudlayer.cc
+++ b/src/Cloudlayer.cc
@@ -127,7 +127,7 @@ void *Cloudlayer(void *argument)
bool zrev = false;
int i;
int offset;
- int nmiss;
+ size_t nmiss;
int aclcacID = -1;
int nvars2 = 0;
int aclcac_code_found = 0;
diff --git a/src/Collgrid.cc b/src/Collgrid.cc
index 39b6ee2..3f80b19 100644
--- a/src/Collgrid.cc
+++ b/src/Collgrid.cc
@@ -29,7 +29,7 @@ typedef struct
int streamID;
int vlistID;
int gridID;
- int nmiss;
+ size_t nmiss;
int gridsize;
int *gridindex;
double *array;
@@ -451,7 +451,7 @@ void *Collgrid(void *argument)
int taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
- int gridsize2 = 0;
+ size_t gridsize2 = 0;
for ( int i = 0; i < ngrids2; ++i )
{
if ( gridIDs[i] != -1 )
@@ -514,7 +514,7 @@ void *Collgrid(void *argument)
if ( cdoVerbose && tsID == 0 ) printf("varID %d %d levelID %d %d\n", varID, varID2, levelID, levelID2);
double missval = vlistInqVarMissval(vlistID2, varID2);
- for ( int i = 0; i < gridsize2; i++ ) array2[i] = missval;
+ for ( size_t i = 0; i < gridsize2; i++ ) array2[i] = missval;
#if defined(_OPENMP)
#pragma omp parallel for default(shared)
@@ -525,8 +525,8 @@ void *Collgrid(void *argument)
if ( vars[varID2] )
{
- int gridsize = ef[fileID].gridsize;
- for ( int i = 0; i < gridsize; ++i )
+ size_t gridsize = ef[fileID].gridsize;
+ for ( size_t i = 0; i < gridsize; ++i )
array2[ef[fileID].gridindex[i]] = ef[fileID].array[i];
}
}
@@ -535,8 +535,8 @@ void *Collgrid(void *argument)
if ( vars[varID2] )
{
- int nmiss = 0;
- for ( int i = 0; i < gridsize2; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < gridsize2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
pstreamWriteRecord(streamID2, array2, nmiss);
diff --git a/src/Command.cc b/src/Command.cc
index 296485d..edde5a9 100644
--- a/src/Command.cc
+++ b/src/Command.cc
@@ -167,7 +167,7 @@ int com_stat(const char *arg)
else
{
int i;
- int nmiss;
+ size_t nmiss;
int gridsize;
double fmin = 1.e50 , fmax = -1.e50, fmean = 0;
counter_t counter;
@@ -321,7 +321,7 @@ void command_init()
void *Command(void *argument)
{
// int recID, varID, levelID;
- // int nmiss;
+ // size_t nmiss;
double s_utime, s_stime;
double e_utime, e_stime;
double c_cputime = 0, c_usertime = 0, c_systime = 0;
diff --git a/src/Comp.cc b/src/Comp.cc
index b553b1e..92f5e28 100644
--- a/src/Comp.cc
+++ b/src/Comp.cc
@@ -103,11 +103,11 @@ void *Comp(void *argument)
nospec(vlistID1);
nospec(vlistID2);
- int gridsize = vlistGridsizeMax(vlistIDx1);
+ size_t gridsizemax = vlistGridsizeMax(vlistIDx1);
- double *array1 = (double*) Malloc(gridsize*sizeof(double));
- double *array2 = (double*) Malloc(gridsize*sizeof(double));
- double *array3 = (double*) Malloc(gridsize*sizeof(double));
+ double *array1 = (double*) Malloc(gridsizemax*sizeof(double));
+ double *array2 = (double*) Malloc(gridsizemax*sizeof(double));
+ double *array3 = (double*) Malloc(gridsizemax*sizeof(double));
double *arrayx1 = array1;
double *arrayx2 = array2;
@@ -140,7 +140,7 @@ void *Comp(void *argument)
vardata = (double **) Malloc(nvars*sizeof(double *));
for ( varID = 0; varID < nvars; varID++ )
{
- gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistIDx2, varID));
vardata[varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
}
@@ -179,7 +179,7 @@ void *Comp(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int nmiss1;
+ size_t nmiss1;
pstreamInqRecord(streamIDx1, &varID, &levelID);
pstreamReadRecord(streamIDx1, arrayx1, &nmiss1);
@@ -187,77 +187,95 @@ void *Comp(void *argument)
{
if ( recID == 0 || filltype != FILL_REC )
{
- int nmiss2;
+ size_t nmiss2;
pstreamInqRecord(streamIDx2, &varID, &levelID);
pstreamReadRecord(streamIDx2, arrayx2, &nmiss2);
}
if ( filltype == FILL_TS )
{
- int gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
- int offset = gridsize*levelID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
+ size_t offset = gridsize*levelID;
memcpy(vardata[varID]+offset, arrayx2, gridsize*sizeof(double));
}
}
else if ( filltype == FILL_TS )
{
- int gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
- int offset = gridsize*levelID;
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
+ size_t offset = gridsize*levelID;
memcpy(arrayx2, vardata[varID]+offset, gridsize*sizeof(double));
}
+ int datatype1 = vlistInqVarDatatype(vlistIDx1, varID);
+ int datatype2 = CDI_UNDEFID;
gridsize1 = gridInqSize(vlistInqVarGrid(vlistIDx1, varID));
*missvalx1 = vlistInqVarMissval(vlistIDx1, varID);
if ( filltype == FILL_REC )
{
- gridsize2 = gridInqSize(vlistInqVarGrid(vlistIDx2, 0));
+ datatype2 = vlistInqVarDatatype(vlistIDx2, 0);
+ gridsize2 = gridInqSize(vlistInqVarGrid(vlistIDx2, 0));
*missvalx2 = vlistInqVarMissval(vlistIDx2, 0);
}
else
{
+ datatype2 = vlistInqVarDatatype(vlistIDx2, varID);
gridsize2 = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
*missvalx2 = vlistInqVarMissval(vlistIDx2, varID);
}
- if ( gridsize1 != gridsize2 ) cdoAbort("Streams have different gridsize (gridsize1 = %d; gridsize2 = %d!",
+ if ( gridsize1 != gridsize2 ) cdoAbort("Streams have different gridsize (gridsize1 = %zu; gridsize2 = %zu!",
gridsize1, gridsize2);
- gridsize = gridsize1;
+ size_t gridsize = gridsize1;
+
+ if ( datatype1 != datatype2 )
+ {
+ if ( datatype1 == CDI_DATATYPE_FLT32 && datatype2 == CDI_DATATYPE_FLT64 )
+ {
+ missval2 = (float) missval2;
+ for ( size_t i = 0; i < gridsize; i++ ) array2[i] = (float) array2[i];
+ }
+ else if ( datatype1 == CDI_DATATYPE_FLT64 && datatype2 == CDI_DATATYPE_FLT32 )
+ {
+ missval1 = (float) missval1;
+ for ( size_t i = 0; i < gridsize; i++ ) array1[i] = (float) array1[i];
+ }
+ }
if ( operatorID == EQ )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
- missval1 : DBL_IS_EQUAL(array1[i], array2[i]));
+ missval1 : IS_EQUAL(array1[i], array2[i]));
}
else if ( operatorID == NE )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
- missval1 : !DBL_IS_EQUAL(array1[i], array2[i]));
+ missval1 : IS_NOT_EQUAL(array1[i], array2[i]));
}
else if ( operatorID == LE )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
missval1 : array1[i] <= array2[i]);
}
else if ( operatorID == LT )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
missval1 : array1[i] < array2[i]);
}
else if ( operatorID == GE )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
missval1 : array1[i] >= array2[i]);
}
else if ( operatorID == GT )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = (DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) ?
missval1 : array1[i] > array2[i]);
}
@@ -266,8 +284,8 @@ void *Comp(void *argument)
cdoAbort("Operator not implemented!");
}
- int nmiss3 = 0;
- for ( int i = 0; i < gridsize; i++ )
+ size_t nmiss3 = 0;
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(array3[i], missval1) ) nmiss3++;
pstreamDefRecord(streamID3, varID, levelID);
diff --git a/src/Compc.cc b/src/Compc.cc
index f815bf0..30d9e14 100644
--- a/src/Compc.cc
+++ b/src/Compc.cc
@@ -37,10 +37,7 @@ void *Compc(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss, nmiss2;
- int i;
- double missval;
- int rc_is_missval;
+ size_t nmiss;
cdoInitialize(argument);
@@ -67,10 +64,10 @@ void *Compc(void *argument)
nospec(vlistID1);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsizemax = vlistGridsizeMax(vlistID1);
- double *array1 = (double*) Malloc(gridsize*sizeof(double));
- double *array2 = (double*) Malloc(gridsize*sizeof(double));
+ double *array1 = (double*) Malloc(gridsizemax*sizeof(double));
+ double *array2 = (double*) Malloc(gridsizemax*sizeof(double));
int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
pstreamDefVlist(streamID2, vlistID2);
@@ -87,48 +84,51 @@ void *Compc(void *argument)
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss);
- missval = vlistInqVarMissval(vlistID1, varID);
- gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+ double missval = vlistInqVarMissval(vlistID1, varID);
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
- rc_is_missval = DBL_IS_EQUAL(rc, missval);
+ bool rc_is_missval = DBL_IS_EQUAL(rc, missval);
+
+ int datatype = vlistInqVarDatatype(vlistID1, varID);
+ double rcv = (datatype == CDI_DATATYPE_FLT32) ? (float)rc : rc;
if ( operatorID == EQC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : DBL_IS_EQUAL(array1[i], rc);
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : IS_EQUAL(array1[i], rcv);
}
else if ( operatorID == NEC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : !DBL_IS_EQUAL(array1[i], rc);
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : IS_NOT_EQUAL(array1[i], rcv);
}
else if ( operatorID == LEC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] <= rc;
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] <= rcv;
}
else if ( operatorID == LTC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] < rc;
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] < rcv;
}
else if ( operatorID == GEC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] >= rc;
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] >= rcv;
}
else if ( operatorID == GTC )
{
- for ( i = 0; i < gridsize; i++ )
- array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] > rc;
+ for ( size_t i = 0; i < gridsize; i++ )
+ array2[i] = DBL_IS_EQUAL(array1[i], missval) || rc_is_missval ? missval : array1[i] > rcv;
}
else
{
cdoAbort("Operator not implemented!");
}
- nmiss2 = 0;
- for ( i = 0; i < gridsize; i++ )
+ size_t nmiss2 = 0;
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss2++;
pstreamDefRecord(streamID2, varID, levelID);
diff --git a/src/Complextorect.cc b/src/Complextorect.cc
index 1e7bf2f..8027d98 100644
--- a/src/Complextorect.cc
+++ b/src/Complextorect.cc
@@ -28,7 +28,7 @@ void *Complextorect(void *argument)
int varID, levelID;
int i;
int datatype;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Cond.cc b/src/Cond.cc
index 809da5f..2e20e9e 100644
--- a/src/Cond.cc
+++ b/src/Cond.cc
@@ -34,12 +34,11 @@ void *Cond(void *argument)
int filltype = FILL_NONE;
int nrecs, nrecs2, nvars = 0, nlev;
int varID, levelID;
- int offset;
- int nmiss1, nmiss2, nmiss3;
- int i;
+ size_t offset;
+ size_t nmiss1, nmiss2, nmiss3;
double missval1 = -9.E33;
double missval2 = -9.E33;
- int **varnmiss1 = NULL;
+ size_t **varnmiss1 = NULL;
double **vardata1 = NULL;
cdoInitialize(argument);
@@ -82,7 +81,7 @@ void *Cond(void *argument)
int streamID3 = pstreamOpenWrite(cdoStreamName(2), cdoFiletype());
pstreamDefVlist(streamID3, vlistID3);
- int gridsize = vlistGridsizeMax(vlistID2);
+ size_t gridsize = vlistGridsizeMax(vlistID2);
if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
@@ -103,13 +102,13 @@ void *Cond(void *argument)
nvars = vlistNvars(vlistID1);
vardata1 = (double **) Malloc(nvars*sizeof(double *));
- varnmiss1 = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss1 = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
vardata1[varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss1[varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss1[varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
}
}
@@ -166,12 +165,12 @@ void *Cond(void *argument)
if ( operatorID == IFTHEN )
{
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = !DBL_IS_EQUAL(array1[i], missval1) && !DBL_IS_EQUAL(array1[i], 0.) ? array2[i] : missval2;
}
else if ( operatorID == IFNOTTHEN )
{
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array3[i] = !DBL_IS_EQUAL(array1[i], missval1) && DBL_IS_EQUAL(array1[i], 0.) ? array2[i] : missval2;
}
else
@@ -180,7 +179,7 @@ void *Cond(void *argument)
}
nmiss3 = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(array3[i], missval2) ) nmiss3++;
pstreamDefRecord(streamID3, varID, levelID);
diff --git a/src/Cond2.cc b/src/Cond2.cc
index 6b4b33d..89e2047 100644
--- a/src/Cond2.cc
+++ b/src/Cond2.cc
@@ -33,12 +33,11 @@ void *Cond2(void *argument)
int filltype = FILL_NONE;
int nrecs, nrecs2, nvars = 0, nlev;
int varID, levelID;
- int offset;
- int nmiss1, nmiss2, nmiss3, nmiss4;
- int i;
+ size_t offset;
+ size_t nmiss1, nmiss2, nmiss3, nmiss4;
double missval1 = -9.E33;
double missval2 = -9.E33;
- int **varnmiss1 = NULL;
+ size_t **varnmiss1 = NULL;
double **vardata1 = NULL;
cdoInitialize(argument);
@@ -83,7 +82,7 @@ void *Cond2(void *argument)
int streamID4 = pstreamOpenWrite(cdoStreamName(3), cdoFiletype());
pstreamDefVlist(streamID4, vlistID4);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
@@ -106,13 +105,13 @@ void *Cond2(void *argument)
nvars = vlistNvars(vlistID1);
vardata1 = (double **) Malloc(nvars*sizeof(double *));
- varnmiss1 = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss1 = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
vardata1[varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss1[varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss1[varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
}
}
@@ -176,7 +175,7 @@ void *Cond2(void *argument)
if ( operatorID == IFTHENELSE )
{
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array4[i] = DBL_IS_EQUAL(array1[i], missval1) ?
missval2 : !DBL_IS_EQUAL(array1[i], 0.) ? array2[i] : array3[i];
}
@@ -186,7 +185,7 @@ void *Cond2(void *argument)
}
nmiss4 = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(array4[i], missval2) ) nmiss4++;
pstreamDefRecord(streamID4, varID, levelID);
diff --git a/src/Condc.cc b/src/Condc.cc
index fdca47e..030c796 100644
--- a/src/Condc.cc
+++ b/src/Condc.cc
@@ -33,7 +33,7 @@ void *Condc(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss, nmiss2;
+ size_t nmiss, nmiss2;
int i;
double missval;
diff --git a/src/Consecstat.cc b/src/Consecstat.cc
index 63a4dea..3c4cd9d 100644
--- a/src/Consecstat.cc
+++ b/src/Consecstat.cc
@@ -127,7 +127,7 @@ void *Consecstat(void *argument)
int nrecs;
int varID;
int levelID, nlevels;
- int nmiss;
+ size_t nmiss;
double refval = 0.0;
cdoInitialize(argument);
@@ -197,7 +197,7 @@ void *Consecstat(void *argument)
{
pstreamInqRecord(istreamID, &varID, &levelID);
pstreamReadRecord(istreamID, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = vlistInqVarGrid(ovlistID, varID);
field.missval = vlistInqVarMissval(ovlistID, varID);
@@ -207,14 +207,14 @@ void *Consecstat(void *argument)
{
case CONSECSUM:
pstreamDefRecord(ostreamID, varID, levelID);
- pstreamWriteRecord(ostreamID, vars[varID][levelID].ptr, (int)vars[varID][levelID].nmiss);
+ pstreamWriteRecord(ostreamID, vars[varID][levelID].ptr, vars[varID][levelID].nmiss);
break;
case CONSECTS:
if ( itsID != 0 )
{
selEndOfPeriod(&periods[varID][levelID], hist[varID][levelID], vars[varID][levelID], FALSE);
pstreamDefRecord(ostreamID, varID, levelID);
- pstreamWriteRecord(ostreamID, periods[varID][levelID].ptr, (int)periods[varID][levelID].nmiss);
+ pstreamWriteRecord(ostreamID, periods[varID][levelID].ptr, periods[varID][levelID].nmiss);
}
#if defined(_OPENMP)
#pragma omp parallel for default(shared) schedule(static)
@@ -249,7 +249,7 @@ void *Consecstat(void *argument)
{
selEndOfPeriod(&periods[varID][levelID], hist[varID][levelID], vars[varID][levelID], TRUE);
pstreamDefRecord(ostreamID, varID, levelID);
- pstreamWriteRecord(ostreamID, periods[varID][levelID].ptr, (int)periods[varID][levelID].nmiss);
+ pstreamWriteRecord(ostreamID, periods[varID][levelID].ptr, periods[varID][levelID].nmiss);
}
}
}
diff --git a/src/Copy.cc b/src/Copy.cc
index a872280..12ea8ac 100644
--- a/src/Copy.cc
+++ b/src/Copy.cc
@@ -44,7 +44,7 @@ void *Copy(void *argument)
int taxisID2 = CDI_UNDEFID;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int ntsteps, nvars;
double *array = NULL;
par_io_t parIO;
@@ -116,7 +116,7 @@ void *Copy(void *argument)
pstreamDefVlist(streamID2, vlistID2);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
array = (double*) Malloc(gridsize*sizeof(double));
if ( cdoParIO )
{
diff --git a/src/Deltat.cc b/src/Deltat.cc
index 4c5ac1d..cda3352 100644
--- a/src/Deltat.cc
+++ b/src/Deltat.cc
@@ -31,7 +31,7 @@
void *Deltat(void *argument)
{
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Deltime.cc b/src/Deltime.cc
index 6a884d1..4a189ec 100644
--- a/src/Deltime.cc
+++ b/src/Deltime.cc
@@ -29,7 +29,7 @@ void *Deltime(void *argument)
int vdate /*, vtime */;
int copytimestep;
int gridsize;
- int nmiss;
+ size_t nmiss;
int year, month, day;
int dday, dmon;
double *array = NULL;
diff --git a/src/Derivepar.cc b/src/Derivepar.cc
index aed1215..eb87393 100644
--- a/src/Derivepar.cc
+++ b/src/Derivepar.cc
@@ -50,7 +50,7 @@ void *Derivepar(void *argument)
char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
double *single2;
// double *lwater = NULL, *iwater = NULL;
- int nmiss, nmissout = 0;
+ size_t nmiss, nmissout = 0;
double *full_press = NULL;
double minval, maxval;
int instNum, tableNum;
diff --git a/src/Detrend.cc b/src/Detrend.cc
index 27eaec9..26c6177 100644
--- a/src/Detrend.cc
+++ b/src/Detrend.cc
@@ -69,7 +69,7 @@ void *Detrend(void *argument)
int gridID, varID, levelID;
int i;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
double missval;
field_type ***vars = NULL;
diff --git a/src/Diff.cc b/src/Diff.cc
index ecf0341..b0a86bd 100644
--- a/src/Diff.cc
+++ b/src/Diff.cc
@@ -34,7 +34,7 @@ void *Diff(void *argument)
int nrecs, nrecs2;
int varID1, varID2;
int levelID;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
int ndrec = 0, nd2rec = 0, ngrec = 0;
char varname[CDI_MAX_NAME];
char paramstr[32];
@@ -65,7 +65,7 @@ void *Diff(void *argument)
vlistCompare(vlistID1, vlistID2, CMP_ALL);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
double *array1 = (double*) Malloc(gridsize*sizeof(double));
double *array2 = (double*) Malloc(gridsize*sizeof(double));
@@ -97,7 +97,7 @@ void *Diff(void *argument)
int code = vlistInqVarCode(vlistID1, varID1);
int gridID = vlistInqVarGrid(vlistID1, varID1);
int zaxisID = vlistInqVarZaxis(vlistID1, varID1);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
double missval1 = vlistInqVarMissval(vlistID1, varID1);
double missval2 = vlistInqVarMissval(vlistID2, varID2);
@@ -116,7 +116,7 @@ void *Diff(void *argument)
double relm = 0.0;
double absdiff;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( (DBL_IS_NAN(array1[i]) && !DBL_IS_NAN(array2[i])) ||
(!DBL_IS_NAN(array1[i]) && DBL_IS_NAN(array2[i])) )
@@ -185,7 +185,7 @@ void *Diff(void *argument)
set_text_color(stdout, RESET, GREEN);
double level = cdoZaxisInqLevel(zaxisID, levelID);
fprintf(stdout, "%7g ", level);
- fprintf(stdout, "%8d %7d ", gridsize, MAX(nmiss1, nmiss2));
+ fprintf(stdout, "%8zu %7zu ", gridsize, MAX(nmiss1, nmiss2));
fprintf(stdout, "%7d ", ndiff);
reset_text_color(stdout);
diff --git a/src/Distgrid.cc b/src/Distgrid.cc
index c96882d..2d2db36 100644
--- a/src/Distgrid.cc
+++ b/src/Distgrid.cc
@@ -24,8 +24,8 @@
#define MAX_BLOCKS 65536
static
-void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, int nyblocks,
- int **gridindex, int *ogridsize, int nsplit)
+void genGrids(int gridID1, int *gridIDs, size_t nxvals, size_t nyvals, size_t nxblocks, size_t nyblocks,
+ size_t **gridindex, size_t *ogridsize, size_t nsplit)
{
double *xpvals = NULL, *ypvals = NULL;
int gridtype = gridInqType(gridID1);
@@ -37,8 +37,8 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
else
cdoAbort("Unsupported grid type: %s!", gridNamePtr(gridtype));
- int nx = gridInqXsize(gridID1);
- int ny = gridInqYsize(gridID1);
+ size_t nx = gridInqXsize(gridID1);
+ size_t ny = gridInqYsize(gridID1);
bool lxcoord = gridInqXvals(gridID1, NULL) > 0;
bool lycoord = gridInqYvals(gridID1, NULL) > 0;
@@ -76,30 +76,30 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
gridInqYvals(gridID1, yvals);
}
- int *xlsize = (int*) Malloc(nxblocks*sizeof(int));
- int *ylsize = (int*) Malloc(nyblocks*sizeof(int));
+ size_t *xlsize = (size_t*) Malloc(nxblocks*sizeof(size_t));
+ size_t *ylsize = (size_t*) Malloc(nyblocks*sizeof(size_t));
- for ( int ix = 0; ix < nxblocks; ++ix ) xlsize[ix] = nxvals;
+ for ( size_t ix = 0; ix < nxblocks; ++ix ) xlsize[ix] = nxvals;
if ( nx%nxblocks != 0 ) xlsize[nxblocks-1] = nx - (nxblocks-1)*nxvals;
- if ( cdoVerbose ) for ( int ix = 0; ix < nxblocks; ++ix ) cdoPrint("xblock %d: %d", ix, xlsize[ix]);
+ if ( cdoVerbose ) for ( size_t ix = 0; ix < nxblocks; ++ix ) cdoPrint("xblock %zu: %zu", ix, xlsize[ix]);
- for ( int iy = 0; iy < nyblocks; ++iy ) ylsize[iy] = nyvals;
+ for ( size_t iy = 0; iy < nyblocks; ++iy ) ylsize[iy] = nyvals;
if ( ny%nyblocks != 0 ) ylsize[nyblocks-1] = ny - (nyblocks-1)*nyvals;
- if ( cdoVerbose ) for ( int iy = 0; iy < nyblocks; ++iy ) cdoPrint("yblock %d: %d", iy, ylsize[iy]);
+ if ( cdoVerbose ) for ( size_t iy = 0; iy < nyblocks; ++iy ) cdoPrint("yblock %zu: %zu", iy, ylsize[iy]);
- int index = 0;
- for ( int iy = 0; iy < nyblocks; ++iy )
- for ( int ix = 0; ix < nxblocks; ++ix )
+ size_t index = 0;
+ for ( size_t iy = 0; iy < nyblocks; ++iy )
+ for ( size_t ix = 0; ix < nxblocks; ++ix )
{
- int offset = iy*nyvals*nx + ix*nxvals;
+ size_t offset = iy*nyvals*nx + ix*nxvals;
- int gridsize2 = xlsize[ix]*ylsize[iy];
- gridindex[index] = (int*) Malloc(gridsize2*sizeof(int));
+ size_t gridsize2 = xlsize[ix]*ylsize[iy];
+ gridindex[index] = (size_t*) Malloc(gridsize2*sizeof(size_t));
gridsize2 = 0;
// printf("iy %d, ix %d offset %d\n", iy, ix, offset);
- for ( int j = 0; j < ylsize[iy]; ++j )
- for ( int i = 0; i < xlsize[ix]; ++i )
+ for ( size_t j = 0; j < ylsize[iy]; ++j )
+ for ( size_t i = 0; i < xlsize[ix]; ++i )
{
// printf(">> %d %d %d\n", j, i, offset + j*nx + i);
if ( !lregular )
@@ -186,9 +186,9 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
}
static
-void window_cell(double *array1, double *array2, long gridsize2, int *cellidx)
+void window_cell(double *array1, double *array2, size_t gridsize2, size_t *cellidx)
{
- for ( long i = 0; i < gridsize2; ++i )
+ for ( size_t i = 0; i < gridsize2; ++i )
array2[i] = array1[cellidx[i]];
}
@@ -196,8 +196,8 @@ typedef struct
{
int gridID;
int *gridIDs;
- int *gridsize;
- int **gridindex;
+ size_t *gridsize;
+ size_t **gridindex;
} sgrid_t;
@@ -210,7 +210,7 @@ void *Distgrid(void *argument)
char filename[8192];
int index;
int gridtype = -1;
- int nmiss;
+ size_t nmiss;
int i;
cdoInitialize(argument);
@@ -218,12 +218,12 @@ void *Distgrid(void *argument)
operatorInputArg("nxblocks, [nyblocks]");
if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
- int nxblocks = parameter2int(operatorArgv()[0]);
- int nyblocks = 1;
+ size_t nxblocks = parameter2int(operatorArgv()[0]);
+ size_t nyblocks = 1;
if ( operatorArgc() == 2 ) nyblocks = parameter2int(operatorArgv()[1]);
- if ( nxblocks <= 0 ) cdoAbort("nxblocks has to be greater than 0!");
- if ( nyblocks <= 0 ) cdoAbort("nyblocks has to be greater than 0!");
+ if ( nxblocks == 0 ) cdoAbort("nxblocks has to be greater than 0!");
+ if ( nyblocks == 0 ) cdoAbort("nyblocks has to be greater than 0!");
int streamID1 = pstreamOpenRead(cdoStreamName(0));
@@ -244,9 +244,9 @@ void *Distgrid(void *argument)
cdoAbort("No Lon/Lat, Gaussian, curvilinear or generic grid found (%s data unsupported)!", gridNamePtr(gridtype));
gridID1 = vlistGrid(vlistID1, 0);
- int gridsize = gridInqSize(gridID1);
- int nx = gridInqXsize(gridID1);
- int ny = gridInqYsize(gridID1);
+ size_t gridsize = gridInqSize(gridID1);
+ size_t nx = gridInqXsize(gridID1);
+ size_t ny = gridInqYsize(gridID1);
for ( int i = 1; i < ngrids; i++ )
{
gridID1 = vlistGrid(vlistID1, i);
@@ -256,22 +256,22 @@ void *Distgrid(void *argument)
if ( nxblocks > nx )
{
- cdoPrint("nxblocks (%d) greater than nx (%d), set to %d!", nxblocks, nx, nx);
+ cdoPrint("nxblocks (%zu) greater than nx (%zu), set to %zu!", nxblocks, nx, nx);
nxblocks = nx;
}
if ( nyblocks > ny )
{
- cdoPrint("nyblocks (%d) greater than ny (%d), set to %d!", nyblocks, ny, ny);
+ cdoPrint("nyblocks (%zu) greater than ny (%zu), set to %zu!", nyblocks, ny, ny);
nyblocks = ny;
}
- int xinc = nx/nxblocks;
- int yinc = ny/nyblocks;
+ size_t xinc = nx/nxblocks;
+ size_t yinc = ny/nyblocks;
if ( nx%xinc && nx%(xinc+1) ) xinc++;
if ( ny%yinc && ny%(yinc+1) ) yinc++;
- int nsplit = nxblocks*nyblocks;
+ size_t nsplit = nxblocks*nyblocks;
if ( nsplit > MAX_BLOCKS ) cdoAbort("Too many blocks (max = %d)!", MAX_BLOCKS);
double *array1 = (double*) Malloc(gridsize*sizeof(double));
@@ -284,13 +284,13 @@ void *Distgrid(void *argument)
{
grids[i].gridID = vlistGrid(vlistID1, i);
grids[i].gridIDs = (int*) Malloc(nsplit*sizeof(int));
- grids[i].gridsize = (int*) Malloc(nsplit*sizeof(int));
- grids[i].gridindex = (int**) Malloc(nsplit*sizeof(int*));
+ grids[i].gridsize = (size_t*) Malloc(nsplit*sizeof(size_t));
+ grids[i].gridindex = (size_t**) Malloc(nsplit*sizeof(size_t*));
- for ( int index = 0; index < nsplit; index++ ) grids[i].gridindex[index] = NULL;
+ for ( size_t index = 0; index < nsplit; index++ ) grids[i].gridindex[index] = NULL;
}
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
vlistIDs[index] = vlistDuplicate(vlistID1);
if ( cdoVerbose ) cdoPrint("ngrids=%d nsplit=%d", ngrids, nsplit);
@@ -301,15 +301,15 @@ void *Distgrid(void *argument)
genGrids(gridID1, grids[i].gridIDs, xinc, yinc, nxblocks, nyblocks, grids[i].gridindex, grids[i].gridsize, nsplit);
/*
if ( cdoVerbose )
- for ( int index = 0; index < nsplit; index++ )
- cdoPrint("Block %d, gridID %d, gridsize %d", index+1, grids[i].gridIDs[index], gridInqSize(grids[i].gridIDs[index]));
+ for ( size_t index = 0; index < nsplit; index++ )
+ cdoPrint("Block %d, gridID %d, gridsize %zu", index+1, grids[i].gridIDs[index], gridInqSize(grids[i].gridIDs[index]));
*/
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
vlistChangeGridIndex(vlistIDs[index], i, grids[i].gridIDs[index]);
}
- int gridsize2max = 0;
- for ( int index = 0; index < nsplit; index++ )
+ size_t gridsize2max = 0;
+ for ( size_t index = 0; index < nsplit; index++ )
if ( grids[0].gridsize[index] > gridsize2max ) gridsize2max = grids[0].gridsize[index];
double *array2 = (double*) Malloc(gridsize2max*sizeof(double));
@@ -321,9 +321,9 @@ void *Distgrid(void *argument)
filesuffix[0] = 0;
cdoGenFileSuffix(filesuffix, sizeof(filesuffix), pstreamInqFiletype(streamID1), vlistID1, refname);
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
{
- sprintf(filename+nchars, "%05d", index);
+ sprintf(filename+nchars, "%05ld", (long)index);
if ( filesuffix[0] )
sprintf(filename+nchars+5, "%s", filesuffix);
@@ -338,7 +338,7 @@ void *Distgrid(void *argument)
int tsID = 0;
while ( (nrecs = pstreamInqTimestep(streamID1, tsID)) )
{
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
pstreamDefTimestep(streamIDs[index], tsID);
for ( int recID = 0; recID < nrecs; recID++ )
@@ -348,7 +348,7 @@ void *Distgrid(void *argument)
double missval = vlistInqVarMissval(vlistID1, varID);
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
{
i = 0;
window_cell(array1, array2, grids[i].gridsize[index], grids[i].gridindex[index]);
@@ -356,7 +356,7 @@ void *Distgrid(void *argument)
if ( nmiss > 0 )
{
nmiss = 0;
- for ( int k = 0; k < grids[i].gridsize[index]; ++k )
+ for ( size_t k = 0; k < grids[i].gridsize[index]; ++k )
if ( DBL_IS_EQUAL(array2[k], missval) ) nmiss++;
}
pstreamWriteRecord(streamIDs[index], array2, nmiss);
@@ -368,7 +368,7 @@ void *Distgrid(void *argument)
pstreamClose(streamID1);
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
{
pstreamClose(streamIDs[index]);
vlistDestroy(vlistIDs[index]);
@@ -382,12 +382,12 @@ void *Distgrid(void *argument)
for ( int i = 0; i < ngrids; i++ )
{
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
gridDestroy(grids[i].gridIDs[index]);
Free(grids[i].gridIDs);
Free(grids[i].gridsize);
- for ( int index = 0; index < nsplit; index++ )
+ for ( size_t index = 0; index < nsplit; index++ )
Free(grids[i].gridindex[index]);
Free(grids[i].gridindex);
}
diff --git a/src/Duplicate.cc b/src/Duplicate.cc
index d9e10af..183697e 100644
--- a/src/Duplicate.cc
+++ b/src/Duplicate.cc
@@ -29,7 +29,7 @@ void *Duplicate(void *argument)
int nrecs;
int varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int *vdate = NULL, *vtime = NULL;
int ndup = 2;
field_type ***vars = NULL;
diff --git a/src/EOFs.cc b/src/EOFs.cc
index 3acf83b..7883990 100644
--- a/src/EOFs.cc
+++ b/src/EOFs.cc
@@ -32,7 +32,6 @@
#include <omp.h>
#endif
-#include <limits.h> // LONG_MAX
#include <cdi.h>
#include "cdo.h"
#include "cdo_int.h"
@@ -168,7 +167,7 @@ void *EOFs(void * argument)
enum {EOF_, EOF_TIME, EOF_SPATIAL};
int nlevs = 0 ;
- int nmiss;
+ size_t nmiss;
int varID, levelID;
int nts = 0;
size_t n = 0;
@@ -279,7 +278,7 @@ void *EOFs(void * argument)
}
else if ( grid_space )
{
- if ( ((double)gridsize)*gridsize > (double)LONG_MAX ) cdoAbort("Grid space too large!");
+ if ( ((double)gridsize)*gridsize > (double)SIZE_MAX ) cdoAbort("Grid space too large!");
if ( (size_t)n_eig > gridsize )
{
@@ -310,7 +309,7 @@ void *EOFs(void * argument)
}
/* allocation of temporary fields and output structures */
- size_t npack = ULONG_MAX;
+ size_t npack = SIZE_MAX;
size_t *pack = (size_t *) Malloc(gridsize*sizeof(size_t));
double *in = (double *) Malloc(gridsize*sizeof(double));
eofdata_t **eofdata = (eofdata_t **) Malloc(nvars*sizeof(eofdata_t*));
@@ -357,7 +356,7 @@ void *EOFs(void * argument)
size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
double missval = vlistInqVarMissval(vlistID1, varID);
- if ( npack == ULONG_MAX )
+ if ( npack == SIZE_MAX )
{
npack = 0;
for ( size_t i = 0; i < gridsize; ++i )
diff --git a/src/Echam5ini.cc b/src/Echam5ini.cc
index b768c83..6d39033 100644
--- a/src/Echam5ini.cc
+++ b/src/Echam5ini.cc
@@ -1433,7 +1433,8 @@ void *Echam5ini(void *argument)
int vlistID1, vlistID2;
int nvars = 0;
int iv, nlev;
- int gridsize, nmiss;
+ int gridsize;
+ size_t nmiss;
int taxisID, tsID;
cdoInitialize(argument);
diff --git a/src/Enlarge.cc b/src/Enlarge.cc
index 478e73f..3e41c15 100644
--- a/src/Enlarge.cc
+++ b/src/Enlarge.cc
@@ -40,10 +40,10 @@ void *Enlarge(void *argument)
int streamID1 = pstreamOpenRead(cdoStreamName(0));
int gridID2 = cdoDefineGrid(operatorArgv()[0]);
- int xsize2 = gridInqXsize(gridID2);
- int ysize2 = gridInqYsize(gridID2);
+ size_t xsize2 = gridInqXsize(gridID2);
+ size_t ysize2 = gridInqYsize(gridID2);
- if ( cdoVerbose ) fprintf(stderr, "gridID2 %d, xsize2 %d, ysize2 %d\n", gridID2, xsize2, ysize2);
+ if ( cdoVerbose ) fprintf(stderr, "gridID2 %d, xsize2 %zu, ysize2 %zu\n", gridID2, xsize2, ysize2);
int vlistID1 = pstreamInqVlist(streamID1);
@@ -53,7 +53,7 @@ void *Enlarge(void *argument)
int taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
- int gridsize2 = gridInqSize(gridID2);
+ size_t gridsize2 = gridInqSize(gridID2);
if ( gridsize2 < vlistGridsizeMax(vlistID1) )
cdoAbort("Gridsize of input stream is greater than new gridsize!");
@@ -79,15 +79,16 @@ void *Enlarge(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int varID, levelID, nmiss;
+ int varID, levelID;
+ size_t nmiss;
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss);
double missval = vlistInqVarMissval(vlistID1, varID);
int gridID1 = vlistInqVarGrid(vlistID1, varID);
- int xsize1 = gridInqXsize(gridID1);
- int ysize1 = gridInqYsize(gridID1);
- int gridsize1 = gridInqSize(gridID1);
+ size_t xsize1 = gridInqXsize(gridID1);
+ size_t ysize1 = gridInqYsize(gridID1);
+ size_t gridsize1 = gridInqSize(gridID1);
if ( xsize1 == 0 ) xsize1 = 1;
if ( ysize1 == 0 ) ysize1 = 1;
@@ -101,8 +102,8 @@ void *Enlarge(void *argument)
linfo = false;
}
- for ( int iy = 0; iy < ysize2; iy++ )
- for ( int ix = 0; ix < xsize2; ix++ )
+ for ( size_t iy = 0; iy < ysize2; iy++ )
+ for ( size_t ix = 0; ix < xsize2; ix++ )
array2[ix+iy*xsize2] = array1[iy];
if ( nmiss ) nmiss *= xsize2;
@@ -115,8 +116,8 @@ void *Enlarge(void *argument)
linfo = false;
}
- for ( int iy = 0; iy < ysize2; iy++ )
- for ( int ix = 0; ix < xsize2; ix++ )
+ for ( size_t iy = 0; iy < ysize2; iy++ )
+ for ( size_t ix = 0; ix < xsize2; ix++ )
array2[ix+iy*xsize2] = array1[ix];
if ( nmiss ) nmiss *= ysize2;
@@ -124,10 +125,8 @@ void *Enlarge(void *argument)
else
{
memcpy(array2, array1, gridsize1*sizeof(double));
- for ( int i = gridsize1; i < gridsize2; i++ )
- {
- array2[i] = array1[gridsize1-1];
- }
+ for ( size_t i = gridsize1; i < gridsize2; i++ )
+ array2[i] = array1[gridsize1-1];
if ( nmiss && DBL_IS_EQUAL(array1[gridsize1-1], missval) ) nmiss += (gridsize2 - gridsize1);
}
diff --git a/src/Enlargegrid.cc b/src/Enlargegrid.cc
index 1b0690a..9780ba9 100644
--- a/src/Enlargegrid.cc
+++ b/src/Enlargegrid.cc
@@ -215,7 +215,8 @@ void *Enlargegrid(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int varID, levelID, nmiss1;
+ int varID, levelID;
+ size_t nmiss1;
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss1);
@@ -226,7 +227,7 @@ void *Enlargegrid(void *argument)
if ( gindex[i] >= 0 )
array2[gindex[i]] = array1[i];
- int nmiss2 = 0;
+ size_t nmiss2 = 0;
for ( int i = 0; i < gridsize2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval1) ) nmiss2++;
diff --git a/src/Ensstat.cc b/src/Ensstat.cc
index 9472f5c..7d6f95b 100644
--- a/src/Ensstat.cc
+++ b/src/Ensstat.cc
@@ -43,7 +43,7 @@ typedef struct
{
int streamID;
int vlistID;
- int nmiss[2];
+ size_t nmiss[2];
double missval[2];
double *array[2];
} ens_file_t;
@@ -87,7 +87,7 @@ void *ensstat_func(void *ensarg)
int gridsize = gridInqSize(gridID);
double missval = vlistInqVarMissval(arg->vlistID1, arg->varID[t]);
- int nmiss = 0;
+ size_t nmiss = 0;
#if defined(_OPENMP)
#pragma omp parallel for default(shared)
#endif
diff --git a/src/Ensstat3.cc b/src/Ensstat3.cc
index e732a73..7f1bdc3 100644
--- a/src/Ensstat3.cc
+++ b/src/Ensstat3.cc
@@ -52,7 +52,8 @@ double roc_curve_integrate(const double **roc, const int n);
void *Ensstat3(void *argument)
{
int i,j;
- int nrecs = 0, nrecs0, nmiss;
+ int nrecs = 0, nrecs0;
+ size_t nmiss;
int cum;
int chksum; // for check of histogram population
int levelID, varID, binID = 0;
diff --git a/src/Ensval.cc b/src/Ensval.cc
index 7615a38..3281d77 100644
--- a/src/Ensval.cc
+++ b/src/Ensval.cc
@@ -43,7 +43,8 @@ enum RESTYPE_CRPS { CRPS_RES,CRPS_RELI,CRPS_POT };
void *Ensval(void *argument)
{
int i,k;
- int nrecs = 0, nrecs0, nmiss, nostreams = 0, ngrids;
+ int nrecs = 0, nrecs0, nostreams = 0, ngrids;
+ size_t nmiss;
int levelID, varID;
int gridsize = 0;
int vlistID;
diff --git a/src/Eof3d.cc b/src/Eof3d.cc
index dda6230..e0080cf 100644
--- a/src/Eof3d.cc
+++ b/src/Eof3d.cc
@@ -53,7 +53,8 @@ void *EOF3d(void * argument)
size_t temp_size = 0, npack = 0;
int varID, levelID;
bool missval_warning = false;
- int nmiss, ngrids;
+ size_t nmiss;
+ int ngrids;
int n = 0;
size_t nlevs = 0;
int timer_cov = 0, timer_eig = 0;
diff --git a/src/Eofcoeff.cc b/src/Eofcoeff.cc
index cf33af6..d3f54ca 100644
--- a/src/Eofcoeff.cc
+++ b/src/Eofcoeff.cc
@@ -37,7 +37,8 @@ void *Eofcoeff(void * argument)
field_type in;
field_type out;
int i, varID, levelID;
- int nrecs, nmiss;
+ int nrecs;
+ size_t nmiss;
cdoInitialize(argument);
@@ -59,7 +60,7 @@ void *Eofcoeff(void * argument)
int gridID1 = vlistInqVarGrid(vlistID1, 0);
int gridID2 = vlistInqVarGrid(vlistID2, 0);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
if ( gridsize != vlistGridsizeMax(vlistID2) )
cdoAbort("Gridsize of input files does not match!");
@@ -108,7 +109,7 @@ void *Eofcoeff(void * argument)
cdoAbort("Internal error - too high levelID");
pstreamReadRecord(streamID1, eof[varID][levelID][eofID].ptr, &nmiss);
- eof[varID][levelID][eofID].nmiss = (size_t) nmiss;
+ eof[varID][levelID][eofID].nmiss = nmiss;
}
eofID++;
}
@@ -181,7 +182,7 @@ void *Eofcoeff(void * argument)
pstreamInqRecord(streamID2, &varID, &levelID);
missval2 = vlistInqVarMissval(vlistID2, varID);
pstreamReadRecord(streamID2, in.ptr, &nmiss);
- in.nmiss = (size_t) nmiss;
+ in.nmiss = nmiss;
for ( eofID = 0; eofID < neof; eofID++ )
{
@@ -190,7 +191,7 @@ void *Eofcoeff(void * argument)
out.ptr[0] = 0;
out.grid = gridID3;
out.missval = missval2;
- for(i=0;i<gridsize;i++)
+ for(size_t i=0;i<gridsize;i++)
{
if (! DBL_IS_EQUAL(in.ptr[i],missval2) &&
! DBL_IS_EQUAL(eof[varID][levelID][eofID].ptr[i],missval1 ))
diff --git a/src/Eofcoeff3d.cc b/src/Eofcoeff3d.cc
index b4e1d8e..c57644b 100644
--- a/src/Eofcoeff3d.cc
+++ b/src/Eofcoeff3d.cc
@@ -36,7 +36,8 @@ void *Eofcoeff3d(void * argument)
double missval1 = -999, missval2 = -999;
field_type in;
int i, varID, levelID;
- int nrecs, nmiss;
+ int nrecs;
+ size_t nmiss;
cdoInitialize(argument);
@@ -57,7 +58,7 @@ void *Eofcoeff3d(void * argument)
int gridID1 = vlistInqVarGrid(vlistID1, 0);
int gridID2 = vlistInqVarGrid(vlistID2, 0);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
if ( gridsize != vlistGridsizeMax(vlistID2) )
cdoAbort("Gridsize of input files does not match!");
@@ -106,7 +107,7 @@ void *Eofcoeff3d(void * argument)
cdoAbort("Internal error - too high levelID");
pstreamReadRecord(streamID1, eof[varID][levelID][eofID].ptr, &nmiss);
- eof[varID][levelID][eofID].nmiss = (size_t) nmiss;
+ eof[varID][levelID][eofID].nmiss = nmiss;
}
eofID++;
}
@@ -199,14 +200,14 @@ void *Eofcoeff3d(void * argument)
pstreamInqRecord(streamID2, &varID, &levelID);
pstreamReadRecord(streamID2, in.ptr, &nmiss);
missval2 = vlistInqVarMissval(vlistID2, varID);
- in.nmiss = (size_t) nmiss;
+ in.nmiss = nmiss;
for ( eofID = 0; eofID < neof; eofID++ )
{
if ( recID == 0 ) pstreamDefTimestep(streamIDs[eofID],tsID);
nmiss = 0;
- for( i=0; i<gridsize; i++ )
+ for( size_t i=0; i<gridsize; i++ )
{
if (! DBL_IS_EQUAL(in.ptr[i],missval2) &&
! DBL_IS_EQUAL(eof[varID][levelID][eofID].ptr[i],missval1 ) )
@@ -235,7 +236,7 @@ void *Eofcoeff3d(void * argument)
for ( eofID = 0; eofID < neof; eofID++ ) {
for ( varID = 0; varID < nvars; varID++ ) {
pstreamDefRecord(streamIDs[eofID], varID, 0);
- pstreamWriteRecord(streamIDs[eofID], out[varID][eofID].ptr, (int)out[varID][eofID].nmiss);
+ pstreamWriteRecord(streamIDs[eofID], out[varID][eofID].ptr, out[varID][eofID].nmiss);
}
}
diff --git a/src/EstFreq.cc b/src/EstFreq.cc
index 4a423e4..68b197b 100644
--- a/src/EstFreq.cc
+++ b/src/EstFreq.cc
@@ -25,7 +25,8 @@ void *EstFreq(void *argument)
{
int nrecs;
int varID, levelID;
- int gridsize, nmiss;
+ int gridsize;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Exprf.cc b/src/Exprf.cc
index 11ca484..e114278 100644
--- a/src/Exprf.cc
+++ b/src/Exprf.cc
@@ -104,6 +104,7 @@ paramType *params_new(int vlistID)
{
int gridID = vlistInqVarGrid(vlistID, varID);
int zaxisID = vlistInqVarZaxis(vlistID, varID);
+ int datatype = vlistInqVarDatatype(vlistID, varID);
int steptype = vlistInqVarTimetype(vlistID, varID);
int ngp = gridInqSize(gridID);
int nlev = zaxisInqSize(zaxisID);
@@ -119,6 +120,7 @@ paramType *params_new(int vlistID)
params[varID].coord = 0;
params[varID].gridID = gridID;
params[varID].zaxisID = zaxisID;
+ params[varID].datatype = datatype;
params[varID].steptype = steptype;
params[varID].ngp = ngp;
params[varID].nlev = nlev;
@@ -217,7 +219,7 @@ int params_add_ts(parse_param_t *parse_arg)
params[varID].steptype = TIME_VARYING;
params[varID].ngp = 1;
params[varID].nlev = 1;
-
+
parse_arg->nparams++;
}
@@ -322,7 +324,7 @@ void *Expr(void *argument)
if ( cdoVerbose )
for ( int varID = 0; varID < parse_arg.nparams; varID++ )
- cdoPrint("var: %d %s ngp=%lu nlev=%lu coord=%c",
+ cdoPrint("var: %d %s ngp=%zu nlev=%zu coord=%c",
varID, params[varID].name, params[varID].ngp, params[varID].nlev, params[varID].coord==0?' ':params[varID].coord);
int *varIDmap = (int*) Malloc(parse_arg.nparams*sizeof(int));
@@ -516,7 +518,7 @@ void *Expr(void *argument)
{
size_t offset = params[varID].ngp*levelID;
double *vardata = params[varID].data + offset;
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, vardata, &nmiss);
params[varID].nmiss += nmiss;
}
@@ -551,7 +553,7 @@ void *Expr(void *argument)
size_t offset = ngp*levelID;
double *vardata = params[pidx].data + offset;
- int nmiss = 0;
+ size_t nmiss = 0;
for ( size_t i = 0; i < ngp; i++ )
if ( DBL_IS_EQUAL(vardata[i], missval) ) nmiss++;
diff --git a/src/FC.cc b/src/FC.cc
index 1afcc03..08b5c46 100644
--- a/src/FC.cc
+++ b/src/FC.cc
@@ -41,8 +41,9 @@ void *FC(void *argument)
int gridIDsp = -1, gridIDgp = -1, gridIDfc = -1;
int gridID1 = -1, gridID2 = -1;
int gridID;
- int nmiss;
- int nlon = 0, nlat = 0, ntr = 0;
+ size_t nmiss;
+ size_t nlon = 0, nlat = 0;
+ int ntr = 0;
int nsp = 0, nfc = 0;
double *array2 = NULL;
SPTRANS *sptrans = NULL;
@@ -218,17 +219,12 @@ void *FC(void *argument)
}
}
- // printf("nfc %d, ntr %d, nlat %d, nlon %d\n", nfc, ntr, nlat, nlon);
+ // printf("nfc %d, ntr %d, nlat %zu, nlon %zu\n", nfc, ntr, nlat, nlon);
int nvars = vlistNvars(vlistID2);
- int *vars = (int*) Malloc(nvars*sizeof(int));
+ bool *vars = (bool*) Malloc(nvars*sizeof(bool));
for ( varID = 0; varID < nvars; varID++ )
- {
- if ( gridID1 == vlistInqVarGrid(vlistID1, varID) )
- vars[varID] = TRUE;
- else
- vars[varID] = FALSE;
- }
+ vars[varID] = gridID1 == vlistInqVarGrid(vlistID1, varID);
if ( gridID1 != -1 ) vlistChangeGrid(vlistID2, gridID1, gridID2);
@@ -236,12 +232,12 @@ void *FC(void *argument)
pstreamDefVlist(streamID2, vlistID2);
- int gridsize = vlistGridsizeMax(vlistID1);
- double *array1 = (double*) Malloc(gridsize*sizeof(double));
+ size_t gridsizemax = vlistGridsizeMax(vlistID1);
+ double *array1 = (double*) Malloc(gridsizemax*sizeof(double));
if ( gridID2 != -1 )
{
- gridsize = gridInqSize(gridID2);
+ size_t gridsize = gridInqSize(gridID2);
array2 = (double*) Malloc(gridsize*sizeof(double));
}
diff --git a/src/Fillmiss.cc b/src/Fillmiss.cc
index d8897fe..64f15dd 100644
--- a/src/Fillmiss.cc
+++ b/src/Fillmiss.cc
@@ -41,7 +41,7 @@ extern "C" {
void fillmiss(field_type *field1, field_type *field2, int nfill)
{
int nx, ny, i, j;
- int nmiss2 = 0;
+ size_t nmiss2 = 0;
int kr, ku, kl, ko;
int ir, iu, il, io;
int kh, kv, k1, k2, kk;
@@ -51,7 +51,7 @@ void fillmiss(field_type *field1, field_type *field2, int nfill)
double **matrix1, **matrix2;
int gridID = field1->grid;
- int nmiss1 = field1->nmiss;
+ size_t nmiss1 = field1->nmiss;
double missval = field1->missval;
double *array1 = field1->ptr;
double *array2 = field2->ptr;
@@ -156,7 +156,7 @@ void fillmiss(field_type *field1, field_type *field2, int nfill)
void fillmiss_one_step(field_type *field1, field_type *field2, int maxfill)
{
int gridID, nx, ny, i, j;
- int nmiss2 = 0;
+ size_t nmiss2 = 0;
int kr, ku, kl, ko;
int ir, iu, il, io;
int kh, kv, k1, k2, kk;
@@ -419,7 +419,7 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
void *Fillmiss(void *argument)
{
- int nmiss;
+ size_t nmiss;
int nrecs, varID, levelID;
void (*fill_method) (field_type *fin , field_type *fout , int) = NULL;
@@ -528,7 +528,7 @@ void *Fillmiss(void *argument)
fill_method(&field1, &field2, nfill);
int gridsize = gridInqSize(field2.grid);
- int nmiss = 0;
+ size_t nmiss = 0;
for ( int i = 0; i < gridsize; ++i )
if ( DBL_IS_EQUAL(field2.ptr[i], field2.missval) ) nmiss++;
diff --git a/src/Filter.cc b/src/Filter.cc
index 33a9a89..f9dbebb 100644
--- a/src/Filter.cc
+++ b/src/Filter.cc
@@ -124,7 +124,7 @@ void *Filter(void *argument)
int nrecs;
int varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int incperiod0, incunit0, incunit;
int year0, month0, day0;
bool use_fftw = false;
@@ -396,7 +396,7 @@ void *Filter(void *argument)
{
if ( vars[tsID][varID][levelID].ptr )
{
- int nmiss = vars[tsID][varID][levelID].nmiss;
+ size_t nmiss = vars[tsID][varID][levelID].nmiss;
pstreamDefRecord(streamID2, varID, levelID);
pstreamWriteRecord(streamID2, vars[tsID][varID][levelID].ptr, nmiss);
diff --git a/src/Fldrms.cc b/src/Fldrms.cc
index 72f0130..bb8ac2a 100644
--- a/src/Fldrms.cc
+++ b/src/Fldrms.cc
@@ -34,7 +34,7 @@ void *Fldrms(void *argument)
int index;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
double sglval;
cdoInitialize(argument);
@@ -116,10 +116,10 @@ void *Fldrms(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
pstreamInqRecord(streamID2, &varID, &levelID);
pstreamReadRecord(streamID2, field2.ptr, &nmiss);
- field2.nmiss = (size_t) nmiss;
+ field2.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field2.grid = vlistInqVarGrid(vlistID2, varID);
@@ -147,7 +147,7 @@ void *Fldrms(void *argument)
fldrms(field1, field2, &field3);
pstreamDefRecord(streamID3, varID, levelID);
- pstreamWriteRecord(streamID3, &sglval, (int)field3.nmiss);
+ pstreamWriteRecord(streamID3, &sglval, field3.nmiss);
}
tsID++;
}
diff --git a/src/Fldstat.cc b/src/Fldstat.cc
index 2eb6a9d..ed9017d 100644
--- a/src/Fldstat.cc
+++ b/src/Fldstat.cc
@@ -87,7 +87,7 @@ void *Fldstat(void *argument)
int index;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
double sglval;
cdoInitialize(argument);
diff --git a/src/Fldstat2.cc b/src/Fldstat2.cc
index 71c2a6b..95ad061 100644
--- a/src/Fldstat2.cc
+++ b/src/Fldstat2.cc
@@ -94,7 +94,7 @@ void *Fldstat2(void *argument)
int gridID3;
int nrecs, nrecs2;
int varID, levelID;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
bool wstatus = false;
bool needWeights = true;
double sglval = 0;
@@ -193,7 +193,7 @@ void *Fldstat2(void *argument)
sglval = covariance_s(array1, array2, weight, missval1, missval2, gridsize);
}
- int nmiss3 = DBL_IS_EQUAL(sglval, missval1) ? 1 : 0;
+ size_t nmiss3 = DBL_IS_EQUAL(sglval, missval1) ? 1 : 0;
pstreamDefRecord(streamID3, varID, levelID);
pstreamWriteRecord(streamID3, &sglval, nmiss3);
diff --git a/src/Fourier.cc b/src/Fourier.cc
index 8cab19f..691caf7 100644
--- a/src/Fourier.cc
+++ b/src/Fourier.cc
@@ -33,7 +33,7 @@ void *Fourier(void *argument)
int nrecs;
int gridID, varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
int *vdate = NULL, *vtime = NULL;
double missval;
diff --git a/src/Gengrid.cc b/src/Gengrid.cc
index 63ef912..8e1b34e 100644
--- a/src/Gengrid.cc
+++ b/src/Gengrid.cc
@@ -30,7 +30,7 @@
void *Gengrid(void *argument)
{
int varID, levelID;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
double missval = 0;
cdoInitialize(argument);
@@ -55,6 +55,9 @@ void *Gengrid(void *argument)
double *array2 = (double*) Malloc(gridsize*sizeof(double));
double *array3 = (double*) Malloc(gridsize*sizeof(double));
+ pstreamInqTimestep(streamID1, 0);
+ pstreamInqTimestep(streamID2, 0);
+
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss1);
pstreamInqRecord(streamID2, &varID, &levelID);
diff --git a/src/Gradsdes.cc b/src/Gradsdes.cc
index 92aaa60..b7d4fa1 100644
--- a/src/Gradsdes.cc
+++ b/src/Gradsdes.cc
@@ -22,7 +22,7 @@
*/
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#include "config.h" /* VERSION */
#endif
@@ -963,7 +963,7 @@ void *Gradsdes(void *argument)
int idmn, idhh, idmm, idyy, iddd;
int dt=1, iik=0, mdt = 0;
int gridsize = 0;
- int nmiss;
+ size_t nmiss;
int prec;
int map_version = 2;
int maxrecs = 0;
diff --git a/src/Gridboxstat.cc b/src/Gridboxstat.cc
index c135b86..8dbef1b 100644
--- a/src/Gridboxstat.cc
+++ b/src/Gridboxstat.cc
@@ -39,16 +39,16 @@
static
-int genBoxGrid(int gridID1, int xinc, int yinc)
+int genBoxGrid(int gridID1, size_t xinc, size_t yinc)
{
- int i, j, i1;
+ size_t i, j, i1;
int gridID2 = -1;
- int nlon1 = 0, nlat1 = 0;
- int gridsize2 = 0, nlon2 = 0, nlat2 = 0;
- int x1, y1, x2, y2;
- int use_x1, use_y1;
- int corner, add, g2_add;
- int g1_add;
+ size_t nlon1 = 0, nlat1 = 0;
+ size_t gridsize2 = 0, nlon2 = 0, nlat2 = 0;
+ size_t x1, y1, x2, y2;
+ size_t use_x1, use_y1;
+ size_t g1_add, g2_add;
+ int corner, add;
int circular = gridIsCircular(gridID1) ;
double *grid1_corner_lon = NULL, *grid1_corner_lat = NULL;
double *grid2_corner_lon = NULL, *grid2_corner_lat = NULL;
@@ -57,7 +57,7 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
double area_norm;
int gridtype = gridInqType(gridID1);
- int gridsize1 = gridInqSize(gridID1);
+ size_t gridsize1 = gridInqSize(gridID1);
if ( xinc < 1 || yinc < 1 )
cdoAbort("xinc and yinc must not be smaller than 1!");
@@ -330,7 +330,7 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
lon = grid1_corner_lon[add];
lat = grid1_corner_lat[add];
g1_add2 = g1_add-1;
- if ( g1_add-nlon1 < 0 )
+ if ( g1_add < nlon1 )
{
cdoWarning("Can't find cell above lower right left");
continue;
@@ -365,7 +365,7 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
lon = grid1_corner_lon[add];
lat = grid1_corner_lat[add];
g1_add2 = g1_add+1;
- if ( g1_add-nlon1 < 0 )
+ if ( g1_add < nlon1 )
{
cdoWarning("Can't find cell above lower right left");
continue;
@@ -446,7 +446,7 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
}
static
-void gridboxstat(field_type *field1, field_type *field2, int xinc, int yinc, int statfunc)
+void gridboxstat(field_type *field1, field_type *field2, size_t xinc, size_t yinc, int statfunc)
{
bool useWeight = (field1->weight != NULL);
/*
@@ -455,7 +455,7 @@ void gridboxstat(field_type *field1, field_type *field2, int xinc, int yinc, int
progressInit();
*/
- int gridsize = xinc*yinc;
+ size_t gridsize = xinc*yinc;
field_type *field = (field_type*) Malloc(ompNumThreads*sizeof(field_type));
for ( int i = 0; i < ompNumThreads; i++ )
{
@@ -472,16 +472,16 @@ void gridboxstat(field_type *field1, field_type *field2, int xinc, int yinc, int
double *array2 = field2->ptr;
double missval = field1->missval;
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
- int nlon2 = gridInqXsize(gridID2);
- int nlat2 = gridInqYsize(gridID2);
+ size_t nlon2 = gridInqXsize(gridID2);
+ size_t nlat2 = gridInqYsize(gridID2);
#if defined(_OPENMP)
#pragma omp parallel for default(shared)
#endif
- for ( int ig = 0; ig < nlat2*nlon2; ++ig )
+ for ( size_t ig = 0; ig < nlat2*nlon2; ++ig )
{
int ompthID = cdo_omp_get_thread_num();
@@ -496,19 +496,19 @@ void gridboxstat(field_type *field1, field_type *field2, int xinc, int yinc, int
findex++;
if ( lprogress ) progressStatus(0, 1, findex/nlat2*nlon2);
*/
- int ilat = ig/nlon2;
- int ilon = ig - ilat*nlon2;
+ size_t ilat = ig/nlon2;
+ size_t ilon = ig - ilat*nlon2;
- int isize = 0;
+ size_t isize = 0;
field[ompthID].nmiss = 0;
- for ( int j = 0; j < yinc; ++j )
+ for ( size_t j = 0; j < yinc; ++j )
{
- int jj = ilat*yinc+j;
+ size_t jj = ilat*yinc+j;
if ( jj >= nlat1 ) break;
- for ( int i = 0; i < xinc; ++i )
+ for ( size_t i = 0; i < xinc; ++i )
{
- int ii = ilon*xinc+i;
- int index = jj*nlon1 + ii;
+ size_t ii = ilon*xinc+i;
+ size_t index = jj*nlon1 + ii;
if ( ii >= nlon1 ) break;
field[ompthID].ptr[isize] = array1[index];
if ( useWeight ) field[ompthID].weight[isize] = field1->weight[index];
@@ -521,8 +521,8 @@ void gridboxstat(field_type *field1, field_type *field2, int xinc, int yinc, int
field2->ptr[ig] = fldfun(field[ompthID], statfunc);
}
- int nmiss = 0;
- for ( int i = 0; i < nlat2*nlon2; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < nlat2*nlon2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
field2->nmiss = nmiss;
@@ -596,11 +596,11 @@ void *Gridboxstat(void *argument)
field_init(&field1);
field_init(&field2);
- int gridsize1 = gridInqSize(gridID1);
+ size_t gridsize1 = gridInqSize(gridID1);
field1.ptr = (double*) Malloc(gridsize1*sizeof(double));
field1.weight = needWeights ? (double*) Malloc(gridsize1*sizeof(double)) : NULL;
- int gridsize2 = gridInqSize(gridID2);
+ size_t gridsize2 = gridInqSize(gridID2);
field2.ptr = (double*) Malloc(gridsize2*sizeof(double));
field2.weight = NULL;
@@ -613,10 +613,10 @@ void *Gridboxstat(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int nmiss;
+ size_t nmiss;
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field1.size = gridInqSize(field1.grid);
@@ -640,7 +640,7 @@ void *Gridboxstat(void *argument)
gridboxstat(&field1, &field2, xinc, yinc, operfunc);
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, field2.ptr, (int)field2.nmiss);
+ pstreamWriteRecord(streamID2, field2.ptr, field2.nmiss);
}
tsID++;
}
diff --git a/src/Harmonic.cc b/src/Harmonic.cc
index 4b1e829..a93c017 100644
--- a/src/Harmonic.cc
+++ b/src/Harmonic.cc
@@ -32,7 +32,7 @@ void *Harmonic(void *argument)
int gridsize;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int offset;
int nlevel;
int vdate = 0, vtime = 0;
diff --git a/src/Hi.cc b/src/Hi.cc
index 9b7bb93..368c290 100644
--- a/src/Hi.cc
+++ b/src/Hi.cc
@@ -49,26 +49,26 @@ static double humidityIndex(double t, double e, double r, double missval)
static void farexpr(field_type *field1, field_type field2, field_type field3, double (*expression)(double, double, double, double))
{
const int grid1 = field1->grid;
- const int nmiss1 = field1->nmiss;
+ const size_t nmiss1 = field1->nmiss;
const double missval1 = field1->missval;
double *array1 = field1->ptr;
const int grid2 = field2.grid;
- const int nmiss2 = field2.nmiss;
+ const size_t nmiss2 = field2.nmiss;
const double missval2 = field2.missval;
const double *array2 = field2.ptr;
const int grid3 = field3.grid;
- const int nmiss3 = field3.nmiss;
+ const size_t nmiss3 = field3.nmiss;
const double missval3 = field3.missval;
const double *array3 = field3.ptr;
- int len = gridInqSize(grid1);
+ size_t len = gridInqSize(grid1);
if ( len != gridInqSize(grid2) || len != gridInqSize(grid3) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 || nmiss3 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) || DBL_IS_EQUAL(array2[i], missval2) || DBL_IS_EQUAL(array3[i], missval3))
array1[i] = missval1;
else
@@ -76,19 +76,19 @@ static void farexpr(field_type *field1, field_type field2, field_type field3, do
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = expression(array1[i], array2[i], array3[i], missval1);
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
void *Hi(void *argument)
{
- int nmiss;
+ size_t nmiss;
int nrecs;
int varID1, varID2, varID3;
int levelID1, levelID2, levelID3;
@@ -111,7 +111,7 @@ void *Hi(void *argument)
vlistCompare(vlistID1, vlistID2, CMP_DIM);
vlistCompare(vlistID1, vlistID3, CMP_DIM);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
field_type field1, field2, field3;
field_init(&field1);
@@ -160,15 +160,15 @@ void *Hi(void *argument)
{
pstreamInqRecord(streamID1, &varID1, &levelID1);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
pstreamInqRecord(streamID2, &varID2, &levelID2);
pstreamReadRecord(streamID2, field2.ptr, &nmiss);
- field2.nmiss = (size_t) nmiss;
+ field2.nmiss = nmiss;
pstreamInqRecord(streamID3, &varID3, &levelID3);
pstreamReadRecord(streamID3, field3.ptr, &nmiss);
- field3.nmiss = (size_t) nmiss;
+ field3.nmiss = nmiss;
if ( varID1 != varID2 || varID1 != varID3 || levelID1 != levelID2 || levelID1 != levelID3 )
cdoAbort("Input streams have different structure!");
@@ -187,7 +187,7 @@ void *Hi(void *argument)
farexpr(&field1, field2, field3, humidityIndex);
pstreamDefRecord(streamID4, varID4, levelID1);
- pstreamWriteRecord(streamID4, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID4, field1.ptr, field1.nmiss);
}
tsID++;
diff --git a/src/Histogram.cc b/src/Histogram.cc
index 8440b2d..9b3d81f 100644
--- a/src/Histogram.cc
+++ b/src/Histogram.cc
@@ -30,7 +30,7 @@
void *Histogram(void *argument)
{
int nrecs, varID, levelID;
- int nmiss;
+ size_t nmiss;
int offset;
int nlevel, zaxisID;
double missval;
diff --git a/src/Importamsr.cc b/src/Importamsr.cc
index cdc22fb..a6c9e74 100644
--- a/src/Importamsr.cc
+++ b/src/Importamsr.cc
@@ -111,7 +111,7 @@ void init_amsr_averaged(int vlistID, int gridID, int zaxisID, int nvars)
}
static
-void read_amsr(FILE *fp, int vlistID, int nvars, double *data[], int *nmiss)
+void read_amsr(FILE *fp, int vlistID, int nvars, double *data[], size_t *nmiss)
{
int varID, i, gridsize;
unsigned char *amsr_data = NULL;
@@ -148,7 +148,7 @@ void read_amsr(FILE *fp, int vlistID, int nvars, double *data[], int *nmiss)
}
static
-void write_data(int streamID, int nvars, double *data[], int *nmiss)
+void write_data(int streamID, int nvars, double *data[], size_t *nmiss)
{
for ( int varID = 0; varID < nvars; ++varID )
{
@@ -176,7 +176,7 @@ void *Importamsr(void *argument)
int vtime = 0;
double xvals[NLON], yvals[NLAT];
double *data[MAX_VARS];
- int nmiss[MAX_VARS];
+ size_t nmiss[MAX_VARS];
cdoInitialize(argument);
diff --git a/src/Importbinary.cc b/src/Importbinary.cc
index 97d3725..260285d 100644
--- a/src/Importbinary.cc
+++ b/src/Importbinary.cc
@@ -188,7 +188,7 @@ int define_level(dsets_t *pfi, int nlev)
void *Importbinary(void *argument)
{
int i;
- int nmiss = 0, n_nan;
+ size_t nmiss = 0, n_nan;
int ivar;
int varID = -1, levelID, tsID;
int gridsize;
@@ -536,7 +536,7 @@ void *Importbinary(void *argument)
}
/*
if ( cdoVerbose )
- printf("%3d %4d %3d %6d %6d %12.5g %12.5g\n", tsID, recID, recoffset, nmiss, n_nan, fmin, fmax);
+ printf("%3d %4d %3d %6zu %6zu %12.5g %12.5g\n", tsID, recID, recoffset, nmiss, n_nan, fmin, fmax);
*/
varID = recVarID[recID];
levelID = recLevelID[recID];
diff --git a/src/Importcmsaf.cc b/src/Importcmsaf.cc
index 85919e2..9db4d0b 100644
--- a/src/Importcmsaf.cc
+++ b/src/Importcmsaf.cc
@@ -769,7 +769,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
char varname[CDI_MAX_NAME];
short *mask = NULL;
double minval, maxval;
- int nmiss;
+ size_t nmiss;
int num_attrs;
attstring[0] = 0;
@@ -1395,7 +1395,7 @@ void *Importcmsaf(void *argument)
int streamID;
int gridID = -1, zaxisID, taxisID, vlistID;
int i, offset;
- int nmiss;
+ size_t nmiss;
int ivar;
int varID, levelID, tsID;
int nx, ny, nz, nt, gridsize;
@@ -1593,7 +1593,7 @@ void *Importcmsaf(void *argument)
if ( DBL_IS_EQUAL(array[i], missval) ) nmiss++;
if ( cdoVerbose )
- cdoPrint(" Write var %d, level %d, nmiss %d, missval %g, minval %g, maxval %g",
+ cdoPrint(" Write var %d, level %d, nmiss %zu, missval %g, minval %g, maxval %g",
varID, levelID, nmiss, missval, minval, maxval);
/*
if ( ! (missval < minval || missval > maxval) )
diff --git a/src/Importobs.cc b/src/Importobs.cc
index 96b0b48..a95e150 100644
--- a/src/Importobs.cc
+++ b/src/Importobs.cc
@@ -66,7 +66,7 @@ void write_data(int streamID, int vlistID, int nvars, double *data[])
pstreamDefRecord(streamID, varID, 0);
- int nmiss = 0;
+ size_t nmiss = 0;
for ( int i = 0; i < gridsize; ++i )
if ( DBL_IS_EQUAL(data[varID][i], missval) ) nmiss++;
diff --git a/src/Info.cc b/src/Info.cc
index 99d83bf..117d854 100644
--- a/src/Info.cc
+++ b/src/Info.cc
@@ -241,7 +241,7 @@ void printMap(int nlon, int nlat, double *array, double missval, double min, dou
typedef struct {
double min, max, sum, sumi;
- long nvals, nmiss, nlevs;
+ size_t nvals, nmiss, nlevs;
} infostat_type;
static
@@ -263,8 +263,8 @@ void *Info(void *argument)
int fpeRaised = 0;
int varID, levelID;
int nrecs;
- int nmiss;
- long imiss = 0;
+ size_t nmiss;
+ size_t imiss = 0;
char varname[CDI_MAX_NAME];
char paramstr[32];
char vdatestr[32], vtimestr[32];
@@ -304,7 +304,7 @@ void *Info(void *argument)
infostat_type *infostat = (infostat_type*) Malloc(nvars*sizeof(infostat_type));
- int gridsizemax = vlistGridsizeMax(vlistID);
+ size_t gridsizemax = vlistGridsizeMax(vlistID);
if ( vlistNumber(vlistID) != CDI_REAL ) gridsizemax *= 2;
double *array = (double*) Malloc(gridsizemax*sizeof(double));
@@ -350,8 +350,8 @@ void *Info(void *argument)
int gridID = vlistInqVarGrid(vlistID, varID);
int zaxisID = vlistInqVarZaxis(vlistID, varID);
int number = vlistInqVarNumber(vlistID, varID);
- long gridsize = gridInqSize(gridID);
- long nlevs = zaxisInqSize(zaxisID);
+ size_t gridsize = gridInqSize(gridID);
+ size_t nlevs = zaxisInqSize(zaxisID);
double level = cdoZaxisInqLevel(zaxisID, levelID);
double missval = vlistInqVarMissval(vlistID, varID);
@@ -383,11 +383,11 @@ void *Info(void *argument)
set_text_color(stdout, RESET, GREEN);
if ( operatorID == XINFON )
- fprintf(stdout, "%7ld ", nlevs);
+ fprintf(stdout, "%7zu ", nlevs);
else
fprintf(stdout, "%7g ", level);
- fprintf(stdout, "%8ld %7ld ", gridsize, infostatp->nmiss);
+ fprintf(stdout, "%8zu %7zu ", gridsize, infostatp->nmiss);
set_text_color(stdout, RESET, BLACK);
fprintf(stdout, ":");
@@ -402,8 +402,8 @@ void *Info(void *argument)
if ( infostatp->nmiss > 0 )
{
- long nvals = 0;
- for ( long i = 0; i < gridsize; ++i )
+ size_t nvals = 0;
+ for ( size_t i = 0; i < gridsize; ++i )
{
if ( !DBL_IS_EQUAL(array[i], missval) )
{
@@ -452,8 +452,8 @@ void *Info(void *argument)
}
else
{
- long nvals = 0;
- for ( long i = 0; i < gridsize; i++ )
+ size_t nvals = 0;
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( !DBL_IS_EQUAL(array[i*2], missval) &&
!DBL_IS_EQUAL(array[i*2+1], missval) )
@@ -505,14 +505,14 @@ void *Info(void *argument)
}
if ( imiss != nmiss && nmiss > 0 )
- cdoPrint("Found %d of %d missing values!", imiss, nmiss);
+ cdoPrint("Found %zu of %zu missing values!", imiss, nmiss);
if ( fpeRaised > 0 ) cdoWarning("floating-point exception reported: %s!", fpe_errstr(fpeRaised));
if ( operatorID == MAP )
{
- int nlon = gridInqXsize(gridID);
- int nlat = gridInqYsize(gridID);
+ size_t nlon = gridInqXsize(gridID);
+ size_t nlat = gridInqYsize(gridID);
if ( gridInqType(gridID) == GRID_GAUSSIAN ||
gridInqType(gridID) == GRID_LONLAT ||
diff --git a/src/Input.cc b/src/Input.cc
index e8372a1..b9372aa 100644
--- a/src/Input.cc
+++ b/src/Input.cc
@@ -245,7 +245,7 @@ void *Input(void *argument)
pstreamDefRecord(streamID, varID, levelID);
int offset = gridsize*levelID;
- int nmiss = 0;
+ size_t nmiss = 0;
for ( i = 0; i < gridsize; ++i )
if ( DBL_IS_EQUAL(array[offset+i], missval) ) nmiss++;
diff --git a/src/Intgrid.cc b/src/Intgrid.cc
index 7c03a86..d6b0bdb 100644
--- a/src/Intgrid.cc
+++ b/src/Intgrid.cc
@@ -30,17 +30,17 @@
#include "grid.h"
-int genThinoutGrid(int gridID1, int xinc, int yinc)
+int genThinoutGrid(int gridID1, size_t xinc, size_t yinc)
{
int gridtype = gridInqType(gridID1);
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
- int nlon2 = nlon1/xinc;
- int nlat2 = nlat1/yinc;
+ size_t nlon2 = nlon1/xinc;
+ size_t nlat2 = nlat1/yinc;
if ( nlon1%xinc ) nlon2++;
if ( nlat1%yinc ) nlat2++;
- int gridsize2 = nlon2*nlat2;
+ size_t gridsize2 = nlon2*nlat2;
int gridID2 = gridCreate(GRID_LONLAT, gridsize2);
gridDefXsize(gridID2, nlon2);
@@ -55,15 +55,15 @@ int genThinoutGrid(int gridID1, int xinc, int yinc)
gridInqXvals(gridID1, xvals1);
gridInqYvals(gridID1, yvals1);
- int olat = 0;
- for ( int ilat = 0; ilat < nlat1; ilat+=yinc )
+ size_t olat = 0;
+ for ( size_t ilat = 0; ilat < nlat1; ilat+=yinc )
{
yvals2[olat] = yvals1[ilat];
olat++;
}
- int olon = 0;
- for ( int ilon = 0; ilon < nlon1; ilon+=xinc )
+ size_t olon = 0;
+ for ( size_t ilon = 0; ilon < nlon1; ilon+=xinc )
{
xvals2[olon] = xvals1[ilon];
olon++;
@@ -88,17 +88,17 @@ int genThinoutGrid(int gridID1, int xinc, int yinc)
int genBoxavgGrid(int gridID1, int xinc, int yinc)
{
- int i, j, i1;
+ size_t i, j, i1;
int gridtype = gridInqType(gridID1);
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
- int nlon2 = nlon1/xinc;
- int nlat2 = nlat1/yinc;
+ size_t nlon2 = nlon1/xinc;
+ size_t nlat2 = nlat1/yinc;
if ( nlon1%xinc ) nlon2++;
if ( nlat1%yinc ) nlat2++;
- int gridsize2 = nlon2*nlat2;
+ size_t gridsize2 = nlon2*nlat2;
int gridID2 = gridCreate(GRID_LONLAT, gridsize2);
gridDefXsize(gridID2, nlon2);
@@ -179,7 +179,7 @@ int genBoxavgGrid(int gridID1, int xinc, int yinc)
}
static
-void boxavg(field_type *field1, field_type *field2, int xinc, int yinc)
+void boxavg(field_type *field1, field_type *field2, size_t xinc, size_t yinc)
{
int gridID1 = field1->grid;
int gridID2 = field2->grid;
@@ -187,35 +187,35 @@ void boxavg(field_type *field1, field_type *field2, int xinc, int yinc)
double *array2 = field2->ptr;
double missval = field1->missval;
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
- int nlon2 = gridInqXsize(gridID2);
- int nlat2 = gridInqYsize(gridID2);
+ size_t nlon2 = gridInqXsize(gridID2);
+ size_t nlat2 = gridInqYsize(gridID2);
double **xfield1 = (double **) Malloc(nlat1*sizeof(double *));
- for ( int ilat = 0; ilat < nlat1; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat1; ilat++ )
xfield1[ilat] = array1 + ilat*nlon1;
double **xfield2 = (double **) Malloc(nlat2 * sizeof(double *));
- for ( int ilat = 0; ilat < nlat2; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat2; ilat++ )
xfield2[ilat] = array2 + ilat*nlon2;
- for ( int ilat = 0; ilat < nlat2; ilat++ )
- for ( int ilon = 0; ilon < nlon2; ilon++ )
+ for ( size_t ilat = 0; ilat < nlat2; ilat++ )
+ for ( size_t ilon = 0; ilon < nlon2; ilon++ )
{
xfield2[ilat][ilon] = 0;
- int in = 0;
- for ( int j = 0; j < yinc; ++j )
+ size_t in = 0;
+ for ( size_t j = 0; j < yinc; ++j )
{
- int jj = ilat*yinc+j;
+ size_t jj = ilat*yinc+j;
if ( jj >= nlat1 ) break;
- for ( int i = 0; i < xinc; ++i )
+ for ( size_t i = 0; i < xinc; ++i )
{
- int ii = ilon*xinc+i;
+ size_t ii = ilon*xinc+i;
if ( ii >= nlon1 ) break;
in++;
xfield2[ilat][ilon] += xfield1[jj][ii];
@@ -224,8 +224,8 @@ void boxavg(field_type *field1, field_type *field2, int xinc, int yinc)
xfield2[ilat][ilon] /= in;
}
- int nmiss = 0;
- for ( int i = 0; i < nlat2*nlon2; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < nlat2*nlon2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
field2->nmiss = nmiss;
@@ -243,27 +243,27 @@ void thinout(field_type *field1, field_type *field2, int xinc, int yinc)
double *array2 = field2->ptr;
double missval = field1->missval;
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
- int nlon2 = gridInqXsize(gridID2);
- int nlat2 = gridInqYsize(gridID2);
+ size_t nlon2 = gridInqXsize(gridID2);
+ size_t nlat2 = gridInqYsize(gridID2);
double **xfield1 = (double **) Malloc(nlat1*sizeof(double *));
- for ( int ilat = 0; ilat < nlat1; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat1; ilat++ )
xfield1[ilat] = array1 + ilat*nlon1;
double **xfield2 = (double **) Malloc(nlat2*sizeof(double *));
- for ( int ilat = 0; ilat < nlat2; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat2; ilat++ )
xfield2[ilat] = array2 + ilat*nlon2;
- int olat = 0;
- for ( int ilat = 0; ilat < nlat1; ilat+=yinc )
+ size_t olat = 0;
+ for ( size_t ilat = 0; ilat < nlat1; ilat+=yinc )
{
- int olon = 0;
- for ( int ilon = 0; ilon < nlon1; ilon+=xinc )
+ size_t olon = 0;
+ for ( size_t ilon = 0; ilon < nlon1; ilon+=xinc )
{
xfield2[olat][olon] = xfield1[ilat][ilon];
olon++;
@@ -271,8 +271,8 @@ void thinout(field_type *field1, field_type *field2, int xinc, int yinc)
olat++;
}
- int nmiss = 0;
- for ( int i = 0; i < nlat2*nlon2; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < nlat2*nlon2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
field2->nmiss = nmiss;
@@ -288,7 +288,7 @@ void *Intgrid(void *argument)
int nrecs;
int varID, levelID;
int gridID1 = -1, gridID2 = -1;
- int nmiss;
+ size_t nmiss;
int xinc = 0, yinc = 0;
double missval;
@@ -375,7 +375,7 @@ void *Intgrid(void *argument)
int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
pstreamDefVlist(streamID2, vlistID2);
- int gridsize = vlistGridsizeMax(vlistID1);
+ size_t gridsize = vlistGridsizeMax(vlistID1);
double *array1 = (double*) Malloc(gridsize*sizeof(double));
gridsize = gridInqSize(gridID2);
diff --git a/src/Intgridtraj.cc b/src/Intgridtraj.cc
index 065a28f..6b4b958 100644
--- a/src/Intgridtraj.cc
+++ b/src/Intgridtraj.cc
@@ -55,7 +55,7 @@ void *Intgridtraj(void *argument)
int gridID1;
int varID, levelID;
int vdate, vtime;
- int nmiss;
+ size_t nmiss;
double point;
double xpos, ypos;
int calendar = CALENDAR_STANDARD;
diff --git a/src/Intlevel.cc b/src/Intlevel.cc
index 902f741..0980013 100644
--- a/src/Intlevel.cc
+++ b/src/Intlevel.cc
@@ -159,7 +159,7 @@ void *Intlevel(void *argument)
int nrecs;
int i, offset;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int zaxisID1 = -1;
int gridID, zaxisID;
int nlevel = 0;
@@ -290,7 +290,7 @@ void *Intlevel(void *argument)
bool *vars = (bool*) Malloc(nvars*sizeof(bool));
bool *varinterp = (bool*) Malloc(nvars*sizeof(bool));
- int **varnmiss = (int**) Malloc(nvars*sizeof(int*));
+ size_t **varnmiss = (size_t**) Malloc(nvars*sizeof(size_t*));
double **vardata1 = (double**) Malloc(nvars*sizeof(double*));
double **vardata2 = (double**) Malloc(nvars*sizeof(double*));
@@ -309,14 +309,14 @@ void *Intlevel(void *argument)
{
varinterp[varID] = true;
vardata2[varID] = (double*) Malloc(gridsize*nlev2*sizeof(double));
- varnmiss[varID] = (int*) Malloc(maxlev*sizeof(int));
- memset(varnmiss[varID], 0, maxlev*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(maxlev*sizeof(size_t));
+ memset(varnmiss[varID], 0, maxlev*sizeof(size_t));
}
else
{
varinterp[varID] = false;
vardata2[varID] = vardata1[varID];
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
}
}
diff --git a/src/Intlevel3d.cc b/src/Intlevel3d.cc
index 5d23e93..19139cb 100644
--- a/src/Intlevel3d.cc
+++ b/src/Intlevel3d.cc
@@ -40,7 +40,7 @@ void *Intlevel3d(void *argument)
int tsID, varID, levelID;
int nvars,nvct;
int nzaxis;
- int nmiss;
+ size_t nmiss;
int nlonIn, nlatIn, nlonOut, nlatOut;
//double *lonIn, *latIn, *lonOut, *latOut;
@@ -53,7 +53,7 @@ void *Intlevel3d(void *argument)
double *single1, *single2;
int taxisID1, taxisID3;
double *zlevels_in, *zlevels_out;
- int zlevels_in_miss, zlevels_out_miss;
+ size_t zlevels_in_miss, zlevels_out_miss;
char varname[10];
cdoInitialize(argument);
@@ -319,7 +319,7 @@ void *Intlevel3d(void *argument)
nvars = vlistNvars(vlistID1);
bool *vars = (bool*) Malloc(nvars*sizeof(bool));
bool *varinterp = (bool*) Malloc(nvars*sizeof(bool)); /* marker for variables to be interpolated */
- int **varnmiss = (int**) Malloc(nvars*sizeof(int*)); /* can for missing values of arbitrary variables */
+ size_t **varnmiss = (size_t**) Malloc(nvars*sizeof(size_t*)); /* can for missing values of arbitrary variables */
double **vardata1 = (double**) Malloc(nvars*sizeof(double*)); /* input */
double **vardata2 = (double**) Malloc(nvars*sizeof(double*)); /* output */
@@ -359,22 +359,22 @@ void *Intlevel3d(void *argument)
{
varinterp[varID] = false;
vardata2[varID] = vardata1[varID];
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
if ( cdoVerbose ) cdoPrint("Ignore variable %s with %d levels",varname,nlevel);
}
else
{
varinterp[varID] = true;
vardata2[varID] = (double*) Malloc(gridsize*nlevo*sizeof(double));
- varnmiss[varID] = (int*) Malloc(maxlev*sizeof(int));
- memset(varnmiss[varID], 0, maxlev*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(maxlev*sizeof(size_t));
+ memset(varnmiss[varID], 0, maxlev*sizeof(size_t));
}
}
else
{
varinterp[varID] = false;
vardata2[varID] = vardata1[varID];
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
if ( cdoVerbose ) cdoPrint("Ignore variable %s with %d levels",varname,nlevel);
}
}
diff --git a/src/Intntime.cc b/src/Intntime.cc
index 9e7ac5f..4b65174 100644
--- a/src/Intntime.cc
+++ b/src/Intntime.cc
@@ -60,8 +60,8 @@ void *Intntime(void *argument)
int gridsize = vlistGridsizeMax(vlistID1);
double *array = (double*) Malloc(gridsize*sizeof(double));
- int **nmiss1 = (int **) Malloc(nvars*sizeof(int *));
- int **nmiss2 = (int **) Malloc(nvars*sizeof(int *));
+ size_t **nmiss1 = (size_t **) Malloc(nvars*sizeof(size_t *));
+ size_t **nmiss2 = (size_t **) Malloc(nvars*sizeof(size_t *));
double **vardata1 = (double **) Malloc(nvars*sizeof(double *));
double **vardata2 = (double **) Malloc(nvars*sizeof(double *));
@@ -69,8 +69,8 @@ void *Intntime(void *argument)
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
- nmiss1[varID] = (int*) Malloc(nlevel*sizeof(int));
- nmiss2[varID] = (int*) Malloc(nlevel*sizeof(int));
+ nmiss1[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
+ nmiss2[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
vardata1[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
vardata2[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
}
@@ -164,7 +164,7 @@ void *Intntime(void *argument)
single1 = vardata1[varID] + offset;
single2 = vardata2[varID] + offset;
- int nmiss3 = 0;
+ size_t nmiss3 = 0;
if ( nmiss1[varID][levelID] > 0 || nmiss2[varID][levelID] > 0 )
{
diff --git a/src/Inttime.cc b/src/Inttime.cc
index bdb0d75..4617b3f 100644
--- a/src/Inttime.cc
+++ b/src/Inttime.cc
@@ -105,8 +105,8 @@ void *Inttime(void *argument)
int gridsize = vlistGridsizeMax(vlistID1);
double *array = (double*) Malloc(gridsize*sizeof(double));
- int **nmiss1 = (int **) Malloc(nvars*sizeof(int *));
- int **nmiss2 = (int **) Malloc(nvars*sizeof(int *));
+ size_t **nmiss1 = (size_t **) Malloc(nvars*sizeof(size_t *));
+ size_t **nmiss2 = (size_t **) Malloc(nvars*sizeof(size_t *));
double **vardata1 = (double **) Malloc(nvars*sizeof(double *));
double **vardata2 = (double **) Malloc(nvars*sizeof(double *));
@@ -114,8 +114,8 @@ void *Inttime(void *argument)
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
- nmiss1[varID] = (int*) Malloc(nlevel*sizeof(int));
- nmiss2[varID] = (int*) Malloc(nlevel*sizeof(int));
+ nmiss1[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
+ nmiss2[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
vardata1[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
vardata2[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
}
@@ -227,7 +227,7 @@ void *Inttime(void *argument)
single1 = vardata1[varID] + offset;
single2 = vardata2[varID] + offset;
- int nmiss3 = 0;
+ size_t nmiss3 = 0;
if ( nmiss1[varID][levelID] > 0 || nmiss2[varID][levelID] > 0 )
{
diff --git a/src/Intyear.cc b/src/Intyear.cc
index 5a028fa..639680a 100644
--- a/src/Intyear.cc
+++ b/src/Intyear.cc
@@ -34,7 +34,7 @@ void *Intyear(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss1, nmiss2, nmiss3;
+ size_t nmiss1, nmiss2, nmiss3;
char filesuffix[32];
char filename[8192];
diff --git a/src/Invert.cc b/src/Invert.cc
index a47d2ac..b216545 100644
--- a/src/Invert.cc
+++ b/src/Invert.cc
@@ -283,7 +283,7 @@ void *Invert(void *argument)
int nrecs;
int varID, levelID;
int gridID1;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Invertlev.cc b/src/Invertlev.cc
index aebfc71..34b03a5 100644
--- a/src/Invertlev.cc
+++ b/src/Invertlev.cc
@@ -93,7 +93,7 @@ void *Invertlev(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nlev, nlevel;
int gridID, zaxisID, offset;
bool linvert = false;
@@ -129,7 +129,7 @@ void *Invertlev(void *argument)
int nvars = vlistNvars(vlistID1);
double **vardata = (double**) Malloc(nvars*sizeof(double*));
- int **varnmiss = (int**) Malloc(nvars*sizeof(int*));
+ size_t **varnmiss = (size_t**) Malloc(nvars*sizeof(size_t*));
for ( varID = 0; varID < nvars; varID++ )
{
@@ -147,7 +147,7 @@ void *Invertlev(void *argument)
{
linvert = true;
vardata[varID] = (double*) Malloc(gridsize*nlev*sizeof(double));
- varnmiss[varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
}
diff --git a/src/Isosurface.cc b/src/Isosurface.cc
index 88d345e..511bdd4 100644
--- a/src/Isosurface.cc
+++ b/src/Isosurface.cc
@@ -81,7 +81,7 @@ void *Isosurface(void *argument)
int gridID;
int i, offset;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int zaxisID, zaxisID1 = -1;
double missval;
double *single;
diff --git a/src/Maggraph.cc b/src/Maggraph.cc
index c63ae3e..7553d69 100644
--- a/src/Maggraph.cc
+++ b/src/Maggraph.cc
@@ -882,7 +882,7 @@ void *Maggraph(void *argument)
int gridID;
int nrecs;
int vlistID0 = -1;
- int nmiss;
+ size_t nmiss;
long nts_alloc;
int nparam = operatorArgc();
diff --git a/src/Magplot.cc b/src/Magplot.cc
index c191e5f..2ce4ace 100644
--- a/src/Magplot.cc
+++ b/src/Magplot.cc
@@ -1102,7 +1102,7 @@ void *Magplot(void *argument)
#if defined(HAVE_LIBMAGICS)
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
char varname[CDI_MAX_NAME];
char units[CDI_MAX_NAME];
char vdatestr[32], vtimestr[32], datetimestr[64];
diff --git a/src/Magvector.cc b/src/Magvector.cc
index 8999637..66443ed 100644
--- a/src/Magvector.cc
+++ b/src/Magvector.cc
@@ -316,7 +316,7 @@ void *Magvector(void *argument)
#if defined(HAVE_LIBMAGICS)
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
char varname[CDI_MAX_NAME];
char units[CDI_MAX_NAME];
char vdatestr[32],vtimestr[32],datetimestr[64];
diff --git a/src/Makefile.am b/src/Makefile.am
index 4b002b2..839b091 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,12 +1,16 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libcdo.la
libcdo_la_SOURCES = \
- argument.h \
- argument.cc \
- array.h \
+ argument.h \
+ argument.cc \
+ array.h \
array.cc \
cdo_int.h \
compare.h \
+ cfortran.h \
+ libncl.h \
+ cfortran.h \
+ cf_interface.h \
cdo_pthread.cc \
cdo_vlist.cc \
cdo_getopt.cc \
@@ -22,8 +26,8 @@ libcdo_la_SOURCES = \
after_dvtrans.cc \
after_vertint.cc \
after_vertint.h \
- after_namelist.cc\
- afterburnerlib.cc\
+ after_namelist.cc \
+ afterburnerlib.cc \
afterburner.h \
vct_l191.h \
calendar.h \
@@ -38,6 +42,8 @@ libcdo_la_SOURCES = \
counter.h \
datetime.cc \
datetime.h \
+ cdoDebugOutput.cc \
+ cdoDebugOutput.h\
dmemory.h \
ecacore.cc \
ecacore.h \
@@ -64,6 +70,8 @@ libcdo_la_SOURCES = \
fieldmer.cc \
fieldzon.cc \
functs.h \
+ getMemorySize.c \
+ getRSS.c \
gradsdeslib.cc \
gradsdeslib.h \
grid.cc \
@@ -289,6 +297,7 @@ cdo_SOURCES += Adisit.cc \
Monarith.cc \
Mrotuv.cc \
Mrotuvb.cc \
+ NCL_wind.cc \
Ninfo.cc \
Nmldump.cc \
Output.cc \
@@ -398,13 +407,13 @@ cdo_SOURCES += Adisit.cc \
cdo.h
cdo_SOURCES += nearpt3c.h
-#if ENABLE_NEARPT3
-#cdo_SOURCES += \
-# nearpt3x.h \
-# nearpt3c.h \
-# nearpt3c.cc \
-# cellsearchorder.h
-#endif
+if ENABLE_NEARPT3
+cdo_SOURCES += \
+ nearpt3x.h \
+ nearpt3c.h \
+ nearpt3c.cc \
+ cellsearchorder.h
+endif
#if ENABLE_MAGICS
cdo_SOURCES += Magplot.cc \
@@ -424,6 +433,9 @@ cdo_SOURCES += Magplot.cc \
cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
cdo_LDADD = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
+if USE_F77
+cdo_LDADD += $(top_builddir)/src/lib/ncl/libncl.la
+endif
cdo_LDFLAGS =
if ENABLE_ALL_STATIC
diff --git a/src/Makefile.in b/src/Makefile.in
index 476d28e..80231d5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -16,7 +16,17 @@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -80,15 +90,21 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = cdo$(EXEEXT)
- at ENABLE_ALL_STATIC_TRUE@am__append_1 = -all-static
+ at ENABLE_NEARPT3_TRUE@am__append_1 = \
+ at ENABLE_NEARPT3_TRUE@ nearpt3x.h \
+ at ENABLE_NEARPT3_TRUE@ nearpt3c.h \
+ at ENABLE_NEARPT3_TRUE@ nearpt3c.cc \
+ at ENABLE_NEARPT3_TRUE@ cellsearchorder.h
+
+ at USE_F77_TRUE@am__append_2 = $(top_builddir)/src/lib/ncl/libncl.la
+ at ENABLE_ALL_STATIC_TRUE@am__append_3 = -all-static
noinst_PROGRAMS = cdotest$(EXEEXT)
- at ENABLE_ALL_STATIC_TRUE@am__append_2 = -all-static
+ at ENABLE_ALL_STATIC_TRUE@am__append_4 = -all-static
subdir = src
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(srcdir)/config.h.in $(top_srcdir)/config/mkinstalldirs \
- $(top_srcdir)/config/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -97,6 +113,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
@@ -114,13 +131,14 @@ am_libcdo_la_OBJECTS = libcdo_la-argument.lo libcdo_la-array.lo \
libcdo_la-afterburnerlib.lo libcdo_la-constants.lo \
libcdo_la-color.lo libcdo_la-commandline.lo \
libcdo_la-convert_units.lo libcdo_la-datetime.lo \
- libcdo_la-ecacore.lo libcdo_la-ecautil.lo \
- libcdo_la-exception.lo libcdo_la-expr.lo libcdo_la-expr_fun.lo \
- libcdo_la-expr_lex.lo libcdo_la-expr_yacc.lo \
- libcdo_la-features.lo libcdo_la-field.lo libcdo_la-field2.lo \
- libcdo_la-fieldc.lo libcdo_la-fieldmem.lo \
- libcdo_la-fieldmer.lo libcdo_la-fieldzon.lo \
- libcdo_la-gradsdeslib.lo libcdo_la-grid.lo \
+ libcdo_la-cdoDebugOutput.lo libcdo_la-ecacore.lo \
+ libcdo_la-ecautil.lo libcdo_la-exception.lo libcdo_la-expr.lo \
+ libcdo_la-expr_fun.lo libcdo_la-expr_lex.lo \
+ libcdo_la-expr_yacc.lo libcdo_la-features.lo \
+ libcdo_la-field.lo libcdo_la-field2.lo libcdo_la-fieldc.lo \
+ libcdo_la-fieldmem.lo libcdo_la-fieldmer.lo \
+ libcdo_la-fieldzon.lo libcdo_la-getMemorySize.lo \
+ libcdo_la-getRSS.lo libcdo_la-gradsdeslib.lo libcdo_la-grid.lo \
libcdo_la-grid_proj.lo libcdo_la-grid_area.lo \
libcdo_la-grid_define.lo libcdo_la-grid_gme.lo \
libcdo_la-grid_rot.lo libcdo_la-grid_from_name.lo \
@@ -168,6 +186,53 @@ am__v_lt_0 = --silent
am__v_lt_1 =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+am__cdo_SOURCES_DIST = cdo.cc Adisit.cc Afterburner.cc Arith.cc \
+ Arithc.cc Arithdays.cc Arithlat.cc CDItest.cc CDIread.cc \
+ CDIwrite.cc Cat.cc Change.cc Change_e5slm.cc Cloudlayer.cc \
+ CMOR.cc CMOR_lite.cc CMOR_table.cc Collgrid.cc Command.cc \
+ Comp.cc Compc.cc Complextorect.cc Cond.cc Cond2.cc Condc.cc \
+ Consecstat.cc Copy.cc Deltat.cc Deltime.cc Derivepar.cc \
+ Detrend.cc Diff.cc Distgrid.cc Duplicate.cc EOFs.cc Eof3d.cc \
+ EcaIndices.cc Echam5ini.cc Enlarge.cc Enlargegrid.cc \
+ Ensstat.cc Ensstat3.cc Ensval.cc Eofcoeff.cc Eofcoeff3d.cc \
+ EstFreq.cc Exprf.cc FC.cc Filedes.cc Fillmiss.cc Filter.cc \
+ Fldrms.cc Fldstat.cc Fldstat2.cc Fourier.cc Gengrid.cc \
+ Gradsdes.cc Gridboxstat.cc Gridcell.cc Gridsearch.cc \
+ Harmonic.cc Hi.cc Histogram.cc Importamsr.cc Importbinary.cc \
+ Importcmsaf.cc Importobs.cc Info.cc Input.cc Intgrid.cc \
+ Intgridtraj.cc Intlevel.cc Intlevel3d.cc Intntime.cc \
+ Inttime.cc Intyear.cc Invert.cc Invertlev.cc Isosurface.cc \
+ Log.cc MapReduce.cc Maskbox.cc Mastrfu.cc Math.cc Merge.cc \
+ Mergegrid.cc Mergetime.cc Merstat.cc Monarith.cc Mrotuv.cc \
+ Mrotuvb.cc NCL_wind.cc Ninfo.cc Nmldump.cc Output.cc \
+ Outputgmt.cc Pack.cc Pardup.cc Pinfo.cc Pressure.cc Regres.cc \
+ Remap.cc Remapeta.cc Replace.cc Replacevalues.cc Rhopot.cc \
+ Rotuv.cc Runpctl.cc Runstat.cc Samplegrid.cc Samplegridicon.cc \
+ Seascount.cc Seaspctl.cc Seasstat.cc Selbox.cc Selgridcell.cc \
+ Select.cc Selmulti.cc Seloperator.cc Selrec.cc Seltime.cc \
+ Selvar.cc Set.cc Setattribute.cc Setbox.cc Setgatt.cc \
+ Setgrid.cc Sethalo.cc Setmiss.cc Setpartab.cc Setrcaname.cc \
+ Settime.cc Setzaxis.cc Shiftxy.cc Showinfo.cc Showattribute.h \
+ Showattribute.cc Sinfo.cc Smooth.cc Sort.cc Sorttimestamp.cc \
+ Specinfo.cc Spectral.cc Spectrum.cc Split.cc Splitrec.cc \
+ Splitsel.cc Splittime.cc Splityear.cc Subtrend.cc Tee.cc \
+ Templates.cc Test.cc Tests.cc Timcount.cc Timcumsum.cc \
+ Timpctl.cc Timselpctl.cc Timselstat.cc Timsort.cc Timstat.cc \
+ Timstat2.cc Timstat3.cc Tinfo.cc Tocomplex.cc Transpose.cc \
+ Trend.cc Trms.cc Tstepcount.cc Vargen.cc Varrms.cc \
+ Vertintml.cc Vertintap.cc Vertstat.cc Vertcum.cc Vertwind.cc \
+ Verifygrid.cc Wct.cc Wind.cc WindTrans.cc Writegrid.cc \
+ Writerandom.cc XTimstat.cc YAR.cc Yearmonstat.cc Ydayarith.cc \
+ Ydaypctl.cc Ydaystat.cc Ydrunpctl.cc Ydrunstat.cc \
+ Yhourarith.cc Yhourstat.cc Ymonarith.cc Ymonpctl.cc \
+ Ymonstat.cc Yseaspctl.cc Yseasstat.cc Zonstat.cc cdo.h \
+ nearpt3c.h nearpt3x.h nearpt3c.cc cellsearchorder.h Magplot.cc \
+ Magvector.cc Maggraph.cc template_parser.h template_parser.cc \
+ results_template_parser.h results_template_parser.cc \
+ magics_template_parser.h magics_template_parser.cc \
+ StringUtilities.h StringUtilities.cc CdoMagicsMapper.h \
+ CdoMagicsMapper.cc
+ at ENABLE_NEARPT3_TRUE@am__objects_1 = cdo-nearpt3c.$(OBJEXT)
am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
cdo-Afterburner.$(OBJEXT) cdo-Arith.$(OBJEXT) \
cdo-Arithc.$(OBJEXT) cdo-Arithdays.$(OBJEXT) \
@@ -210,7 +275,8 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
cdo-Mastrfu.$(OBJEXT) cdo-Math.$(OBJEXT) cdo-Merge.$(OBJEXT) \
cdo-Mergegrid.$(OBJEXT) cdo-Mergetime.$(OBJEXT) \
cdo-Merstat.$(OBJEXT) cdo-Monarith.$(OBJEXT) \
- cdo-Mrotuv.$(OBJEXT) cdo-Mrotuvb.$(OBJEXT) cdo-Ninfo.$(OBJEXT) \
+ cdo-Mrotuv.$(OBJEXT) cdo-Mrotuvb.$(OBJEXT) \
+ cdo-NCL_wind.$(OBJEXT) cdo-Ninfo.$(OBJEXT) \
cdo-Nmldump.$(OBJEXT) cdo-Output.$(OBJEXT) \
cdo-Outputgmt.$(OBJEXT) cdo-Pack.$(OBJEXT) \
cdo-Pardup.$(OBJEXT) cdo-Pinfo.$(OBJEXT) \
@@ -260,14 +326,15 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
cdo-Yhourstat.$(OBJEXT) cdo-Ymonarith.$(OBJEXT) \
cdo-Ymonpctl.$(OBJEXT) cdo-Ymonstat.$(OBJEXT) \
cdo-Yseaspctl.$(OBJEXT) cdo-Yseasstat.$(OBJEXT) \
- cdo-Zonstat.$(OBJEXT) cdo-Magplot.$(OBJEXT) \
+ cdo-Zonstat.$(OBJEXT) $(am__objects_1) cdo-Magplot.$(OBJEXT) \
cdo-Magvector.$(OBJEXT) cdo-Maggraph.$(OBJEXT) \
cdo-template_parser.$(OBJEXT) \
cdo-results_template_parser.$(OBJEXT) \
cdo-magics_template_parser.$(OBJEXT) \
cdo-StringUtilities.$(OBJEXT) cdo-CdoMagicsMapper.$(OBJEXT)
cdo_OBJECTS = $(am_cdo_OBJECTS)
-cdo_DEPENDENCIES = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
+cdo_DEPENDENCIES = libcdo.la $(top_builddir)/libcdi/src/libcdi.la \
+ $(am__append_2)
cdo_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(cdo_LDFLAGS) $(LDFLAGS) -o $@
@@ -330,7 +397,8 @@ am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libcdo_la_SOURCES) $(cdo_SOURCES) $(cdotest_SOURCES)
-DIST_SOURCES = $(libcdo_la_SOURCES) $(cdo_SOURCES) $(cdotest_SOURCES)
+DIST_SOURCES = $(libcdo_la_SOURCES) $(am__cdo_SOURCES_DIST) \
+ $(cdotest_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -356,6 +424,9 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/config/depcomp \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -398,18 +469,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -485,6 +560,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -534,20 +610,22 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libcdo.la
libcdo_la_SOURCES = argument.h argument.cc array.h array.cc cdo_int.h \
- compare.h cdo_pthread.cc cdo_vlist.cc cdo_getopt.cc \
- cdo_getopt.h cdo_task.cc cdo_task.h cdo_history.cc cdo_read.cc \
- cdi_uuid.h cmortable_parser.cc after_sptrans.cc \
- after_fctrans.cc after_dvtrans.cc after_vertint.cc \
- after_vertint.h after_namelist.cc afterburnerlib.cc \
- afterburner.h vct_l191.h calendar.h constants.h constants.cc \
- color.cc color.h commandline.cc const.h convert_units.cc \
- convert_units.h counter.h datetime.cc datetime.h dmemory.h \
- ecacore.cc ecacore.h ecautil.cc ecautil.h error.h etopo.h \
- temp.h mask.h exception.cc expr.cc expr.h expr_fun.cc \
- expr_fun.h expr_lex.cc expr_yacc.cc expr_yacc.h features.cc \
- field.cc field.h field2.cc fieldc.cc fieldmem.cc fieldmer.cc \
- fieldzon.cc functs.h gradsdeslib.cc gradsdeslib.h grid.cc \
- grid.h grid_proj.cc grid_proj.h grid_area.cc grid_define.cc \
+ compare.h cfortran.h libncl.h cfortran.h cf_interface.h \
+ cdo_pthread.cc cdo_vlist.cc cdo_getopt.cc cdo_getopt.h \
+ cdo_task.cc cdo_task.h cdo_history.cc cdo_read.cc cdi_uuid.h \
+ cmortable_parser.cc after_sptrans.cc after_fctrans.cc \
+ after_dvtrans.cc after_vertint.cc after_vertint.h \
+ after_namelist.cc afterburnerlib.cc afterburner.h vct_l191.h \
+ calendar.h constants.h constants.cc color.cc color.h \
+ commandline.cc const.h convert_units.cc convert_units.h \
+ counter.h datetime.cc datetime.h cdoDebugOutput.cc \
+ cdoDebugOutput.h dmemory.h ecacore.cc ecacore.h ecautil.cc \
+ ecautil.h error.h etopo.h temp.h mask.h exception.cc expr.cc \
+ expr.h expr_fun.cc expr_fun.h expr_lex.cc expr_yacc.cc \
+ expr_yacc.h features.cc field.cc field.h field2.cc fieldc.cc \
+ fieldmem.cc fieldmer.cc fieldzon.cc functs.h getMemorySize.c \
+ getRSS.c gradsdeslib.cc gradsdeslib.h grid.cc grid.h \
+ grid_proj.cc grid_proj.h grid_area.cc grid_define.cc \
grid_gme.cc grid_rot.cc grid_from_name.cc grid_read.cc \
grid_read_pingo.cc grid_print.cc gridreference.cc griddes.cc \
griddes.h griddes_h5.cc griddes_nc.cc hetaeta.cc hetaeta.h \
@@ -582,13 +660,6 @@ libcdo_la_SOURCES = argument.h argument.cc array.h array.cc cdo_int.h \
clipping/grid_cell.c clipping/grid_cell.h \
clipping/intersection.c clipping/utils.c clipping/utils.h
#
-#if ENABLE_NEARPT3
-#cdo_SOURCES += \
-# nearpt3x.h \
-# nearpt3c.h \
-# nearpt3c.cc \
-# cellsearchorder.h
-#endif
#if ENABLE_MAGICS
cdo_SOURCES = cdo.cc Adisit.cc Afterburner.cc Arith.cc Arithc.cc \
@@ -609,15 +680,15 @@ cdo_SOURCES = cdo.cc Adisit.cc Afterburner.cc Arith.cc Arithc.cc \
Inttime.cc Intyear.cc Invert.cc Invertlev.cc Isosurface.cc \
Log.cc MapReduce.cc Maskbox.cc Mastrfu.cc Math.cc Merge.cc \
Mergegrid.cc Mergetime.cc Merstat.cc Monarith.cc Mrotuv.cc \
- Mrotuvb.cc Ninfo.cc Nmldump.cc Output.cc Outputgmt.cc Pack.cc \
- Pardup.cc Pinfo.cc Pressure.cc Regres.cc Remap.cc Remapeta.cc \
- Replace.cc Replacevalues.cc Rhopot.cc Rotuv.cc Runpctl.cc \
- Runstat.cc Samplegrid.cc Samplegridicon.cc Seascount.cc \
- Seaspctl.cc Seasstat.cc Selbox.cc Selgridcell.cc Select.cc \
- Selmulti.cc Seloperator.cc Selrec.cc Seltime.cc Selvar.cc \
- Set.cc Setattribute.cc Setbox.cc Setgatt.cc Setgrid.cc \
- Sethalo.cc Setmiss.cc Setpartab.cc Setrcaname.cc Settime.cc \
- Setzaxis.cc Shiftxy.cc Showinfo.cc Showattribute.h \
+ Mrotuvb.cc NCL_wind.cc Ninfo.cc Nmldump.cc Output.cc \
+ Outputgmt.cc Pack.cc Pardup.cc Pinfo.cc Pressure.cc Regres.cc \
+ Remap.cc Remapeta.cc Replace.cc Replacevalues.cc Rhopot.cc \
+ Rotuv.cc Runpctl.cc Runstat.cc Samplegrid.cc Samplegridicon.cc \
+ Seascount.cc Seaspctl.cc Seasstat.cc Selbox.cc Selgridcell.cc \
+ Select.cc Selmulti.cc Seloperator.cc Selrec.cc Seltime.cc \
+ Selvar.cc Set.cc Setattribute.cc Setbox.cc Setgatt.cc \
+ Setgrid.cc Sethalo.cc Setmiss.cc Setpartab.cc Setrcaname.cc \
+ Settime.cc Setzaxis.cc Shiftxy.cc Showinfo.cc Showattribute.h \
Showattribute.cc Sinfo.cc Smooth.cc Sort.cc Sorttimestamp.cc \
Specinfo.cc Spectral.cc Spectrum.cc Split.cc Splitrec.cc \
Splitsel.cc Splittime.cc Splityear.cc Subtrend.cc Tee.cc \
@@ -631,22 +702,23 @@ cdo_SOURCES = cdo.cc Adisit.cc Afterburner.cc Arith.cc Arithc.cc \
Ydaypctl.cc Ydaystat.cc Ydrunpctl.cc Ydrunstat.cc \
Yhourarith.cc Yhourstat.cc Ymonarith.cc Ymonpctl.cc \
Ymonstat.cc Yseaspctl.cc Yseasstat.cc Zonstat.cc cdo.h \
- nearpt3c.h Magplot.cc Magvector.cc Maggraph.cc \
+ nearpt3c.h $(am__append_1) Magplot.cc Magvector.cc Maggraph.cc \
template_parser.h template_parser.cc results_template_parser.h \
results_template_parser.cc magics_template_parser.h \
magics_template_parser.cc StringUtilities.h StringUtilities.cc \
CdoMagicsMapper.h CdoMagicsMapper.cc
#endif
cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
-cdo_LDADD = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
-cdo_LDFLAGS = $(am__append_1)
+cdo_LDADD = libcdo.la $(top_builddir)/libcdi/src/libcdi.la \
+ $(am__append_2)
+cdo_LDFLAGS = $(am__append_3)
libcdo_la_CPPFLAGS = $(cdo_CPPFLAGS)
cdotest_SOURCES = cdo_int.h \
cdotest.cc
cdotest_LDADD = $(cdo_LDADD)
cdotest_CPPFLAGS = $(cdo_CPPFLAGS)
-cdotest_LDFLAGS = $(cdo_LDFLAGS) $(am__append_2)
+cdotest_LDFLAGS = $(cdo_LDFLAGS) $(am__append_4)
#cdo-userlog.o: userlog.cc config.h
# $(COMPILE) -DLOGPATH=${exec_prefix}/log -c -o cdo-userlog.o `test -f 'userlog.cc' || echo '$(srcdir)/'`userlog.cc
@@ -671,7 +743,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -935,6 +1006,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Monarith.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Mrotuv.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Mrotuvb.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-NCL_wind.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Ninfo.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Nmldump.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Output.Po at am__quote@
@@ -1043,6 +1115,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Zonstat.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-magics_template_parser.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-nearpt3c.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-results_template_parser.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-template_parser.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdotest-cdotest.Po at am__quote@
@@ -1054,6 +1127,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-afterburnerlib.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-argument.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-array.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdoDebugOutput.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_getopt.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_history.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_pthread.Plo at am__quote@
@@ -1080,6 +1154,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldmem.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldmer.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldzon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-getMemorySize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-getRSS.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-gradsdeslib.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid_area.Plo at am__quote@
@@ -1182,6 +1258,20 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+libcdo_la-getMemorySize.lo: getMemorySize.c
+ at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-getMemorySize.lo -MD -MP -MF $(DEPDIR)/libcdo_la-getMemorySize.Tpo -c -o libcdo_la-getMemorySize.lo `test -f 'getMemorySize.c' || echo '$(srcdir)/'`getMemorySize.c
+ at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-getMemorySize.Tpo $(DEPDIR)/libcdo_la-getMemorySize.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getMemorySize.c' object='libcdo_la-getMemorySize.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-getMemorySize.lo `test -f 'getMemorySize.c' || echo '$(srcdir)/'`getMemorySize.c
+
+libcdo_la-getRSS.lo: getRSS.c
+ at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-getRSS.lo -MD -MP -MF $(DEPDIR)/libcdo_la-getRSS.Tpo -c -o libcdo_la-getRSS.lo `test -f 'getRSS.c' || echo '$(srcdir)/'`getRSS.c
+ at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-getRSS.Tpo $(DEPDIR)/libcdo_la-getRSS.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getRSS.c' object='libcdo_la-getRSS.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-getRSS.lo `test -f 'getRSS.c' || echo '$(srcdir)/'`getRSS.c
+
json/libcdo_la-jsmn.lo: json/jsmn.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT json/libcdo_la-jsmn.lo -MD -MP -MF json/$(DEPDIR)/libcdo_la-jsmn.Tpo -c -o json/libcdo_la-jsmn.lo `test -f 'json/jsmn.c' || echo '$(srcdir)/'`json/jsmn.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) json/$(DEPDIR)/libcdo_la-jsmn.Tpo json/$(DEPDIR)/libcdo_la-jsmn.Plo
@@ -1395,6 +1485,13 @@ libcdo_la-datetime.lo: datetime.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libcdo_la-datetime.lo `test -f 'datetime.cc' || echo '$(srcdir)/'`datetime.cc
+libcdo_la-cdoDebugOutput.lo: cdoDebugOutput.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libcdo_la-cdoDebugOutput.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdoDebugOutput.Tpo -c -o libcdo_la-cdoDebugOutput.lo `test -f 'cdoDebugOutput.cc' || echo '$(srcdir)/'`cdoDebugOutput.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdoDebugOutput.Tpo $(DEPDIR)/libcdo_la-cdoDebugOutput.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdoDebugOutput.cc' object='libcdo_la-cdoDebugOutput.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libcdo_la-cdoDebugOutput.lo `test -f 'cdoDebugOutput.cc' || echo '$(srcdir)/'`cdoDebugOutput.cc
+
libcdo_la-ecacore.lo: ecacore.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libcdo_la-ecacore.lo -MD -MP -MF $(DEPDIR)/libcdo_la-ecacore.Tpo -c -o libcdo_la-ecacore.lo `test -f 'ecacore.cc' || echo '$(srcdir)/'`ecacore.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-ecacore.Tpo $(DEPDIR)/libcdo_la-ecacore.Plo
@@ -3257,6 +3354,20 @@ cdo-Mrotuvb.obj: Mrotuvb.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Mrotuvb.obj `if test -f 'Mrotuvb.cc'; then $(CYGPATH_W) 'Mrotuvb.cc'; else $(CYGPATH_W) '$(srcdir)/Mrotuvb.cc'; fi`
+cdo-NCL_wind.o: NCL_wind.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-NCL_wind.o -MD -MP -MF $(DEPDIR)/cdo-NCL_wind.Tpo -c -o cdo-NCL_wind.o `test -f 'NCL_wind.cc' || echo '$(srcdir)/'`NCL_wind.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-NCL_wind.Tpo $(DEPDIR)/cdo-NCL_wind.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='NCL_wind.cc' object='cdo-NCL_wind.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-NCL_wind.o `test -f 'NCL_wind.cc' || echo '$(srcdir)/'`NCL_wind.cc
+
+cdo-NCL_wind.obj: NCL_wind.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-NCL_wind.obj -MD -MP -MF $(DEPDIR)/cdo-NCL_wind.Tpo -c -o cdo-NCL_wind.obj `if test -f 'NCL_wind.cc'; then $(CYGPATH_W) 'NCL_wind.cc'; else $(CYGPATH_W) '$(srcdir)/NCL_wind.cc'; fi`
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-NCL_wind.Tpo $(DEPDIR)/cdo-NCL_wind.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='NCL_wind.cc' object='cdo-NCL_wind.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-NCL_wind.obj `if test -f 'NCL_wind.cc'; then $(CYGPATH_W) 'NCL_wind.cc'; else $(CYGPATH_W) '$(srcdir)/NCL_wind.cc'; fi`
+
cdo-Ninfo.o: Ninfo.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Ninfo.o -MD -MP -MF $(DEPDIR)/cdo-Ninfo.Tpo -c -o cdo-Ninfo.o `test -f 'Ninfo.cc' || echo '$(srcdir)/'`Ninfo.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Ninfo.Tpo $(DEPDIR)/cdo-Ninfo.Po
@@ -4727,6 +4838,20 @@ cdo-Zonstat.obj: Zonstat.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Zonstat.obj `if test -f 'Zonstat.cc'; then $(CYGPATH_W) 'Zonstat.cc'; else $(CYGPATH_W) '$(srcdir)/Zonstat.cc'; fi`
+cdo-nearpt3c.o: nearpt3c.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-nearpt3c.o -MD -MP -MF $(DEPDIR)/cdo-nearpt3c.Tpo -c -o cdo-nearpt3c.o `test -f 'nearpt3c.cc' || echo '$(srcdir)/'`nearpt3c.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-nearpt3c.Tpo $(DEPDIR)/cdo-nearpt3c.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='nearpt3c.cc' object='cdo-nearpt3c.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-nearpt3c.o `test -f 'nearpt3c.cc' || echo '$(srcdir)/'`nearpt3c.cc
+
+cdo-nearpt3c.obj: nearpt3c.cc
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-nearpt3c.obj -MD -MP -MF $(DEPDIR)/cdo-nearpt3c.Tpo -c -o cdo-nearpt3c.obj `if test -f 'nearpt3c.cc'; then $(CYGPATH_W) 'nearpt3c.cc'; else $(CYGPATH_W) '$(srcdir)/nearpt3c.cc'; fi`
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-nearpt3c.Tpo $(DEPDIR)/cdo-nearpt3c.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='nearpt3c.cc' object='cdo-nearpt3c.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-nearpt3c.obj `if test -f 'nearpt3c.cc'; then $(CYGPATH_W) 'nearpt3c.cc'; else $(CYGPATH_W) '$(srcdir)/nearpt3c.cc'; fi`
+
cdo-Magplot.o: Magplot.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Magplot.o -MD -MP -MF $(DEPDIR)/cdo-Magplot.Tpo -c -o cdo-Magplot.o `test -f 'Magplot.cc' || echo '$(srcdir)/'`Magplot.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Magplot.Tpo $(DEPDIR)/cdo-Magplot.Po
@@ -5077,6 +5202,8 @@ uninstall-am: uninstall-binPROGRAMS
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS
+.PRECIOUS: Makefile
+
#
clean-local: clean-local-dirs
.PHONY: clean-local-dirs
diff --git a/src/MapReduce.cc b/src/MapReduce.cc
index f40132d..cb5d339 100644
--- a/src/MapReduce.cc
+++ b/src/MapReduce.cc
@@ -38,7 +38,8 @@
* function definition */
void read_first_record(char *filename, double *field)
{
- int nmiss,varID,levelID;
+ size_t nmiss;
+ int varID,levelID;
int streamID = streamOpenRead(filename);
streamInqTimestep(streamID,0);
streamInqRecord(streamID,&varID,&levelID);
@@ -72,7 +73,7 @@ void *MapReduce(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nobounds = FALSE;
int nocoords = FALSE;
/*double missval1, missval2; */
@@ -85,7 +86,7 @@ void *MapReduce(void *argument)
/* check input grid type and size - this will be used for selecting relevant
* variables from the input file*/
int inputGridID = cdoDefineGrid(operatorArgv()[0]);
- int inputGridSize = gridInqSize(inputGridID);
+ size_t inputGridSize = gridInqSize(inputGridID);
int inputGridType = gridInqType(inputGridID);
if ( cdoDebug ) cdoPrint("MapReduce: input gridSize:%d", inputGridSize);
@@ -100,8 +101,8 @@ void *MapReduce(void *argument)
int *maskIndexList = (int *) Malloc(maskSize*sizeof(int));
for (int m = 0; m < maskSize; m++) maskIndexList[m] = -1;
- int k = 0;
- for (int i = 0; i < inputGridSize; i++)
+ size_t k = 0;
+ for (size_t i = 0; i < inputGridSize; i++)
{
if (!DBL_IS_EQUAL(inputMaskField[i],0.0))
{
diff --git a/src/Maskbox.cc b/src/Maskbox.cc
index 4fc2bb5..b860d0e 100644
--- a/src/Maskbox.cc
+++ b/src/Maskbox.cc
@@ -399,7 +399,7 @@ void *Maskbox(void *argument)
if ( vars[varID] )
{
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, array, &nmiss);
double missval = vlistInqVarMissval(vlistID1, varID);
diff --git a/src/Mastrfu.cc b/src/Mastrfu.cc
index 857e0c7..063fd78 100644
--- a/src/Mastrfu.cc
+++ b/src/Mastrfu.cc
@@ -30,7 +30,7 @@
static
-void mastrfu(int gridID, int zaxisID, double *array1, double *array2, int nmiss, double missval)
+void mastrfu(int gridID, int zaxisID, double *array1, double *array2, size_t nmiss, double missval)
{
int ilev, ilat, n;
double fact = 4*atan(1.0) * 6371000 / 9.81;
@@ -109,7 +109,7 @@ void *Mastrfu(void *argument)
int nrecs;
int varID, levelID;
int offset;
- int nmiss, nmiss1;
+ size_t nmiss, nmiss1;
cdoInitialize(argument);
diff --git a/src/Math.cc b/src/Math.cc
index 7cf9de0..c0b61c4 100644
--- a/src/Math.cc
+++ b/src/Math.cc
@@ -46,7 +46,7 @@ void *Math(void *argument)
enum {ABS, FINT, FNINT, SQR, SQRT, EXP, LN, LOG10, SIN, COS, TAN, ASIN, ACOS, ATAN, POW, RECI};
int nrecs;
int varID, levelID;
- int nmiss, nmiss2;
+ size_t nmiss, nmiss2;
int i;
cdoInitialize(argument);
diff --git a/src/Merge.cc b/src/Merge.cc
index e0fb869..51340a0 100644
--- a/src/Merge.cc
+++ b/src/Merge.cc
@@ -127,7 +127,7 @@ void *Merge(void *argument)
int levelID, levelID2;
int index;
int gridsize;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Mergegrid.cc b/src/Mergegrid.cc
index 4eaf7b8..c167ca4 100644
--- a/src/Mergegrid.cc
+++ b/src/Mergegrid.cc
@@ -160,7 +160,7 @@ void *Mergegrid(void *argument)
{
int varID, levelID;
int nrecs = 0;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
int index;
cdoInitialize(argument);
diff --git a/src/Mergetime.cc b/src/Mergetime.cc
index f987eed..53007ce 100644
--- a/src/Mergetime.cc
+++ b/src/Mergetime.cc
@@ -185,7 +185,7 @@ void *Mergetime(void *argument)
}
else
{
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(sf[fileID].streamID, array, &nmiss);
pstreamWriteRecord(streamID2, array, nmiss);
}
diff --git a/src/Merstat.cc b/src/Merstat.cc
index d480c91..a7fe558 100644
--- a/src/Merstat.cc
+++ b/src/Merstat.cc
@@ -44,7 +44,7 @@ void *Merstat(void *argument)
int gridID1, gridID2 = -1, lastgrid = -1;
int wstatus = FALSE;
int index;
- int nmiss;
+ size_t nmiss;
int nrecs;
int varID, levelID;
char varname[CDI_MAX_NAME];
@@ -139,7 +139,7 @@ void *Merstat(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
if ( needWeights && field1.grid != lastgrid )
{
@@ -160,7 +160,7 @@ void *Merstat(void *argument)
merfun(field1, &field2, operfunc);
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, field2.ptr, (int)field2.nmiss);
+ pstreamWriteRecord(streamID2, field2.ptr, field2.nmiss);
}
tsID++;
diff --git a/src/Monarith.cc b/src/Monarith.cc
index 9e3426f..a32c39f 100644
--- a/src/Monarith.cc
+++ b/src/Monarith.cc
@@ -35,7 +35,7 @@ void *Monarith(void *argument)
int nrecs, nrecs2, nlev;
int varID, levelID;
int offset;
- int nmiss;
+ size_t nmiss;
int yearmon2 = -1;
cdoInitialize(argument);
@@ -76,14 +76,14 @@ void *Monarith(void *argument)
int nvars = vlistNvars(vlistID2);
double **vardata2 = (double **) Malloc(nvars*sizeof(double *));
- int **varnmiss2 = (int **) Malloc(nvars*sizeof(int *));
+ size_t **varnmiss2 = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
vardata2[varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss2[varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss2[varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
int tsID = 0;
@@ -138,7 +138,7 @@ void *Monarith(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field1.missval = vlistInqVarMissval(vlistID1, varID);
@@ -152,7 +152,7 @@ void *Monarith(void *argument)
farfun(&field1, field2, operfunc);
pstreamDefRecord(streamID3, varID, levelID);
- pstreamWriteRecord(streamID3, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID3, field1.ptr, field1.nmiss);
}
tsID++;
diff --git a/src/Mrotuv.cc b/src/Mrotuv.cc
index bbb9f6a..d345b8a 100644
--- a/src/Mrotuv.cc
+++ b/src/Mrotuv.cc
@@ -194,7 +194,7 @@ void *Mrotuv(void *argument)
int nrecs;
int levelID;
int varID, varid;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
int uid = -1, vid = -1;
cdoInitialize(argument);
@@ -228,7 +228,7 @@ void *Mrotuv(void *argument)
int gridID1 = vlistInqVarGrid(vlistID1, uid);
int gridID2 = vlistInqVarGrid(vlistID1, vid);
- int gridsize = gridInqSize(gridID1);
+ size_t gridsize = gridInqSize(gridID1);
if ( gridID1 != gridID2 ) cdoAbort("Input grids differ!");
if ( gridInqType(gridID1) != GRID_LONLAT &&
@@ -241,8 +241,8 @@ void *Mrotuv(void *argument)
if ( gridsize != gridInqSize(gridID1) ) cdoAbort("Internal problem: gridsize changed!");
- int nlon = gridInqXsize(gridID1);
- int nlat = gridInqYsize(gridID1);
+ size_t nlon = gridInqXsize(gridID1);
+ size_t nlat = gridInqYsize(gridID1);
double *grid1x = (double*) Malloc(gridsize*sizeof(double));
double *grid1y = (double*) Malloc(gridsize*sizeof(double));
@@ -251,7 +251,7 @@ void *Mrotuv(void *argument)
double *gridvx = (double*) Malloc(gridsize*sizeof(double));
double *gridvy = (double*) Malloc(gridsize*sizeof(double));
- int gridsizex = (nlon+2)*nlat;
+ size_t gridsizex = (nlon+2)*nlat;
gridInqXvals(gridID1, grid1x);
gridInqYvals(gridID1, grid1y);
@@ -281,7 +281,7 @@ void *Mrotuv(void *argument)
gridDefXvals(gridIDv, gridvx);
gridDefYvals(gridIDv, gridvy);
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
grid1x[i] *= DEG2RAD;
grid1y[i] *= DEG2RAD;
@@ -349,7 +349,7 @@ void *Mrotuv(void *argument)
/* remove missing values */
if ( nmiss1 || nmiss2 )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( DBL_IS_EQUAL(urfield[levelID][i], missval1) ) urfield[levelID][i] = 0;
if ( DBL_IS_EQUAL(vrfield[levelID][i], missval2) ) vrfield[levelID][i] = 0;
@@ -361,15 +361,15 @@ void *Mrotuv(void *argument)
rotate_uv(urfield[levelID], vrfield[levelID], nlon, nlat, grid1x, grid1y, ufield, vfield);
/* load to a help field */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
uhelp[IX2D(j,i+1,nlon+2)] = ufield[IX2D(j,i,nlon)];
vhelp[IX2D(j,i+1,nlon+2)] = vfield[IX2D(j,i,nlon)];
}
/* make help field cyclic */
- for ( int j = 0; j < nlat; j++ )
+ for ( size_t j = 0; j < nlat; j++ )
{
uhelp[IX2D(j,0,nlon+2)] = uhelp[IX2D(j,nlon,nlon+2)];
uhelp[IX2D(j,nlon+1,nlon+2)] = uhelp[IX2D(j,1,nlon+2)];
@@ -378,19 +378,19 @@ void *Mrotuv(void *argument)
}
/* interpolate on u/v points */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
ufield[IX2D(j,i,nlon)] = (uhelp[IX2D(j,i+1,nlon+2)]+uhelp[IX2D(j,i+2,nlon+2)])*0.5;
}
- for ( int j = 0; j < nlat-1; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat-1; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
vfield[IX2D(j,i,nlon)] = (vhelp[IX2D(j,i+1,nlon+2)]+vhelp[IX2D(j+1,i+1,nlon+2)])*0.5;
}
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
vfield[IX2D(nlat-1,i,nlon)] = vhelp[IX2D(nlat-1,i+1,nlon+2)];
}
diff --git a/src/Mrotuvb.cc b/src/Mrotuvb.cc
index 8fdd986..6c5b8ad 100644
--- a/src/Mrotuvb.cc
+++ b/src/Mrotuvb.cc
@@ -151,26 +151,26 @@ void rotate_uv2(double *u_i, double *v_j, int ix, int iy,
static
-void uv_to_p_grid(int nlon, int nlat, double *grid1x, double *grid1y,
+void uv_to_p_grid(size_t nlon, size_t nlat, double *grid1x, double *grid1y,
double *grid2x, double *grid2y, double *grid3x, double *grid3y)
{
double gx, gy;
double gx2, gy2;
- int gridsizex = (nlon+2)*nlat;
+ size_t gridsizex = (nlon+2)*nlat;
double *gxhelp = (double*) Malloc(gridsizex*sizeof(double));
double *gyhelp = (double*) Malloc(gridsizex*sizeof(double));
/* load to a help field */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
gxhelp[IX2D(j,i+1,nlon+2)] = grid1x[IX2D(j,i,nlon)];
gyhelp[IX2D(j,i+1,nlon+2)] = grid1y[IX2D(j,i,nlon)];
}
/* make help field cyclic */
- for ( int j = 0; j < nlat; j++ )
+ for ( size_t j = 0; j < nlat; j++ )
{
gxhelp[IX2D(j,0,nlon+2)] = gxhelp[IX2D(j,nlon,nlon+2)];
gxhelp[IX2D(j,nlon+1,nlon+2)] = gxhelp[IX2D(j,1,nlon+2)];
@@ -179,8 +179,8 @@ void uv_to_p_grid(int nlon, int nlat, double *grid1x, double *grid1y,
}
/* interpolate u to scalar points */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
grid3x[IX2D(j,i,nlon)] = (gxhelp[IX2D(j,i,nlon+2)]+gxhelp[IX2D(j,i+1,nlon+2)])*0.5;
if ( (gxhelp[IX2D(j,i,nlon+2)] > 340 && gxhelp[IX2D(j,i+1,nlon+2)] < 20) ||
@@ -196,15 +196,15 @@ void uv_to_p_grid(int nlon, int nlat, double *grid1x, double *grid1y,
}
/* load to a help field */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
gxhelp[IX2D(j,i+1,nlon+2)] = grid2x[IX2D(j,i,nlon)];
gyhelp[IX2D(j,i+1,nlon+2)] = grid2y[IX2D(j,i,nlon)];
}
/* make help field cyclic */
- for ( int j = 0; j < nlat; j++ )
+ for ( size_t j = 0; j < nlat; j++ )
{
gxhelp[IX2D(j,0,nlon+2)] = gxhelp[IX2D(j,nlon,nlon+2)];
gxhelp[IX2D(j,nlon+1,nlon+2)] = gxhelp[IX2D(j,1,nlon+2)];
@@ -213,8 +213,8 @@ void uv_to_p_grid(int nlon, int nlat, double *grid1x, double *grid1y,
}
/* interpolate v to scalar points */
- for ( int j = 1; j < nlat-1; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 1; j < nlat-1; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
gx = (gxhelp[IX2D(j,i+1,nlon+2)]+gxhelp[IX2D(j-1,i+1,nlon+2)])*0.5;
if ( (gxhelp[IX2D(j,i+1,nlon+2)] > 340 && gxhelp[IX2D(j-1,i+1,nlon+2)] < 20) ||
@@ -258,7 +258,7 @@ void *Mrotuvb(void *argument)
int nrecs, nrecs2;
int levelID;
int varID1, varID2;
- int nmiss1, nmiss2;
+ size_t nmiss1, nmiss2;
bool gpint = true;
cdoInitialize(argument);
@@ -279,9 +279,9 @@ void *Mrotuvb(void *argument)
int gridID1 = vlistGrid(vlistID1, 0);
int gridID2 = vlistGrid(vlistID2, 0);
- int gridsize = gridInqSize(gridID1);
- if ( gpint == TRUE && gridID1 == gridID2 ) cdoAbort("Input grids are the same, use parameter >noint< to disable interpolation!");
- if ( gpint == FALSE && gridID1 != gridID2 ) cdoAbort("Input grids are not the same!");
+ size_t gridsize = gridInqSize(gridID1);
+ if ( gpint == true && gridID1 == gridID2 ) cdoAbort("Input grids are the same, use parameter >noint< to disable interpolation!");
+ if ( gpint == false && gridID1 != gridID2 ) cdoAbort("Input grids are not the same!");
if ( gridsize != gridInqSize(gridID2) ) cdoAbort("Grids have different size!");
if ( gridInqType(gridID1) != GRID_LONLAT &&
@@ -299,8 +299,8 @@ void *Mrotuvb(void *argument)
if ( gridsize != gridInqSize(gridID2) ) cdoAbort("Internal problem: gridsize changed!");
- int nlon = gridInqXsize(gridID1);
- int nlat = gridInqYsize(gridID1);
+ size_t nlon = gridInqXsize(gridID1);
+ size_t nlat = gridInqYsize(gridID1);
double *grid1x = (double*) Malloc(gridsize*sizeof(double));
double *grid1y = (double*) Malloc(gridsize*sizeof(double));
@@ -355,7 +355,7 @@ void *Mrotuvb(void *argument)
gridDefXvals(gridID3, grid3x);
gridDefYvals(gridID3, grid3y);
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
grid3x[i] *= DEG2RAD;
grid3y[i] *= DEG2RAD;
@@ -393,7 +393,7 @@ void *Mrotuvb(void *argument)
double *uhelp = NULL, *vhelp = NULL;
if ( gpint )
{
- int gridsizex = (nlon+2)*nlat;
+ size_t gridsizex = (nlon+2)*nlat;
uhelp = (double*) Malloc(gridsizex*sizeof(double));
vhelp = (double*) Malloc(gridsizex*sizeof(double));
}
@@ -420,7 +420,7 @@ void *Mrotuvb(void *argument)
/* remove missing values */
if ( nmiss1 || nmiss2 )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( DBL_IS_EQUAL(ufield[i], missval1) ) ufield[i] = 0;
if ( DBL_IS_EQUAL(vfield[i], missval2) ) vfield[i] = 0;
@@ -430,15 +430,15 @@ void *Mrotuvb(void *argument)
if ( gpint )
{
/* load to a help field */
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
uhelp[IX2D(j,i+1,nlon+2)] = ufield[IX2D(j,i,nlon)];
vhelp[IX2D(j,i+1,nlon+2)] = vfield[IX2D(j,i,nlon)];
}
/* make help field cyclic */
- for ( int j = 0; j < nlat; j++ )
+ for ( size_t j = 0; j < nlat; j++ )
{
uhelp[IX2D(j,0,nlon+2)] = uhelp[IX2D(j,nlon,nlon+2)];
uhelp[IX2D(j,nlon+1,nlon+2)] = uhelp[IX2D(j,1,nlon+2)];
@@ -447,15 +447,15 @@ void *Mrotuvb(void *argument)
}
/* interpolate on pressure points */
- for ( int j = 1; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 1; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
ufield[IX2D(j,i,nlon)] = (uhelp[IX2D(j,i,nlon+2)]+uhelp[IX2D(j,i+1,nlon+2)])*0.5;
vfield[IX2D(j,i,nlon)] = (vhelp[IX2D(j-1,i+1,nlon+2)]+vhelp[IX2D(j,i+1,nlon+2)])*0.5;
}
}
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
ufield[IX2D(0,i,nlon)] = 0;
vfield[IX2D(0,i,nlon)] = 0;
diff --git a/src/NCL_wind.cc b/src/NCL_wind.cc
new file mode 100644
index 0000000..6839f00
--- /dev/null
+++ b/src/NCL_wind.cc
@@ -0,0 +1,328 @@
+/*
+ This file is part of CDO. CDO is a collection of Operators to
+ manipulate and analyse Climate model Data.
+
+ Copyright (C) 2003-2017 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+ See COPYING file for copying and redistribution conditions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+*/
+
+#include <limits.h>
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+#include "libncl.h"
+
+static
+void uv2dv_cfd_W(double missval, double *u, double *v, double *lon, double *lat, size_t nlon, size_t nlat, size_t nlev, int boundOpt, double *div)
+{
+ int ierror;
+
+ // Test dimension sizes.
+ if ( (nlon > INT_MAX) || (nlat > INT_MAX) )
+ cdoAbort("nlat and/or nlon is greater than INT_MAX!");
+
+ int inlon = (int) nlon;
+ int inlat = (int) nlat;
+
+ size_t gridsize_uv = nlat * nlon;
+
+ for ( size_t k = 0; k < nlev; ++k )
+ {
+ double *tmp_u = u + k*gridsize_uv;
+ double *tmp_v = v + k*gridsize_uv;
+ double *tmp_div = div + k*gridsize_uv;
+ // Init output array.
+ memset(tmp_div, 0, gridsize_uv*sizeof(double));
+ // Call the Fortran routine.
+#ifdef HAVE_CF_INTERFACE
+ DDVFIDF(tmp_u, tmp_v, lat, lon, inlon, inlat, missval, boundOpt, tmp_div, ierror);
+#else
+ cdoAbort("Fortran support not compiled in!");
+#endif
+ }
+}
+
+static
+void uv2vr_cfd_W(double missval, double *u, double *v, double *lon, double *lat, size_t nlon, size_t nlat, size_t nlev, int boundOpt, double *vort)
+{
+ int ierror;
+
+ // Test dimension sizes.
+ if ( (nlon > INT_MAX) || (nlat > INT_MAX) )
+ cdoAbort("nlat and/or nlon is greater than INT_MAX!");
+
+ int inlon = (int) nlon;
+ int inlat = (int) nlat;
+
+ size_t gridsize_uv = nlat * nlon;
+
+ for ( size_t k = 0; k < nlev; ++k )
+ {
+ double *tmp_u = u + k*gridsize_uv;
+ double *tmp_v = v + k*gridsize_uv;
+ double *tmp_vort = vort + k*gridsize_uv;
+ // Init output array.
+ memset(tmp_vort, 0, gridsize_uv*sizeof(double));
+ // Call the Fortran routine.
+#ifdef HAVE_CF_INTERFACE
+ DVRFIDF(tmp_u, tmp_v, lat, lon, inlon, inlat, missval, boundOpt, tmp_vort, ierror);
+#else
+ cdoAbort("Fortran support not compiled in!");
+#endif
+ }
+}
+
+static
+int find_name(int vlistID, char *name)
+{
+ char varname[CDI_MAX_NAME];
+
+ int nvars = vlistNvars(vlistID);
+ for ( int varID = 0; varID < nvars; ++varID )
+ {
+ vlistInqVarName(vlistID, varID, varname);
+ if ( STR_IS_EQ(name, varname) ) return varID;
+ }
+
+ return CDI_UNDEFID;
+}
+
+enum OUTMODE {OUTMODE_NEW, OUTMODE_APPEND, OUTMODE_REPLACE};
+
+// Parameter
+int outMode = OUTMODE_NEW;
+int boundOpt = -1;
+char name_u[CDI_MAX_NAME], name_v[CDI_MAX_NAME];
+
+static
+void print_parameter(void)
+{
+ cdoPrint("u=%s, v=%s, boundOpt=%d, outMode=%s", name_u, name_v, boundOpt,
+ outMode==OUTMODE_NEW?"new":outMode==OUTMODE_APPEND?"append":"replace");
+}
+
+static
+void set_parameter(void)
+{
+ strcpy(name_u, "u");
+ strcpy(name_v, "v");
+
+ int pargc = operatorArgc();
+ if ( pargc )
+ {
+ char **pargv = operatorArgv();
+
+ list_t *kvlist = list_new(sizeof(keyValues_t *), free_keyval, "PARAMETER");
+ if ( kvlist_parse_cmdline(kvlist, pargc, pargv) != 0 ) cdoAbort("Parse error!");
+ if ( cdoVerbose ) kvlist_print(kvlist);
+
+ for ( listNode_t *kvnode = kvlist->head; kvnode; kvnode = kvnode->next )
+ {
+ keyValues_t *kv = *(keyValues_t **)kvnode->data;
+ const char *key = kv->key;
+ if ( kv->nvalues > 1 ) cdoAbort("Too many values for parameter key >%s<!", key);
+ if ( kv->nvalues < 1 ) cdoAbort("Missing value for parameter key >%s<!", key);
+ const char *value = kv->values[0];
+
+ if ( STR_IS_EQ(key, "u") ) strcpy(name_u, value);
+ else if ( STR_IS_EQ(key, "v") ) strcpy(name_v, value);
+ else if ( STR_IS_EQ(key, "boundOpt") ) boundOpt = parameter2int(value);
+ else if ( STR_IS_EQ(key, "outMode") )
+ {
+ if ( STR_IS_EQ(value, "new") ) outMode = OUTMODE_NEW;
+ else if ( STR_IS_EQ(value, "append") ) outMode = OUTMODE_APPEND;
+ else if ( STR_IS_EQ(value, "replace") ) outMode = OUTMODE_REPLACE;
+ else cdoAbort("Invalid parameter key value: outMode=%s (valid are: new/append/replace)", value);
+ }
+ else cdoAbort("Invalid parameter key >%s<!", key);
+ }
+
+ list_destroy(kvlist);
+ }
+
+ if ( cdoVerbose ) print_parameter();
+}
+
+
+void *NCL_wind(void *argument)
+{
+ int nrecs;
+ int varID, levelID;
+ size_t nmiss;
+
+ cdoInitialize(argument);
+
+ int UV2DV_CFD = cdoOperatorAdd("uv2dv_cfd", 0, 0, "[u, v, boundsOpt, outMode]");
+ int UV2VR_CFD = cdoOperatorAdd("uv2vr_cfd", 0, 0, "[u, v, boundsOpt, outMode]");
+
+ int operatorID = cdoOperatorID();
+
+ set_parameter();
+
+ int streamID1 = pstreamOpenRead(cdoStreamName(0));
+
+ int vlistID1 = pstreamInqVlist(streamID1);
+ int vlistID2 = CDI_UNDEFID;
+ if ( outMode == OUTMODE_NEW )
+ vlistID2 = vlistCreate();
+ else if ( outMode == OUTMODE_APPEND )
+ vlistID2 = vlistDuplicate(vlistID1);
+ else
+ cdoAbort("outMode=%d unsupported!", outMode);
+
+ int varIDu = find_name(vlistID1, name_u);
+ int varIDv = find_name(vlistID1, name_v);
+
+ if ( varIDu == CDI_UNDEFID ) cdoAbort("%s not found!", name_u);
+ if ( varIDv == CDI_UNDEFID ) cdoAbort("%s not found!", name_v);
+
+ int gridIDu = vlistInqVarGrid(vlistID1, varIDu);
+ int gridIDv = vlistInqVarGrid(vlistID1, varIDv);
+ int gridtype = gridInqType(gridIDu);
+ size_t gridsizeuv = gridInqSize(gridIDu);
+
+ if ( !((gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN) && gridtype == gridInqType(gridIDv)) )
+ cdoAbort("u and v must be on a regular lonlat or Gaussian grid!");
+
+ if ( !(gridsizeuv == gridInqSize(gridIDv)) )
+ cdoAbort("u and v must have the same grid size!");
+
+ if ( boundOpt == -1 ) boundOpt = gridIsCircular(gridIDu) ? 1 : 0;
+ if ( cdoVerbose ) print_parameter();
+ if ( boundOpt < 0 || boundOpt > 3 ) cdoAbort("Parameter boundOpt=%d out of bounds (0-3)!", boundOpt);
+
+ size_t nlon = gridInqXsize(gridIDu);
+ size_t nlat = gridInqYsize(gridIDu);
+
+ int zaxisIDu = vlistInqVarZaxis(vlistID1, varIDu);
+ int nlev = zaxisInqSize(zaxisIDu);
+
+ if ( nlev != zaxisInqSize(vlistInqVarZaxis(vlistID1, varIDv)) )
+ cdoAbort("u and v must have the same number of level!");
+
+
+ double missvalu = vlistInqVarMissval(vlistID1, varIDu);
+ double missvalv = vlistInqVarMissval(vlistID1, varIDv);
+
+ int timetype = vlistInqVarTimetype(vlistID1, varIDu);
+ int varIDo = vlistDefVar(vlistID2, gridIDu, zaxisIDu, timetype);
+ if ( operatorID == UV2DV_CFD )
+ {
+ vlistDefVarName(vlistID2, varIDo, "d");
+ vlistDefVarLongname(vlistID2, varIDo, "divergence");
+ vlistDefVarUnits(vlistID2, varIDo, "1/s");
+ }
+ else if ( operatorID == UV2VR_CFD )
+ {
+ vlistDefVarName(vlistID2, varIDo, "vo");
+ vlistDefVarLongname(vlistID2, varIDo, "vorticity");
+ vlistDefVarUnits(vlistID2, varIDo, "1/s");
+ }
+
+ vlistDefVarMissval(vlistID2, varIDo, missvalu);
+
+ double *lon = (double*) Malloc(nlon*sizeof(double));
+ double *lat = (double*) Malloc(nlat*sizeof(double));
+
+ gridInqXvals(gridIDu, lon);
+ gridInqYvals(gridIDu, lat);
+
+ int taxisID1 = vlistInqTaxis(vlistID1);
+ int taxisID2 = taxisDuplicate(taxisID1);
+ vlistDefTaxis(vlistID2, taxisID2);
+
+ int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+ pstreamDefVlist(streamID2, vlistID2);
+
+ size_t gridsizemax = vlistGridsizeMax(vlistID1);
+ double *array = (double*) Malloc(gridsizemax*sizeof(double));
+ double *arrayu = (double*) Malloc(nlev*gridsizeuv*sizeof(double));
+ double *arrayv = (double*) Malloc(nlev*gridsizeuv*sizeof(double));
+ double *arrayo = (double*) Malloc(nlev*gridsizeuv*sizeof(double));
+
+ int tsID = 0;
+ while ( (nrecs = pstreamInqTimestep(streamID1, tsID)) )
+ {
+ size_t nmissu = 0, nmissv = 0;
+
+ taxisCopyTimestep(taxisID2, taxisID1);
+ pstreamDefTimestep(streamID2, tsID);
+
+ for ( int recID = 0; recID < nrecs; recID++ )
+ {
+ pstreamInqRecord(streamID1, &varID, &levelID);
+ pstreamReadRecord(streamID1, array, &nmiss);
+
+ if ( varID == varIDu || varID == varIDv )
+ {
+ if ( varID == varIDu ) { memcpy(arrayu+levelID*gridsizeuv, array, gridsizeuv*sizeof(double)); nmissu += nmiss; }
+ if ( varID == varIDv ) { memcpy(arrayv+levelID*gridsizeuv, array, gridsizeuv*sizeof(double)); nmissv += nmiss; }
+ }
+
+ if ( outMode == OUTMODE_APPEND )
+ {
+ pstreamDefRecord(streamID2, varID, levelID);
+ pstreamWriteRecord(streamID2, array, nmiss);
+ }
+ }
+
+ if ( nmissu != nmissv )
+ {
+ cdoAbort("u and v have different number of missing values!");
+ if ( nmissu > 0 && !DBL_IS_EQUAL(missvalu, missvalv) )
+ {
+ for ( levelID = 0; levelID < nlev; ++levelID )
+ {
+ double *parray = arrayv+levelID*gridsizeuv;
+ for ( size_t i = 0; i < gridsizeuv; ++i )
+ if ( DBL_IS_EQUAL(parray[i], missvalv) ) parray[i] = missvalu;
+
+ }
+ }
+ }
+
+ if ( operatorID == UV2DV_CFD )
+ uv2dv_cfd_W(missvalu, arrayu, arrayv, lon, lat, nlon, nlat, nlev, boundOpt, arrayo);
+ else if ( operatorID == UV2VR_CFD )
+ uv2vr_cfd_W(missvalu, arrayu, arrayv, lon, lat, nlon, nlat, nlev, boundOpt, arrayo);
+
+ for ( levelID = 0; levelID < nlev; ++levelID )
+ {
+ double *parray = arrayo+levelID*gridsizeuv;
+ nmiss = 0;
+ for ( size_t i = 0; i < gridsizeuv; ++i )
+ if ( DBL_IS_EQUAL(parray[i], missvalu) ) nmiss++;
+
+ pstreamDefRecord(streamID2, varIDo, levelID);
+ pstreamWriteRecord(streamID2, parray, nmiss);
+ }
+
+ tsID++;
+ }
+
+ pstreamClose(streamID1);
+ pstreamClose(streamID2);
+
+ vlistDestroy(vlistID2);
+
+ if ( array ) Free(array);
+ if ( arrayu ) Free(arrayu);
+ if ( arrayv ) Free(arrayv);
+ if ( arrayo ) Free(arrayo);
+
+ cdoFinish();
+
+ return 0;
+}
diff --git a/src/Output.cc b/src/Output.cc
index a9844c9..439ab32 100644
--- a/src/Output.cc
+++ b/src/Output.cc
@@ -40,7 +40,7 @@ void *Output(void *argument)
int gridID;
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
int nelem = 1;
int len;
int index;
diff --git a/src/Outputgmt.cc b/src/Outputgmt.cc
index ffb4d60..6613076 100644
--- a/src/Outputgmt.cc
+++ b/src/Outputgmt.cc
@@ -204,7 +204,7 @@ void *Outputgmt(void *argument)
int gridsize2 = 0;
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
int ninc = 1;
bool lzon = false, lmer = false, lhov = false;
bool lgrid_gen_bounds = false, luse_grid_corner = false;
diff --git a/src/Pack.cc b/src/Pack.cc
index 1c69646..b0c0b6a 100644
--- a/src/Pack.cc
+++ b/src/Pack.cc
@@ -85,7 +85,7 @@ void *Pack(void *argument)
int nrecs;
int gridID, varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
int datatype = CDI_DATATYPE_INT16;
dtlist_type *dtlist = dtlist_new();
diff --git a/src/Pardup.cc b/src/Pardup.cc
index ce8bce3..8fc0885 100644
--- a/src/Pardup.cc
+++ b/src/Pardup.cc
@@ -34,7 +34,7 @@ void *Pardup(void *argument)
int varID, varID2, levelID;
long offset;
int nmul = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
double *single;
@@ -75,14 +75,14 @@ void *Pardup(void *argument)
int gridsize = vlistGridsizeMax(vlistID1);
double *array = (double*) Malloc(gridsize*sizeof(double));
double **vardata = (double **) Malloc(nvars*sizeof(double *));
- int **varnmiss = (int **) Malloc(nvars*sizeof(int *));
+ size_t **varnmiss = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
vardata[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
}
for ( int i = 1; i < nmul; i++ )
diff --git a/src/Pinfo.cc b/src/Pinfo.cc
index 4b402ed..fe69976 100644
--- a/src/Pinfo.cc
+++ b/src/Pinfo.cc
@@ -33,8 +33,8 @@ void *Pinfo(void *argument)
int varID;
int nrecs;
int levelID;
- int nmiss;
- int ivals = 0, imiss = 0;
+ size_t nmiss, imiss = 0;
+ int ivals = 0;
char varname[CDI_MAX_NAME];
char vdatestr[32], vtimestr[32];
double level;
@@ -113,7 +113,7 @@ void *Pinfo(void *argument)
level = cdoZaxisInqLevel(zaxisID, levelID);
fprintf(stdout, " %7g ", level);
- fprintf(stdout, "%7d %7d :", gridsize, nmiss);
+ fprintf(stdout, "%7d %7zu :", gridsize, nmiss);
if ( gridInqType(gridID) == GRID_SPECTRAL ||
(gridsize == 1 && nmiss == 0) )
@@ -170,7 +170,7 @@ void *Pinfo(void *argument)
}
if ( imiss != nmiss && nmiss > 0 )
- fprintf(stdout, "Found %d of %d missing values!\n", imiss, nmiss);
+ fprintf(stdout, "Found %zu of %zu missing values!\n", imiss, nmiss);
}
for ( i = 0; i < gridsize; i++ ) array2[i] = array1[i];
diff --git a/src/Pressure.cc b/src/Pressure.cc
index 221e5a5..1aa0278 100644
--- a/src/Pressure.cc
+++ b/src/Pressure.cc
@@ -43,7 +43,7 @@ void *Pressure(void *argument)
int zaxisIDp, zaxisIDh = -1;
int nhlevf = 0, nhlevh = 0, nlevel = 0;
int nvct = 0;
- int nmiss;
+ size_t nmiss;
int psID = -1, lnpsID = -1;
char paramstr[32];
char varname[CDI_MAX_NAME];
diff --git a/src/Regres.cc b/src/Regres.cc
index 520d2b9..5702bc5 100644
--- a/src/Regres.cc
+++ b/src/Regres.cc
@@ -33,7 +33,7 @@ void *Regres(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
double temp1, temp2;
enum {nwork = 5};
field_type **work[nwork];
diff --git a/src/Remap.cc b/src/Remap.cc
index c0f622e..d1dcc3f 100644
--- a/src/Remap.cc
+++ b/src/Remap.cc
@@ -117,7 +117,7 @@ int maptype2operfunc(int map_type, int submap_type, int num_neighbors, int remap
}
static
-void print_remap_info(int operfunc, int remap_genweights, remapgrid_t *src_grid, remapgrid_t *tgt_grid, int nmiss)
+void print_remap_info(int operfunc, bool remap_genweights, remapgrid_t *src_grid, remapgrid_t *tgt_grid, size_t nmiss)
{
char line[256], tmpstr[256];
@@ -155,7 +155,7 @@ void print_remap_info(int operfunc, int remap_genweights, remapgrid_t *src_grid,
if ( nmiss > 0 )
{
- snprintf(tmpstr, sizeof(tmpstr), ", with source mask (%d)", gridInqSize(src_grid->gridID)-nmiss);
+ snprintf(tmpstr, sizeof(tmpstr), ", with source mask (%zu)", gridInqSize(src_grid->gridID)-nmiss);
strcat(line, tmpstr);
}
@@ -163,7 +163,7 @@ void print_remap_info(int operfunc, int remap_genweights, remapgrid_t *src_grid,
}
static
-void print_remap_warning(const char *remap_file, int operfunc, remapgrid_t *src_grid, int nmiss)
+void print_remap_warning(const char *remap_file, int operfunc, remapgrid_t *src_grid, size_t nmiss)
{
char line[256];
char tmpstr[256];
@@ -196,7 +196,7 @@ void print_remap_warning(const char *remap_file, int operfunc, remapgrid_t *src_
if ( nmiss > 0 )
{
- snprintf(tmpstr, sizeof(tmpstr), " with mask (%d)", gridInqSize(src_grid->gridID)-nmiss);
+ snprintf(tmpstr, sizeof(tmpstr), " with mask (%zu)", gridInqSize(src_grid->gridID)-nmiss);
strcat(line, tmpstr);
}
@@ -218,7 +218,7 @@ static bool lextrapolate = false;
int max_remaps = -1;
int sort_mode = HEAP_SORT;
double remap_frac_min = 0;
-int remap_genweights = TRUE;
+bool REMAP_genweights = true;
static
void get_remap_env(void)
@@ -417,19 +417,15 @@ void get_remap_env(void)
if ( *envstr )
{
if ( memcmp(envstr, "ON", 2) == 0 || memcmp(envstr, "on", 2) == 0 )
- {
- remap_genweights = TRUE;
- }
+ REMAP_genweights = true;
else if ( memcmp(envstr, "OFF", 3) == 0 || memcmp(envstr, "off", 3) == 0 )
- {
- remap_genweights = FALSE;
- }
+ REMAP_genweights = false;
else
cdoWarning("Environment variable CDO_REMAP_GENWEIGHTS has wrong value!");
if ( cdoVerbose )
{
- if ( remap_genweights == TRUE )
+ if ( REMAP_genweights )
cdoPrint("Generation of weights enabled!");
else
cdoPrint("Generation of weights disabled!");
@@ -775,20 +771,21 @@ void sort_remap_add(remapvars_t *remapvars)
void *Remap(void *argument)
{
+ bool remap_genweights = REMAP_genweights;
+ bool need_gradiants = false;
int streamID2 = -1;
int nrecs;
int varID, levelID;
size_t gridsize, gridsize2;
int gridID1 = -1, gridID2;
- int nmiss1, nmiss2;
- size_t i, j;
+ size_t nmiss1, nmiss2;
+ size_t j;
int r = -1;
int nremaps = 0;
int norm_opt = NORM_OPT_NONE;
int map_type = -1;
int submap_type = SUBMAP_TYPE_NONE;
int num_neighbors = 0;
- int need_gradiants = FALSE;
char varname[CDI_MAX_NAME];
double missval;
remap_t *remaps = NULL;
@@ -901,20 +898,17 @@ void *Remap(void *argument)
}
}
- if ( lwrite_remap || lremapxxx )
- remap_genweights = TRUE;
+ if ( lwrite_remap || lremapxxx ) remap_genweights = true;
if ( lremapxxx )
{
- size_t gridsize2;
-
read_remap_scrip(remap_file, gridID1, gridID2, &map_type, &submap_type, &num_neighbors,
&remap_order, &remaps[0].src_grid, &remaps[0].tgt_grid, &remaps[0].vars);
if ( remaps[0].vars.links_per_value == 0 ) links_per_value(&remaps[0].vars);
nremaps = 1;
- gridsize = remaps[0].src_grid.size;
+ size_t gridsize = remaps[0].src_grid.size;
remaps[0].gridID = gridID1;
remaps[0].gridsize = gridInqSize(gridID1);
@@ -934,7 +928,7 @@ void *Remap(void *argument)
if ( gridInqType(gridID1) == GRID_GME ) gridsize = remaps[0].src_grid.size;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( remaps[0].src_grid.mask[i] == FALSE )
remaps[0].nmiss++;
@@ -965,22 +959,22 @@ void *Remap(void *argument)
get_map_type(operfunc, &map_type, &submap_type, &num_neighbors, &remap_order);
}
- if ( remap_genweights == FALSE &&
+ if ( !remap_genweights &&
map_type != MAP_TYPE_BILINEAR && map_type != MAP_TYPE_BICUBIC &&
map_type != MAP_TYPE_DISTWGT && map_type != MAP_TYPE_CONSERV_YAC )
- remap_genweights = TRUE;
+ remap_genweights = true;
- remap_set_int(REMAP_GENWEIGHTS, remap_genweights);
+ remap_set_int(REMAP_GENWEIGHTS, (int)remap_genweights);
if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSERV_YAC ) norm_opt = get_norm_opt();
size_t grid1sizemax = vlistGridsizeMax(vlistID1);
- if ( map_type == MAP_TYPE_BICUBIC ) need_gradiants = TRUE;
+ if ( map_type == MAP_TYPE_BICUBIC ) need_gradiants = true;
if ( map_type == MAP_TYPE_CONSERV && remap_order == 2 )
{
if ( cdoVerbose ) cdoPrint("Second order remapping");
- need_gradiants = TRUE;
+ need_gradiants = true;
}
else
remap_order = 1;
@@ -1037,6 +1031,7 @@ void *Remap(void *argument)
if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = true;
if ( map_type == MAP_TYPE_DISTWGT && !remap_extrapolate && gridInqSize(gridID1) > 1 && !is_global_grid(gridID1) )
{
+ if ( cdoVerbose ) cdoPrint("---> Expand array!");
long nx = gridInqXsize(gridID1);
long ny = gridInqYsize(gridID1);
size_t gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
@@ -1045,13 +1040,6 @@ void *Remap(void *argument)
grid1sizemax = gridsize_new;
array1 = (double*) Realloc(array1, grid1sizemax*sizeof(double));
imask = (int*) Realloc(imask, grid1sizemax*sizeof(int));
-
- if ( need_gradiants )
- {
- grad1_lat = (double*) Realloc(grad1_lat, grid1sizemax*sizeof(double));
- grad1_lon = (double*) Realloc(grad1_lon, grid1sizemax*sizeof(double));
- grad1_latlon = (double*) Realloc(grad1_latlon, grid1sizemax*sizeof(double));
- }
}
for ( long j = ny-1; j >= 0; j-- )
@@ -1064,7 +1052,7 @@ void *Remap(void *argument)
nmiss1 += 4*(nx+2) + 4*(ny+2);
}
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
imask[i] = DBL_IS_EQUAL(array1[i], missval) ? FALSE : TRUE;
for ( r = nremaps-1; r >= 0; r-- )
@@ -1108,9 +1096,7 @@ void *Remap(void *argument)
if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = true;
remaps[r].src_grid.non_global = false;
if ( map_type == MAP_TYPE_DISTWGT && !remap_extrapolate && gridInqSize(gridID1) > 1 && !is_global_grid(gridID1) )
- {
- remaps[r].src_grid.non_global = true;
- }
+ remaps[r].src_grid.non_global = true;
/*
remaps[r].src_grid.luse_cell_area = FALSE;
remaps[r].tgt_grid.luse_cell_area = FALSE;
@@ -1152,7 +1138,7 @@ void *Remap(void *argument)
if ( gridInqType(gridID1) == GRID_GME )
{
j = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( remaps[r].src_grid.vgpm[i] ) imask[j++] = imask[i];
}
@@ -1196,7 +1182,7 @@ void *Remap(void *argument)
if ( gridInqType(gridID1) == GRID_GME )
{
j = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
if ( remaps[r].src_grid.vgpm[i] ) array1[j++] = array1[i];
}
@@ -1207,7 +1193,7 @@ void *Remap(void *argument)
if ( need_gradiants )
{
if ( remaps[r].src_grid.rank != 2 && remap_order == 2 )
- cdoAbort("Second order remapping is not only available for unstructured grids!");
+ cdoAbort("Second order remapping is not available for unstructured grids!");
remap_gradients(remaps[r].src_grid, array1, grad1_lat, grad1_lon, grad1_latlon);
}
@@ -1243,16 +1229,16 @@ void *Remap(void *argument)
if ( operfunc == REMAPSUM )
{
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
printf("1 %zd %g %g %g %g\n", i, array1[i], remaps[r].src_grid.cell_frac[i], remaps[r].src_grid.cell_area[i],remaps[r].src_grid.cell_frac[i]);
double array1sum = 0;
- for ( i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array1sum += remaps[r].src_grid.cell_area[i];
- for ( i = 0; i < gridsize2; i++ )
+ for ( size_t i = 0; i < gridsize2; i++ )
printf("2 %zd %g %g %g %g\n", i, array2[i], remaps[r].tgt_grid.cell_frac[i],remaps[r].tgt_grid.cell_area[i],remaps[r].tgt_grid.cell_frac[i]);
double array2sum = 0;
- for ( i = 0; i < gridsize2; i++ )
+ for ( size_t i = 0; i < gridsize2; i++ )
array2sum += remaps[r].tgt_grid.cell_area[i];
printf("array1sum %g, array2sum %g\n", array1sum, array2sum);
@@ -1275,14 +1261,14 @@ void *Remap(void *argument)
gridInqParamGME(gridID2, &nd, &ni, &ni2, &ni3);
j = remaps[r].tgt_grid.size;
- for ( i = gridsize2; i > 0 ; i-- )
+ for ( size_t i = gridsize2; i > 0 ; i-- )
if ( remaps[r].tgt_grid.vgpm[i-1] ) array2[i-1] = array2[--j];
gme_grid_restore(array2, ni, nd);
}
nmiss2 = 0;
- for ( i = 0; i < gridsize2; i++ )
+ for ( size_t i = 0; i < gridsize2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss2++;
SKIPVAR:
diff --git a/src/Remapeta.cc b/src/Remapeta.cc
index 83ce4d5..1ca6bb8 100644
--- a/src/Remapeta.cc
+++ b/src/Remapeta.cc
@@ -243,7 +243,7 @@ Remapeta(void *argument)
double *t1 = NULL, *q1 = NULL;
double *t2 = NULL, *q2 = NULL;
double *tscor = NULL, *pscor = NULL, *secor = NULL;
- int nmiss, nmissout = 0;
+ size_t nmiss, nmissout = 0;
bool ltq = false;
bool lfis2 = false;
int varids[MAX_VARS3D];
diff --git a/src/Replace.cc b/src/Replace.cc
index 39994c9..1785ab0 100644
--- a/src/Replace.cc
+++ b/src/Replace.cc
@@ -38,10 +38,10 @@ void *Replace(void *argument)
int nchvars = 0;
int idx;
char varname1[CDI_MAX_NAME], varname2[CDI_MAX_NAME];
- int nmiss;
+ size_t nmiss;
int varlist1[MAX_VARS], varlist2[MAX_VARS];
int **varlevel = NULL;
- int **varnmiss2 = NULL;
+ size_t **varnmiss2 = NULL;
double **vardata2 = NULL;
double *parray;
@@ -102,7 +102,7 @@ void *Replace(void *argument)
if ( nchvars )
{
vardata2 = (double **) Malloc(nchvars*sizeof(double *));
- varnmiss2 = (int **) Malloc(nchvars*sizeof(int *));
+ varnmiss2 = (size_t **) Malloc(nchvars*sizeof(size_t *));
varlevel = (int **) Malloc(nchvars*sizeof(int *));
for ( idx = 0; idx < nchvars; idx++ )
{
@@ -112,7 +112,7 @@ void *Replace(void *argument)
int nlevel2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
int gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
vardata2[idx] = (double*) Malloc(nlevel2*gridsize*sizeof(double));
- varnmiss2[idx] = (int*) Malloc(nlevel2*sizeof(int));
+ varnmiss2[idx] = (size_t*) Malloc(nlevel2*sizeof(size_t));
varlevel[idx] = (int*) Malloc(nlevel1*sizeof(int));
/*
for ( levelID = 0; levelID < nlevel1; levelID++ )
diff --git a/src/Replacevalues.cc b/src/Replacevalues.cc
index 06598b5..9dfb78c 100644
--- a/src/Replacevalues.cc
+++ b/src/Replacevalues.cc
@@ -34,7 +34,7 @@ void *Replacevalues(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nvals = 0;
lista_t *flista = lista_new(FLT_LISTA);
double *fltarr = NULL;
diff --git a/src/Rhopot.cc b/src/Rhopot.cc
index 694e118..c771873 100644
--- a/src/Rhopot.cc
+++ b/src/Rhopot.cc
@@ -155,7 +155,7 @@ void *Rhopot(void *argument)
int varID, levelID;
int zaxisID;
int offset;
- int nmiss;
+ size_t nmiss;
int toID = -1, saoID = -1, thoID = -1;
char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
double pin = -1;
diff --git a/src/Rotuv.cc b/src/Rotuv.cc
index c321972..5e24cfd 100644
--- a/src/Rotuv.cc
+++ b/src/Rotuv.cc
@@ -127,7 +127,7 @@ void *Rotuv(void *argument)
int *recVarID = (int*) Malloc(nrecs*sizeof(int));
int *recLevelID = (int*) Malloc(nrecs*sizeof(int));
- int **varnmiss = (int **) Malloc(nvars*sizeof(int *));
+ size_t **varnmiss = (size_t **) Malloc(nvars*sizeof(size_t *));
double **vardata = (double **) Malloc(nvars*sizeof(double *));
bool lfound[MAXARG];
@@ -164,7 +164,7 @@ void *Rotuv(void *argument)
gridsize = gridInqSize(gridID);
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
vardata[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
}
diff --git a/src/Runpctl.cc b/src/Runpctl.cc
index d1418ef..6e5c888 100644
--- a/src/Runpctl.cc
+++ b/src/Runpctl.cc
@@ -33,7 +33,7 @@ void *Runpctl(void *argument)
int timestat_date = TIMESTAT_MEAN;
int varID;
int levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Runstat.cc b/src/Runstat.cc
index 2f82511..6177567 100644
--- a/src/Runstat.cc
+++ b/src/Runstat.cc
@@ -40,7 +40,7 @@ void *Runstat(void *argument)
int timestat_date = TIMESTAT_MEAN;
int varID;
int levelID;
- int nmiss;
+ size_t nmiss;
int runstat_nomiss = 0;
cdoInitialize(argument);
diff --git a/src/Samplegrid.cc b/src/Samplegrid.cc
index 2a758e9..7282807 100644
--- a/src/Samplegrid.cc
+++ b/src/Samplegrid.cc
@@ -58,7 +58,7 @@ void *Samplegrid(void *argument)
int resampleFactor;
int subI0 = 0, subI1 = 0, subJ0 = 0, subJ1 = 0;
int index;
- int nmiss;
+ size_t nmiss;
typedef struct {
int gridSrcID, gridIDsampled;
int *cellidx, nvals;
diff --git a/src/Samplegridicon.cc b/src/Samplegridicon.cc
index d635608..8915b9d 100644
--- a/src/Samplegridicon.cc
+++ b/src/Samplegridicon.cc
@@ -14,19 +14,19 @@ extern "C" {
constexpr int MAX_CHILDS = 9;
typedef struct {
- int ncells;
- int *neighbor; // neighbor cell index
- int *parent; // parent cell index
- int *child; // child cell index
+ long ncells;
+ long *neighbor; // neighbor cell index
+ long *parent; // parent cell index
+ long *child; // child cell index
const char *filename;
} cellindex_type;
static
-void copy_data_to_index(int ncells, const double *restrict data, int *restrict cellindex)
+void copy_data_to_index(long ncells, const double *restrict data, long *restrict cellindex)
{
- for ( int i = 0; i < ncells; ++i )
- cellindex[i] = (int) lround(data[i]);
+ for ( long i = 0; i < ncells; ++i )
+ cellindex[i] = lround(data[i]);
}
static
@@ -75,14 +75,14 @@ cellindex_type *read_cellindex(const char *filename)
if ( pid == CDI_UNDEFID ) cdoAbort("parent_cell_index not found in %s!", filename);
// if ( cid == CDI_UNDEFID ) cdoAbort("child_cell_index not found in %s!", filename);
- int ncells = gridInqSize(gridID);
+ long ncells = gridInqSize(gridID);
cellindex_type *cellindex = (cellindex_type*) Malloc(sizeof(cellindex_type));
cellindex->ncells = ncells;
cellindex->neighbor = NULL;
- // cellindex->neighbor = (int*) Malloc(3*ncells*sizeof(int));
- cellindex->parent = (int*) Malloc( ncells*sizeof(int));
+ // cellindex->neighbor = (long*) Malloc(3*ncells*sizeof(long));
+ cellindex->parent = (long*) Malloc( ncells*sizeof(long));
cellindex->child = NULL;
// cellindex->child = (cid != CDI_UNDEFID) ? (int*) Malloc(MAX_CHILDS*ncells*sizeof(int)) : NULL;
double *data = (double *) Malloc(ncells*sizeof(double));
@@ -90,7 +90,8 @@ cellindex_type *read_cellindex(const char *filename)
int nrecs = streamInqTimestep(streamID, 0);
for ( int recID = 0; recID < nrecs; recID++ )
{
- int varID, levelID, nmiss;
+ int varID, levelID;
+ size_t nmiss;
streamInqRecord(streamID, &varID, &levelID);
if ( varID == pid /* || varID == nid || varID == cid */ )
{
@@ -102,8 +103,8 @@ cellindex_type *read_cellindex(const char *filename)
}
// Fortran to C index
- for ( int i = 0; i < ncells; ++i ) cellindex->parent[i] -= 1;
- // for ( int i = 0; i < 3*ncells; ++i ) cellindex->neighbor[i] -= 1;
+ for ( long i = 0; i < ncells; ++i ) cellindex->parent[i] -= 1;
+ // for ( long i = 0; i < 3*ncells; ++i ) cellindex->neighbor[i] -= 1;
streamClose(streamID);
@@ -149,11 +150,11 @@ int read_grid(const char *filename)
* @param search the element to find a position for
*/
static
-int find_index(int search, int n, const int *restrict array)
+long find_index(int search, long n, const long *restrict array)
{
- int first = 0;
- int last = n - 1;
- int middle = (first+last)/2;
+ long first = 0;
+ long last = n - 1;
+ long middle = (first+last)/2;
while ( first <= last )
{
@@ -161,7 +162,7 @@ int find_index(int search, int n, const int *restrict array)
first = middle + 1;
else if ( array[middle] == search )
{
- for ( int i = middle; i >= 0; i-- )
+ for ( long i = middle; i >= 0; i-- )
{
if ( array[i] == search ) middle = i;
else break;
@@ -199,23 +200,23 @@ int cmpsinfo(const void *s1, const void *s2)
static
void compute_child_from_parent(cellindex_type *cellindex1, cellindex_type *cellindex2)
{
- int ncells1 = cellindex1->ncells;
- int *parent1 = cellindex1->parent;
+ long ncells1 = cellindex1->ncells;
+ long *parent1 = cellindex1->parent;
- int *idx1 = (int*) Malloc(ncells1*sizeof(int));
- for ( int i = 0; i < ncells1; ++i ) idx1[i] = i;
- for ( int i = 1; i < ncells1; ++i )
+ long *idx1 = (long*) Malloc(ncells1*sizeof(long));
+ for ( long i = 0; i < ncells1; ++i ) idx1[i] = i;
+ for ( long i = 1; i < ncells1; ++i )
if ( parent1[i] < parent1[i-1] )
{
if ( cdoVerbose ) cdoPrint("Sort parent index of %s!", cellindex1->filename);
sinfo_t *sinfo = (sinfo_t*)Malloc(ncells1*sizeof(sinfo_t));
- for ( int j = 0; j < ncells1; ++j )
+ for ( long j = 0; j < ncells1; ++j )
{
sinfo[j].p = parent1[j];
sinfo[j].i = idx1[j];
}
qsort(sinfo, ncells1, sizeof(sinfo_t), cmpsinfo);
- for ( int j = 0; j < ncells1; ++j )
+ for ( long j = 0; j < ncells1; ++j )
{
parent1[j] = sinfo[j].p;
idx1[j] = sinfo[j].i;
@@ -224,15 +225,15 @@ void compute_child_from_parent(cellindex_type *cellindex1, cellindex_type *celli
break;
}
- int ncells2 = cellindex2->ncells;
- int *child2 = (int*) Malloc(MAX_CHILDS*ncells2*sizeof(int));
+ long ncells2 = cellindex2->ncells;
+ long *child2 = (long*) Malloc(MAX_CHILDS*ncells2*sizeof(long));
cellindex2->child = child2;
- for ( int i = 0; i< ncells2; ++i )
+ for ( long i = 0; i< ncells2; ++i )
{
- for ( int k = 0; k < MAX_CHILDS; ++k ) child2[i*MAX_CHILDS+k] = -1;
- int j = find_index(i, ncells1, parent1);
+ for ( long k = 0; k < MAX_CHILDS; ++k ) child2[i*MAX_CHILDS+k] = -1;
+ long j = find_index(i, ncells1, parent1);
if ( j < 0 ) continue;
- for ( int k = 0; k < MAX_CHILDS; ++k )
+ for ( long k = 0; k < MAX_CHILDS; ++k )
{
if ( i != parent1[j+k] ) break;
// child2[i*MAX_CHILDS+k] = j+k;
@@ -244,7 +245,7 @@ void compute_child_from_parent(cellindex_type *cellindex1, cellindex_type *celli
}
static
-void read_coordinates(const char *filename, int n, double *lon, double *lat, int nv, double *lon_bnds, double *lat_bnds)
+void read_coordinates(const char *filename, long n, double *lon, double *lat, int nv, double *lon_bnds, double *lat_bnds)
{
openLock();
int streamID = streamOpenRead(filename);
@@ -259,7 +260,7 @@ void read_coordinates(const char *filename, int n, double *lon, double *lat, int
{
gridID = vlistGrid(vlistID, index);
if ( gridInqType(gridID) == GRID_UNSTRUCTURED &&
- gridInqSize(gridID) == n &&
+ (long)gridInqSize(gridID) == n &&
gridInqNvertex(gridID) == 3 ) break;
}
@@ -299,8 +300,8 @@ int winding_numbers_algorithm(double cell_corners[], int number_corners, double
#define MAX_SEARCH 128 // the triangles are distorted!
static
-void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *grid_center_lon2, double *grid_center_lat2, double *grid_corner_lon2,
- double *grid_corner_lat2, int ncells1, double *grid_center_lon1, double *grid_center_lat1)
+void compute_child_from_bounds(cellindex_type *cellindex2, long ncells2, double *grid_center_lon2, double *grid_center_lat2, double *grid_corner_lon2,
+ double *grid_corner_lat2, long ncells1, double *grid_center_lon1, double *grid_center_lat1)
{
struct gridsearch *gs = gridsearch_create(ncells1, grid_center_lon1, grid_center_lat1);
size_t nbr_add[MAX_SEARCH]; // source address at nearest neighbors
@@ -313,9 +314,9 @@ void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *
double cell_corners_plane_projection[8];
double center_point_plane_projection[2];
- int *child2 = (int*) Malloc(MAX_CHILDS*ncells2*sizeof(int));
+ long *child2 = (long*) Malloc(MAX_CHILDS*ncells2*sizeof(long));
cellindex2->child = child2;
- for ( int cell_no2 = 0; cell_no2 < ncells2; ++cell_no2 )
+ for ( long cell_no2 = 0; cell_no2 < ncells2; ++cell_no2 )
{
for ( int k = 0; k < MAX_CHILDS; ++k ) child2[cell_no2*MAX_CHILDS+k] = -1;
@@ -377,7 +378,7 @@ void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *
for ( int i = 0; i < MAX_SEARCH; ++i )
{
size_t cell_no1 = nbr_add[i];
- if ( cell_no1 < ULONG_MAX )
+ if ( cell_no1 < SIZE_MAX )
{
LLtoXYZ(grid_center_lon1[cell_no1], grid_center_lat1[cell_no1], center_point_xyz);
@@ -401,7 +402,7 @@ void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *
if ( winding_number != 0 )
{
if ( k >= MAX_CHILDS ) cdoAbort("Internal problem, limit of MAX_CHILDS reached (limit=9).");
- child2[cell_no2*MAX_CHILDS+k++] = (int)cell_no1;
+ child2[cell_no2*MAX_CHILDS+k++] = (long)cell_no1;
}
}
}
@@ -412,8 +413,8 @@ void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *
static
void compute_child_from_coordinates(cellindex_type *cellindex1, cellindex_type *cellindex2)
{
- int ncells1 = cellindex1->ncells;
- int ncells2 = cellindex2->ncells;
+ long ncells1 = cellindex1->ncells;
+ long ncells2 = cellindex2->ncells;
double *lon1 = (double*) Malloc(ncells1*sizeof(double));
double *lat1 = (double*) Malloc(ncells1*sizeof(double));
@@ -439,10 +440,10 @@ static
void compute_child(cellindex_type *cellindex1, cellindex_type *cellindex2)
{
bool lparent = true;
- int ncells1 = cellindex1->ncells;
- int *parent1 = cellindex1->parent;
+ long ncells1 = cellindex1->ncells;
+ long *parent1 = cellindex1->parent;
{
- int i;
+ long i;
for ( i = 0; i < ncells1; ++i ) if ( parent1[i] >= 0 ) break;
if ( i == ncells1 ) lparent = false;
}
@@ -457,15 +458,15 @@ void compute_child(cellindex_type *cellindex1, cellindex_type *cellindex2)
}
static
-void compute_sum(int i, int *n, double *sum, double *sumq, int kci, cellindex_type **cellindex, double *array)
+void compute_sum(long i, long *n, double *sum, double *sumq, long kci, cellindex_type **cellindex, double *array)
{
// printf("compute: i, kci %d %d\n", i, kci);
- int ncells2 = cellindex[kci]->ncells;
- if ( i < 0 || i > ncells2 ) cdoAbort("Child grid cell index %d out of bounds %d!", i, ncells2);
+ long ncells2 = cellindex[kci]->ncells;
+ if ( i < 0 || i > ncells2 ) cdoAbort("Child grid cell index %ld out of bounds %ld!", i, ncells2);
for ( int k = 0; k < MAX_CHILDS; ++k )
{
- int index = cellindex[kci]->child[i*MAX_CHILDS+k];
+ long index = cellindex[kci]->child[i*MAX_CHILDS+k];
if ( index == -1 ) break;
if ( kci == 1 )
{
@@ -478,19 +479,19 @@ void compute_sum(int i, int *n, double *sum, double *sumq, int kci, cellindex_ty
}
static
-void samplegrid(double missval, int nci, cellindex_type **cellindex, double *array1, double *array2, double *array3)
+void samplegrid(double missval, long nci, cellindex_type **cellindex, double *array1, double *array2, double *array3)
{
static bool lstat = true;
- int kci = nci-1;
- int ncells2 = cellindex[kci]->ncells;
- int nx = 0;
+ long kci = nci-1;
+ long ncells2 = cellindex[kci]->ncells;
+ long nx = 0;
double x = 0;
#if defined(_OPENMP)
//#pragma omp parallel for default(none) shared(missval, ncells2, kci, cellindex, array1, array2, array3)
#endif
- for ( int i = 0; i < ncells2; ++i )
+ for ( long i = 0; i < ncells2; ++i )
{
- int n = 0;
+ long n = 0;
double sum = 0, sumq = 0;
compute_sum(i, &n, &sum, &sumq, kci, cellindex, array1);
array2[i] = n ? sum/n : missval; // mean
@@ -524,7 +525,7 @@ void *Samplegridicon(void *argument)
{
cellindex[i] = read_cellindex(operatorArgv()[i]);
cellindex[i]->filename = operatorArgv()[i];
- if ( cdoVerbose ) cdoPrint("Found %d grid cells in %s", cellindex[i]->ncells, cellindex[i]->filename);
+ if ( cdoVerbose ) cdoPrint("Found %ld grid cells in %s", cellindex[i]->ncells, cellindex[i]->filename);
}
for ( int i = 0; i < nsamplegrids-1; ++i )
@@ -536,10 +537,10 @@ void *Samplegridicon(void *argument)
int vlistID1 = pstreamInqVlist(streamID1);
- int gridsize = vlistGridsizeMax(vlistID1);
- if ( cdoVerbose ) cdoPrint("Source gridsize = %d", gridsize);
+ long gridsize = vlistGridsizeMax(vlistID1);
+ if ( cdoVerbose ) cdoPrint("Source gridsize = %zu", gridsize);
if ( gridsize != cellindex[0]->ncells )
- cdoAbort("Gridsize (%d) of input stream and first grid (%d) differ!", gridsize, cellindex[0]->ncells);
+ cdoAbort("Gridsize (%ls) of input stream and first grid (%ld) differ!", gridsize, cellindex[0]->ncells);
if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
double *array1 = (double *) Malloc(gridsize*sizeof(double));
@@ -570,8 +571,8 @@ void *Samplegridicon(void *argument)
int streamID3 = pstreamOpenWrite(cdoStreamName(2), cdoFiletype());
pstreamDefVlist(streamID3, vlistID3);
- int gridsize2 = gridInqSize(gridID2);
- if ( cdoVerbose ) cdoPrint("Target gridsize = %d", gridsize2);
+ long gridsize2 = gridInqSize(gridID2);
+ if ( cdoVerbose ) cdoPrint("Target gridsize = %ld", gridsize2);
if ( vlistNumber(vlistID2) != CDI_REAL ) gridsize2 *= 2;
double *array2 = (double *) Malloc(gridsize2*sizeof(double));
double *array3 = (double *) Malloc(gridsize2*sizeof(double));
@@ -586,7 +587,7 @@ void *Samplegridicon(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int nmiss;
+ size_t nmiss;
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss);
@@ -595,14 +596,14 @@ void *Samplegridicon(void *argument)
samplegrid(missval, nsamplegrids, cellindex.data(), array1, array2, array3);
nmiss = 0;
- for ( int i = 0; i < gridsize2; ++i )
+ for ( long i = 0; i < gridsize2; ++i )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
pstreamDefRecord(streamID2, varID, levelID);
pstreamWriteRecord(streamID2, array2, nmiss);
nmiss = 0;
- for ( int i = 0; i < gridsize2; ++i )
+ for ( long i = 0; i < gridsize2; ++i )
if ( DBL_IS_EQUAL(array3[i], missval) ) nmiss++;
pstreamDefRecord(streamID3, varID, levelID);
diff --git a/src/Seascount.cc b/src/Seascount.cc
index c504ec0..66b0469 100644
--- a/src/Seascount.cc
+++ b/src/Seascount.cc
@@ -34,7 +34,7 @@ void *Seascount(void *argument)
int vdate0 = 0, vtime0 = 0;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int year, month, day, seas0 = 0;
int oldmon = 0;
@@ -120,7 +120,7 @@ void *Seascount(void *argument)
}
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = vars1[varID][levelID].grid;
field.missval = vars1[varID][levelID].missval;
@@ -147,7 +147,7 @@ void *Seascount(void *argument)
if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, (int)vars1[varID][levelID].nmiss);
+ pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, vars1[varID][levelID].nmiss);
}
if ( nrecs == 0 ) break;
diff --git a/src/Seaspctl.cc b/src/Seaspctl.cc
index 8cd136b..f9062a1 100644
--- a/src/Seaspctl.cc
+++ b/src/Seaspctl.cc
@@ -36,7 +36,7 @@ void *Seaspctl(void *argument)
int nrecs;
int gridID, varID, levelID;
int year, month, day, seas0 = 0;
- int nmiss;
+ size_t nmiss;
int nlevels;
int oldmon = 0;
int season_start;
diff --git a/src/Seasstat.cc b/src/Seasstat.cc
index 4a7aeb0..9920807 100644
--- a/src/Seasstat.cc
+++ b/src/Seasstat.cc
@@ -45,7 +45,7 @@ void *Seasstat(void *argument)
int nrecs;
int varID, levelID;
int year, month, day, seas0 = 0;
- int nmiss;
+ size_t nmiss;
int oldmon = 0;
int nseason = 0;
const char *seas_name[4];
@@ -164,7 +164,7 @@ void *Seasstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t)nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
pvars2->nmiss = pvars1->nmiss;
@@ -184,7 +184,7 @@ void *Seasstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -306,7 +306,7 @@ void *Seasstat(void *argument)
field_type *pvars1 = &vars1[varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
if ( nrecs == 0 ) break;
diff --git a/src/Selbox.cc b/src/Selbox.cc
index 6b001d6..e3dab01 100644
--- a/src/Selbox.cc
+++ b/src/Selbox.cc
@@ -847,7 +847,7 @@ void *Selbox(void *argument)
int varID, levelID;
int gridID1 = -1, gridID2;
int index, gridtype = -1;
- int nmiss;
+ size_t nmiss;
double missval;
typedef struct {
int gridID1, gridID2;
diff --git a/src/Select.cc b/src/Select.cc
index 03cd35c..cdc555f 100644
--- a/src/Select.cc
+++ b/src/Select.cc
@@ -44,7 +44,7 @@ void write_const_vars(int streamID2, int vlistID2, int nvars, double **vardata2)
for ( int levelID2c = 0; levelID2c < nlevel; ++levelID2c )
{
double *pdata = vardata2[varID2c]+gridsize*levelID2c;
- int nmiss = 0;
+ size_t nmiss = 0;
for ( int i = 0; i < gridsize; ++i )
if ( DBL_IS_EQUAL(pdata[i], missval) ) nmiss++;
@@ -632,7 +632,7 @@ void *Select(void *argument)
}
else
{
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, array, &nmiss);
pstreamWriteRecord(streamID2, array, nmiss);
}
@@ -661,7 +661,7 @@ void *Select(void *argument)
int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
vardata2[varID2] = (double*) Malloc(gridsize*nlevel*sizeof(double));
}
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, vardata2[varID2]+gridsize*levelID2, &nmiss);
}
}
diff --git a/src/Selgridcell.cc b/src/Selgridcell.cc
index 6873794..7f20c78 100644
--- a/src/Selgridcell.cc
+++ b/src/Selgridcell.cc
@@ -210,7 +210,8 @@ void *Selgridcell(void *argument)
for ( int recID = 0; recID < nrecs; recID++ )
{
- int nmiss, varID, levelID;
+ size_t nmiss;
+ int varID, levelID;
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, array1, &nmiss);
diff --git a/src/Selmulti.cc b/src/Selmulti.cc
index bbaf01a..0d28f91 100644
--- a/src/Selmulti.cc
+++ b/src/Selmulti.cc
@@ -165,7 +165,7 @@ void *Selmulti(void *argument)
int varID2, levelID2;
int sellevel, selcode, selltype;
bool lcopy = false;
- int nmiss;
+ size_t nmiss;
int simpleMath=0; // 1: simple array arithmetics ( *,+), 0: do nothing
float scale = 1.0;
float offset = 0.0; // If SCALE and/or OFFSET are defined, then the data values are scaled as SCALE*(VALUE-OFFSET).
diff --git a/src/Seloperator.cc b/src/Seloperator.cc
index 24216b5..6abd35a 100644
--- a/src/Seloperator.cc
+++ b/src/Seloperator.cc
@@ -29,7 +29,7 @@ void *Seloperator(void *argument)
int levID, ltype = 0;
int varID2, levelID2;
int sellevel, selcode, selltype;
- int gridsize, nmiss;
+ size_t gridsize, nmiss;
double slevel = 0, level;
double *array = NULL;
diff --git a/src/Seltime.cc b/src/Seltime.cc
index 7a2a08c..f75be89 100644
--- a/src/Seltime.cc
+++ b/src/Seltime.cc
@@ -173,7 +173,7 @@ void *Seltime(void *argument)
int varID, levelID;
int nsel = 0;
int i;
- int nmiss;
+ size_t nmiss;
int ncts = 0, nts, it;
int hour = 0, minute = 0, second = 0;
int nts1 = 0, nts2 = 0;
diff --git a/src/Selvar.cc b/src/Selvar.cc
index 43c7d1d..9924560 100644
--- a/src/Selvar.cc
+++ b/src/Selvar.cc
@@ -53,7 +53,7 @@ void *Selvar(void *argument)
char zaxistypename[CDI_MAX_NAME];
char zaxisname[CDI_MAX_NAME];
char **argnames = NULL;
- int nmiss;
+ size_t nmiss;
int gridnum = 0;
lista_t *ilista = lista_new(INT_LISTA);
lista_t *flista = lista_new(FLT_LISTA);
diff --git a/src/Set.cc b/src/Set.cc
index 80f2a31..d3f3bc7 100644
--- a/src/Set.cc
+++ b/src/Set.cc
@@ -48,7 +48,7 @@ void *Set(void *argument)
{
int nrecs, nvars, newval = -1, tabnum = 0;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int index, zaxisID1, zaxisID2, nzaxis, nlevs;
int zaxistype;
int newparam = 0;
diff --git a/src/Setattribute.cc b/src/Setattribute.cc
index 1374d01..3373cf8 100644
--- a/src/Setattribute.cc
+++ b/src/Setattribute.cc
@@ -255,7 +255,7 @@ void *Setattribute(void *argument)
}
else
{
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, array, &nmiss);
pstreamWriteRecord(streamID2, array, nmiss);
}
diff --git a/src/Setbox.cc b/src/Setbox.cc
index 6e52692..4b9ae34 100644
--- a/src/Setbox.cc
+++ b/src/Setbox.cc
@@ -64,7 +64,7 @@ void *Setbox(void *argument)
int vlistID1, vlistID2;
int gridID = -1;
int index, ngrids, gridtype;
- int nmiss;
+ size_t nmiss;
int *vars;
int i;
int ndiffgrids;
diff --git a/src/Setgatt.cc b/src/Setgatt.cc
index c04fbbe..8b13d44 100644
--- a/src/Setgatt.cc
+++ b/src/Setgatt.cc
@@ -33,7 +33,7 @@ void *Setgatt(void *argument)
int nrecs;
int varID, levelID;
int gridsize;
- int nmiss;
+ size_t nmiss;
char *attname = NULL, *attstring = NULL, *attfile = NULL;
cdoInitialize(argument);
diff --git a/src/Setgrid.cc b/src/Setgrid.cc
index fbc5dc4..a7de880 100644
--- a/src/Setgrid.cc
+++ b/src/Setgrid.cc
@@ -37,7 +37,7 @@ void *Setgrid(void *argument)
int varID, levelID;
int gridID2 = -1;
int gridtype = -1;
- int nmiss;
+ size_t nmiss;
int areasize = 0;
int masksize = 0;
bool lregular = false;
diff --git a/src/Sethalo.cc b/src/Sethalo.cc
index 3f539e5..45fc14e 100644
--- a/src/Sethalo.cc
+++ b/src/Sethalo.cc
@@ -444,7 +444,7 @@ void *Sethalo(void *argument)
int gridsize, gridsize2;
int gridID1 = -1, gridID2;
int index, gridtype;
- int nmiss;
+ size_t nmiss;
int i;
int lhalo = 0, rhalo = 0;
double missval;
diff --git a/src/Setmiss.cc b/src/Setmiss.cc
index fec30bb..f81d2dd 100644
--- a/src/Setmiss.cc
+++ b/src/Setmiss.cc
@@ -44,7 +44,7 @@ void *Setmiss(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int i;
double missval, missval2 = 0;
double rconst = 0, rmin = 0, rmax = 0;
diff --git a/src/Setpartab.cc b/src/Setpartab.cc
index d7b4d92..3eb2e2b 100644
--- a/src/Setpartab.cc
+++ b/src/Setpartab.cc
@@ -302,7 +302,7 @@ void *Setpartab(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int tableID = -1;
int tableformat = 0;
bool delvars = false;
diff --git a/src/Setrcaname.cc b/src/Setrcaname.cc
index 9be5e82..70a41a0 100644
--- a/src/Setrcaname.cc
+++ b/src/Setrcaname.cc
@@ -32,7 +32,7 @@ void *Setrcaname(void *argument)
int scode, sltype, slevel;
int zaxisID, ltype, code, nlev;
int level;
- int gridsize, nmiss;
+ size_t gridsize, nmiss;
double *array = NULL;
cdoInitialize(argument);
diff --git a/src/Settime.cc b/src/Settime.cc
index 2b84354..634d202 100644
--- a/src/Settime.cc
+++ b/src/Settime.cc
@@ -164,7 +164,7 @@ void *Settime(void *argument)
int vdateb[2], vtimeb[2];
int sdate = 0, stime = 0;
int taxisID2 = CDI_UNDEFID;
- int nmiss;
+ size_t nmiss;
int gridsize;
int tunit = TUNIT_DAY;
int ijulinc = 0, incperiod = 1, incunit = 86400;
diff --git a/src/Setzaxis.cc b/src/Setzaxis.cc
index bc64f80..98f1d90 100644
--- a/src/Setzaxis.cc
+++ b/src/Setzaxis.cc
@@ -57,7 +57,7 @@ void *Setzaxis(void *argument)
int varID, levelID;
int zaxisID1, zaxisID2 = -1;
int nzaxis, index;
- int nmiss;
+ size_t nmiss;
int found;
bool lztop = false, lzbot = false;
double ztop = 0, zbot = 0;
diff --git a/src/Shiftxy.cc b/src/Shiftxy.cc
index 91175a7..3e03b31 100644
--- a/src/Shiftxy.cc
+++ b/src/Shiftxy.cc
@@ -161,7 +161,7 @@ void *Shiftxy(void *argument)
bool lcoord = false;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Sinfo.cc b/src/Sinfo.cc
index 0d60ce8..a0d07a9 100644
--- a/src/Sinfo.cc
+++ b/src/Sinfo.cc
@@ -213,9 +213,9 @@ void *Sinfo(void *argument)
fprintf(stdout, "%3d ", vlistZaxisIndex(vlistID, zaxisID) + 1);
/* grid info */
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
set_text_color(stdout, RESET, GREEN);
- fprintf(stdout, "%9d ", gridsize);
+ fprintf(stdout, "%9zu ", gridsize);
reset_text_color(stdout);
fprintf(stdout, "%3d ", vlistGridIndex(vlistID, gridID) + 1);
diff --git a/src/Smooth.cc b/src/Smooth.cc
index da71c1e..cd9fcd1 100644
--- a/src/Smooth.cc
+++ b/src/Smooth.cc
@@ -36,7 +36,7 @@ enum {FORM_LINEAR};
static const char *Form[] = {"linear"};
typedef struct {
- int maxpoints;
+ size_t maxpoints;
int form;
double radius;
double weight0;
@@ -58,7 +58,7 @@ double smooth_knn_compute_weights(size_t num_neighbors, const bool *restrict src
for ( size_t n = 0; n < num_neighbors; ++n )
{
nbr_mask[n] = false;
- if ( nbr_add[n] < ULONG_MAX && src_grid_mask[nbr_add[n]] )
+ if ( nbr_add[n] < SIZE_MAX && src_grid_mask[nbr_add[n]] )
{
nbr_dist[n] = intlin(nbr_dist[n], weight0, 0, weightR, search_radius);
dist_tot += nbr_dist[n];
@@ -93,7 +93,7 @@ size_t smooth_knn_normalize_weights(unsigned num_neighbors, double dist_tot, str
}
static
-void smooth(int gridID, double missval, const double *restrict array1, double *restrict array2, int *nmiss, smoothpoint_t spoint)
+void smooth(int gridID, double missval, const double *restrict array1, double *restrict array2, size_t *nmiss, smoothpoint_t spoint)
{
*nmiss = 0;
int gridID0 = gridID;
@@ -216,7 +216,7 @@ void smooth9_sum(size_t ij, bool *mask, double sfac, const double *restrict arra
}
static
-void smooth9(int gridID, double missval, const double *restrict array1, double *restrict array2, int *nmiss)
+void smooth9(int gridID, double missval, const double *restrict array1, double *restrict array2, size_t *nmiss)
{
size_t gridsize = gridInqSize(gridID);
size_t nlon = gridInqXsize(gridID);
@@ -350,7 +350,7 @@ int convert_form(const char *formstr)
}
static
-void smooth_set_parameter(int *xnsmooth, smoothpoint_t *spoint)
+void set_parameter(int *xnsmooth, smoothpoint_t *spoint)
{
int pargc = operatorArgc();
@@ -371,7 +371,7 @@ void smooth_set_parameter(int *xnsmooth, smoothpoint_t *spoint)
const char *value = kv->values[0];
if ( STR_IS_EQ(key, "nsmooth") ) *xnsmooth = parameter2int(value);
- else if ( STR_IS_EQ(key, "maxpoints") ) spoint->maxpoints = parameter2int(value);
+ else if ( STR_IS_EQ(key, "maxpoints") ) spoint->maxpoints = parameter2sizet(value);
else if ( STR_IS_EQ(key, "weight0") ) spoint->weight0 = parameter2double(value);
else if ( STR_IS_EQ(key, "weightR") ) spoint->weightR = parameter2double(value);
else if ( STR_IS_EQ(key, "radius") ) spoint->radius = radius_str_to_deg(value);
@@ -383,7 +383,7 @@ void smooth_set_parameter(int *xnsmooth, smoothpoint_t *spoint)
}
if ( cdoVerbose )
- cdoPrint("nsmooth = %d, maxpoints = %d, radius = %gdeg, form = %s, weight0 = %g, weightR = %g",
+ cdoPrint("nsmooth = %d, maxpoints = %zu, radius = %gdeg, form = %s, weight0 = %g, weightR = %g",
*xnsmooth, spoint->maxpoints, spoint->radius, Form[spoint->form], spoint->weight0, spoint->weightR);
}
@@ -392,10 +392,10 @@ void *Smooth(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int xnsmooth = 1;
smoothpoint_t spoint;
- spoint.maxpoints = INT_MAX;
+ spoint.maxpoints = SIZE_MAX;
spoint.radius = 1;
spoint.form = FORM_LINEAR;
spoint.weight0 = 0.25;
@@ -410,7 +410,7 @@ void *Smooth(void *argument)
int operatorID = cdoOperatorID();
- if ( operatorID == SMOOTH ) smooth_set_parameter(&xnsmooth, &spoint);
+ if ( operatorID == SMOOTH ) set_parameter(&xnsmooth, &spoint);
if ( spoint.radius < 0 || spoint.radius > 180 ) cdoAbort("%s=%g out of bounds (0-180 deg)!", "radius", spoint.radius);
diff --git a/src/Sort.cc b/src/Sort.cc
index b073ad6..257e197 100644
--- a/src/Sort.cc
+++ b/src/Sort.cc
@@ -29,8 +29,8 @@
typedef struct
{
- int nmiss;
int levelID;
+ size_t nmiss;
double level;
}
levinfo_t;
@@ -106,7 +106,7 @@ int cmpvarlevelrev(const void *s1, const void *s2)
}
static
-void setNmiss(int varID, int levelID, int nvars, varinfo_t *varInfo, int nmiss)
+void setNmiss(int varID, int levelID, int nvars, varinfo_t *varInfo, size_t nmiss)
{
int vindex, lindex;
@@ -151,7 +151,7 @@ void *Sort(void *argument)
int vindex, lindex;
int nrecs, nlevs, offset;
int gridsize;
- int nmiss;
+ size_t nmiss;
double *single;
int (*cmpvarlev)(const void *, const void *) = cmpvarlevel;
diff --git a/src/Sorttimestamp.cc b/src/Sorttimestamp.cc
index 50e4fc6..f3f2b24 100644
--- a/src/Sorttimestamp.cc
+++ b/src/Sorttimestamp.cc
@@ -61,7 +61,7 @@ void *Sorttimestamp(void *argument)
int tsID, lasttsID = -1;
int nalloc = 0;
int vlistID2 = -1, taxisID2 = -1;
- int nmiss;
+ size_t nmiss;
int nvars = 0, nlevel;
int *vdate = NULL, *vtime = NULL;
field_type ***vars = NULL;
diff --git a/src/Spectral.cc b/src/Spectral.cc
index 8d1cb23..21d2008 100644
--- a/src/Spectral.cc
+++ b/src/Spectral.cc
@@ -44,7 +44,7 @@ void *Spectral(void *argument)
int gridIDsp = -1, gridIDgp = -1;
int gridID1 = -1, gridID2 = -1;
int gridID;
- int nmiss;
+ size_t nmiss;
int ncut = 0;
int *wnums = NULL, *waves = NULL;
int *vars;
diff --git a/src/Spectrum.cc b/src/Spectrum.cc
index 7103dff..b35cf91 100644
--- a/src/Spectrum.cc
+++ b/src/Spectrum.cc
@@ -169,7 +169,7 @@ void *Spectrum(void *argument)
int gridID, varID, levelID;
int i, k;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
int *vdate = NULL, *vtime = NULL;
int freq;
diff --git a/src/Split.cc b/src/Split.cc
index 337c1c1..519cd7f 100644
--- a/src/Split.cc
+++ b/src/Split.cc
@@ -55,7 +55,7 @@ void *Split(void *argument)
char filesuffix[32];
char filename[8192];
int nsplit = 0;
- int nmiss;
+ size_t nmiss;
bool swap_obase = false;
const char *uuid_attribute = NULL;
diff --git a/src/Splitrec.cc b/src/Splitrec.cc
index 044a3d4..537a75e 100644
--- a/src/Splitrec.cc
+++ b/src/Splitrec.cc
@@ -35,7 +35,7 @@ void *Splitrec(void *argument)
char filename[8192];
const char *refname;
int gridsize;
- int nmiss;
+ size_t nmiss;
double *array = NULL;
cdoInitialize(argument);
diff --git a/src/Splitsel.cc b/src/Splitsel.cc
index 7b579fb..86b83bf 100644
--- a/src/Splitsel.cc
+++ b/src/Splitsel.cc
@@ -33,7 +33,7 @@ void *Splitsel(void *argument)
int nrecs = 0;
int varID, levelID;
int tsID;
- int nmiss;
+ size_t nmiss;
int gridID;
int nlevel;
int i2 = 0;
diff --git a/src/Splittime.cc b/src/Splittime.cc
index 3aedb5c..6241775 100644
--- a/src/Splittime.cc
+++ b/src/Splittime.cc
@@ -62,7 +62,7 @@ void *Splittime(void *argument)
int streamIDs[MAX_STREAMS], tsIDs[MAX_STREAMS];
int index = 0;
int gridsize;
- int nmiss;
+ size_t nmiss;
int gridID;
int nlevel;
char filesuffix[32];
diff --git a/src/Splityear.cc b/src/Splityear.cc
index 47d28a2..fc9dffc 100644
--- a/src/Splityear.cc
+++ b/src/Splityear.cc
@@ -44,7 +44,7 @@ void *Splityear(void *argument)
int gridsize;
int ic = 0;
int cyear[MAX_YEARS];
- int nmiss;
+ size_t nmiss;
int gridID;
int nlevel;
char filesuffix[32];
diff --git a/src/Subtrend.cc b/src/Subtrend.cc
index 748af3a..bf1f442 100644
--- a/src/Subtrend.cc
+++ b/src/Subtrend.cc
@@ -31,7 +31,7 @@
void *Subtrend(void *argument)
{
int gridID, varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Tee.cc b/src/Tee.cc
index a8e9258..e55d639 100644
--- a/src/Tee.cc
+++ b/src/Tee.cc
@@ -25,7 +25,7 @@ void *Tee(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Templates.cc b/src/Templates.cc
index 632e60a..305dce2 100644
--- a/src/Templates.cc
+++ b/src/Templates.cc
@@ -25,7 +25,7 @@ void *Template1(void *argument)
{
int nrecs;
int varID, levelID;
- int gridsize, nmiss;
+ size_t gridsize, nmiss;
cdoInitialize(argument);
@@ -93,7 +93,7 @@ void *Template2(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Test.cc b/src/Test.cc
index fdd4ddb..1885a53 100644
--- a/src/Test.cc
+++ b/src/Test.cc
@@ -69,7 +69,7 @@ void *Testdata(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Tests.cc b/src/Tests.cc
index 64bdc7d..8a7d2fa 100644
--- a/src/Tests.cc
+++ b/src/Tests.cc
@@ -26,7 +26,7 @@ void *Tests(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
double degree_of_freedom = 0, p = 0, q = 0, n = 0, d = 0;
double missval;
diff --git a/src/Timcount.cc b/src/Timcount.cc
index f4f6c53..dcbfe64 100644
--- a/src/Timcount.cc
+++ b/src/Timcount.cc
@@ -38,7 +38,7 @@ void *Timcount(void *argument)
int vdate0 = 0, vtime0 = 0;
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nwpv; // number of words per value; real:1 complex:2
cdoInitialize(argument);
@@ -122,7 +122,7 @@ void *Timcount(void *argument)
}
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = vars1[varID][levelID].grid;
field.missval = vars1[varID][levelID].missval;
@@ -149,7 +149,7 @@ void *Timcount(void *argument)
if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, (int)vars1[varID][levelID].nmiss);
+ pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, vars1[varID][levelID].nmiss);
}
if ( nrecs == 0 ) break;
diff --git a/src/Timcumsum.cc b/src/Timcumsum.cc
index a426da9..5824df1 100644
--- a/src/Timcumsum.cc
+++ b/src/Timcumsum.cc
@@ -32,7 +32,7 @@ void *Timcumsum(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
@@ -74,7 +74,7 @@ void *Timcumsum(void *argument)
if ( tsID == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- // pvars1->nmiss = (size_t)nmiss;
+ // pvars1->nmiss = nmiss;
if ( nmiss )
for ( int i = 0; i < gridsize; ++i )
if ( DBL_IS_EQUAL(pvars1->ptr[i], pvars1->missval) ) pvars1->ptr[i] = 0;
@@ -82,7 +82,7 @@ void *Timcumsum(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- // field.nmiss = (size_t)nmiss;
+ // field.nmiss = nmiss;
field.size = gridsize;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -95,7 +95,7 @@ void *Timcumsum(void *argument)
}
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
tsID++;
diff --git a/src/Timpctl.cc b/src/Timpctl.cc
index 75139bb..f9f9a7b 100644
--- a/src/Timpctl.cc
+++ b/src/Timpctl.cc
@@ -40,7 +40,7 @@ void timpctl(int operatorID)
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
int nrecs;
int gridID, varID, levelID;
- int nmiss;
+ size_t nmiss;
int nlevels;
operatorInputArg("percentile number");
diff --git a/src/Timselpctl.cc b/src/Timselpctl.cc
index 3bc179d..00bde7d 100644
--- a/src/Timselpctl.cc
+++ b/src/Timselpctl.cc
@@ -35,7 +35,7 @@ void *Timselpctl(void *argument)
int nrecs = 0;
int gridID, varID, levelID;
int tsID;
- int nmiss;
+ size_t nmiss;
int nlevels;
cdoInitialize(argument);
diff --git a/src/Timselstat.cc b/src/Timselstat.cc
index e75a05c..95ba0a2 100644
--- a/src/Timselstat.cc
+++ b/src/Timselstat.cc
@@ -44,7 +44,7 @@ void *Timselstat(void *argument)
int varID, levelID;
int tsID;
int nsets;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
@@ -164,10 +164,10 @@ void *Timselstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t)nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
- pvars2->nmiss = (size_t)nmiss;
+ pvars2->nmiss = nmiss;
for ( int i = 0; i < gridsize; i++ )
pvars2->ptr[i] = pvars1->ptr[i];
}
@@ -184,7 +184,7 @@ void *Timselstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -283,7 +283,7 @@ void *Timselstat(void *argument)
field_type *pvars1 = &vars1[varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
if ( nrecs == 0 ) break;
diff --git a/src/Timsort.cc b/src/Timsort.cc
index 0a7fe15..dc082e9 100644
--- a/src/Timsort.cc
+++ b/src/Timsort.cc
@@ -50,7 +50,7 @@ void *Timsort(void *argument)
int nrecs;
int gridID, varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
int *vdate = NULL, *vtime = NULL;
field_type ***vars = NULL;
diff --git a/src/Timstat.cc b/src/Timstat.cc
index 76206ad..7413470 100644
--- a/src/Timstat.cc
+++ b/src/Timstat.cc
@@ -86,7 +86,7 @@ void *Timstat(void *argument)
int varID, levelID;
int streamID3 = -1;
int vlistID3, taxisID3 = -1;
- int nmiss;
+ size_t nmiss;
bool lvfrac = false;
int nwpv; // number of words per value; real:1 complex:2
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
diff --git a/src/Timstat2.cc b/src/Timstat2.cc
index 4dc197f..e158a86 100644
--- a/src/Timstat2.cc
+++ b/src/Timstat2.cc
@@ -106,7 +106,7 @@ void *Timstat2(void *argument)
int vdate = 0, vtime = 0;
int nrecs2, nlevs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Timstat3.cc b/src/Timstat3.cc
index 347b72b..47bcfea 100644
--- a/src/Timstat3.cc
+++ b/src/Timstat3.cc
@@ -42,7 +42,7 @@ void *Timstat3(void *argument)
int nlevs;
int is;
int varID, levelID, gridID;
- int nmiss;
+ size_t nmiss;
double missval, missval1, missval2;
double fractil_1, fractil_2, statistic;
int ***iwork[NIWORK];
diff --git a/src/Tocomplex.cc b/src/Tocomplex.cc
index b1fab11..c8b6893 100644
--- a/src/Tocomplex.cc
+++ b/src/Tocomplex.cc
@@ -26,7 +26,7 @@ void *Tocomplex(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Transpose.cc b/src/Transpose.cc
index 15b86f7..3b1efaf 100644
--- a/src/Transpose.cc
+++ b/src/Transpose.cc
@@ -62,7 +62,7 @@ void *Transpose(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Trend.cc b/src/Trend.cc
index 0e10ba8..9359536 100644
--- a/src/Trend.cc
+++ b/src/Trend.cc
@@ -32,7 +32,7 @@ void *Trend(void *argument)
{
int vdate = 0, vtime = 0;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int nrecs;
double temp1, temp2;
enum {nwork = 5};
diff --git a/src/Trms.cc b/src/Trms.cc
index 319ca67..4a408a0 100644
--- a/src/Trms.cc
+++ b/src/Trms.cc
@@ -30,7 +30,8 @@
void trms(field_type field1, field_type field2, double *dp, field_type *field3)
{
- int i, k, nlev, len, rnmiss = 0;
+ int k, nlev;
+ size_t rnmiss = 0;
int zaxis = field1.zaxis;
int grid1 = field1.grid;
double *array1 = field1.ptr;
@@ -42,12 +43,12 @@ void trms(field_type field1, field_type field2, double *dp, field_type *field3)
double rsum = 0, rsumw = 0, ravg = 0, wp;
nlev = zaxisInqSize(zaxis);
- len = gridInqSize(grid1);
+ size_t len = gridInqSize(grid1);
if ( len != gridInqSize(grid2) )
cdoAbort("fields have different size!");
for ( k = 0; k < nlev; k++ )
- for ( i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
wp = w[i]*dp[k*len+i];
rsum = ADDMN(rsum, MULMN(wp, MULMN( SUBMN(array2[k*len+i], array1[k*len+i]),
@@ -69,10 +70,10 @@ void *Trms(void *argument)
int code = 0, oldcode = 0;
int zaxisID;
int nrecs;
- int nmiss;
+ size_t nmiss;
int varID, levelID;
int pcode = 152, pvarID = -1;
- long offset;
+ size_t offset;
size_t vctsize = 0;
const double *va = NULL, *vb = NULL;
double *single;
@@ -157,7 +158,7 @@ void *Trms(void *argument)
double **vardata1 = (double**) Malloc(nvars*sizeof(double*));
double **vardata2 = (double**) Malloc(nvars*sizeof(double*));
- int gridsize = gridInqSize(vlistInqVarGrid(vlistID1, pvarID));
+ size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, pvarID));
int nlevel = vctsize/2 - 1;
double *dp = (double*) Malloc(gridsize*nlevel*sizeof(double));
@@ -174,7 +175,7 @@ void *Trms(void *argument)
field_init(&field2);
field_init(&field3);
- int lim = vlistGridsizeMax(vlistID1);
+ size_t lim = vlistGridsizeMax(vlistID1);
field1.weight = NULL;
if ( needWeights )
field1.weight = (double*) Malloc(lim*sizeof(double));
@@ -211,7 +212,7 @@ void *Trms(void *argument)
}
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, pvarID));
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
vardata1[pvarID][i] = exp(vardata1[pvarID][i]);
vardata2[pvarID][i] = exp(vardata2[pvarID][i]);
@@ -221,7 +222,7 @@ void *Trms(void *argument)
for ( int k = 0; k < nlevel; k++ )
{
offset = gridsize*k;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
double dp1 = (va[k+1] + vb[k+1]*vardata1[pvarID][i]) - (va[k] + vb[k]*vardata1[pvarID][i]);
double dp2 = (va[k+1] + vb[k+1]*vardata2[pvarID][i]) - (va[k] + vb[k]*vardata2[pvarID][i]);
diff --git a/src/Tstepcount.cc b/src/Tstepcount.cc
index 1fefdbb..ddc4e87 100644
--- a/src/Tstepcount.cc
+++ b/src/Tstepcount.cc
@@ -57,7 +57,7 @@ void *Tstepcount(void *argument)
int nrecs;
int gridID, varID, levelID;
int nalloc = 0;
- int nmiss;
+ size_t nmiss;
int nlevel;
int vdate = 0, vtime = 0;
double missval;
diff --git a/src/Vargen.cc b/src/Vargen.cc
index d72c0d5..73628a5 100644
--- a/src/Vargen.cc
+++ b/src/Vargen.cc
@@ -88,10 +88,10 @@ double std_atm_pressure(double height)
}
static
-void conv_generic_grid(int gridID, int gridsize, double *xvals2D, double *yvals2D)
+void conv_generic_grid(int gridID, size_t gridsize, double *xvals2D, double *yvals2D)
{
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
assert(gridsize==xsize*ysize);
@@ -103,7 +103,7 @@ void conv_generic_grid(int gridID, int gridsize, double *xvals2D, double *yvals2
double xmin = xcoord[0];
double xmax = xcoord[0];
- for ( int i = 1; i < xsize; ++i )
+ for ( size_t i = 1; i < xsize; ++i )
{
if ( xcoord[i] < xmin ) xmin = xcoord[i];
if ( xcoord[i] > xmax ) xmax = xcoord[i];
@@ -111,7 +111,7 @@ void conv_generic_grid(int gridID, int gridsize, double *xvals2D, double *yvals2
double ymin = ycoord[0];
double ymax = ycoord[0];
- for ( int i = 1; i < ysize; ++i )
+ for ( size_t i = 1; i < ysize; ++i )
{
if ( ycoord[i] < ymin ) ymin = ycoord[i];
if ( ycoord[i] > ymax ) ymax = ycoord[i];
@@ -120,8 +120,8 @@ void conv_generic_grid(int gridID, int gridsize, double *xvals2D, double *yvals2
double xrange = xmax - xmin;
double yrange = ymax - ymin;
- for ( int j = 0; j < ysize; ++j )
- for ( int i = 0; i < xsize; ++i )
+ for ( size_t j = 0; j < ysize; ++j )
+ for ( size_t i = 0; i < xsize; ++i )
{
xvals2D[j*xsize+i] = xcoord[i]*M_PI/xrange;
yvals2D[j*xsize+i] = ycoord[j]*M_PI/yrange;
@@ -132,13 +132,13 @@ void conv_generic_grid(int gridID, int gridsize, double *xvals2D, double *yvals2
}
static
-void remap_nn_reg2d_reg2d(int nx, int ny, const double *restrict data, int gridID, double *restrict array)
+void remap_nn_reg2d_reg2d(size_t nx, size_t ny, const double *restrict data, int gridID, double *restrict array)
{
if ( gridInqType(gridID) != GRID_LONLAT )
cdoAbort("Internal error, wrong grid type!");
- int nxvals = gridInqXsize(gridID);
- int nyvals = gridInqYsize(gridID);
+ size_t nxvals = gridInqXsize(gridID);
+ size_t nyvals = gridInqYsize(gridID);
double *xvals = (double*) Malloc(nxvals*sizeof(double));
double *yvals = (double*) Malloc(nyvals*sizeof(double));
@@ -152,12 +152,12 @@ void remap_nn_reg2d_reg2d(int nx, int ny, const double *restrict data, int gridI
gridInqYunits(gridID, units);
grid_to_degree(units, nyvals, yvals, "grid center lat");
- int ii, jj;
+ size_t ii, jj;
double xval, yval;
- for ( int j = 0; j < nyvals; j++ )
+ for ( size_t j = 0; j < nyvals; j++ )
{
yval = yvals[j];
- for ( int i = 0; i < nxvals; i++ )
+ for ( size_t i = 0; i < nxvals; i++ )
{
xval = xvals[i];
if ( xval >= 180 ) xval -= 360;
@@ -175,10 +175,10 @@ void remap_nn_reg2d_reg2d(int nx, int ny, const double *restrict data, int gridI
}
static
-void remap_nn_reg2d_nonreg2d(int nx, int ny, const double *restrict data, int gridID, double *restrict array)
+void remap_nn_reg2d_nonreg2d(size_t nx, size_t ny, const double *restrict data, int gridID, double *restrict array)
{
int gridID2 = gridID;
- int gridsize = gridInqSize(gridID2);
+ size_t gridsize = gridInqSize(gridID2);
double *xvals = (double*) Malloc(gridsize*sizeof(double));
double *yvals = (double*) Malloc(gridsize*sizeof(double));
@@ -197,9 +197,9 @@ void remap_nn_reg2d_nonreg2d(int nx, int ny, const double *restrict data, int gr
gridInqYunits(gridID2, units);
grid_to_degree(units, gridsize, yvals, "grid center lat");
- int ii, jj;
+ size_t ii, jj;
double xval, yval;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
xval = xvals[i];
yval = yvals[i];
@@ -219,7 +219,7 @@ void remap_nn_reg2d_nonreg2d(int nx, int ny, const double *restrict data, int gr
}
static
-void remap_nn_reg2d(int nx, int ny, const double *restrict data, int gridID, double *restrict array)
+void remap_nn_reg2d(size_t nx, size_t ny, const double *restrict data, int gridID, double *restrict array)
{
if ( gridInqType(gridID) == GRID_LONLAT )
remap_nn_reg2d_reg2d(nx, ny, data, gridID, array);
@@ -239,8 +239,8 @@ void *Vargen(void *argument)
double rconst = 0;
double *levels = NULL;
double lon[NLON], lat[NLAT];
- int nlon = NLON;
- int nlat = NLAT;
+ size_t nlon = NLON;
+ size_t nlat = NLAT;
cdoInitialize(argument);
@@ -291,8 +291,8 @@ void *Vargen(void *argument)
gridDefXsize(gridIDdata, nlon);
gridDefYsize(gridIDdata, nlat);
- for ( int i = 0; i < nlon; i++ ) lon[i] = -179.75 + i*0.5;
- for ( int i = 0; i < nlat; i++ ) lat[i] = -89.75 + i*0.5;
+ for ( size_t i = 0; i < nlon; i++ ) lon[i] = -179.75 + i*0.5;
+ for ( size_t i = 0; i < nlat; i++ ) lat[i] = -89.75 + i*0.5;
gridDefXvals(gridIDdata, lon);
gridDefYvals(gridIDdata, lat);
@@ -404,8 +404,8 @@ void *Vargen(void *argument)
pstreamDefVlist(streamID, vlistID);
- int gridsize = gridInqSize(gridID);
- int datasize = gridsize;
+ size_t gridsize = gridInqSize(gridID);
+ size_t datasize = gridsize;
double *array = (double*) Malloc(gridsize*sizeof(double));
double *data = array;
if ( gridID != gridIDdata && gridIDdata != -1 )
@@ -444,7 +444,7 @@ void *Vargen(void *argument)
if ( operatorID == RANDOM )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array[i] = ((double)rand())/((double)RAND_MAX);
}
else if ( operatorID == SINCOS || operatorID == COSHILL )
@@ -476,12 +476,12 @@ void *Vargen(void *argument)
if ( operatorID == SINCOS )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array[i] = cos(1.0 * xvals[i]) * sin(2.0 * yvals[i]);
}
else if ( operatorID == COSHILL )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array[i] = 2 - cos(acos(cos(xvals[i]) * cos(yvals[i]))/1.2);
}
@@ -490,13 +490,13 @@ void *Vargen(void *argument)
}
else if ( operatorID == CONST )
{
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
array[i] = rconst;
}
else if ( operatorID == TOPO )
{
#if defined(ENABLE_DATA)
- for ( int i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
data[i] = etopo[i]/etopo_scale - etopo_offset;
#else
cdoAbort("Operator support disabled!");
@@ -505,7 +505,7 @@ void *Vargen(void *argument)
else if ( operatorID == TEMP )
{
#if defined(ENABLE_DATA)
- for ( int i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
data[i] = temp[i]/temp_scale - temp_offset;
#else
cdoAbort("Operator support disabled!");
@@ -514,7 +514,7 @@ void *Vargen(void *argument)
else if ( operatorID == MASK )
{
#if defined(ENABLE_DATA)
- for ( int i = 0; i < datasize; i++ )
+ for ( size_t i = 0; i < datasize; i++ )
data[i] = mask[i]/mask_scale - mask_offset;
#else
cdoAbort("Operator support disabled!");
diff --git a/src/Varrms.cc b/src/Varrms.cc
index 82824b4..d1a8153 100644
--- a/src/Varrms.cc
+++ b/src/Varrms.cc
@@ -35,7 +35,7 @@ void *Varrms(void *argument)
int oldcode = 0;
int nrecs;
int gridsize;
- int nmiss;
+ size_t nmiss;
int varID, levelID;
long offset;
double *single;
diff --git a/src/Verifygrid.cc b/src/Verifygrid.cc
index c56142f..2caad05 100644
--- a/src/Verifygrid.cc
+++ b/src/Verifygrid.cc
@@ -157,26 +157,14 @@ void find_unit_normal(double a[3], double b[3], double c[3], double *unit_normal
int find_coordinate_to_ignore(double *cell_corners_xyz)
{
- double corner_coordinates[3];
- double second_corner_coordinates[3];
- double third_corner_coordinates[3];
-
/* Takes the first three corners/vertices of the cell and calculates the unit normal via determinants. */
- corner_coordinates[0] = cell_corners_xyz[0];
- corner_coordinates[1] = cell_corners_xyz[1];
- corner_coordinates[2] = cell_corners_xyz[2];
-
- second_corner_coordinates[0] = cell_corners_xyz[3 + 0];
- second_corner_coordinates[1] = cell_corners_xyz[3 + 1];
- second_corner_coordinates[2] = cell_corners_xyz[3 + 2];
+ double *pcorner_coordinates1 = &cell_corners_xyz[0];
+ double *pcorner_coordinates2 = &cell_corners_xyz[3];
+ double *pcorner_coordinates3 = &cell_corners_xyz[6];
- third_corner_coordinates[0] = cell_corners_xyz[6 + 0];
- third_corner_coordinates[1] = cell_corners_xyz[6 + 1];
- third_corner_coordinates[2] = cell_corners_xyz[6 + 2];
-
double surface_normal_of_the_cell[3];
- find_unit_normal(corner_coordinates, second_corner_coordinates, third_corner_coordinates, surface_normal_of_the_cell);
+ find_unit_normal(pcorner_coordinates1, pcorner_coordinates2, pcorner_coordinates3, surface_normal_of_the_cell);
/* The surface normal is used to choose the coordinate to ignore. */
@@ -433,6 +421,12 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
Free(center_point_array);
+ // used only actual_number_of_corners
+ int *marked_duplicate_indices = (int*) Malloc(ncorner*sizeof(int));
+ double *cell_corners_xyz_without_duplicates = (double*) Malloc(3*ncorner*sizeof(double));
+ double *cell_corners_xyz = (double*) Malloc(3*(ncorner+1)*sizeof(double));
+ double *cell_corners_plane_projection = (double*) Malloc(2*(ncorner+1)*sizeof(double));
+
/*
Latitude and longitude are spherical coordinates on a unit circle. Each such coordinate tuple is transformed into a triple of Cartesian coordinates in Euclidean space.
This is first done for the presumed center point of the cell and then for all the corners of the cell. LLtoXYZ is defined in clipping/geometry.h
@@ -494,7 +488,6 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
/* Checks if there are any duplicate vertices in the list of corners. Note that the last (additional) corner has not been set yet. */
- int *marked_duplicate_indices = (int*) Malloc(actual_number_of_corners*sizeof(int));
for ( int i = 0; i < actual_number_of_corners; i++ ) marked_duplicate_indices[i] = 0;
int no_duplicates = 0;
@@ -514,8 +507,6 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
}
/* Writes the unique corner vertices in a new array. */
-
- double *cell_corners_xyz_without_duplicates = (double*) Malloc(3*(actual_number_of_corners - no_duplicates)*sizeof(double));
int unique_corner_number = 0;
@@ -548,8 +539,6 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
/* We are creating a closed polygon/cell by setting the additional last corner to be the same as the first one. */
- double *cell_corners_xyz = (double*) Malloc(3*(actual_number_of_corners + 1)*sizeof(double));
-
for ( int corner_no = 0; corner_no < actual_number_of_corners; corner_no++ )
{
int off = corner_no * 3;
@@ -565,8 +554,6 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
int coordinate_to_ignore = find_coordinate_to_ignore(cell_corners_xyz);
/* The remaining two-dimensional coordinates are extracted into one array for all the cell's corners and into one array for the center point. */
-
- double *cell_corners_plane_projection = (double*) Malloc(2*(actual_number_of_corners +1)*sizeof(double));
/* The following projection on the plane that two coordinate axes lie on changes the arrangement of
the polygon vertices if the coordinate to be ignored along the third axis is smaller than 0.
@@ -643,13 +630,13 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
printf(" %g/%g ", grid_corner_lon[cell_no * ncorner + corner_no], grid_corner_lat[cell_no * ncorner + corner_no]);
printf("\n");
}
-
- Free(cell_corners_plane_projection);
- Free(cell_corners_xyz);
- Free(cell_corners_xyz_without_duplicates);
- Free(marked_duplicate_indices);
}
+ Free(marked_duplicate_indices);
+ Free(cell_corners_plane_projection);
+ Free(cell_corners_xyz);
+ Free(cell_corners_xyz_without_duplicates);
+
int no_nonunique_cells = gridsize - no_unique_center_points;
int no_nonconvex_cells = (int) gridsize - no_convex_cells;
int no_nonusable_cells = (int) gridsize - no_usable_cells;
diff --git a/src/Vertcum.cc b/src/Vertcum.cc
index f8d7696..50b4a5e 100644
--- a/src/Vertcum.cc
+++ b/src/Vertcum.cc
@@ -60,7 +60,7 @@ void *Vertcum(void *argument)
int nrecs;
int i, nlevshl = 0;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
@@ -77,7 +77,7 @@ void *Vertcum(void *argument)
int vlistID2 = vlistDuplicate(vlistID1);
int nvars = vlistNvars(vlistID1);
- int **varnmiss = (int**) Malloc(nvars*sizeof(int*));
+ size_t **varnmiss = (size_t**) Malloc(nvars*sizeof(size_t*));
double ***vardata1 = (double***) Malloc(nvars*sizeof(double**));
double ***vardata2 = (double***) Malloc(nvars*sizeof(double**));
@@ -131,7 +131,7 @@ void *Vertcum(void *argument)
int nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
int nlevs2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
- varnmiss[varID] = (int*) Malloc(nlevs*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevs*sizeof(size_t));
vardata1[varID] = (double**) Malloc(nlevs*sizeof(double*));
vardata2[varID] = (double**) Malloc(nlevs2*sizeof(double*));
for ( levelID = 0; levelID < nlevs; ++levelID )
diff --git a/src/Vertintap.cc b/src/Vertintap.cc
index 0145f90..3b1b704 100644
--- a/src/Vertintap.cc
+++ b/src/Vertintap.cc
@@ -217,13 +217,13 @@ void *Vertintap(void *argument)
std::vector<bool> vars(nvars);
std::vector<bool> varinterp(nvars);
- std::vector<int *> varnmiss(nvars);
+ std::vector<size_t *> varnmiss(nvars);
std::vector<double *> vardata1(nvars);
std::vector<double *> vardata2(nvars);
int maxlev = nhlevh > nplev ? nhlevh : nplev;
- int *pnmiss = extrapolate ? NULL : (int *) Malloc(nplev*sizeof(int));
+ size_t *pnmiss = extrapolate ? NULL : (size_t *) Malloc(nplev*sizeof(size_t));
// check levels
if ( zaxisIDh != -1 )
@@ -286,8 +286,8 @@ void *Vertintap(void *argument)
{
varinterp[varID] = true;
vardata2[varID] = (double *) Malloc(gridsize*nplev*sizeof(double));
- varnmiss[varID] = (int *) Malloc(maxlev*sizeof(int));
- memset(varnmiss[varID], 0, maxlev*sizeof(int));
+ varnmiss[varID] = (size_t *) Malloc(maxlev*sizeof(size_t));
+ memset(varnmiss[varID], 0, maxlev*sizeof(size_t));
}
else
{
@@ -300,7 +300,7 @@ void *Vertintap(void *argument)
varinterp[varID] = false;
vardata2[varID] = vardata1[varID];
- varnmiss[varID] = (int *) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t *) Malloc(nlevel*sizeof(size_t));
}
}
@@ -436,7 +436,7 @@ void *Vertintap(void *argument)
interp_X(vardata1[varID], vardata2[varID], hyb_press,
vert_index, plev, nplev, gridsize, nlevel, missval);
- if ( !extrapolate ) memcpy(varnmiss[varID], pnmiss, nplev*sizeof(int));
+ if ( !extrapolate ) memcpy(varnmiss[varID], pnmiss, nplev*sizeof(size_t));
}
}
}
diff --git a/src/Vertintml.cc b/src/Vertintml.cc
index b955e37..755def2 100644
--- a/src/Vertintml.cc
+++ b/src/Vertintml.cc
@@ -186,13 +186,13 @@ void *Vertintml(void *argument)
std::vector<bool> vars(nvars);
std::vector<bool> varinterp(nvars);
- std::vector<int *> varnmiss(nvars);
+ std::vector<size_t *> varnmiss(nvars);
std::vector<double *> vardata1(nvars);
std::vector<double *> vardata2(nvars);
int maxlev = nhlevh > nplev ? nhlevh : nplev;
- int *pnmiss = extrapolate ? NULL : (int*) Malloc(nplev*sizeof(int));
+ size_t *pnmiss = extrapolate ? NULL : (size_t*) Malloc(nplev*sizeof(size_t));
// check levels
if ( zaxisIDh != -1 )
@@ -362,8 +362,8 @@ void *Vertintml(void *argument)
{
varinterp[varID] = true;
vardata2[varID] = (double*) Malloc(gridsize*nplev*sizeof(double));
- varnmiss[varID] = (int*) Malloc(maxlev*sizeof(int));
- memset(varnmiss[varID], 0, maxlev*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(maxlev*sizeof(size_t));
+ memset(varnmiss[varID], 0, maxlev*sizeof(size_t));
}
else
{
@@ -376,7 +376,7 @@ void *Vertintml(void *argument)
varinterp[varID] = false;
vardata2[varID] = vardata1[varID];
- varnmiss[varID] = (int*) Malloc(nlevel*sizeof(int));
+ varnmiss[varID] = (size_t*) Malloc(nlevel*sizeof(size_t));
}
}
@@ -597,7 +597,7 @@ void *Vertintml(void *argument)
vert_index, plev, nplev, gridsize, nlevel, missval);
}
- if ( !extrapolate ) memcpy(varnmiss[varID], pnmiss, nplev*sizeof(int));
+ if ( !extrapolate ) memcpy(varnmiss[varID], pnmiss, nplev*sizeof(size_t));
}
}
}
diff --git a/src/Vertstat.cc b/src/Vertstat.cc
index bf55642..172031b 100644
--- a/src/Vertstat.cc
+++ b/src/Vertstat.cc
@@ -158,7 +158,7 @@ void *Vertstat(void *argument)
int nrecs;
int gridID;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
typedef struct {
int zaxisID;
int status;
@@ -337,10 +337,10 @@ void *Vertstat(void *argument)
if ( levelID == 0 )
{
pstreamReadRecord(streamID1, vars1[varID].ptr, &nmiss);
- vars1[varID].nmiss = (size_t)nmiss;
+ vars1[varID].nmiss = nmiss;
if ( lrange )
{
- vars2[varID].nmiss = (size_t)nmiss;
+ vars2[varID].nmiss = nmiss;
for ( int i = 0; i < gridsize; i++ )
vars2[varID].ptr[i] = vars1[varID].ptr[i];
}
@@ -376,7 +376,7 @@ void *Vertstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = vars1[varID].grid;
field.missval = vars1[varID].missval;
@@ -456,7 +456,7 @@ void *Vertstat(void *argument)
}
pstreamDefRecord(streamID2, varID, 0);
- pstreamWriteRecord(streamID2, vars1[varID].ptr, (int)vars1[varID].nmiss);
+ pstreamWriteRecord(streamID2, vars1[varID].ptr, vars1[varID].nmiss);
vars1[varID].nsamp = 0;
}
}
diff --git a/src/Vertwind.cc b/src/Vertwind.cc
index 73f9bbc..1184319 100644
--- a/src/Vertwind.cc
+++ b/src/Vertwind.cc
@@ -37,7 +37,7 @@ void *Vertwind(void *argument)
int nrecs;
int varID, levelID;
int nvct = 0;
- int nmiss;
+ size_t nmiss;
int tempID = -1, sqID = -1, psID = -1, omegaID = -1;
char varname[CDI_MAX_NAME];
double *vct = NULL;
@@ -214,7 +214,7 @@ void *Vertwind(void *argument)
{
size_t offset = (size_t)levelID*gridsize;
- int nmiss_out = 0;
+ size_t nmiss_out = 0;
for ( int i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(wms[offset+i],missval_out) )
nmiss_out++;
diff --git a/src/Wct.cc b/src/Wct.cc
index 71e26ba..c8bf4a7 100644
--- a/src/Wct.cc
+++ b/src/Wct.cc
@@ -45,18 +45,17 @@ static double windchillTemperature(double t, double ff, double missval)
static void farexpr(field_type *field1, field_type field2, double (*expression)(double, double, double))
{
- int i, len;
+ size_t i, len;
const int grid1 = field1->grid;
- const int nmiss1 = field1->nmiss;
+ const size_t nmiss1 = field1->nmiss;
const double missval1 = field1->missval;
double *array1 = field1->ptr;
const int grid2 = field2.grid;
- const int nmiss2 = field2.nmiss;
+ const size_t nmiss2 = field2.nmiss;
const double missval2 = field2.missval;
const double *array2 = field2.ptr;
len = gridInqSize(grid1);
-
if ( len != gridInqSize(grid2) )
cdoAbort("Fields have different gridsize (%s)", __func__);
@@ -83,7 +82,7 @@ static void farexpr(field_type *field1, field_type field2, double (*expression)(
void *Wct(void *argument)
{
int nrecs, nrecs2;
- int nmiss;
+ size_t nmiss;
int varID1, varID2;
int levelID1, levelID2;
@@ -145,11 +144,11 @@ void *Wct(void *argument)
{
pstreamInqRecord(streamID1, &varID1, &levelID1);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
pstreamInqRecord(streamID2, &varID2, &levelID2);
pstreamReadRecord(streamID2, field2.ptr, &nmiss);
- field2.nmiss = (size_t) nmiss;
+ field2.nmiss = nmiss;
if ( varID1 != varID2 || levelID1 != levelID2 )
cdoAbort("Input streams have different structure!");
@@ -166,7 +165,7 @@ void *Wct(void *argument)
farexpr(&field1, field2, windchillTemperature);
pstreamDefRecord(streamID3, varID3, levelID1);
- pstreamWriteRecord(streamID3, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID3, field1.ptr, field1.nmiss);
}
tsID++;
diff --git a/src/Wind.cc b/src/Wind.cc
index 43d82ae..6a56812 100644
--- a/src/Wind.cc
+++ b/src/Wind.cc
@@ -42,7 +42,7 @@ void *Wind(void *argument)
int gridIDsp = -1, gridIDgp = -1;
int gridID1 = -1, gridID2 = -1;
int gridID;
- int nmiss;
+ size_t nmiss;
int nlon, nlat, ntr = -1;
int code, param;
int pnum, pcat, pdis;
diff --git a/src/WindTrans.cc b/src/WindTrans.cc
index 5fdf79a..28a6633 100644
--- a/src/WindTrans.cc
+++ b/src/WindTrans.cc
@@ -14,7 +14,7 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
- This program is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
@@ -78,9 +78,9 @@ int PROJUVLATLON;
static
void destaggerUorV(double *fu, double *fuOut,
- int klev, int nlat, int nlon, int UorV, long offset)
+ int klev, long nlat, long nlon, long UorV, long offset)
{
- int lat0, lon0;
+ long lat0, lon0;
double u0,u1;
double u_dstg;
long next;
@@ -132,9 +132,9 @@ void destaggerUorV(double *fu, double *fuOut,
static
void destaggerUorV_positiveOrder(double *fu, double *fuOut,
- int klev, int nlat, int nlon, int UorV, long offset)
+ int klev, long nlat, long nlon, int UorV, long offset)
{
- int latE, lonE;
+ long latE, lonE;
double u0,u1;
double u_dstg;
long next;
@@ -157,9 +157,9 @@ void destaggerUorV_positiveOrder(double *fu, double *fuOut,
for ( int lev = 0; lev < klev; lev++ )
{
- for ( int lat = 0; lat < latE; lat++ )
+ for ( long lat = 0; lat < latE; lat++ )
{
- for ( int lon = 0; lon < lonE; lon++ )
+ for ( long lon = 0; lon < lonE; lon++ )
{
u0 = fu[idx];
u1 = fu[idx+next];
@@ -175,7 +175,7 @@ void destaggerUorV_positiveOrder(double *fu, double *fuOut,
}
}
if (latE<nlat) // the last row we let as it is
- for ( int lon = 0; lon < nlon; lon++ )
+ for ( long lon = 0; lon < nlon; lon++ )
{
u0 = fu[idx];
fuOut[idx] = u0;
@@ -192,7 +192,7 @@ void *DestaggerUV()
int varID1 = CDI_UNDEFID, varID2 = CDI_UNDEFID;
int zaxisID1 = CDI_UNDEFID, zaxisID2 = CDI_UNDEFID;
int varID1stg = CDI_UNDEFID, varID2stg = CDI_UNDEFID;
- int gridsize;
+ size_t gridsize;
int chcodes[MAXARG];
char *chvars[MAXARG];
char varname[CDI_MAX_NAME];
@@ -202,7 +202,7 @@ void *DestaggerUV()
int gridID;
bool lcopy = false;
int UorV;
- int nlon = 0, nlat = 0;
+ size_t nlon = 0, nlat = 0;
double *ivar = NULL, *ovar = NULL;
double dxU = 0, dyU = 0, dxV = 0, dyV = 0;
@@ -410,7 +410,7 @@ void *DestaggerUV()
cdoPrint("Grid info: (xfirst_R = %3.2f; yfirst_R = %3.2f); (xfirst_U = %3.2f; yfirst_U = %3.2f); (xfirst_V = %3.2f; yfirst_V = %3.2f);",
xfirst_R,yfirst_R,xfirst_U,yfirst_U,xfirst_V,yfirst_V);
cdoPrint("Grid info: (dxU; dyU) = (%3.2f; %3.2f); (dxV; dyV) = (%3.2f; %3.2f) ", dxU, dyU, dxV, dyV);
- cdoPrint("Grid info: nlon=%d, nlat=%d ", nlon, nlat);
+ cdoPrint("Grid info: nlon=%zu, nlat=%zu ", nlon, nlat);
}
if ( cdoDebugExt )
{
@@ -460,7 +460,7 @@ void *DestaggerUV()
gridsize = gridInqSize(gridID1); // actual size of U-wind should be same as V-wind
if ( cdoDebugExt )
- cdoPrint("Allocating memory for gridsize (destaggered output)= %ld; nlon=%d, nlat=%d",gridsize,nlon,nlat );
+ cdoPrint("Allocating memory for gridsize (destaggered output)= %ld; nlon=%zu, nlat=%zu",gridsize,nlon,nlat );
ovar = (double *) Malloc(gridsize*sizeof(double));
} // end of if (!lcopy)
@@ -540,7 +540,7 @@ void *DestaggerUV()
if (UorV>=0) // re-check again since it could mean that current record with U or V is not staggered
{
- int nmiss;
+ size_t nmiss;
pstreamReadRecord(streamID1, ivar, &nmiss);
// read the original record with staggered u or v
gridsize = gridInqSize(gridID1);
@@ -665,8 +665,8 @@ void rot_uv_north(int gridID, double *us, double *vs)
iDirectionIncrementInDegrees = 0.1;
*/
- int nx = gridInqXsize(gridID);
- int ny = gridInqYsize(gridID);
+ size_t nx = gridInqXsize(gridID);
+ size_t ny = gridInqYsize(gridID);
double *xvals = (double *) Malloc(nx*ny*sizeof(double));
double *yvals = (double *) Malloc(nx*ny*sizeof(double));
@@ -693,10 +693,10 @@ void rot_uv_north(int gridID, double *us, double *vs)
if (cdoDebugExt)
- cdoPrint("%s(gridname=%s) .. processing grid with UV [nx*ny] (%d * %d)", __func__, gridNamePtr(gridInqType(gridID)), nx, ny );
+ cdoPrint("%s(gridname=%s) .. processing grid with UV [nx*ny] (%zu * %zu)", __func__, gridNamePtr(gridInqType(gridID)), nx, ny );
if (gridInqSize(gridID) != (nx*ny) )
- cdoAbort("Incorrect gridsize (%d) != nx*ny (%d * %d)", gridInqSize(gridID), nx, ny);
+ cdoAbort("Incorrect gridsize (%zu) != nx*ny (%zu * %zu)", gridInqSize(gridID), nx, ny);
// this should never happen
#define OPTrotuvNorth 1 // ACTIVATE SPEED - OPTIMIZATION
@@ -980,8 +980,8 @@ void project_uv_latlon(int gridID, double *us, double *vs)
double uu;
double vv;
- int nx = gridInqXsize(gridID);
- int ny = gridInqYsize(gridID);
+ size_t nx = gridInqXsize(gridID);
+ size_t ny = gridInqYsize(gridID);
double *xvals = (double *) Malloc(nx*ny*sizeof(double));
double *yvals = (double *) Malloc(nx*ny*sizeof(double));
@@ -992,10 +992,10 @@ void project_uv_latlon(int gridID, double *us, double *vs)
int signLat=( (yvals[1] - yvals[0]) < 0 )?-1:1;
if (cdoDebugExt)
- cdoPrint("%s(gridname=%s) .. processing grid with UV [nx*ny] (%d * %d)", __func__, gridNamePtr(gridInqType(gridID)), nx, ny );
+ cdoPrint("%s(gridname=%s) .. processing grid with UV [nx*ny] (%zu * %zu)", __func__, gridNamePtr(gridInqType(gridID)), nx, ny );
if (gridInqSize(gridID) != (nx*ny) )
- cdoAbort("Incorrect gridsize (%d) != nx*ny (%d * %d)", gridInqSize(gridID), nx, ny);
+ cdoAbort("Incorrect gridsize (%zu) != nx*ny (%zu * %zu)", gridInqSize(gridID), nx, ny);
// this should never happen
for ( j = 0; j < ny; j++ )
@@ -1072,11 +1072,11 @@ void *TransformUV(int operatorID)
{
int varID, levelID;
int varID1, varID2, nlevel1, nlevel2;
- int gridsize = 0;
+ size_t gridsize = 0;
int code, gridID;
int param, ltype, level, nlevs, zaxisID;
int pnum, pcat, pdis;
- int offset;
+ size_t offset;
int chcodes[MAXARG];
char *chvars[MAXARG];
char varname[CDI_MAX_NAME];
@@ -1124,7 +1124,7 @@ void *TransformUV(int operatorID)
int *recVarID = (int *) Malloc(nrecs*sizeof(int));
int *recLevelID = (int *) Malloc(nrecs*sizeof(int));
- int **varnmiss = (int **) Malloc(nvars*sizeof(int *));
+ size_t **varnmiss = (size_t **) Malloc(nvars*sizeof(size_t *));
double **vardata = (double **) Malloc(nvars*sizeof(double *));
// 0: set to '0'; 1: set to '1'
@@ -1186,9 +1186,9 @@ void *TransformUV(int operatorID)
{
gridsize = gridInqSize(gridID);
if ( cdoDebugExt )
- cdoPrint("Allocating memory for variableID %4d (code=%3d): gridsize(%d)*nlevels(%d) = %ld [%4.3f MB]",
+ cdoPrint("Allocating memory for variableID %4d (code=%3d): gridsize(%zu)*nlevels(%d) = %zu [%4.3f MB]",
varID, vlistInqVarCode(vlistID2, varID), gridsize, nlevs, gridsize*nlevs,gridsize*nlevs*sizeof(double)/(1024.0*1024));
- varnmiss[varID] = (int *) Malloc(nlevs*sizeof(int));
+ varnmiss[varID] = (size_t *) Malloc(nlevs*sizeof(size_t));
vardata[varID] = (double *) Malloc(gridsize*nlevs*sizeof(double));
}
}
@@ -1356,7 +1356,7 @@ void *TransformUV(int operatorID)
cdoPrint("grid Xlast %4.3f, grid Ylast %4.3f", gridInqXval(gridIDcurvl, gridInqSize(gridIDcurvl) -1), gridInqYval(gridIDcurvl, gridInqSize(gridIDcurvl) -1));
if ( cdoDebugExt>=20 )
{
- printf("Xvals (size=%d):\n",gridInqSize(gridIDcurvl));
+ printf("Xvals (size=%zu):\n",gridInqSize(gridIDcurvl));
int ii;
for (ii=0; ii< 10; ii++)
printf("%4.3f ", gridInqXval(gridIDcurvl,ii));
@@ -1364,7 +1364,7 @@ void *TransformUV(int operatorID)
for (ii=gridInqSize(gridIDcurvl)-10; ii< gridInqSize(gridIDcurvl); ii++)
printf("%4.3f ", gridInqXval(gridIDcurvl,ii));
printf("\n");
- printf("Yvals (size=%d):\n",gridInqSize(gridIDcurvl));
+ printf("Yvals (size=%zu):\n",gridInqSize(gridIDcurvl));
for (ii=0; ii< 10; ii++)
printf("%4.3f ", gridInqYval(gridIDcurvl,ii));
printf("\n...\n");
diff --git a/src/Writerandom.cc b/src/Writerandom.cc
index b88469f..2f7ad1f 100644
--- a/src/Writerandom.cc
+++ b/src/Writerandom.cc
@@ -58,7 +58,7 @@ void *Writerandom(void *argument)
double **recdata = (double**) Malloc(nrecs*sizeof(double*));
int *recvarID = (int*) Malloc(nrecs*sizeof(int));
int *reclevelID = (int*) Malloc(nrecs*sizeof(int));
- int *recnmiss = (int*) Malloc(nrecs*sizeof(int));
+ size_t *recnmiss = (size_t*) Malloc(nrecs*sizeof(size_t));
int *recindex = (int*) Malloc(nrecs*sizeof(int));
for ( int recID = 0; recID < nrecs; recID++ )
diff --git a/src/XTimstat.cc b/src/XTimstat.cc
index e2e6b00..51980a3 100644
--- a/src/XTimstat.cc
+++ b/src/XTimstat.cc
@@ -87,7 +87,8 @@ static int num_recs = 0;
static
void *cdoReadTimestep(void *rarg)
{
- int varID, levelID, nmiss;
+ int varID, levelID;
+ size_t nmiss;
readarg_t *readarg = (readarg_t *) rarg;
field_type **input_vars = readarg->vars;
recinfo_type *recinfo = readarg->recinfo;
@@ -158,7 +159,7 @@ void *XTimstat(void *argument)
int varID;
int streamID3 = -1;
int vlistID3, taxisID3 = -1;
- int nmiss;
+ size_t nmiss;
bool lvfrac = false;
int nwpv; // number of words per value; real:1 complex:2
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
@@ -370,7 +371,7 @@ void *XTimstat(void *argument)
int nwpv = pvars1->nwpv;
int gridsize = pvars1->size;
- int nmiss = pinput_var->nmiss;
+ size_t nmiss = pinput_var->nmiss;
farcpy(pvars1, *pinput_var);
pvars1->nmiss = nmiss;
@@ -399,7 +400,7 @@ void *XTimstat(void *argument)
int nwpv = pvars1->nwpv;
int gridsize = pvars1->size;
- int nmiss = pinput_var->nmiss;
+ size_t nmiss = pinput_var->nmiss;
if ( nmiss > 0 || samp1[varID][levelID].ptr )
{
diff --git a/src/YAR.cc b/src/YAR.cc
index 8776a68..42c6687 100644
--- a/src/YAR.cc
+++ b/src/YAR.cc
@@ -361,7 +361,7 @@ void yar_remap_bil(field_type *field1, field_type *field2)
remap.vars.num_wts, remap.vars.tgt_cell_add, remap.vars.src_cell_add, array1);
if ( cdoTimer ) timer_stop(timer_yar_remap);
- int nmiss = 0;
+ size_t nmiss = 0;
for ( int i = 0; i < gridInqSize(gridIDout); ++i )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
@@ -658,7 +658,7 @@ void yar_remap_con(field_type *field1, field_type *field2)
remap.vars.num_wts, remap.vars.tgt_cell_add, remap.vars.src_cell_add, array1);
if ( cdoTimer ) timer_stop(timer_yar_remap);
- int nmiss = 0;
+ size_t nmiss = 0;
for ( int i = 0; i < gridInqSize(gridIDout); ++i )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
@@ -689,7 +689,7 @@ void *YAR(void *argument)
int index;
int varID, levelID;
int gridID1 = -1;
- int nmiss;
+ size_t nmiss;
double missval;
if ( cdoTimer )
diff --git a/src/Ydayarith.cc b/src/Ydayarith.cc
index 0a8b509..a7a0c1c 100644
--- a/src/Ydayarith.cc
+++ b/src/Ydayarith.cc
@@ -36,9 +36,9 @@ void *Ydayarith(void *argument)
{
int nrecs;
int varID, levelID;
- int nmiss;
+ size_t nmiss;
int year, month, day;
- int **varnmiss2[MAX_DOY];
+ size_t **varnmiss2[MAX_DOY];
double **vardata2[MAX_DOY];
cdoInitialize(argument);
@@ -96,14 +96,14 @@ void *Ydayarith(void *argument)
if ( vardata2[dayoy] != NULL ) cdoAbort("Day of year %d already allocatd (date=%d)!", dayoy, vdate);
vardata2[dayoy] = (double **) Malloc(nvars*sizeof(double *));
- varnmiss2[dayoy] = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss2[dayoy] = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
size_t nlev = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
vardata2[dayoy][varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss2[dayoy][varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss2[dayoy][varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
for ( int recID = 0; recID < nrecs; recID++ )
@@ -142,7 +142,7 @@ void *Ydayarith(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
size_t offset = gridsize*levelID;
@@ -158,7 +158,7 @@ void *Ydayarith(void *argument)
farfun(&field1, field2, operfunc);
- nmiss = (int) field1.nmiss;
+ nmiss = field1.nmiss;
pstreamDefRecord(streamID3, varID, levelID);
pstreamWriteRecord(streamID3, field1.ptr, nmiss);
}
diff --git a/src/Ydaypctl.cc b/src/Ydaypctl.cc
index 2869b12..cc8833b 100644
--- a/src/Ydaypctl.cc
+++ b/src/Ydaypctl.cc
@@ -40,7 +40,7 @@ void *Ydaypctl(void *argument)
int year, month, day, dayoy;
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
int nlevels;
int vdates1[NDAY], vtimes1[NDAY];
int vdates2[NDAY];
diff --git a/src/Ydaystat.cc b/src/Ydaystat.cc
index 0c976f6..23eda70 100644
--- a/src/Ydaystat.cc
+++ b/src/Ydaystat.cc
@@ -38,6 +38,36 @@
#define MAX_DOY 373
+int yearMode = 0;
+
+static
+void set_parameter(void)
+{
+ int pargc = operatorArgc();
+ if ( pargc )
+ {
+ char **pargv = operatorArgv();
+
+ list_t *kvlist = list_new(sizeof(keyValues_t *), free_keyval, "PARAMETER");
+ if ( kvlist_parse_cmdline(kvlist, pargc, pargv) != 0 ) cdoAbort("Parse error!");
+ if ( cdoVerbose ) kvlist_print(kvlist);
+
+ for ( listNode_t *kvnode = kvlist->head; kvnode; kvnode = kvnode->next )
+ {
+ keyValues_t *kv = *(keyValues_t **)kvnode->data;
+ const char *key = kv->key;
+ if ( kv->nvalues > 1 ) cdoAbort("Too many values for parameter key >%s<!", key);
+ if ( kv->nvalues < 1 ) cdoAbort("Missing value for parameter key >%s<!", key);
+ const char *value = kv->values[0];
+
+ if ( STR_IS_EQ(key, "yearMode") ) yearMode = parameter2int(value);
+ else cdoAbort("Invalid parameter key >%s<!", key);
+ }
+
+ list_destroy(kvlist);
+ }
+}
+
void *Ydaystat(void *argument)
{
@@ -45,12 +75,14 @@ void *Ydaystat(void *argument)
int year, month, day;
int nrecs;
int dayoy_nsets[MAX_DOY];
- int nmiss;
+ size_t nmiss;
int vdates[MAX_DOY], vtimes[MAX_DOY];
field_type **vars1[MAX_DOY], **vars2[MAX_DOY], **samp1[MAX_DOY];
cdoInitialize(argument);
+ set_parameter();
+
// clang-format off
cdoOperatorAdd("ydayrange", func_range, 0, NULL);
cdoOperatorAdd("ydaymin", func_min, 0, NULL);
@@ -152,7 +184,7 @@ void *Ydaystat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t)nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
pvars2->nmiss = pvars1->nmiss;
@@ -172,7 +204,7 @@ void *Ydaystat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -225,20 +257,23 @@ void *Ydaystat(void *argument)
}
// set the year to the minimum of years found on output timestep
- int outyear = 1e9;
- for ( int dayoy = 0; dayoy < MAX_DOY; dayoy++ )
- if ( dayoy_nsets[dayoy] )
- {
- cdiDecodeDate(vdates[dayoy], &year, &month, &day);
- if ( year < outyear ) outyear = year;
- }
- for ( int dayoy = 0; dayoy < MAX_DOY; dayoy++ )
- if ( dayoy_nsets[dayoy] )
- {
- cdiDecodeDate(vdates[dayoy], &year, &month, &day);
- if ( year > outyear ) vdates[dayoy] = cdiEncodeDate(outyear, month, day);
- // printf("vdates[%d] = %d nsets = %d\n", dayoy, vdates[dayoy], nsets[dayoy]);
- }
+ if ( yearMode )
+ {
+ int outyear = 1e9;
+ for ( int dayoy = 0; dayoy < MAX_DOY; dayoy++ )
+ if ( dayoy_nsets[dayoy] )
+ {
+ cdiDecodeDate(vdates[dayoy], &year, &month, &day);
+ if ( year < outyear ) outyear = year;
+ }
+ for ( int dayoy = 0; dayoy < MAX_DOY; dayoy++ )
+ if ( dayoy_nsets[dayoy] )
+ {
+ cdiDecodeDate(vdates[dayoy], &year, &month, &day);
+ if ( year > outyear ) vdates[dayoy] = cdiEncodeDate(outyear, month, day);
+ // printf("vdates[%d] = %d nsets = %d\n", dayoy, vdates[dayoy], nsets[dayoy]);
+ }
+ }
for ( int dayoy = 0; dayoy < MAX_DOY; dayoy++ )
if ( dayoy_nsets[dayoy] )
@@ -291,7 +326,7 @@ void *Ydaystat(void *argument)
field_type *pvars1 = &vars1[dayoy][varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
otsID++;
diff --git a/src/Ydrunpctl.cc b/src/Ydrunpctl.cc
index 8c83906..2d584ec 100644
--- a/src/Ydrunpctl.cc
+++ b/src/Ydrunpctl.cc
@@ -46,7 +46,7 @@ void *Ydrunpctl(void *argument)
int nrecs;
int levelID;
int inp, its;
- int nmiss;
+ size_t nmiss;
int nlevels;
int year, month, day, dayoy;
int vdate, vtime;
diff --git a/src/Ydrunstat.cc b/src/Ydrunstat.cc
index 1083e88..213af61 100644
--- a/src/Ydrunstat.cc
+++ b/src/Ydrunstat.cc
@@ -64,7 +64,7 @@ void *Ydrunstat(void *argument)
int levelID;
int tsID;
int inp, its;
- int nmiss;
+ size_t nmiss;
cdoInitialize(argument);
diff --git a/src/Yearmonstat.cc b/src/Yearmonstat.cc
index daa8b59..cd20b9b 100644
--- a/src/Yearmonstat.cc
+++ b/src/Yearmonstat.cc
@@ -41,7 +41,7 @@ void *Yearmonstat(void *argument)
int dpm;
int year0 = 0, month0 = 0;
int year, month, day;
- int nmiss;
+ size_t nmiss;
int nlevel;
long nsets;
double dsets;
@@ -135,7 +135,7 @@ void *Yearmonstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, vars1[varID][levelID].ptr, &nmiss);
- vars1[varID][levelID].nmiss = (size_t) nmiss;
+ vars1[varID][levelID].nmiss = nmiss;
farcmul(&vars1[varID][levelID], dpm);
@@ -154,7 +154,7 @@ void *Yearmonstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t) nmiss;
+ field.nmiss = nmiss;
field.grid = vars1[varID][levelID].grid;
field.missval = vars1[varID][levelID].missval;
@@ -219,7 +219,7 @@ void *Yearmonstat(void *argument)
if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, (int)vars1[varID][levelID].nmiss);
+ pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, vars1[varID][levelID].nmiss);
}
if ( nrecs == 0 ) break;
diff --git a/src/Yhourarith.cc b/src/Yhourarith.cc
index 1415a1f..3ce2002 100644
--- a/src/Yhourarith.cc
+++ b/src/Yhourarith.cc
@@ -64,9 +64,9 @@ void *Yhourarith(void *argument)
int varID, levelID;
int offset;
int vdate, vtime;
- int nmiss;
+ size_t nmiss;
int houroy;
- int **varnmiss2[MAX_HOUR];
+ size_t **varnmiss2[MAX_HOUR];
double **vardata2[MAX_HOUR];
cdoInitialize(argument);
@@ -118,14 +118,14 @@ void *Yhourarith(void *argument)
if ( vardata2[houroy] != NULL ) cdoAbort("Hour of year %d already allocatd!", houroy);
vardata2[houroy] = (double **) Malloc(nvars*sizeof(double *));
- varnmiss2[houroy] = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss2[houroy] = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
vardata2[houroy][varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss2[houroy][varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss2[houroy][varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
for ( int recID = 0; recID < nrecs; recID++ )
@@ -159,7 +159,7 @@ void *Yhourarith(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field1.missval = vlistInqVarMissval(vlistID1, varID);
@@ -173,7 +173,7 @@ void *Yhourarith(void *argument)
farfun(&field1, field2, operfunc);
pstreamDefRecord(streamID3, varID, levelID);
- pstreamWriteRecord(streamID3, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID3, field1.ptr, field1.nmiss);
}
tsID++;
diff --git a/src/Yhourstat.cc b/src/Yhourstat.cc
index 3ecdb10..c81d1d7 100644
--- a/src/Yhourstat.cc
+++ b/src/Yhourstat.cc
@@ -71,7 +71,7 @@ void *Yhourstat(void *argument)
int nrecs;
int levelID;
int houroy_nsets[MAX_HOUR];
- int nmiss;
+ size_t nmiss;
int vdates[MAX_HOUR], vtimes[MAX_HOUR];
field_type **vars1[MAX_HOUR], **vars2[MAX_HOUR], **samp1[MAX_HOUR];
@@ -172,7 +172,7 @@ void *Yhourstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t) nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
pvars2->nmiss = pvars1->nmiss;
@@ -192,7 +192,7 @@ void *Yhourstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t) nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -295,7 +295,7 @@ void *Yhourstat(void *argument)
field_type *pvars1 = &vars1[houroy][varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
otsID++;
diff --git a/src/Ymonarith.cc b/src/Ymonarith.cc
index 13371d2..9c2bcbb 100644
--- a/src/Ymonarith.cc
+++ b/src/Ymonarith.cc
@@ -43,9 +43,9 @@ void *Ymonarith(void *argument)
int nrecs, nlev;
int varID, levelID;
int offset;
- int nmiss;
+ size_t nmiss;
int vdate, year, mon, day;
- int **varnmiss2[MAX_MON];
+ size_t **varnmiss2[MAX_MON];
double **vardata2[MAX_MON];
const char *seas_name[4];
@@ -117,14 +117,14 @@ void *Ymonarith(void *argument)
}
vardata2[mon] = (double **) Malloc(nvars*sizeof(double *));
- varnmiss2[mon] = (int **) Malloc(nvars*sizeof(int *));
+ varnmiss2[mon] = (size_t **) Malloc(nvars*sizeof(size_t *));
for ( varID = 0; varID < nvars; varID++ )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
nlev = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
vardata2[mon][varID] = (double*) Malloc(nlev*gridsize*sizeof(double));
- varnmiss2[mon][varID] = (int*) Malloc(nlev*sizeof(int));
+ varnmiss2[mon][varID] = (size_t*) Malloc(nlev*sizeof(size_t));
}
for ( int recID = 0; recID < nrecs; recID++ )
@@ -168,7 +168,7 @@ void *Ymonarith(void *argument)
{
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field1.missval = vlistInqVarMissval(vlistID1, varID);
@@ -176,14 +176,14 @@ void *Ymonarith(void *argument)
offset = gridsize*levelID;
memcpy(field2.ptr, vardata2[mon][varID]+offset, gridsize*sizeof(double));
- field2.nmiss = varnmiss2[mon][varID][levelID];
+ field2.nmiss = varnmiss2[mon][varID][levelID];
field2.grid = vlistInqVarGrid(vlistID2, varID);
field2.missval = vlistInqVarMissval(vlistID2, varID);
farfun(&field1, field2, operfunc);
pstreamDefRecord(streamID3, varID, levelID);
- pstreamWriteRecord(streamID3, field1.ptr, (int)field1.nmiss);
+ pstreamWriteRecord(streamID3, field1.ptr, field1.nmiss);
}
tsID++;
}
diff --git a/src/Ymonpctl.cc b/src/Ymonpctl.cc
index a5d5dd9..e1f04e7 100644
--- a/src/Ymonpctl.cc
+++ b/src/Ymonpctl.cc
@@ -45,7 +45,7 @@ void *Ymonpctl(void *argument)
int vdate, vtime;
int year, month, day;
int levelID;
- int nmiss;
+ size_t nmiss;
int nrecs, nlevels;
int vdates1[NMONTH], vtimes1[NMONTH];
int vdates2[NMONTH];
diff --git a/src/Ymonstat.cc b/src/Ymonstat.cc
index 88fd8f3..af53301 100644
--- a/src/Ymonstat.cc
+++ b/src/Ymonstat.cc
@@ -62,7 +62,7 @@ void *Ymonstat(void *argument)
int nrecs;
int levelID;
int month_nsets[NMONTH];
- int nmiss;
+ size_t nmiss;
int vdates[NMONTH], vtimes[NMONTH];
int mon[NMONTH];
int nmon = 0;
@@ -168,7 +168,7 @@ void *Ymonstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t) nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
pvars2->nmiss = pvars1->nmiss;
@@ -188,7 +188,7 @@ void *Ymonstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t) nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -319,7 +319,7 @@ void *Ymonstat(void *argument)
field_type *pvars1 = &vars1[month][varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
otsID++;
diff --git a/src/Yseaspctl.cc b/src/Yseaspctl.cc
index 24b6739..f57795e 100644
--- a/src/Yseaspctl.cc
+++ b/src/Yseaspctl.cc
@@ -49,7 +49,7 @@ void *Yseaspctl(void *argument)
int year, month, day, seas;
int nrecs;
int levelID;
- int nmiss;
+ size_t nmiss;
int nlevels;
long nsets[NSEAS];
date_time_t datetime1[NSEAS], datetime2[NSEAS];
diff --git a/src/Yseasstat.cc b/src/Yseasstat.cc
index aa142ef..bc0bde0 100644
--- a/src/Yseasstat.cc
+++ b/src/Yseasstat.cc
@@ -67,7 +67,7 @@ void *Yseasstat(void *argument)
int nrecs;
int levelID;
int seas_nsets[NSEAS];
- int nmiss;
+ size_t nmiss;
date_time_t datetime[NSEAS];
field_type **vars1[NSEAS], **vars2[NSEAS], **samp1[NSEAS];
@@ -168,7 +168,7 @@ void *Yseasstat(void *argument)
if ( nsets == 0 )
{
pstreamReadRecord(streamID1, pvars1->ptr, &nmiss);
- pvars1->nmiss = (size_t)nmiss;
+ pvars1->nmiss = nmiss;
if ( lrange )
{
pvars2->nmiss = pvars1->nmiss;
@@ -188,7 +188,7 @@ void *Yseasstat(void *argument)
else
{
pstreamReadRecord(streamID1, field.ptr, &nmiss);
- field.nmiss = (size_t)nmiss;
+ field.nmiss = nmiss;
field.grid = pvars1->grid;
field.missval = pvars1->missval;
@@ -291,7 +291,7 @@ void *Yseasstat(void *argument)
field_type *pvars1 = &vars1[seas][varID][levelID];
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, pvars1->ptr, (int)pvars1->nmiss);
+ pstreamWriteRecord(streamID2, pvars1->ptr, pvars1->nmiss);
}
otsID++;
diff --git a/src/Zonstat.cc b/src/Zonstat.cc
index 0a3421f..d0210d7 100644
--- a/src/Zonstat.cc
+++ b/src/Zonstat.cc
@@ -44,7 +44,7 @@ void *Zonstat(void *argument)
int gridID1 = -1, gridID2 = -1;
int zongridID = -1;
int index;
- int nmiss;
+ size_t nmiss;
int nrecs;
int varID, levelID;
@@ -156,7 +156,7 @@ void *Zonstat(void *argument)
pstreamInqRecord(streamID1, &varID, &levelID);
pstreamReadRecord(streamID1, field1.ptr, &nmiss);
- field1.nmiss = (size_t) nmiss;
+ field1.nmiss = nmiss;
field1.grid = vlistInqVarGrid(vlistID1, varID);
field1.missval = vlistInqVarMissval(vlistID1, varID);
field2.missval = vlistInqVarMissval(vlistID1, varID);
@@ -175,7 +175,7 @@ void *Zonstat(void *argument)
}
pstreamDefRecord(streamID2, varID, levelID);
- pstreamWriteRecord(streamID2, field2.ptr, (int)field2.nmiss);
+ pstreamWriteRecord(streamID2, field2.ptr, field2.nmiss);
}
tsID++;
diff --git a/src/after_vertint.cc b/src/after_vertint.cc
index 26eaae1..7980d64 100644
--- a/src/after_vertint.cc
+++ b/src/after_vertint.cc
@@ -100,7 +100,7 @@ void genind(int *nx, const double *restrict plev, const double *restrict fullp,
} /* genind */
-void genindmiss(int *nx, const double *restrict plev, int ngp, int nplev, const double *restrict ps_prog, int *restrict pnmiss)
+void genindmiss(int *nx, const double *restrict plev, int ngp, int nplev, const double *restrict ps_prog, size_t *restrict pnmiss)
{
#if defined(_OPENMP)
#pragma omp parallel for default(none) shared(nx,plev,ngp,nplev,ps_prog,pnmiss)
diff --git a/src/after_vertint.h b/src/after_vertint.h
index 4ddfbeb..4b23175 100644
--- a/src/after_vertint.h
+++ b/src/after_vertint.h
@@ -1,5 +1,5 @@
-#ifndef _VINTERP_H
-#define _VINTERP_H
+#ifndef VINTERP_H
+#define VINTERP_H
#include <stdbool.h>
@@ -7,25 +7,25 @@
extern "C" {
#endif
-void height2pressure(double * restrict phlev, const double * restrict hlev, long nphlev);
+void height2pressure(double *restrict phlev, const double *restrict hlev, long nphlev);
-void presh(double * restrict fullp, double * halfp, const double *restrict vct,
+void presh(double *restrict fullp, double *halfp, const double *restrict vct,
const double *restrict ps, long nhlev, long ngp);
-void genind(int *nx, const double * restrict plev, const double * restrict fullp, long ngp, long nplev, long nhlev);
-void genindmiss(int *nx, const double * restrict plev, int ngp, int nplev, const double * restrict ps_prog, int * restrict pnmiss);
+void genind(int *nx, const double *restrict plev, const double *restrict fullp, long ngp, long nplev, long nhlev);
+void genindmiss(int *nx, const double *restrict plev, int ngp, int nplev, const double *restrict ps_prog, size_t *restrict pnmiss);
-void extra_P(double * restrict slp, const double * restrict halfp, const double * restrict fullp,
- const double * restrict geop, const double * restrict temp, long ngp);
+void extra_P(double *restrict slp, const double *restrict halfp, const double *restrict fullp,
+ const double *restrict geop, const double *restrict temp, long ngp);
-void interp_T(const double * restrict geop, const double * restrict gt, double *pt, const double * restrict fullp,
- const double * restrict halfp, const int *nx, const double * restrict plev, long nplev, long ngp,
+void interp_T(const double *restrict geop, const double *restrict gt, double *pt, const double *restrict fullp,
+ const double *restrict halfp, const int *nx, const double *restrict plev, long nplev, long ngp,
long nhlev, double missval);
-void interp_Z(const double * restrict geop, const double * restrict gz, double *pz, const double * restrict fullp,
- const double * restrict halfp, const int *nx, const double * restrict gt, const double * restrict plev,
+void interp_Z(const double *restrict geop, const double *restrict gz, double *pz, const double *restrict fullp,
+ const double *restrict halfp, const int *nx, const double *restrict gt, const double *restrict plev,
long nplev, long ngp, long nhlev, double missval);
-void interp_X(const double * restrict gt, double *pt, const double * restrict hyb_press, const int *nx,
- const double * restrict plev, long nplev, long ngp, long nhlev, double missval);
+void interp_X(const double *restrict gt, double *pt, const double *restrict hyb_press, const int *nx,
+ const double *restrict plev, long nplev, long ngp, long nhlev, double missval);
void vert_interp_lev3d(int gridsize, double missval, double *vardata1, double *vardata2,
@@ -39,4 +39,4 @@ void vert_gen_weights3d1d(bool expol, int nlev1, int gridsize, double *lev1, int
}
#endif
-#endif /* _VINTERP_H */
+#endif /* VINTERP_H */
diff --git a/src/afterburner.h b/src/afterburner.h
index 29884be..ae1d0b7 100644
--- a/src/afterburner.h
+++ b/src/afterburner.h
@@ -80,7 +80,7 @@ struct Control
double *vct;
int *vert_index;
- int *pnmiss;
+ size_t *pnmiss;
double *Orography;
double *p_of_height;
@@ -141,8 +141,8 @@ struct Variable
int ogridID;
int izaxisID;
int ozaxisID;
- int nmiss0;
- int nmiss;
+ size_t nmiss0;
+ size_t nmiss;
double missval;
double *spectral;
double *spectral0;
@@ -241,9 +241,9 @@ void after_EchamCompGP(struct Control *globs, struct Variable *vars);
void after_processPL(struct Control *globs, struct Variable *vars);
void after_processML(struct Control *globs, struct Variable *vars);
-void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss);
+void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, size_t nmiss);
double *after_get_dataptr(struct Variable *vars, int code, int gridID, int zaxisID, int levelID);
-void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss);
+void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, size_t nmiss);
void after_AnalysisDependencies(struct Variable *vars, int ncodes);
void after_EchamDependencies(struct Variable *vars, int ncodes, int type, int source);
diff --git a/src/afterburnerlib.cc b/src/afterburnerlib.cc
index 5190630..a7c35c7 100644
--- a/src/afterburnerlib.cc
+++ b/src/afterburnerlib.cc
@@ -148,7 +148,7 @@ void VarQuaSum(double *Variance, const double *restrict Sum, int len, int n)
}
static
-void AddVector(double * restrict dest, const double *restrict src, long len, int *nmiss, double missval)
+void AddVector(double * restrict dest, const double *restrict src, long len, size_t *nmiss, double missval)
{
if ( *nmiss > 0 )
{
@@ -191,7 +191,7 @@ void Sub2Vectors(double *dest, const double *restrict srcA, const double *restri
}
static
-void MultVectorScalar(double *dest, const double *restrict src, double factor, int len, int nmiss, double missval)
+void MultVectorScalar(double *dest, const double *restrict src, double factor, int len, size_t nmiss, double missval)
{
if ( nmiss > 0 )
{
@@ -210,7 +210,7 @@ void MultVectorScalar(double *dest, const double *restrict src, double factor, i
}
static
-void DivVectorIvector(double *dest, const double *restrict src, const int *samp, int len, int *nmiss, double missval)
+void DivVectorIvector(double *dest, const double *restrict src, const int *samp, int len, size_t *nmiss, double missval)
{
*nmiss = 0;
@@ -1565,7 +1565,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
int lindex, nlevel;
int offset;
int leveltype;
- int nmiss;
+ size_t nmiss;
double *pressureLevel = NULL;
globs->MeanCount++;
@@ -1923,7 +1923,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
nmiss = 0;
if ( ! globs->Extrapolate )
{
- if ( globs->pnmiss == NULL ) globs->pnmiss = (int *) Malloc(globs->NumLevelRequest*sizeof(int));
+ if ( globs->pnmiss == NULL ) globs->pnmiss = (size_t *) Malloc(globs->NumLevelRequest*sizeof(size_t));
genindmiss(globs->vert_index, pressureLevel, globs->DimGP, globs->NumLevelRequest, vars[PS_PROG].hybrid, globs->pnmiss);
for ( i = 0; i < globs->NumLevelRequest; i++ ) nmiss += globs->pnmiss[i];
}
@@ -2393,7 +2393,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
}
}
-void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, size_t nmiss)
{
long fieldSize;
int truncation;
@@ -2506,7 +2506,7 @@ double *after_get_dataptr(struct Variable *vars, int code, int gridID, int zaxis
}
-void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, size_t nmiss)
{
int gridtype = gridInqType(gridID);
int leveltype = zaxisInqType(zaxisID);
diff --git a/src/argument.cc b/src/argument.cc
index 34e0f03..0c7b99d 100644
--- a/src/argument.cc
+++ b/src/argument.cc
@@ -97,7 +97,7 @@ void argument_free(argument_t *argument)
argument->args = NULL;
}
- Free(argument);
+ delete(argument);
}
}
@@ -109,16 +109,34 @@ void argument_fill(argument_t *argument, int argc, char *argv[])
argument->argv[iarg] = strdup(argv[iarg]);
}
-void print_argument(argument_t * p_argument)
+std::string print_argument(argument_t * p_argument)
{
- std::cout << "argv with " << p_argument->argc << " arguments:" << std::endl;
+ std::string output = "";
+ output += "argv with " + std::to_string(p_argument->argc) + " arguments:\n" ;
for(int i = 0; i < p_argument->argc; i++)
{
- std::cout << p_argument->argv[i] << " ";
+ output += std::string(p_argument->argv[i]) + " ";
}
- std::cout << std::endl;
+ output += "\n";
+
+ output += "OperatorName: " + p_argument->operatorName + "\n";
- std::cout << "OperatorName: "<< p_argument->operatorName << std::endl;
+ output += "operatorArguments";
+ if(p_argument->operatorArguments){
+ output += ": " + std::string(p_argument->operatorArguments) + "\n";
+ }
+ else
+ {
+ output += " not set\n";
+ }
- std::cout << "operatorArguments: " << p_argument->operatorArguments << std::endl;
+ output += "args";
+ if(p_argument->operatorArguments){
+ output += ": " + std::string(p_argument->args) + "\n";
+ }
+ else
+ {
+ output += " not set\n";
+ }
+ return output;
}
diff --git a/src/argument.h b/src/argument.h
index f45cdc3..394ef11 100644
--- a/src/argument.h
+++ b/src/argument.h
@@ -22,5 +22,5 @@ void file_argument_free(argument_t *argument);
argument_t *argument_new(size_t argc, size_t len);
void argument_free(argument_t *argument);
void argument_fill(argument_t *argument, int argc, char *argv[]);
-void print_argument(argument_t *argument);
+std::string print_argument(argument_t *argument);
#endif
diff --git a/src/cdo.cc b/src/cdo.cc
index 2b3902b..a109c10 100644
--- a/src/cdo.cc
+++ b/src/cdo.cc
@@ -49,6 +49,7 @@
#include "cdo_task.h"
#include "cdo_getopt.h"
+#include "cdoDebugOutput.h"
#if defined(HAVE_LIBPTHREAD)
#include "pstream_int.h"
@@ -56,6 +57,7 @@
#endif
#include "modules.h"
+#include "process.h"
#include "error.h"
#include "grid_proj.h"
@@ -79,7 +81,7 @@ static int numThreads = 0;
static int timer_total;
static int CDO_netcdf_hdr_pad = 0;
static int CDO_Rusage = 0;
-static const char *username;
+const char *CDO_username;
#ifdef __cplusplus
extern "C" {
@@ -111,7 +113,7 @@ void gridsearch_set_method(const char *methodstr);
} \
}
-#define ITSME (strcmp(username, "\x6d\x32\x31\x34\x30\x30\x33") == 0)
+#define ITSME (strcmp(CDO_username, "\x6d\x32\x31\x34\x30\x30\x33") == 0)
static
void cdo_stackframe(void)
@@ -190,22 +192,28 @@ void cdo_version(void)
const int filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5};
const char* typenames[] = { "srv", "ext", "ieg", "grb1", "grb2", "nc1", "nc2", "nc4", "nc4c", "nc5"};
- fprintf(stderr, "%s\n", CDO_Version);
+ fprintf(stderr, "%s\n", CDO_version);
#if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n", USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
#endif
#if defined(CXX_COMPILER)
fprintf(stderr, "CXX Compiler: %s\n", CXX_COMPILER);
-#endif
#if defined(CXX_VERSION)
fprintf(stderr, "CXX version : %s\n", CXX_VERSION);
#endif
+#endif
#if defined(C_COMPILER)
fprintf(stderr, "C Compiler: %s\n", C_COMPILER);
-#endif
#if defined(C_VERSION)
fprintf(stderr, "C version : %s\n", C_VERSION);
#endif
+#endif
+#if defined(F77_COMPILER)
+ fprintf(stderr, "F77 Compiler: %s\n", F77_COMPILER);
+#if defined(F77_VERSION)
+ fprintf(stderr, "F77 version : %s\n", F77_VERSION);
+#endif
+#endif
printFeatures();
printLibraries();
@@ -226,7 +234,7 @@ void cdo_usage(void)
{
const char *name;
- /* fprintf(stderr, "%s\n", CDO_Version);*/
+ /* fprintf(stderr, "%s\n", CDO_version);*/
/* fprintf(stderr, "\n");*/
fprintf(stderr, "usage : cdo [Options] Operator1 [-Operator2 [-OperatorN]]\n");
fprintf(stderr, "\n");
@@ -340,7 +348,7 @@ void cdoPrintHelp(std::vector<std::string> help/*, char *xoperator*/)
for(unsigned long i = 0; i < help.size(); i++)
{
lprint = !(help[i][0] == '\0' && help[i+1][0] == ' ');
-
+
if ( lprint )
{
if ( COLOR_STDOUT )
@@ -725,11 +733,11 @@ void defineVarnames(const char *arg)
static
void get_env_vars(void)
{
- username = getenv("LOGNAME");
- if ( username == NULL )
+ CDO_username = getenv("LOGNAME");
+ if ( CDO_username == NULL )
{
- username = getenv("USER");
- if ( username == NULL ) username = "unknown";
+ CDO_username = getenv("USER");
+ if ( CDO_username == NULL ) CDO_username = "unknown";
}
char *envstr = getenv("CDO_GRID_SEARCH_DIR");
@@ -912,6 +920,7 @@ void print_system_info()
#endif
fprintf(stderr, "\n");
+ fprintf(stderr, "sizeof(size_t) = %zu\n", sizeof(size_t));
fprintf(stderr, "mem alignment = %d\n\n", getMemAlignment());
#if defined(HAVE_MMAP)
@@ -1103,6 +1112,7 @@ int parse_options_long(int argc, char *argv[])
int lsortparam;
int ldebLevel;
int lscmode;
+ bool sepDebugFromLog;
// clang-format off
struct cdo_option opt_long[] =
@@ -1141,6 +1151,7 @@ int parse_options_long(int argc, char *argv[])
{ "version", no_argument, NULL, 'V' },
{ "Dkext", required_argument, &ldebLevel, 1 },
{ "outputGribDataScanningMode", required_argument, &lscmode, 1 },
+ { "seperateDebugFromLog", required_argument, NULL, 2 },
{ NULL, 0, NULL, 0 }
};
// clang-format on
@@ -1205,7 +1216,7 @@ int parse_options_long(int argc, char *argv[])
else if ( strcmp(CDO_optarg, "UNDERFLOW") == 0 ) except = FE_UNDERFLOW;
else if ( strcmp(CDO_optarg, "ALL_EXCEPT") == 0 ) except = FE_ALL_EXCEPT;
if ( except < 0 ) cdoAbort("option --%s: unsupported argument: %s", "enableexcept", CDO_optarg);
- cdo_feenableexcept((unsigned)except);
+ cdo_feenableexcept(except);
if ( signal(SIGFPE, cdo_sig_handler) == SIG_ERR ) cdoWarning("can't catch SIGFPE!");
}
else if ( ltimestat_date )
@@ -1247,7 +1258,7 @@ int parse_options_long(int argc, char *argv[])
int intarg = parameter2int(CDO_optarg);
if ( intarg != 0 && intarg != 1 )
cdoAbort("Unsupported value for option --remap_genweights %d [0/1]", intarg);
- remap_genweights = intarg;
+ REMAP_genweights = intarg;
}
else if ( lsortname )
{
@@ -1413,6 +1424,12 @@ int parse_options_long(int argc, char *argv[])
case 'z':
defineCompress(CDO_optarg);
break;
+ case 2:
+#ifdef DEBUG
+ CdoDebug::outfile = CDO_optarg;
+ CdoDebug::print_to_seperate_file = true;
+#endif
+ break;
}
}
@@ -1474,11 +1491,9 @@ int main(int argc, char *argv[])
setCommandLine(argc, argv);
- Progname = getProgname(argv[0]);
-
- if ( strncmp(Progname, "cdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
-
- if ( noff ) setDefaultFileType(Progname+noff, 0);
+ CDO_progname = getProgname(argv[0]);
+ if ( strncmp(CDO_progname, "cdo", 3) == 0 && strlen(CDO_progname) > 3 ) noff = 3;
+ if ( noff ) setDefaultFileType(CDO_progname+noff, 0);
get_env_vars();
init_modules();
@@ -1608,13 +1623,18 @@ int main(int argc, char *argv[])
timer_start(timer_total);
+#ifdef DEBUG
+ CdoDebug::Message_(":==CDO==","Start");
+#endif
#ifdef CUSTOM_MODULES
load_custom_modules("custom_modules");
operatorModule(operatorName)(argument);
close_library_handles();
#else
operatorModule(operatorName)(argument);
-
+#endif
+#ifdef DEBUG
+ CdoDebug::Message_(":==CDO==","End\n");
#endif
timer_stop(timer_total);
diff --git a/src/cdoDebugOutput.cc b/src/cdoDebugOutput.cc
new file mode 100644
index 0000000..1bd3c0d
--- /dev/null
+++ b/src/cdoDebugOutput.cc
@@ -0,0 +1,22 @@
+#include "cdoDebugOutput.h"
+
+
+
+namespace CdoDebug{
+
+#if defined(DEBUG_PSTREAM) || defined(DEBUG)
+ int PSTREAM = 1;
+#else
+ int PSTREAM = 0;
+#endif
+
+#if defined(DEBUG_PROCESS) || defined(DEBUG)
+ bool PROCESS = true;
+#else
+ bool PROCESS = false;
+#endif
+
+ std::string outfile = "";
+ bool print_to_seperate_file = false;
+}
+
diff --git a/src/cdoDebugOutput.h b/src/cdoDebugOutput.h
new file mode 100644
index 0000000..28fc437
--- /dev/null
+++ b/src/cdoDebugOutput.h
@@ -0,0 +1,112 @@
+#ifndef DEBUG_SWITCHES_H
+#define DEBUG_SWITCHES_H
+#include <iostream>
+#include <sstream>
+
+#include <fstream>
+
+namespace CdoDebug
+{
+ extern int PSTREAM;
+ extern bool PROCESS;
+ extern std::string outfile;
+ extern bool print_to_seperate_file;
+
+ namespace{
+ void printMessageToFile(std::stringstream &p_message)
+ {
+ if(!outfile.empty()){
+ std::fstream outfile_stream(outfile,std::fstream::in | std::fstream::app );
+
+ outfile_stream << p_message.str();
+ }
+ }
+ }
+
+
+ template <typename ...T>
+ void Message_ (std::stringstream &p_message, T&& ...args)
+ {
+ //for showing that the dummy array is never used
+ using expander = int[];
+ //creating dummy array with expanding the parameter pack in its
+ //initializer list while writing each element of the pack into message
+ expander{0,(void(p_message << std::forward<T>(args)),0)...};
+ p_message << std::endl;
+ }
+
+ template <typename ...T>
+ void Message_ (const char * p_func, T&& ...args)
+ {
+ std::stringstream message;
+ message << p_func <<": ";
+ Message_(message, args...);
+ if(print_to_seperate_file)
+ {
+ printMessageToFile(message);
+ }
+ else
+ {
+ std::cout << message.str();
+ }
+ }
+}
+
+namespace CdoError{
+ static int _ExitOnError = 1;
+
+ template <typename ...T>
+ void Error_(const char* p_file, const int p_line, const char* caller, T&& ...args)
+ {
+ std::stringstream message;
+ message << "Error in: " << p_file << ":" << p_line << " ";
+ CdoDebug::Message_(message, args...);
+ std::cout << message.str();
+ if ( CdoError::_ExitOnError )
+ {
+ exit(EXIT_FAILURE);
+ }
+ }
+ template <typename ...T>
+ void Warning_(T&& ...args)
+ {
+ std::stringstream message;
+ message << "Warning: ";
+ CdoDebug::Message_(message, args...);
+ std::cout << message.str();
+ }
+
+ template <typename ...T>
+ void SysError_(const char* p_file, const int p_line, const char* p_func, T&& ...args)
+ {
+ int saved_errno = errno;
+ std::stringstream message;
+ message << "SysError in:" << p_file << std::endl;
+ message << " " << "in function: p_func ,line: " << p_line << std::endl;
+ CdoDebug::Message_(message, args...);
+
+ if(saved_errno)
+ {
+ errno = saved_errno;
+ perror("Sytem error message");
+ }
+ exit(EXIT_FAILURE);
+ }
+}
+#if defined WITH_CALLER_NAME
+# define SYS_ERROR(...) CdoError::SysError_( __FILE__ , __LINE__ , __func__ , __VA_ARGS__)
+# define ERROR_C(...) CdoError::Error_( __FILE__ , __LINE__ , caller, __VA_ARGS__)
+# define ERROR(...) CdoError::Error_( __FILE__ , __LINE__ , __func__ , __VA_ARGS__)
+# define WARNING(...) CdoError::Warning_( __func__ , __VA_ARGS__)
+# define MESSAGE_C(...) CdoDebug::Message_( caller , __VA_ARGS__)
+# define MESSAGE(...) CdoDebug::Message_( __func__ , __VA_ARGS__)
+#else
+# define SYS_ERROR(...) CdoError::SysError_(__FILE__, __LINE__,"", __VA_ARGS__)
+# define ERROR_C(...) CdoError::Error_(__FILE__, __LINE__,"", __VA_ARGS__)
+# define ERROR(...) CdoError::Error_(__FILE__, __LINE__,"", __VA_ARGS__)
+# define WARNING(...) CdoError::Warning_(__VA_ARGS__)
+# define MESSAGE_C(...) CdoDebug::Message_(__VA_ARGS__)
+# define MESSAGE(...) CdoDebug::Message_(__func__,__VA_ARGS__)
+#endif
+
+#endif
diff --git a/src/cdo_int.h b/src/cdo_int.h
index 8ba955c..b83eac9 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -15,11 +15,11 @@
GNU General Public License for more details.
*/
-#ifndef _CDO_INT_H
-#define _CDO_INT_H
+#ifndef CDO_INT_H
+#define CDO_INT_H
-#if defined(HAVE_CONFIG_H)
-# include "config.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#include <assert.h>
@@ -103,10 +103,10 @@ enum T_EIGEN_MODE {JACOBI, DANIELSON_LANCZOS};
#endif
-#define NEW_2D(T, P2D, N, M) T **P2D = (N)?new T*[(N)]:nullptr; \
- if ((N)) { P2D[0] = (M)?new T[(N)*(M)]:nullptr; \
- for ( size_t i = 1; i < (size_t) (N); ++i ) P2D[i] = P2D[0] + i*(M); }
-#define DELETE_2D(P2D) if (P2D) { if (P2D[0]) delete[] P2D[0]; delete[] P2D; P2D = nullptr; }
+#define NEW_2D(T, P2D, N, M) T **P2D = (N)?new T*[(N)]:nullptr; \
+ if ((N)) { P2D[0] = (M)?new T[(N)*(M)]:nullptr; \
+ for ( size_t i = 1; i < (size_t) (N); ++i ) P2D[i] = P2D[0] + i*(M); }
+#define DELETE_2D(P2D) if (P2D) { if (P2D[0]) delete[] P2D[0]; delete[] P2D; P2D = nullptr; }
#define IX2D(y,x,nx) ((y)*(nx)+(x))
@@ -163,6 +163,7 @@ const char *parameter2word(const char *string);
double parameter2double(const char *string);
bool parameter2bool(const char *string);
int parameter2int(const char *string);
+size_t parameter2sizet(const char *string);
int parameter2intlist(const char *string);
int referenceToGrid(int gridID1);
@@ -204,4 +205,4 @@ int vlistCompareX(int vlistID1, int vlistID2, int flag);
}
#endif
-#endif /* _CDO_INT_H */
+#endif /* CDO_INT_H */
diff --git a/src/cdo_read.cc b/src/cdo_read.cc
index ebed97f..41c0cae 100644
--- a/src/cdo_read.cc
+++ b/src/cdo_read.cc
@@ -45,7 +45,7 @@ bool *cdo_read_timestepmask(const char *maskfile, int *n)
if ( nrecs != 1 ) cdoAbort("Internal error; unexprected number of records!");
int varID, levelID;
- int nmiss;
+ size_t nmiss;
double value;
streamInqRecord(streamID, &varID, &levelID);
streamReadRecord(streamID, &value, &nmiss);
@@ -86,7 +86,7 @@ bool *cdo_read_mask(const char *maskfile, int *n)
if ( nrecs != 1 ) cdoAbort("Internal error; unexprected number of records!");
int varID, levelID;
- int nmiss;
+ size_t nmiss;
streamInqRecord(streamID, &varID, &levelID);
streamReadRecord(streamID, dmask, &nmiss);
diff --git a/src/cdo_vlist.cc b/src/cdo_vlist.cc
index a7874d4..bf21271 100644
--- a/src/cdo_vlist.cc
+++ b/src/cdo_vlist.cc
@@ -50,7 +50,7 @@ int cdoZaxisInqLevels(int zaxisID, double *levels)
}
static
-void compare_lat_reg2d(int ysize, int gridID1, int gridID2)
+void compare_lat_reg2d(size_t ysize, int gridID1, int gridID2)
{
if ( ysize > 1 )
{
@@ -70,7 +70,7 @@ void compare_lat_reg2d(int ysize, int gridID1, int gridID2)
}
else
{
- for ( int i = 0; i < ysize; ++i )
+ for ( size_t i = 0; i < ysize; ++i )
if ( fabs(yvals1[i] - yvals2[i]) > 3.e-5 )
{
cdoWarning("Grid latitudes differ!");
@@ -84,7 +84,7 @@ void compare_lat_reg2d(int ysize, int gridID1, int gridID2)
}
static
-void compare_lon_reg2d(int xsize, int gridID1, int gridID2)
+void compare_lon_reg2d(size_t xsize, int gridID1, int gridID2)
{
if ( xsize > 1 )
{
@@ -94,7 +94,7 @@ void compare_lon_reg2d(int xsize, int gridID1, int gridID2)
gridInqXvals(gridID1, xvals1);
gridInqXvals(gridID2, xvals2);
- for ( int i = 0; i < xsize; ++i )
+ for ( size_t i = 0; i < xsize; ++i )
if ( fabs(xvals1[i] - xvals2[i]) > 3.e-5 )
{
cdoWarning("Grid longitudes differ!");
@@ -112,7 +112,7 @@ void compare_grid_unstructured(int gridID1, int gridID2)
if ( gridInqXvals(gridID1, NULL) && gridInqXvals(gridID1, NULL) == gridInqXvals(gridID2, NULL) &&
gridInqYvals(gridID1, NULL) && gridInqYvals(gridID1, NULL) == gridInqYvals(gridID2, NULL) )
{
- int gridsize = gridInqSize(gridID1);
+ size_t gridsize = gridInqSize(gridID1);
double *xvals1 = (double*) Malloc(gridsize*sizeof(double));
double *xvals2 = (double*) Malloc(gridsize*sizeof(double));
@@ -125,7 +125,7 @@ void compare_grid_unstructured(int gridID1, int gridID2)
gridInqYvals(gridID2, yvals2);
int inc = gridsize > 10000 ? gridsize/1000 : 1;
- for ( int i = 0; i < gridsize; i += inc )
+ for ( size_t i = 0; i < gridsize; i += inc )
if ( fabs(xvals1[i] - xvals2[i]) > 2.e-5 || fabs(yvals1[i] - yvals2[i]) > 2.e-5 )
{
// printf("%d %g %g %g %g %g %g\n", i, xvals1[i], xvals2[i], yvals1[i], yvals2[i], xvals1[i] - xvals2[i], yvals1[i] - yvals2[i]);
@@ -149,8 +149,8 @@ void cdoCompareGrids(int gridID1, int gridID2)
{
if ( gridInqType(gridID1) == GRID_GAUSSIAN || gridInqType(gridID1) == GRID_LONLAT )
{
- int xsize = gridInqXsize(gridID1);
- int ysize = gridInqYsize(gridID1);
+ size_t xsize = gridInqXsize(gridID1);
+ size_t ysize = gridInqYsize(gridID1);
if ( ysize == gridInqYsize(gridID2) )
compare_lat_reg2d(ysize, gridID1, gridID2);
@@ -367,12 +367,12 @@ int vlistInqNWPV(int vlistID, int varID)
}
-int vlist_check_gridsize(int vlistID)
+size_t vlist_check_gridsize(int vlistID)
{
bool lerror = false;
int ngrids = vlistNgrids(vlistID);
int gridID = vlistGrid(vlistID, 0);
- int ngp = gridInqSize(gridID);
+ size_t ngp = gridInqSize(gridID);
/* check gridsize */
for ( int index = 0; index < ngrids; ++index )
@@ -392,7 +392,7 @@ int vlist_check_gridsize(int vlistID)
for ( int index = 0; index < ngrids; ++index )
{
gridID = vlistGrid(vlistID, index);
- cdoPrint(" grid=%d type=%s points=%d", index+1, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID));
+ cdoPrint(" grid=%d type=%s points=%zu", index+1, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID));
}
cdoAbort("The input stream contains variables on different horizontal grids!");
}
diff --git a/src/cdotest.cc b/src/cdotest.cc
index 3b2516e..03ef603 100644
--- a/src/cdotest.cc
+++ b/src/cdotest.cc
@@ -54,7 +54,8 @@ void readNcFile(const char path[], double **vars, int nvars, int nts)
{
int taxisID;
int vlistID, varID, streamID, tsID;
- int nmiss, nrecs;
+ size_t nmiss;
+ int nrecs;
streamID = streamOpenRead(path);
if ( streamID < 0 )
@@ -93,7 +94,7 @@ void writeNcFile(const char path[], const double array[], int length)
{
int gridID, zaxisID, taxisID;
int vlistID, varID, streamID, tsID;
- int nmiss;
+ size_t nmiss;
double lons[] = {0.0};
double lats[] = {0.0};
diff --git a/src/cellsearchorder.h b/src/cellsearchorder.h
new file mode 100644
index 0000000..4126e7d
--- /dev/null
+++ b/src/cellsearchorder.h
@@ -0,0 +1,30000 @@
+0,0,0,13,
+0,0,1,18,
+0,1,1,24,
+1,1,1,31,
+0,0,2,31,
+0,1,2,33,
+1,1,2,39,
+0,2,2,42,
+1,2,2,49,
+0,0,3,49,
+0,1,3,49,
+1,1,3,51,
+2,2,2,56,
+0,2,3,56,
+1,2,3,61,
+0,0,4,61,
+0,1,4,61,
+2,2,3,72,
+0,3,3,72,
+1,1,4,72,
+1,3,3,75,
+0,2,4,75,
+1,2,4,77,
+2,3,3,86,
+2,2,4,89,
+0,0,5,89,
+0,3,4,89,
+0,1,5,89,
+1,3,4,92,
+1,1,5,92,
+3,3,3,101,
+2,3,4,104,
+0,2,5,104,
+1,2,5,104,
+0,4,4,104,
+2,2,5,110,
+1,4,4,110,
+3,3,4,120,
+0,3,5,120,
+1,3,5,120,
+0,0,6,120,
+2,4,4,121,
+0,1,6,121,
+1,1,6,121,
+2,3,5,128,
+0,2,6,128,
+3,4,4,135,
+0,4,5,135,
+1,2,6,135,
+1,4,5,135,
+3,3,5,141,
+2,2,6,141,
+2,4,5,147,
+0,3,6,147,
+1,3,6,147,
+4,4,4,159,
+2,3,6,159,
+0,0,7,159,
+0,1,7,159,
+0,5,5,159,
+3,4,5,164,
+1,1,7,164,
+1,5,5,164,
+0,4,6,164,
+1,4,6,164,
+0,2,7,164,
+1,2,7,164,
+3,3,6,170,
+2,5,5,170,
+2,4,6,173,
+2,2,7,173,
+4,4,5,182,
+0,3,7,182,
+3,5,5,187,
+1,3,7,187,
+3,4,6,191,
+0,5,6,191,
+1,5,6,191,
+2,3,7,191,
+0,0,8,191,
+0,4,7,191,
+0,1,8,191,
+2,5,6,199,
+1,1,8,199,
+1,4,7,199,
+4,5,5,211,
+3,3,7,211,
+4,4,6,213,
+0,2,8,213,
+2,4,7,213,
+1,2,8,213,
+3,5,6,218,
+0,6,6,218,
+2,2,8,218,
+0,3,8,218,
+1,6,6,218,
+1,3,8,218,
+3,4,7,224,
+0,5,7,224,
+5,5,5,236,
+1,5,7,236,
+2,6,6,236,
+4,5,6,241,
+2,3,8,241,
+2,5,7,241,
+0,4,8,241,
+4,4,7,251,
+1,4,8,251,
+3,6,6,251,
+0,0,9,251,
+3,3,8,251,
+0,1,9,251,
+3,5,7,255,
+1,1,9,255,
+2,4,8,255,
+0,6,7,255,
+0,2,9,255,
+5,5,6,268,
+1,6,7,268,
+1,2,9,268,
+4,6,6,272,
+2,6,7,272,
+3,4,8,272,
+2,2,9,272,
+0,5,8,272,
+4,5,7,277,
+0,3,9,277,
+1,5,8,277,
+1,3,9,277,
+2,5,8,277,
+3,6,7,285,
+2,3,9,285,
+4,4,8,290,
+5,6,6,300,
+0,4,9,300,
+1,4,9,300,
+3,5,8,300,
+0,7,7,300,
+5,5,7,306,
+1,7,7,306,
+3,3,9,306,
+0,6,8,306,
+0,0,10,306,
+4,6,7,311,
+2,4,9,311,
+1,6,8,311,
+0,1,10,311,
+2,7,7,311,
+1,1,10,311,
+0,2,10,311,
+2,6,8,311,
+1,2,10,311,
+4,5,8,320,
+0,5,9,320,
+3,4,9,320,
+3,7,7,325,
+1,5,9,325,
+2,2,10,325,
+6,6,6,331,
+0,3,10,331,
+3,6,8,331,
+5,6,7,339,
+2,5,9,339,
+1,3,10,339,
+2,3,10,339,
+4,4,9,339,
+0,7,8,339,
+1,7,8,339,
+4,7,7,350,
+5,5,8,350,
+3,5,9,350,
+4,6,8,353,
+0,4,10,353,
+2,7,8,353,
+0,6,9,353,
+1,4,10,353,
+3,3,10,353,
+1,6,9,353,
+2,4,10,353,
+6,6,7,378,
+2,6,9,378,
+0,0,11,378,
+4,5,9,378,
+0,1,11,378,
+3,7,8,378,
+1,1,11,378,
+5,7,7,382,
+0,2,11,382,
+5,6,8,386,
+3,4,10,386,
+0,5,10,386,
+3,6,9,386,
+1,5,10,386,
+1,2,11,386,
+0,8,8,386,
+1,8,8,386,
+4,7,8,393,
+2,2,11,393,
+2,5,10,393,
+0,7,9,393,
+0,3,11,393,
+5,5,9,399,
+1,7,9,399,
+1,3,11,399,
+4,4,10,399,
+2,8,8,399,
+4,6,9,404,
+3,5,10,404,
+2,3,11,404,
+6,7,7,416,
+2,7,9,416,
+0,6,10,416,
+6,6,8,421,
+1,6,10,421,
+3,8,8,421,
+0,4,11,421,
+1,4,11,421,
+5,7,8,429,
+3,3,11,429,
+3,7,9,429,
+2,6,10,429,
+4,5,10,429,
+2,4,11,429,
+5,6,9,439,
+0,0,12,439,
+4,8,8,442,
+0,1,12,442,
+0,8,9,442,
+3,6,10,442,
+4,7,9,447,
+1,1,12,447,
+3,4,11,447,
+0,5,11,447,
+1,8,9,447,
+7,7,7,459,
+1,5,11,459,
+0,2,12,459,
+2,8,9,459,
+6,7,8,465,
+0,7,10,465,
+1,2,12,465,
+5,5,10,465,
+2,5,11,465,
+1,7,10,465,
+2,2,12,465,
+4,6,10,465,
+5,8,8,475,
+0,3,12,475,
+2,7,10,475,
+6,6,9,475,
+4,4,11,475,
+3,8,9,475,
+1,3,12,475,
+5,7,9,483,
+3,5,11,483,
+2,3,12,483,
+0,6,11,483,
+1,6,11,483,
+3,7,10,483,
+0,4,12,483,
+2,6,11,483,
+5,6,10,494,
+4,8,9,494,
+1,4,12,494,
+7,7,8,509,
+3,3,12,509,
+0,9,9,509,
+4,5,11,509,
+1,9,9,509,
+6,8,8,512,
+2,4,12,512,
+0,8,10,512,
+4,7,10,512,
+1,8,10,512,
+2,9,9,512,
+6,7,9,520,
+3,6,11,520,
+2,8,10,520,
+3,4,12,520,
+0,5,12,520,
+0,0,13,520,
+0,1,13,520,
+0,7,11,520,
+5,8,9,533,
+1,5,12,533,
+1,7,11,533,
+3,9,9,533,
+5,5,11,533,
+1,1,13,533,
+6,6,10,535,
+4,6,11,535,
+2,5,12,535,
+0,2,13,535,
+3,8,10,535,
+5,7,10,541,
+2,7,11,541,
+1,2,13,541,
+4,4,12,541,
+7,8,8,559,
+2,2,13,559,
+4,9,9,559,
+3,5,12,559,
+0,3,13,559,
+1,3,13,559,
+7,7,9,563,
+3,7,11,563,
+0,6,12,563,
+4,8,10,563,
+1,6,12,563,
+0,9,10,563,
+6,8,9,567,
+5,6,11,567,
+2,3,13,567,
+1,9,10,567,
+2,6,12,567,
+0,8,11,567,
+6,7,10,576,
+0,4,13,576,
+4,5,12,576,
+2,9,10,576,
+1,8,11,576,
+1,4,13,576,
+4,7,11,576,
+3,3,13,576,
+5,9,9,585,
+2,8,11,585,
+3,6,12,585,
+2,4,13,585,
+5,8,10,592,
+3,9,10,592,
+8,8,8,613,
+6,6,11,613,
+0,7,12,613,
+7,8,9,618,
+1,7,12,618,
+3,4,13,618,
+5,5,12,618,
+0,5,13,618,
+3,8,11,618,
+5,7,11,618,
+1,5,13,618,
+0,0,14,618,
+4,6,12,618,
+2,7,12,618,
+4,9,10,618,
+0,1,14,618,
+2,5,13,618,
+1,1,14,618,
+6,9,9,631,
+7,7,10,631,
+0,2,14,631,
+6,8,10,635,
+0,10,10,635,
+4,4,13,635,
+4,8,11,635,
+1,2,14,635,
+1,10,10,635,
+3,7,12,635,
+0,9,11,635,
+3,5,13,635,
+1,9,11,635,
+2,10,10,635,
+2,2,14,635,
+0,3,14,635,
+5,6,12,638,
+0,6,13,638,
+1,6,13,638,
+5,9,10,651,
+6,7,11,651,
+1,3,14,651,
+2,9,11,651,
+0,8,12,651,
+1,8,12,651,
+4,7,12,651,
+2,6,13,651,
+3,10,10,651,
+2,3,14,651,
+8,8,9,667,
+4,5,13,667,
+5,8,11,667,
+7,9,9,672,
+3,9,11,672,
+2,8,12,672,
+0,4,14,672,
+7,8,10,681,
+1,4,14,681,
+3,3,14,681,
+3,6,13,681,
+2,4,14,681,
+4,10,10,681,
+6,6,12,681,
+3,8,12,681,
+6,9,10,695,
+4,9,11,695,
+0,7,13,695,
+5,7,12,695,
+7,7,11,699,
+5,5,13,699,
+1,7,13,699,
+0,5,14,699,
+0,10,11,699,
+6,8,11,704,
+4,6,13,704,
+3,4,14,704,
+2,7,13,704,
+1,5,14,704,
+1,10,11,704,
+4,8,12,704,
+2,10,11,704,
+5,10,10,711,
+0,0,15,711,
+0,9,12,711,
+2,5,14,711,
+8,9,9,735,
+1,9,12,735,
+0,1,15,735,
+5,9,11,735,
+1,1,15,735,
+3,7,13,735,
+8,8,10,738,
+4,4,14,738,
+0,2,15,738,
+6,7,12,738,
+2,9,12,738,
+5,6,13,738,
+3,10,11,738,
+7,9,10,743,
+3,5,14,743,
+1,2,15,743,
+0,6,14,743,
+5,8,12,743,
+0,8,13,743,
+2,2,15,743,
+1,6,14,743,
+1,8,13,743,
+0,3,15,743,
+4,7,13,743,
+7,8,11,755,
+3,9,12,755,
+1,3,15,755,
+6,10,10,756,
+2,6,14,756,
+2,8,13,756,
+4,10,11,756,
+4,5,14,756,
+6,9,11,766,
+2,3,15,766,
+3,6,14,766,
+0,4,15,766,
+4,9,12,766,
+6,6,13,766,
+1,4,15,766,
+0,11,11,766,
+3,8,13,766,
+7,7,12,776,
+5,7,13,776,
+1,11,11,776,
+9,9,9,792,
+3,3,15,792,
+6,8,12,792,
+0,10,12,792,
+0,7,14,792,
+2,4,15,792,
+8,9,10,799,
+1,10,12,799,
+5,10,11,799,
+5,5,14,799,
+1,7,14,799,
+2,11,11,799,
+4,6,14,799,
+2,10,12,799,
+7,10,10,810,
+8,8,11,810,
+4,8,13,810,
+2,7,14,810,
+3,4,15,810,
+5,9,12,810,
+0,9,13,810,
+0,5,15,810,
+1,5,15,810,
+1,9,13,810,
+7,9,11,818,
+3,11,11,818,
+3,10,12,818,
+6,7,13,818,
+2,5,15,818,
+3,7,14,818,
+2,9,13,818,
+0,0,16,818,
+4,4,15,818,
+6,10,11,837,
+0,1,16,837,
+5,6,14,837,
+7,8,12,837,
+4,11,11,837,
+1,1,16,837,
+5,8,13,837,
+3,9,13,837,
+3,5,15,837,
+0,2,16,837,
+0,8,14,837,
+4,10,12,837,
+4,7,14,837,
+6,9,12,848,
+1,2,16,848,
+1,8,14,848,
+0,6,15,848,
+9,9,10,859,
+1,6,15,859,
+2,2,16,859,
+2,8,14,859,
+8,10,10,865,
+0,3,16,865,
+0,11,12,865,
+2,6,15,865,
+4,5,15,865,
+1,3,16,865,
+4,9,13,865,
+8,9,11,875,
+1,11,12,875,
+5,11,11,875,
+7,7,13,875,
+6,6,14,875,
+5,10,12,875,
+2,3,16,875,
+0,10,13,875,
+3,8,14,875,
+6,8,13,875,
+2,11,12,875,
+7,10,11,885,
+1,10,13,885,
+5,7,14,885,
+3,6,15,885,
+0,4,16,885,
+8,8,12,892,
+2,10,13,892,
+1,4,16,892,
+7,9,12,899,
+0,7,15,899,
+3,3,16,899,
+3,11,12,899,
+5,9,13,899,
+1,7,15,899,
+5,5,15,899,
+4,8,14,899,
+2,4,16,899,
+4,6,15,899,
+0,9,14,899,
+1,9,14,899,
+6,11,11,912,
+3,10,13,912,
+2,7,15,912,
+6,10,12,917,
+2,9,14,917,
+6,7,14,917,
+9,10,10,933,
+4,11,12,933,
+0,5,16,933,
+3,4,16,933,
+7,8,13,933,
+1,5,16,933,
+9,9,11,942,
+3,7,15,942,
+4,10,13,942,
+8,10,11,947,
+2,5,16,947,
+5,8,14,947,
+3,9,14,947,
+5,6,15,947,
+6,9,13,947,
+0,12,12,947,
+4,4,16,947,
+8,9,12,958,
+0,8,15,958,
+1,12,12,958,
+0,0,17,958,
+1,8,15,958,
+3,5,16,958,
+0,11,13,958,
+4,7,15,958,
+0,1,17,958,
+5,11,12,958,
+7,11,11,966,
+1,11,13,966,
+1,1,17,966,
+0,6,16,966,
+2,12,12,966,
+0,2,17,966,
+1,6,16,966,
+2,8,15,966,
+7,10,12,971,
+4,9,14,971,
+1,2,17,971,
+2,11,13,971,
+5,10,13,971,
+7,7,14,971,
+6,8,14,971,
+2,6,16,971,
+0,10,14,971,
+4,5,16,971,
+6,6,15,971,
+8,8,13,985,
+1,10,14,985,
+2,2,17,985,
+3,12,12,985,
+3,8,15,985,
+0,3,17,985,
+5,7,15,985,
+3,11,13,985,
+1,3,17,985,
+7,9,13,992,
+10,10,10,1003,
+2,10,14,1003,
+3,6,16,1003,
+6,11,12,1003,
+5,9,14,1003,
+2,3,17,1003,
+9,10,11,1013,
+4,12,12,1013,
+3,10,14,1013,
+0,4,17,1013,
+4,8,15,1013,
+0,7,16,1013,
+6,10,13,1013,
+4,11,13,1013,
+9,9,12,1025,
+5,5,16,1025,
+8,11,11,1025,
+0,9,15,1025,
+1,7,16,1025,
+1,4,17,1025,
+3,3,17,1025,
+1,9,15,1025,
+4,6,16,1025,
+8,10,12,1028,
+7,8,14,1028,
+2,7,16,1028,
+2,4,17,1028,
+2,9,15,1028,
+6,7,15,1028,
+4,10,14,1028,
+5,12,12,1035,
+6,9,14,1035,
+0,12,13,1035,
+8,9,13,1052,
+1,12,13,1052,
+0,5,17,1052,
+3,4,17,1052,
+3,7,16,1052,
+5,8,15,1052,
+7,11,12,1052,
+1,5,17,1052,
+5,11,13,1052,
+3,9,15,1052,
+2,12,13,1052,
+0,11,14,1052,
+5,6,16,1052,
+1,11,14,1052,
+2,5,17,1052,
+7,10,13,1065,
+0,8,16,1065,
+5,10,14,1065,
+2,11,14,1065,
+10,10,11,1085,
+4,4,17,1085,
+1,8,16,1085,
+4,7,16,1085,
+4,9,15,1085,
+3,12,13,1085,
+3,5,17,1085,
+7,7,15,1085,
+9,11,11,1098,
+2,8,16,1098,
+0,0,18,1098,
+6,12,12,1098,
+8,8,14,1098,
+0,1,18,1098,
+0,10,15,1098,
+6,8,15,1098,
+9,10,12,1107,
+0,6,17,1107,
+1,10,15,1107,
+7,9,14,1107,
+3,11,14,1107,
+1,6,17,1107,
+6,11,13,1107,
+1,1,18,1107,
+0,2,18,1107,
+6,6,16,1107,
+4,12,13,1107,
+2,6,17,1107,
+2,10,15,1107,
+1,2,18,1107,
+8,11,12,1115,
+3,8,16,1115,
+4,5,17,1115,
+5,7,16,1115,
+5,9,15,1115,
+9,9,13,1122,
+6,10,14,1122,
+2,2,18,1122,
+8,10,13,1129,
+4,11,14,1129,
+0,3,18,1129,
+1,3,18,1129,
+3,10,15,1129,
+3,6,17,1129,
+4,8,16,1129,
+2,3,18,1129,
+7,12,12,1140,
+0,9,16,1140,
+7,8,15,1140,
+0,13,13,1140,
+5,12,13,1140,
+1,9,16,1140,
+0,7,17,1140,
+1,7,17,1140,
+5,5,17,1140,
+7,11,13,1148,
+1,13,13,1148,
+0,12,14,1148,
+0,4,18,1148,
+8,9,14,1153,
+1,4,18,1153,
+4,10,15,1153,
+6,7,16,1153,
+1,12,14,1153,
+4,6,17,1153,
+2,9,16,1153,
+2,13,13,1153,
+5,11,14,1153,
+10,11,11,1167,
+6,9,15,1167,
+3,3,18,1167,
+2,7,17,1167,
+10,10,12,1172,
+2,4,18,1172,
+2,12,14,1172,
+5,8,16,1172,
+7,10,14,1172,
+0,11,15,1172,
+9,11,12,1186,
+3,9,16,1186,
+3,13,13,1186,
+1,11,15,1186,
+3,7,17,1186,
+0,5,18,1186,
+3,12,14,1186,
+6,12,13,1186,
+3,4,18,1186,
+1,5,18,1186,
+5,6,17,1186,
+5,10,15,1186,
+2,11,15,1186,
+9,10,13,1199,
+8,12,12,1206,
+0,8,17,1206,
+4,9,16,1206,
+8,8,15,1206,
+2,5,18,1206,
+6,11,14,1206,
+8,11,13,1217,
+4,13,13,1217,
+1,8,17,1217,
+4,7,17,1217,
+7,7,16,1217,
+7,9,15,1217,
+3,11,15,1217,
+4,4,18,1217,
+0,10,16,1217,
+6,8,16,1217,
+4,12,14,1217,
+1,10,16,1217,
+2,8,17,1217,
+3,5,18,1217,
+9,9,14,1226,
+0,6,18,1226,
+2,10,16,1226,
+8,10,14,1232,
+6,10,15,1232,
+6,6,17,1232,
+1,6,18,1232,
+0,0,19,1232,
+3,8,17,1232,
+7,12,13,1240,
+5,9,16,1240,
+0,1,19,1240,
+4,11,15,1240,
+5,7,17,1240,
+11,11,11,1256,
+1,1,19,1256,
+5,13,13,1256,
+2,6,18,1256,
+10,11,12,1264,
+0,2,19,1264,
+4,5,18,1264,
+5,12,14,1264,
+0,13,14,1264,
+3,10,16,1264,
+1,13,14,1264,
+1,2,19,1264,
+7,11,14,1264,
+0,12,15,1264,
+7,8,16,1264,
+2,13,14,1264,
+10,10,13,1275,
+9,12,12,1275,
+2,2,19,1275,
+3,6,18,1275,
+4,8,17,1275,
+0,9,17,1275,
+1,12,15,1275,
+8,9,15,1275,
+0,3,19,1275,
+9,11,13,1283,
+5,11,15,1283,
+1,9,17,1283,
+1,3,19,1283,
+4,10,16,1283,
+2,12,15,1283,
+0,7,18,1283,
+6,9,16,1283,
+6,13,13,1283,
+7,10,15,1283,
+1,7,18,1283,
+2,3,19,1283,
+2,9,17,1283,
+6,7,17,1283,
+5,5,18,1283,
+3,13,14,1283,
+6,12,14,1287,
+4,6,18,1287,
+0,4,19,1287,
+0,11,16,1287,
+8,12,13,1305,
+2,7,18,1305,
+9,10,14,1305,
+1,4,19,1305,
+5,8,17,1305,
+3,12,15,1305,
+1,11,16,1305,
+3,9,17,1305,
+3,3,19,1305,
+5,10,16,1305,
+8,11,14,1319,
+2,11,16,1319,
+4,13,14,1319,
+2,4,19,1319,
+3,7,18,1319,
+6,11,15,1319,
+8,8,16,1319,
+5,6,18,1319,
+4,12,15,1319,
+7,9,16,1322,
+3,4,19,1322,
+0,5,19,1322,
+3,11,16,1322,
+4,9,17,1322,
+11,11,12,1353,
+9,9,15,1353,
+7,13,13,1353,
+1,5,19,1353,
+7,7,17,1353,
+0,8,18,1353,
+10,12,12,1357,
+1,8,18,1357,
+0,10,17,1357,
+6,8,17,1357,
+7,12,14,1357,
+8,10,15,1357,
+4,7,18,1357,
+2,5,19,1357,
+5,13,14,1357,
+1,10,17,1357,
+10,11,13,1364,
+0,14,14,1364,
+6,10,16,1364,
+2,8,18,1364,
+1,14,14,1364,
+4,11,16,1364,
+2,10,17,1364,
+4,4,19,1364,
+5,12,15,1364,
+9,12,13,1378,
+0,13,15,1378,
+7,11,15,1378,
+1,13,15,1378,
+3,5,19,1378,
+5,9,17,1378,
+10,10,14,1380,
+2,14,14,1380,
+6,6,18,1380,
+3,8,18,1380,
+0,6,19,1380,
+1,6,19,1380,
+3,10,17,1380,
+9,11,14,1395,
+5,7,18,1395,
+2,13,15,1395,
+0,12,16,1395,
+0,0,20,1395,
+8,9,16,1395,
+1,12,16,1395,
+3,14,14,1395,
+0,1,20,1395,
+2,6,19,1395,
+6,13,14,1395,
+5,11,16,1395,
+1,1,20,1395,
+7,8,17,1395,
+8,13,13,1412,
+4,5,19,1412,
+3,13,15,1412,
+0,2,20,1412,
+4,8,18,1412,
+8,12,14,1414,
+2,12,16,1414,
+6,12,15,1414,
+1,2,20,1414,
+0,9,18,1414,
+4,10,17,1414,
+7,10,16,1414,
+9,10,15,1422,
+1,9,18,1422,
+3,6,19,1422,
+6,9,17,1422,
+2,2,20,1422,
+4,14,14,1422,
+0,3,20,1422,
+2,9,18,1422,
+11,12,12,1444,
+6,7,18,1444,
+3,12,16,1444,
+1,3,20,1444,
+0,11,17,1444,
+0,7,19,1444,
+8,11,15,1444,
+4,13,15,1444,
+5,5,19,1444,
+1,7,19,1444,
+11,11,13,1452,
+1,11,17,1452,
+4,6,19,1452,
+6,11,16,1452,
+10,12,13,1458,
+5,8,18,1458,
+2,3,20,1458,
+2,7,19,1458,
+2,11,17,1458,
+7,13,14,1458,
+5,10,17,1458,
+3,9,18,1458,
+0,4,20,1458,
+4,12,16,1458,
+10,11,14,1476,
+1,4,20,1476,
+8,8,17,1476,
+5,14,14,1476,
+3,3,20,1476,
+7,12,15,1476,
+9,9,16,1476,
+3,7,19,1476,
+5,13,15,1476,
+9,13,13,1483,
+7,9,17,1483,
+3,11,17,1483,
+2,4,20,1483,
+8,10,16,1483,
+4,9,18,1483,
+9,12,14,1487,
+0,14,15,1487,
+5,6,19,1487,
+1,14,15,1487,
+7,7,18,1487,
+6,8,18,1487,
+0,10,18,1487,
+6,10,17,1487,
+0,13,16,1487,
+0,8,19,1487,
+0,5,20,1487,
+2,14,15,1487,
+5,12,16,1487,
+1,10,18,1487,
+3,4,20,1487,
+10,10,15,1496,
+7,11,16,1496,
+4,11,17,1496,
+1,13,16,1496,
+1,5,20,1496,
+4,7,19,1496,
+1,8,19,1496,
+9,11,15,1507,
+2,10,18,1507,
+6,14,14,1507,
+8,13,14,1517,
+2,8,19,1517,
+2,13,16,1517,
+2,5,20,1517,
+3,14,15,1517,
+5,9,18,1517,
+6,13,15,1517,
+12,12,12,1545,
+4,4,20,1545,
+8,12,15,1545,
+0,12,17,1545,
+6,6,19,1545,
+3,10,18,1545,
+1,12,17,1545,
+8,9,17,1545,
+11,12,13,1554,
+3,13,16,1554,
+3,8,19,1554,
+3,5,20,1554,
+5,11,17,1554,
+5,7,19,1554,
+0,6,20,1554,
+6,12,16,1554,
+4,14,15,1554,
+2,12,17,1554,
+1,6,20,1554,
+7,8,18,1554,
+9,10,16,1554,
+10,13,13,1572,
+7,10,17,1572,
+11,11,14,1572,
+4,10,18,1572,
+2,6,20,1572,
+10,12,14,1578,
+4,5,20,1578,
+6,9,18,1578,
+4,8,19,1578,
+4,13,16,1578,
+8,11,16,1578,
+7,14,14,1578,
+0,0,21,1578,
+0,1,21,1578,
+0,9,19,1578,
+3,12,17,1578,
+7,13,15,1578,
+1,9,19,1578,
+1,1,21,1578,
+0,11,18,1578,
+3,6,20,1578,
+0,2,21,1578,
+9,13,14,1598,
+2,9,19,1598,
+5,14,15,1598,
+1,2,21,1598,
+10,11,15,1598,
+1,11,18,1598,
+6,11,17,1598,
+6,7,19,1598,
+5,10,18,1598,
+4,12,17,1598,
+7,12,16,1598,
+2,11,18,1598,
+2,2,21,1598,
+0,7,20,1598,
+1,7,20,1598,
+9,12,15,1612,
+5,5,20,1612,
+0,15,15,1612,
+5,8,19,1612,
+0,3,21,1612,
+5,13,16,1612,
+9,9,17,1612,
+1,15,15,1612,
+1,3,21,1612,
+3,9,19,1612,
+0,14,16,1612,
+8,8,18,1612,
+4,6,20,1612,
+2,7,20,1612,
+8,10,17,1612,
+1,14,16,1612,
+2,15,15,1612,
+7,9,18,1612,
+3,11,18,1612,
+2,3,21,1612,
+8,14,14,1632,
+10,10,16,1632,
+2,14,16,1632,
+0,4,21,1632,
+6,14,15,1632,
+12,12,13,1650,
+3,7,20,1650,
+4,9,19,1650,
+1,4,21,1650,
+8,13,15,1650,
+5,12,17,1650,
+0,13,17,1650,
+9,11,16,1650,
+3,15,15,1650,
+7,11,17,1650,
+7,7,19,1650,
+3,3,21,1650,
+1,13,17,1650,
+11,13,13,1656,
+6,10,18,1656,
+6,13,16,1656,
+2,4,21,1656,
+3,14,16,1656,
+11,12,14,1666,
+5,6,20,1666,
+6,8,19,1666,
+0,10,19,1666,
+4,11,18,1666,
+2,13,17,1666,
+1,10,19,1666,
+8,12,16,1666,
+0,8,20,1666,
+1,8,20,1666,
+4,7,20,1666,
+10,13,14,1674,
+2,10,19,1674,
+0,5,21,1674,
+3,4,21,1674,
+4,15,15,1674,
+3,13,17,1674,
+1,5,21,1674,
+5,9,19,1674,
+11,11,15,1688,
+4,14,16,1688,
+2,8,20,1688,
+0,12,18,1688,
+10,12,15,1700,
+1,12,18,1700,
+6,12,17,1700,
+8,9,18,1700,
+7,14,15,1700,
+2,5,21,1700,
+9,10,17,1700,
+5,11,18,1700,
+3,10,19,1700,
+2,12,18,1700,
+6,6,20,1700,
+9,14,14,1713,
+4,4,21,1713,
+7,10,18,1713,
+3,8,20,1713,
+5,7,20,1713,
+4,13,17,1713,
+7,13,16,1713,
+7,8,19,1713,
+8,11,17,1713,
+3,5,21,1713,
+9,13,15,1722,
+5,15,15,1722,
+10,11,16,1726,
+0,6,21,1726,
+5,14,16,1726,
+4,10,19,1726,
+3,12,18,1726,
+1,6,21,1726,
+6,9,19,1726,
+4,8,20,1726,
+0,15,16,1726,
+9,12,16,1740,
+0,9,20,1740,
+2,6,21,1740,
+6,11,18,1740,
+12,13,13,1760,
+7,12,17,1760,
+1,9,20,1760,
+1,15,16,1760,
+0,11,19,1760,
+4,5,21,1760,
+1,11,19,1760,
+5,13,17,1760,
+12,12,14,1764,
+4,12,18,1764,
+0,0,22,1764,
+8,14,15,1764,
+2,9,20,1764,
+0,1,22,1764,
+6,7,20,1764,
+0,14,17,1764,
+2,15,16,1764,
+1,1,22,1764,
+9,9,18,1764,
+5,10,19,1764,
+3,6,21,1764,
+6,15,15,1764,
+2,11,19,1764,
+11,13,14,1779,
+1,14,17,1779,
+0,2,22,1779,
+6,14,16,1779,
+8,10,18,1779,
+2,14,17,1779,
+1,2,22,1779,
+10,10,17,1779,
+8,13,16,1779,
+8,8,19,1779,
+5,8,20,1779,
+3,15,16,1779,
+3,9,20,1779,
+11,12,15,1795,
+0,7,21,1795,
+5,5,21,1795,
+7,9,19,1795,
+3,11,19,1795,
+9,11,17,1795,
+1,7,21,1795,
+10,14,14,1798,
+2,2,22,1798,
+0,3,22,1798,
+5,12,18,1798,
+0,13,18,1798,
+4,6,21,1798,
+3,14,17,1798,
+6,13,17,1798,
+10,13,15,1807,
+2,7,21,1807,
+7,11,18,1807,
+1,13,18,1807,
+1,3,22,1807,
+2,3,22,1807,
+6,10,19,1807,
+4,15,16,1807,
+8,12,17,1807,
+4,9,20,1807,
+2,13,18,1807,
+7,7,20,1807,
+11,11,16,1826,
+4,11,19,1826,
+7,15,15,1826,
+3,7,21,1826,
+6,8,20,1826,
+0,4,22,1826,
+0,10,20,1826,
+10,12,16,1829,
+1,10,20,1829,
+4,14,17,1829,
+1,4,22,1829,
+7,14,16,1829,
+3,13,18,1829,
+3,3,22,1829,
+5,6,21,1829,
+9,14,15,1843,
+6,12,18,1843,
+2,10,20,1843,
+2,4,22,1843,
+0,12,19,1843,
+9,10,18,1843,
+0,8,21,1843,
+5,9,20,1843,
+1,8,21,1843,
+9,13,16,1851,
+5,15,16,1851,
+1,12,19,1851,
+8,9,19,1851,
+4,7,21,1851,
+5,11,19,1851,
+13,13,13,1869,
+7,13,17,1869,
+2,12,19,1869,
+3,10,20,1869,
+4,13,18,1869,
+3,4,22,1869,
+12,13,14,1880,
+8,11,18,1880,
+0,5,22,1880,
+2,8,21,1880,
+7,10,19,1880,
+1,5,22,1880,
+10,11,17,1880,
+5,14,17,1880,
+0,16,16,1880,
+7,8,20,1880,
+12,12,15,1896,
+6,6,21,1896,
+1,16,16,1896,
+11,14,14,1896,
+2,5,22,1896,
+0,15,17,1896,
+8,15,15,1896,
+9,12,17,1896,
+3,12,19,1896,
+3,8,21,1896,
+11,13,15,1902,
+5,7,21,1902,
+1,15,17,1902,
+2,16,16,1902,
+4,10,20,1902,
+4,4,22,1902,
+8,14,16,1902,
+6,9,20,1902,
+6,15,16,1902,
+7,12,18,1902,
+3,5,22,1902,
+5,13,18,1902,
+2,15,17,1902,
+6,11,19,1902,
+0,14,18,1902,
+0,6,22,1902,
+11,12,16,1930,
+4,8,21,1930,
+4,12,19,1930,
+0,11,20,1930,
+1,14,18,1930,
+10,14,15,1930,
+6,14,17,1930,
+3,16,16,1930,
+1,6,22,1930,
+1,11,20,1930,
+8,13,17,1930,
+0,9,21,1930,
+1,9,21,1930,
+9,9,19,1930,
+3,15,17,1930,
+2,14,18,1930,
+2,6,22,1930,
+10,10,18,1930,
+2,11,20,1930,
+4,5,22,1930,
+5,10,20,1930,
+10,13,16,1947,
+8,10,19,1947,
+9,11,18,1947,
+2,9,21,1947,
+6,7,21,1947,
+4,16,16,1947,
+8,8,20,1947,
+3,14,18,1947,
+0,0,23,1947,
+3,6,22,1947,
+6,13,18,1947,
+7,15,16,1950,
+7,9,20,1950,
+5,12,19,1950,
+4,15,17,1950,
+0,1,23,1950,
+0,13,19,1950,
+5,8,21,1950,
+3,11,20,1950,
+11,11,17,1970,
+9,15,15,1970,
+3,9,21,1970,
+7,11,19,1970,
+1,13,19,1970,
+1,1,23,1970,
+8,12,18,1970,
+10,12,17,1979,
+9,14,16,1979,
+0,7,22,1979,
+0,2,23,1979,
+2,13,19,1979,
+1,7,22,1979,
+1,2,23,1979,
+13,13,14,1997,
+7,14,17,1997,
+5,5,22,1997,
+4,6,22,1997,
+4,14,18,1997,
+12,14,14,2002,
+6,10,20,2002,
+2,2,23,2002,
+4,11,20,2002,
+2,7,22,2002,
+5,16,16,2002,
+0,3,23,2002,
+12,13,15,2013,
+4,9,21,2013,
+3,13,19,2013,
+9,13,17,2013,
+1,3,23,2013,
+7,7,21,2013,
+5,15,17,2013,
+6,8,21,2013,
+0,10,21,2013,
+6,12,19,2013,
+1,10,21,2013,
+11,14,15,2028,
+3,7,22,2028,
+7,13,18,2028,
+9,10,19,2028,
+2,3,23,2028,
+12,12,16,2033,
+0,12,20,2033,
+1,12,20,2033,
+0,16,17,2033,
+0,4,23,2033,
+5,14,18,2033,
+8,9,20,2033,
+8,15,16,2033,
+10,11,18,2033,
+2,10,21,2033,
+5,6,22,2033,
+8,11,19,2033,
+1,4,23,2033,
+5,11,20,2033,
+1,16,17,2033,
+11,13,16,2040,
+4,13,19,2040,
+5,9,21,2040,
+3,3,23,2040,
+2,12,20,2040,
+6,16,16,2040,
+0,8,22,2040,
+9,12,18,2040,
+4,7,22,2040,
+1,8,22,2040,
+0,15,18,2040,
+8,14,17,2040,
+2,4,23,2040,
+2,16,17,2040,
+7,10,20,2040,
+10,15,15,2052,
+6,15,17,2052,
+1,15,18,2052,
+3,10,21,2052,
+2,8,22,2052,
+10,14,16,2058,
+2,15,18,2058,
+3,12,20,2058,
+11,12,17,2074,
+0,5,23,2074,
+3,4,23,2074,
+7,8,21,2074,
+7,12,19,2074,
+3,16,17,2074,
+1,5,23,2074,
+5,13,19,2074,
+6,6,22,2074,
+6,14,18,2074,
+8,13,18,2074,
+3,8,22,2074,
+4,10,21,2074,
+0,14,19,2074,
+6,11,20,2074,
+5,7,22,2074,
+3,15,18,2074,
+6,9,21,2074,
+10,13,17,2090,
+1,14,19,2090,
+2,5,23,2090,
+4,12,20,2090,
+4,16,17,2090,
+2,14,19,2090,
+13,14,14,2118,
+10,10,19,2118,
+4,4,23,2118,
+7,16,16,2118,
+9,15,16,2118,
+9,9,20,2118,
+0,11,21,2118,
+7,15,17,2118,
+3,5,23,2118,
+1,11,21,2118,
+9,11,19,2118,
+13,13,15,2128,
+8,10,20,2128,
+4,8,22,2128,
+0,6,23,2128,
+4,15,18,2128,
+0,9,22,2128,
+12,14,15,2139,
+5,10,21,2139,
+1,9,22,2139,
+1,6,23,2139,
+2,11,21,2139,
+3,14,19,2139,
+9,14,17,2139,
+6,13,19,2139,
+11,11,18,2139,
+10,12,18,2139,
+6,7,22,2139,
+8,12,19,2139,
+2,9,22,2139,
+2,6,23,2139,
+5,12,20,2139,
+12,13,16,2149,
+8,8,21,2149,
+7,14,18,2149,
+0,13,20,2149,
+4,5,23,2149,
+7,11,20,2149,
+5,16,17,2149,
+1,13,20,2149,
+7,9,21,2149,
+3,11,21,2149,
+11,15,15,2162,
+5,8,22,2162,
+4,14,19,2162,
+2,13,20,2162,
+11,14,16,2172,
+3,9,22,2172,
+5,15,18,2172,
+3,6,23,2172,
+9,13,18,2172,
+8,16,16,2172,
+0,0,24,2172,
+6,10,21,2172,
+12,12,17,2182,
+0,1,24,2182,
+0,7,23,2182,
+8,15,17,2182,
+1,1,24,2182,
+4,11,21,2182,
+0,17,17,2182,
+3,13,20,2182,
+5,5,23,2182,
+7,13,19,2182,
+1,7,23,2182,
+1,17,17,2182,
+11,13,17,2194,
+0,16,18,2194,
+6,12,20,2194,
+0,2,24,2194,
+1,16,18,2194,
+10,15,16,2201,
+6,16,17,2201,
+9,10,20,2201,
+4,6,23,2201,
+1,2,24,2201,
+4,9,22,2201,
+7,7,22,2201,
+2,7,23,2201,
+10,11,19,2201,
+2,17,17,2201,
+5,14,19,2201,
+2,2,24,2201,
+8,14,18,2201,
+2,16,18,2201,
+6,8,22,2201,
+0,10,22,2201,
+0,3,24,2201,
+6,15,18,2201,
+0,12,21,2201,
+1,10,22,2201,
+10,14,17,2219,
+8,11,20,2219,
+4,13,20,2219,
+9,12,19,2219,
+1,12,21,2219,
+1,3,24,2219,
+0,15,19,2219,
+8,9,21,2219,
+3,17,17,2219,
+3,7,23,2219,
+5,11,21,2219,
+1,15,19,2219,
+14,14,14,2237,
+2,10,22,2237,
+2,3,24,2237,
+3,16,18,2237,
+11,12,18,2237,
+2,12,21,2237,
+13,14,15,2251,
+5,6,23,2251,
+5,9,22,2251,
+2,15,19,2251,
+7,10,21,2251,
+0,4,24,2251,
+10,13,18,2251,
+3,10,22,2251,
+6,14,19,2251,
+1,4,24,2251,
+0,8,23,2251,
+7,12,20,2251,
+9,16,16,2251,
+4,17,17,2251,
+3,12,21,2251,
+8,13,19,2251,
+13,13,16,2273,
+5,13,20,2273,
+3,3,24,2273,
+7,16,17,2273,
+12,15,15,2273,
+1,8,23,2273,
+4,7,23,2273,
+3,15,19,2273,
+9,15,17,2273,
+2,4,24,2273,
+12,14,16,2279,
+4,16,18,2279,
+0,14,20,2279,
+1,14,20,2279,
+7,8,22,2279,
+2,8,23,2279,
+7,15,18,2279,
+6,11,21,2279,
+4,10,22,2279,
+2,14,20,2279,
+10,10,20,2279,
+9,14,18,2283,
+3,4,24,2283,
+6,9,22,2283,
+0,5,24,2283,
+4,12,21,2283,
+6,6,23,2283,
+1,5,24,2283,
+4,15,19,2283,
+11,15,16,2306,
+3,8,23,2306,
+12,13,17,2306,
+9,11,20,2306,
+9,9,21,2306,
+11,11,19,2306,
+5,7,23,2306,
+5,17,17,2306,
+10,12,19,2306,
+5,16,18,2306,
+0,11,22,2306,
+2,5,24,2306,
+8,10,21,2306,
+3,14,20,2306,
+6,13,20,2306,
+11,14,17,2318,
+1,11,22,2318,
+7,14,19,2318,
+8,12,20,2318,
+4,4,24,2318,
+8,16,17,2318,
+2,11,22,2318,
+4,8,23,2318,
+5,10,22,2318,
+0,13,21,2318,
+0,9,23,2318,
+3,5,24,2318,
+5,12,21,2318,
+1,13,21,2318,
+5,15,19,2318,
+1,9,23,2318,
+9,13,19,2321,
+7,11,21,2321,
+8,8,22,2321,
+10,16,16,2340,
+12,12,18,2340,
+0,6,24,2340,
+4,14,20,2340,
+0,17,18,2340,
+8,15,18,2340,
+1,6,24,2340,
+10,15,17,2354,
+2,13,21,2354,
+3,11,22,2354,
+6,17,17,2354,
+11,13,18,2354,
+6,7,23,2354,
+2,9,23,2354,
+7,9,22,2354,
+1,17,18,2354,
+2,6,24,2354,
+6,16,18,2354,
+0,16,19,2354,
+14,14,15,2382,
+2,17,18,2382,
+4,5,24,2382,
+1,16,19,2382,
+5,8,23,2382,
+7,13,20,2382,
+13,15,15,2392,
+3,9,23,2392,
+3,13,21,2392,
+10,14,18,2392,
+6,10,22,2392,
+3,6,24,2392,
+2,16,19,2392,
+13,14,16,2400,
+4,11,22,2400,
+10,11,20,2400,
+6,12,21,2400,
+8,14,19,2400,
+5,14,20,2400,
+3,17,18,2400,
+9,10,21,2400,
+6,15,19,2400,
+0,15,20,2400,
+12,15,16,2418,
+0,0,25,2418,
+9,12,20,2418,
+0,7,24,2418,
+1,15,20,2418,
+4,9,23,2418,
+1,7,24,2418,
+5,5,24,2418,
+11,12,19,2418,
+4,13,21,2418,
+8,11,21,2418,
+9,16,17,2418,
+0,1,25,2418,
+3,16,19,2418,
+13,13,17,2431,
+7,17,17,2431,
+1,1,25,2431,
+7,7,23,2431,
+4,6,24,2431,
+0,12,22,2431,
+6,8,23,2431,
+12,14,17,2436,
+7,16,18,2436,
+0,10,23,2436,
+8,9,22,2436,
+2,7,24,2436,
+2,15,20,2436,
+0,2,25,2436,
+4,17,18,2436,
+1,12,22,2436,
+10,13,19,2436,
+1,2,25,2436,
+1,10,23,2436,
+5,11,22,2436,
+9,15,18,2436,
+2,12,22,2436,
+6,14,20,2436,
+2,2,25,2436,
+11,16,16,2445,
+7,10,22,2445,
+4,16,19,2445,
+2,10,23,2445,
+8,13,20,2445,
+7,12,21,2445,
+3,15,20,2445,
+0,3,25,2445,
+3,7,24,2445,
+5,13,21,2445,
+11,15,17,2458,
+5,9,23,2458,
+7,15,19,2458,
+1,3,25,2458,
+3,12,22,2458,
+0,14,21,2458,
+12,13,18,2469,
+5,6,24,2469,
+2,3,25,2469,
+3,10,23,2469,
+1,14,21,2469,
+9,14,19,2469,
+5,17,18,2469,
+0,8,24,2469,
+11,14,18,2488,
+1,8,24,2488,
+4,7,24,2488,
+0,4,25,2488,
+10,10,21,2488,
+6,11,22,2488,
+4,15,20,2488,
+2,14,21,2488,
+1,4,25,2488,
+7,8,23,2488,
+11,11,20,2488,
+5,16,19,2488,
+8,17,17,2488,
+3,3,25,2488,
+9,11,21,2488,
+4,12,22,2488,
+8,16,18,2488,
+2,8,24,2488,
+10,12,20,2488,
+7,14,20,2488,
+2,4,25,2488,
+4,10,23,2488,
+10,16,17,2501,
+6,13,21,2501,
+14,15,15,2520,
+6,9,23,2520,
+9,9,22,2520,
+3,14,21,2520,
+14,14,16,2529,
+6,6,24,2529,
+8,10,22,2529,
+0,18,18,2529,
+12,12,19,2529,
+10,15,18,2529,
+8,12,21,2529,
+3,8,24,2529,
+6,17,18,2529,
+1,18,18,2529,
+0,17,19,2529,
+13,15,16,2537,
+5,7,24,2537,
+0,5,25,2537,
+3,4,25,2537,
+0,11,23,2537,
+9,13,20,2537,
+5,15,20,2537,
+8,15,19,2537,
+1,5,25,2537,
+1,17,19,2537,
+11,13,19,2537,
+1,11,23,2537,
+2,18,18,2537,
+6,16,19,2537,
+5,12,22,2537,
+4,14,21,2537,
+0,13,22,2537,
+2,11,23,2537,
+5,10,23,2537,
+13,14,17,2551,
+2,5,25,2551,
+7,11,22,2551,
+1,13,22,2551,
+2,17,19,2551,
+0,16,20,2551,
+12,16,16,2557,
+4,8,24,2557,
+2,13,22,2557,
+1,16,20,2557,
+10,14,19,2557,
+8,8,23,2557,
+0,9,24,2557,
+4,4,25,2557,
+3,18,18,2557,
+12,15,17,2576,
+1,9,24,2576,
+9,17,17,2576,
+7,9,23,2576,
+3,5,25,2576,
+7,13,21,2576,
+3,11,23,2576,
+3,17,19,2576,
+8,14,20,2576,
+2,16,20,2576,
+6,7,24,2576,
+0,6,25,2576,
+2,9,24,2576,
+6,15,20,2576,
+9,16,18,2576,
+10,11,21,2576,
+13,13,18,2593,
+7,17,18,2593,
+5,14,21,2593,
+1,6,25,2593,
+3,13,22,2593,
+4,18,18,2593,
+12,14,18,2600,
+6,12,22,2600,
+5,8,24,2600,
+2,6,25,2600,
+6,10,23,2600,
+3,16,20,2600,
+11,12,20,2600,
+9,10,22,2600,
+4,17,19,2600,
+9,12,21,2600,
+3,9,24,2600,
+7,16,19,2600,
+4,5,25,2600,
+4,11,23,2600,
+11,16,17,2614,
+0,15,21,2614,
+1,15,21,2614,
+9,15,19,2614,
+8,11,22,2614,
+10,13,20,2614,
+4,13,22,2614,
+2,15,21,2614,
+11,15,18,2629,
+3,6,25,2629,
+4,16,20,2629,
+4,9,24,2629,
+6,14,21,2629,
+0,12,23,2629,
+5,18,18,2629,
+12,13,19,2641,
+8,9,23,2641,
+1,12,23,2641,
+7,15,20,2641,
+8,13,21,2641,
+0,7,25,2641,
+7,7,24,2641,
+1,7,25,2641,
+5,11,23,2641,
+5,5,25,2641,
+5,17,19,2641,
+3,15,21,2641,
+15,15,15,2666,
+6,8,24,2666,
+0,0,26,2666,
+0,10,24,2666,
+9,14,20,2666,
+4,6,25,2666,
+0,1,26,2666,
+7,12,22,2666,
+2,12,23,2666,
+14,15,16,2676,
+1,10,24,2676,
+8,17,18,2676,
+5,13,22,2676,
+11,14,19,2676,
+1,1,26,2676,
+2,7,25,2676,
+10,17,17,2676,
+7,10,23,2676,
+10,16,18,2676,
+0,2,26,2676,
+2,10,24,2676,
+0,14,22,2676,
+5,16,20,2676,
+13,16,16,2690,
+1,14,22,2690,
+8,16,19,2690,
+1,2,26,2690,
+14,14,17,2690,
+3,12,23,2690,
+4,15,21,2690,
+5,9,24,2690,
+3,7,25,2690,
+13,15,17,2701,
+11,11,21,2701,
+2,14,22,2701,
+10,10,22,2701,
+6,18,18,2701,
+2,2,26,2701,
+3,10,24,2701,
+0,18,19,2701,
+10,12,21,2701,
+0,3,26,2701,
+7,14,21,2701,
+1,3,26,2701,
+10,15,19,2701,
+6,17,19,2701,
+9,11,22,2701,
+1,18,19,2701,
+5,6,25,2701,
+6,11,23,2701,
+12,12,20,2704,
+6,13,22,2704,
+4,12,23,2704,
+8,15,20,2704,
+12,16,17,2723,
+7,8,24,2723,
+0,17,20,2723,
+2,3,26,2723,
+13,14,18,2723,
+3,14,22,2723,
+0,8,25,2723,
+2,18,19,2723,
+11,13,20,2723,
+1,8,25,2723,
+1,17,20,2723,
+4,7,25,2723,
+9,9,23,2723,
+9,13,21,2723,
+5,15,21,2723,
+6,16,20,2723,
+0,4,26,2723,
+4,10,24,2723,
+8,12,22,2723,
+2,8,25,2723,
+12,15,18,2744,
+1,4,26,2744,
+2,17,20,2744,
+6,9,24,2744,
+8,10,23,2744,
+3,3,26,2744,
+9,17,18,2744,
+3,18,19,2744,
+10,14,20,2744,
+4,14,22,2744,
+2,4,26,2744,
+6,6,25,2744,
+0,11,24,2744,
+0,16,21,2744,
+7,18,18,2744,
+1,16,21,2744,
+0,13,23,2744,
+1,11,24,2744,
+3,17,20,2744,
+3,8,25,2744,
+5,12,23,2744,
+9,16,19,2749,
+13,13,19,2770,
+7,17,19,2770,
+11,17,17,2770,
+1,13,23,2770,
+5,7,25,2770,
+7,11,23,2770,
+8,14,21,2770,
+4,18,19,2770,
+2,16,21,2770,
+3,4,26,2770,
+0,5,26,2770,
+2,11,24,2770,
+12,14,19,2777,
+11,16,18,2777,
+5,10,24,2777,
+6,15,21,2777,
+7,13,22,2777,
+1,5,26,2777,
+2,13,23,2777,
+8,8,24,2777,
+2,5,26,2777,
+7,16,20,2777,
+10,11,22,2777,
+4,8,25,2777,
+4,17,20,2777,
+5,14,22,2777,
+3,11,24,2777,
+9,15,20,2784,
+15,15,16,2820,
+3,16,21,2820,
+7,9,24,2820,
+0,9,25,2820,
+11,12,21,2820,
+3,13,23,2820,
+1,9,25,2820,
+11,15,19,2820,
+4,4,26,2820,
+14,16,16,2823,
+0,15,22,2823,
+9,12,22,2823,
+6,12,23,2823,
+5,18,19,2823,
+6,7,25,2823,
+2,9,25,2823,
+9,10,23,2823,
+10,13,21,2823,
+3,5,26,2823,
+14,15,17,2837,
+1,15,22,2837,
+6,10,24,2837,
+0,6,26,2837,
+8,18,18,2837,
+4,11,24,2837,
+12,13,20,2837,
+2,15,22,2837,
+1,6,26,2837,
+4,16,21,2837,
+10,17,18,2837,
+13,16,17,2857,
+5,17,20,2857,
+4,13,23,2857,
+8,11,23,2857,
+8,17,19,2857,
+5,8,25,2857,
+7,15,21,2857,
+3,9,25,2857,
+6,14,22,2857,
+2,6,26,2857,
+14,14,18,2859,
+8,13,22,2859,
+10,16,19,2859,
+11,14,20,2859,
+4,5,26,2859,
+13,15,18,2873,
+3,15,22,2873,
+9,14,21,2873,
+8,16,20,2873,
+0,12,24,2873,
+8,9,24,2873,
+1,12,24,2873,
+6,18,19,2873,
+3,6,26,2873,
+4,9,25,2873,
+7,12,23,2873,
+12,17,17,2891,
+5,11,24,2891,
+5,16,21,2891,
+0,19,19,2891,
+7,7,25,2891,
+1,19,19,2891,
+5,13,23,2891,
+0,18,20,2891,
+12,16,18,2896,
+2,12,24,2896,
+6,17,20,2896,
+6,8,25,2896,
+0,10,25,2896,
+10,15,20,2896,
+7,10,24,2896,
+0,14,23,2896,
+4,15,22,2896,
+1,18,20,2896,
+0,7,26,2896,
+5,5,26,2896,
+1,7,26,2896,
+2,19,19,2896,
+13,14,19,2907,
+1,14,23,2907,
+1,10,25,2907,
+11,11,22,2907,
+4,6,26,2907,
+2,18,20,2907,
+10,12,22,2907,
+9,18,18,2907,
+12,12,21,2907,
+2,7,26,2907,
+3,12,24,2907,
+2,10,25,2907,
+10,10,23,2907,
+7,14,22,2907,
+0,0,27,2907,
+2,14,23,2907,
+0,17,21,2907,
+8,15,21,2907,
+0,1,27,2907,
+12,15,19,2927,
+3,19,19,2927,
+5,9,25,2927,
+9,11,23,2927,
+9,17,19,2927,
+1,1,27,2927,
+1,17,21,2927,
+11,13,21,2927,
+6,16,21,2927,
+6,11,24,2927,
+3,18,20,2927,
+0,2,27,2927,
+11,17,18,2944,
+3,14,23,2944,
+6,13,23,2944,
+7,18,19,2944,
+3,10,25,2944,
+9,13,22,2944,
+3,7,26,2944,
+5,15,22,2944,
+2,17,21,2944,
+1,2,27,2944,
+4,12,24,2944,
+10,14,21,2944,
+9,16,20,2944,
+2,2,27,2944,
+15,16,16,2974,
+5,6,26,2974,
+8,12,23,2974,
+11,16,19,2974,
+4,19,19,2974,
+0,3,27,2974,
+9,9,24,2974,
+7,17,20,2974,
+13,13,20,2974,
+7,8,25,2974,
+15,15,17,2983,
+1,3,27,2983,
+3,17,21,2983,
+4,18,20,2983,
+0,8,26,2983,
+12,14,20,2983,
+8,10,24,2983,
+0,16,22,2983,
+4,14,23,2983,
+4,10,25,2983,
+1,8,26,2983,
+1,16,22,2983,
+4,7,26,2983,
+14,16,17,2996,
+2,3,27,2996,
+6,9,25,2996,
+8,14,22,2996,
+2,8,26,2996,
+2,16,22,2996,
+0,4,27,2996,
+14,15,18,3009,
+6,15,22,3009,
+5,12,24,3009,
+0,13,24,3009,
+1,4,27,3009,
+7,11,24,3009,
+1,13,24,3009,
+11,15,20,3009,
+4,17,21,3009,
+0,11,25,3009,
+7,16,21,3009,
+5,19,19,3009,
+3,3,27,3009,
+9,15,21,3009,
+7,13,23,3009,
+1,11,25,3009,
+13,17,17,3017,
+6,6,26,3017,
+10,18,18,3017,
+13,16,18,3024,
+3,8,26,3024,
+8,18,19,3024,
+5,18,20,3024,
+2,13,24,3024,
+2,4,27,3024,
+3,16,22,3024,
+11,12,22,3024,
+5,14,23,3024,
+2,11,25,3024,
+10,11,23,3024,
+5,7,26,3024,
+5,10,25,3024,
+10,17,19,3024,
+10,13,22,3024,
+14,14,19,3046,
+8,8,25,3046,
+8,17,20,3046,
+3,4,27,3046,
+9,12,23,3046,
+0,5,27,3046,
+0,15,23,3046,
+12,13,21,3046,
+3,13,24,3046,
+1,15,23,3046,
+3,11,25,3046,
+5,17,21,3046,
+13,15,19,3056,
+7,9,25,3056,
+1,5,27,3056,
+4,8,26,3056,
+10,16,20,3056,
+6,12,24,3056,
+4,16,22,3056,
+0,9,26,3056,
+12,17,18,3060,
+9,10,24,3060,
+6,19,19,3060,
+2,5,27,3060,
+1,9,26,3060,
+2,15,23,3060,
+11,14,21,3060,
+7,15,22,3060,
+6,18,20,3060,
+6,10,25,3060,
+4,13,24,3060,
+0,19,20,3060,
+2,9,26,3060,
+12,16,19,3069,
+6,7,26,3069,
+8,11,24,3069,
+6,14,23,3069,
+8,16,21,3069,
+4,4,27,3069,
+9,14,22,3069,
+8,13,23,3069,
+4,11,25,3069,
+1,19,20,3069,
+3,5,27,3069,
+3,15,23,3069,
+5,8,26,3069,
+0,6,27,3069,
+5,16,22,3069,
+13,14,20,3099,
+0,18,21,3099,
+2,19,20,3099,
+3,9,26,3099,
+1,6,27,3099,
+10,15,21,3099,
+9,18,19,3099,
+1,18,21,3099,
+6,17,21,3099,
+16,16,16,3133,
+7,12,24,3133,
+0,12,25,3133,
+11,18,18,3133,
+12,15,20,3133,
+2,18,21,3133,
+2,6,27,3133,
+1,12,25,3133,
+8,9,25,3133,
+5,13,24,3133,
+15,16,17,3145,
+3,19,20,3145,
+9,17,20,3145,
+4,5,27,3145,
+4,15,23,3145,
+5,11,25,3145,
+7,19,19,3145,
+11,17,19,3145,
+11,11,23,3145,
+12,12,22,3145,
+0,14,24,3145,
+8,15,22,3145,
+2,12,25,3145,
+10,12,23,3145,
+0,17,22,3145,
+1,14,24,3145,
+4,9,26,3145,
+7,18,20,3145,
+7,14,23,3145,
+7,7,26,3145,
+15,15,18,3160,
+11,13,22,3160,
+1,17,22,3160,
+14,17,17,3160,
+3,6,27,3160,
+7,10,25,3160,
+3,18,21,3160,
+14,16,18,3169,
+6,16,22,3169,
+2,14,24,3169,
+6,8,26,3169,
+10,10,24,3169,
+0,10,26,3169,
+11,16,20,3169,
+4,19,20,3169,
+1,10,26,3169,
+2,17,22,3169,
+9,11,24,3169,
+3,12,25,3169,
+0,7,27,3169,
+9,16,21,3169,
+7,17,21,3169,
+5,5,27,3169,
+1,7,27,3169,
+5,15,23,3169,
+13,13,21,3169,
+9,13,23,3169,
+10,14,22,3169,
+2,10,26,3169,
+12,14,21,3177,
+4,18,21,3177,
+6,13,24,3177,
+4,6,27,3177,
+3,14,24,3177,
+14,15,19,3203,
+5,9,26,3203,
+2,7,27,3203,
+6,11,25,3203,
+3,17,22,3203,
+13,17,18,3203,
+0,0,28,3203,
+8,12,24,3203,
+4,12,25,3203,
+0,16,23,3203,
+0,1,28,3203,
+10,18,19,3203,
+3,10,26,3203,
+8,19,19,3203,
+1,1,28,3203,
+13,16,19,3225,
+1,16,23,3225,
+5,19,20,3225,
+3,7,27,3225,
+9,9,25,3225,
+11,15,21,3225,
+4,14,24,3225,
+0,2,28,3225,
+8,18,20,3225,
+1,2,28,3225,
+8,14,23,3225,
+7,8,26,3225,
+8,10,25,3225,
+10,17,20,3225,
+4,17,22,3225,
+7,16,22,3225,
+2,16,23,3225,
+5,18,21,3225,
+9,15,22,3225,
+5,6,27,3225,
+6,15,23,3225,
+12,18,18,3243,
+14,14,20,3243,
+4,10,26,3243,
+2,2,28,3243,
+6,9,26,3243,
+0,3,28,3243,
+0,8,27,3243,
+1,8,27,3243,
+5,12,25,3243,
+3,16,23,3243,
+0,13,25,3243,
+8,17,21,3243,
+7,13,24,3243,
+4,7,27,3243,
+12,17,19,3254,
+13,15,20,3254,
+11,12,23,3254,
+1,3,28,3254,
+1,13,25,3254,
+7,11,25,3254,
+10,11,24,3254,
+6,19,20,3254,
+10,16,21,3254,
+12,13,22,3254,
+5,14,24,3254,
+2,3,28,3254,
+2,8,27,3254,
+0,11,26,3254,
+5,17,22,3254,
+2,13,25,3254,
+1,11,26,3254,
+10,13,23,3254,
+12,16,20,3279,
+0,4,28,3279,
+0,20,20,3279,
+1,4,28,3279,
+1,20,20,3279,
+4,16,23,3279,
+2,11,26,3279,
+9,12,24,3279,
+16,16,17,3294,
+0,15,24,3294,
+6,18,21,3294,
+11,14,22,3294,
+5,10,26,3294,
+6,6,27,3294,
+1,15,24,3294,
+3,8,27,3294,
+3,3,28,3294,
+0,19,21,3294,
+7,15,23,3294,
+9,19,19,3294,
+1,19,21,3294,
+5,7,27,3294,
+15,17,17,3309,
+3,13,25,3309,
+2,4,28,3309,
+2,20,20,3309,
+8,8,26,3309,
+8,16,22,3309,
+6,12,25,3309,
+9,18,20,3309,
+15,16,18,3317,
+2,15,24,3317,
+13,14,21,3317,
+2,19,21,3317,
+9,10,25,3317,
+7,9,26,3317,
+9,14,23,3317,
+11,18,19,3317,
+3,11,26,3317,
+6,14,24,3317,
+0,18,22,3317,
+3,4,28,3317,
+4,8,27,3317,
+1,18,22,3317,
+14,17,18,3337,
+3,20,20,3337,
+10,15,22,3337,
+6,17,22,3337,
+0,5,28,3337,
+8,13,24,3337,
+3,15,24,3337,
+7,19,20,3337,
+1,5,28,3337,
+12,15,21,3337,
+5,16,23,3337,
+4,13,25,3337,
+0,9,27,3337,
+11,17,20,3337,
+8,11,25,3337,
+3,19,21,3337,
+15,15,19,3349,
+9,17,21,3349,
+1,9,27,3349,
+6,10,26,3349,
+2,18,22,3349,
+14,16,19,3355,
+2,5,28,3355,
+4,11,26,3355,
+2,9,27,3355,
+6,7,27,3355,
+7,18,21,3355,
+4,20,20,3355,
+4,4,28,3355,
+12,12,23,3355,
+3,18,22,3355,
+4,15,24,3355,
+13,18,18,3376,
+3,5,28,3376,
+11,16,21,3376,
+7,12,25,3376,
+11,11,24,3376,
+5,8,27,3376,
+4,19,21,3376,
+0,17,23,3376,
+8,15,23,3376,
+13,17,19,3388,
+11,13,23,3388,
+3,9,27,3388,
+5,13,25,3388,
+1,17,23,3388,
+0,6,28,3388,
+0,12,26,3388,
+10,12,24,3388,
+7,14,24,3388,
+1,12,26,3388,
+1,6,28,3388,
+14,15,20,3401,
+0,14,25,3401,
+6,16,23,3401,
+9,16,22,3401,
+8,9,26,3401,
+1,14,25,3401,
+7,17,22,3401,
+13,13,22,3401,
+10,19,19,3401,
+5,11,26,3401,
+2,17,23,3401,
+4,18,22,3401,
+2,12,26,3401,
+10,18,20,3401,
+12,14,22,3401,
+2,6,28,3401,
+10,14,23,3401,
+5,20,20,3401,
+7,10,26,3401,
+4,5,28,3401,
+13,16,20,3411,
+2,14,25,3411,
+10,10,25,3411,
+8,19,20,3411,
+5,15,24,3411,
+4,9,27,3411,
+9,13,24,3411,
+5,19,21,3411,
+3,17,23,3411,
+9,11,25,3411,
+7,7,27,3411,
+3,12,26,3411,
+0,10,27,3411,
+8,18,21,3411,
+6,8,27,3411,
+3,6,28,3411,
+12,18,19,3435,
+3,14,25,3435,
+11,15,22,3435,
+10,17,21,3435,
+6,13,25,3435,
+1,10,27,3435,
+0,16,24,3435,
+1,16,24,3435,
+8,12,25,3435,
+12,17,20,3451,
+6,11,26,3451,
+5,18,22,3451,
+0,7,28,3451,
+14,14,21,3451,
+2,10,27,3451,
+16,17,17,3479,
+1,7,28,3479,
+5,5,28,3479,
+4,17,23,3479,
+7,16,23,3479,
+5,9,27,3479,
+13,15,21,3479,
+9,15,23,3479,
+4,12,26,3479,
+2,16,24,3479,
+4,6,28,3479,
+8,14,24,3479,
+6,20,20,3479,
+16,16,18,3481,
+6,15,24,3481,
+8,17,22,3481,
+2,7,28,3481,
+4,14,25,3481,
+3,10,27,3481,
+15,17,18,3500,
+6,19,21,3500,
+9,9,26,3500,
+8,10,26,3500,
+10,16,22,3500,
+0,0,29,3500,
+3,16,24,3500,
+0,20,21,3500,
+12,16,21,3500,
+11,12,24,3500,
+1,20,21,3500,
+15,16,19,3516,
+3,7,28,3516,
+7,8,27,3516,
+0,1,29,3516,
+12,13,23,3516,
+9,19,20,3516,
+11,19,19,3516,
+7,13,25,3516,
+5,17,23,3516,
+1,1,29,3516,
+6,18,22,3516,
+14,18,18,3519,
+0,19,22,3519,
+10,13,24,3519,
+5,6,28,3519,
+4,10,27,3519,
+5,12,26,3519,
+11,18,20,3519,
+0,13,26,3519,
+0,2,29,3519,
+2,20,21,3519,
+1,19,22,3519,
+7,11,26,3519,
+10,11,25,3519,
+14,17,19,3530,
+6,9,27,3530,
+1,2,29,3530,
+5,14,25,3530,
+9,18,21,3530,
+11,14,23,3530,
+1,13,26,3530,
+0,8,28,3530,
+4,16,24,3530,
+1,8,28,3530,
+2,19,22,3530,
+8,16,23,3530,
+4,7,28,3530,
+2,2,29,3530,
+13,14,22,3530,
+7,20,20,3530,
+2,13,26,3530,
+15,15,20,3553,
+9,12,25,3553,
+0,3,29,3553,
+0,15,25,3553,
+3,20,21,3553,
+0,11,27,3553,
+7,15,24,3553,
+1,11,27,3553,
+1,15,25,3553,
+7,19,21,3553,
+1,3,29,3553,
+11,17,21,3553,
+14,16,20,3558,
+2,8,28,3558,
+12,15,22,3558,
+9,14,24,3558,
+0,18,23,3558,
+3,13,26,3558,
+10,15,23,3558,
+1,18,23,3558,
+9,17,22,3558,
+2,11,27,3558,
+2,15,25,3558,
+13,18,19,3568,
+2,3,29,3568,
+3,19,22,3568,
+5,10,27,3568,
+6,17,23,3568,
+6,6,28,3568,
+6,12,26,3568,
+8,8,27,3568,
+4,20,21,3568,
+2,18,23,3568,
+0,4,29,3568,
+7,18,22,3568,
+6,14,25,3568,
+9,10,26,3568,
+3,8,28,3568,
+5,16,24,3568,
+8,13,25,3568,
+13,17,20,3594,
+5,7,28,3594,
+1,4,29,3594,
+7,9,27,3594,
+3,3,29,3594,
+3,11,27,3594,
+3,15,25,3594,
+4,19,22,3594,
+4,13,26,3594,
+11,16,22,3594,
+10,19,20,3594,
+2,4,29,3594,
+8,11,26,3594,
+14,15,21,3611,
+3,18,23,3611,
+8,20,20,3611,
+12,12,24,3611,
+4,8,28,3611,
+0,9,28,3611,
+0,17,24,3611,
+6,10,27,3611,
+8,15,24,3611,
+10,18,21,3611,
+9,16,23,3611,
+4,11,27,3611,
+0,5,29,3611,
+4,15,25,3611,
+12,19,19,3632,
+11,13,24,3632,
+5,20,21,3632,
+1,17,24,3632,
+13,16,21,3632,
+8,19,21,3632,
+3,4,29,3632,
+1,9,28,3632,
+13,13,23,3632,
+11,11,25,3632,
+1,5,29,3632,
+7,17,23,3632,
+17,17,17,3651,
+6,16,24,3651,
+12,18,20,3651,
+7,12,26,3651,
+12,14,23,3651,
+2,17,24,3651,
+10,12,25,3651,
+16,17,18,3659,
+4,18,23,3659,
+6,7,28,3659,
+2,9,28,3659,
+5,13,26,3659,
+7,14,25,3659,
+5,19,22,3659,
+2,5,29,3659,
+0,14,26,3659,
+8,18,22,3659,
+10,14,24,3659,
+16,16,19,3679,
+10,17,22,3679,
+4,4,29,3679,
+0,12,27,3679,
+5,8,28,3679,
+15,18,18,3679,
+1,14,26,3679,
+1,12,27,3679,
+12,17,21,3679,
+8,9,27,3679,
+3,9,28,3679,
+3,17,24,3679,
+5,15,25,3679,
+15,17,19,3692,
+9,13,25,3692,
+5,11,27,3692,
+11,15,23,3692,
+3,5,29,3692,
+14,14,22,3692,
+2,14,26,3692,
+10,10,26,3692,
+0,6,29,3692,
+2,12,27,3692,
+6,20,21,3692,
+13,15,22,3692,
+5,18,23,3692,
+7,10,27,3692,
+9,11,26,3692,
+1,6,29,3692,
+7,16,24,3692,
+4,17,24,3692,
+6,13,26,3692,
+9,20,20,3692,
+6,19,22,3692,
+3,14,26,3692,
+14,18,19,3718,
+2,6,29,3718,
+15,16,20,3718,
+0,16,25,3718,
+4,9,28,3718,
+1,16,25,3718,
+4,5,29,3718,
+0,21,21,3718,
+8,17,23,3718,
+3,12,27,3718,
+7,7,28,3718,
+9,15,24,3718,
+11,19,20,3718,
+1,21,21,3718,
+9,19,21,3718,
+0,20,22,3718,
+0,10,28,3718,
+6,8,28,3718,
+8,12,26,3718,
+12,16,22,3718,
+8,14,25,3718,
+10,16,23,3718,
+14,17,20,3739,
+1,20,22,3739,
+2,16,25,3739,
+1,10,28,3739,
+6,11,27,3739,
+6,15,25,3739,
+2,21,21,3739,
+3,6,29,3739,
+11,18,21,3739,
+4,14,26,3739,
+2,10,28,3739,
+2,20,22,3739,
+12,13,24,3739,
+6,18,23,3739,
+9,18,22,3739,
+4,12,27,3739,
+3,16,25,3739,
+5,9,28,3739,
+7,20,21,3739,
+0,19,23,3739,
+0,7,29,3739,
+11,12,25,3739,
+5,17,24,3739,
+1,19,23,3739,
+15,15,21,3770,
+3,21,21,3770,
+1,7,29,3770,
+5,5,29,3770,
+13,19,19,3770,
+9,9,27,3770,
+4,6,29,3770,
+13,18,20,3785,
+14,16,21,3785,
+3,20,22,3785,
+11,14,24,3785,
+8,10,27,3785,
+3,10,28,3785,
+7,13,26,3785,
+13,14,23,3785,
+10,13,25,3785,
+2,19,23,3785,
+2,7,29,3785,
+7,19,22,3785,
+11,17,22,3785,
+8,16,24,3785,
+4,16,25,3785,
+5,14,26,3785,
+10,11,26,3785,
+7,8,28,3785,
+5,12,27,3785,
+0,13,27,3785,
+4,21,21,3785,
+12,15,23,3789,
+13,17,21,3808,
+9,17,23,3808,
+7,11,27,3808,
+3,7,29,3808,
+7,15,25,3808,
+1,13,27,3808,
+3,19,23,3808,
+4,10,28,3808,
+4,20,22,3808,
+10,20,20,3808,
+0,0,30,3808,
+0,18,24,3808,
+6,9,28,3808,
+0,15,26,3808,
+6,17,24,3808,
+1,18,24,3808,
+9,12,26,3808,
+0,1,30,3808,
+10,15,24,3808,
+5,6,29,3808,
+17,17,18,3840,
+1,1,30,3840,
+10,19,21,3840,
+2,13,27,3840,
+7,18,23,3840,
+9,14,25,3840,
+1,15,26,3840,
+0,2,30,3840,
+16,18,18,3849,
+2,18,24,3849,
+1,2,30,3849,
+8,20,21,3849,
+14,15,22,3849,
+0,11,28,3849,
+12,19,20,3849,
+2,15,26,3849,
+0,8,29,3849,
+1,8,29,3849,
+11,16,23,3849,
+5,16,25,3849,
+1,11,28,3849,
+16,17,19,3865,
+4,19,23,3865,
+4,7,29,3865,
+3,13,27,3865,
+5,21,21,3865,
+2,2,30,3865,
+6,14,26,3865,
+10,18,22,3865,
+13,16,22,3865,
+2,11,28,3865,
+0,3,30,3865,
+6,12,27,3865,
+12,18,21,3865,
+8,19,22,3865,
+8,13,26,3865,
+3,18,24,3865,
+5,20,22,3865,
+5,10,28,3865,
+2,8,29,3865,
+3,15,26,3865,
+1,3,30,3865,
+15,18,19,3884,
+9,10,27,3884,
+8,8,28,3884,
+16,16,20,3890,
+9,16,24,3890,
+6,6,29,3890,
+2,3,30,3890,
+12,12,25,3890,
+15,17,20,3906,
+8,15,25,3906,
+7,9,28,3906,
+3,11,28,3906,
+4,13,27,3906,
+3,8,29,3906,
+7,17,24,3906,
+0,17,25,3906,
+8,11,27,3906,
+13,13,24,3906,
+5,7,29,3906,
+11,13,25,3906,
+1,17,25,3906,
+5,19,23,3906,
+0,4,30,3906,
+4,18,24,3906,
+12,14,24,3906,
+12,17,22,3906,
+4,15,26,3906,
+8,18,23,3906,
+6,16,25,3906,
+1,4,30,3906,
+11,11,26,3906,
+6,21,21,3906,
+3,3,30,3906,
+14,19,19,3916,
+10,17,23,3916,
+2,17,25,3916,
+10,12,26,3916,
+6,20,22,3916,
+14,18,20,3929,
+2,4,30,3929,
+6,10,28,3929,
+4,11,28,3929,
+11,20,20,3929,
+10,14,25,3929,
+4,8,29,3929,
+7,14,26,3929,
+14,14,23,3929,
+7,12,27,3929,
+15,16,21,3940,
+9,20,21,3940,
+0,9,29,3940,
+11,15,24,3940,
+5,13,27,3940,
+13,15,23,3940,
+3,17,25,3940,
+11,19,21,3940,
+1,9,29,3940,
+0,5,30,3940,
+0,14,27,3940,
+0,21,22,3940,
+5,18,24,3940,
+3,4,30,3940,
+9,13,26,3940,
+9,19,22,3940,
+5,15,26,3940,
+6,19,23,3940,
+1,5,30,3940,
+14,17,21,3958,
+1,14,27,3958,
+2,9,29,3958,
+6,7,29,3958,
+1,21,22,3958,
+0,12,28,3958,
+0,20,23,3958,
+2,5,30,3958,
+8,17,24,3958,
+12,16,23,3958,
+8,9,28,3958,
+1,12,28,3958,
+10,10,27,3958,
+11,18,22,3958,
+2,14,27,3958,
+2,21,22,3958,
+5,11,28,3958,
+1,20,23,3958,
+13,19,20,3970,
+5,8,29,3970,
+4,17,25,3970,
+7,16,25,3970,
+7,21,21,3970,
+3,9,29,3970,
+9,15,25,3970,
+9,11,27,3970,
+10,16,24,3970,
+0,16,26,3970,
+2,12,28,3970,
+4,4,30,3970,
+2,20,23,3970,
+1,16,26,3970,
+7,10,28,3970,
+7,20,22,3970,
+3,14,27,3970,
+3,5,30,3970,
+15,15,22,3992,
+6,13,27,3992,
+13,18,21,3992,
+9,18,23,3992,
+3,21,22,3992,
+2,16,26,3992,
+6,18,24,3992,
+14,16,22,4000,
+0,6,30,4000,
+8,14,26,4000,
+3,12,28,4000,
+0,19,24,4000,
+17,18,18,4035,
+1,6,30,4035,
+6,15,26,4035,
+8,12,27,4035,
+1,19,24,4035,
+3,20,23,4035,
+12,13,25,4035,
+4,9,29,4035,
+7,7,29,4035,
+5,17,25,4035,
+11,17,23,4035,
+7,19,23,4035,
+17,17,19,4042,
+2,6,30,4042,
+11,12,26,4042,
+13,14,24,4042,
+0,10,29,4042,
+4,14,27,4042,
+6,8,29,4042,
+10,20,21,4042,
+3,16,26,4042,
+2,19,24,4042,
+6,11,28,4042,
+4,21,22,4042,
+16,18,19,4051,
+4,5,30,4051,
+13,17,22,4051,
+11,14,25,4051,
+1,10,29,4051,
+12,20,20,4051,
+4,12,28,4051,
+8,16,25,4051,
+10,13,26,4051,
+12,15,24,4051,
+3,6,30,4051,
+2,10,29,4051,
+4,20,23,4051,
+16,17,20,4074,
+10,19,22,4074,
+12,19,21,4074,
+8,21,21,4074,
+9,9,28,4074,
+3,19,24,4074,
+9,17,24,4074,
+5,9,29,4074,
+15,19,19,4084,
+7,13,27,4084,
+4,16,26,4084,
+8,20,22,4084,
+8,10,28,4084,
+7,18,24,4084,
+0,18,25,4084,
+0,7,30,4084,
+15,18,20,4095,
+5,21,22,4095,
+7,15,26,4095,
+10,11,27,4095,
+10,15,25,4095,
+1,18,25,4095,
+5,14,27,4095,
+14,15,23,4095,
+5,5,30,4095,
+1,7,30,4095,
+6,17,25,4095,
+3,10,29,4095,
+12,18,22,4095,
+4,6,30,4095,
+9,14,26,4095,
+11,16,24,4095,
+2,7,30,4095,
+2,18,25,4095,
+16,16,21,4111,
+5,12,28,4111,
+10,18,23,4111,
+4,19,24,4111,
+0,13,28,4111,
+9,12,27,4111,
+13,16,23,4111,
+7,11,28,4111,
+8,19,23,4111,
+1,13,28,4111,
+5,20,23,4111,
+0,15,27,4111,
+7,8,29,4111,
+1,15,27,4111,
+15,17,21,4124,
+14,19,20,4136,
+4,10,29,4136,
+5,16,26,4136,
+2,13,28,4136,
+3,7,30,4136,
+6,9,29,4136,
+3,18,25,4136,
+2,15,27,4136,
+5,6,30,4136,
+6,21,22,4136,
+6,14,27,4136,
+0,0,31,4136,
+14,18,21,4148,
+0,1,31,4148,
+5,19,24,4148,
+11,20,21,4148,
+12,17,23,4148,
+8,13,27,4148,
+0,11,29,4148,
+3,13,28,4148,
+9,16,25,4148,
+7,17,25,4148,
+1,1,31,4148,
+9,21,21,4148,
+1,11,29,4148,
+3,15,27,4148,
+13,13,25,4148,
+6,12,28,4148,
+8,18,24,4148,
+12,12,26,4148,
+0,8,30,4148,
+6,20,23,4148,
+1,8,30,4148,
+9,10,28,4148,
+4,7,30,4148,
+10,17,24,4148,
+8,15,26,4148,
+9,20,22,4148,
+4,18,25,4148,
+15,16,22,4172,
+12,14,25,4172,
+0,2,31,4172,
+0,17,26,4172,
+11,13,26,4172,
+11,19,22,4172,
+1,17,26,4172,
+2,11,29,4172,
+5,10,29,4172,
+1,2,31,4172,
+2,8,30,4172,
+6,16,26,4172,
+14,14,24,4172,
+0,22,22,4172,
+13,20,20,4194,
+1,22,22,4194,
+2,2,31,4194,
+8,8,29,4194,
+14,17,22,4194,
+4,13,28,4194,
+8,11,28,4194,
+2,17,26,4194,
+0,3,31,4194,
+13,15,24,4194,
+4,15,27,4194,
+0,21,23,4194,
+13,19,21,4205,
+3,11,29,4205,
+11,11,27,4205,
+1,3,31,4205,
+1,21,23,4205,
+7,9,29,4205,
+11,15,25,4205,
+9,19,23,4205,
+2,22,22,4205,
+18,18,18,4219,
+6,6,30,4219,
+10,14,26,4219,
+10,12,27,4219,
+6,19,24,4219,
+3,8,30,4219,
+3,17,26,4219,
+7,21,22,4219,
+5,7,30,4219,
+2,21,23,4219,
+7,14,27,4219,
+2,3,31,4219,
+17,18,19,4231,
+11,18,23,4231,
+5,18,25,4231,
+12,16,24,4231,
+0,20,24,4231,
+1,20,24,4231,
+0,4,31,4231,
+6,10,29,4231,
+13,18,22,4231,
+7,12,28,4231,
+3,22,22,4231,
+5,13,28,4231,
+1,4,31,4231,
+7,20,23,4231,
+8,17,25,4231,
+4,11,29,4231,
+17,17,20,4260,
+16,19,19,4260,
+3,21,23,4260,
+5,15,27,4260,
+9,13,27,4260,
+15,15,23,4260,
+3,3,31,4260,
+0,14,28,4260,
+16,18,20,4263,
+2,20,24,4263,
+4,8,30,4263,
+9,18,24,4263,
+1,14,28,4263,
+10,16,25,4263,
+2,4,31,4263,
+4,17,26,4263,
+14,16,23,4263,
+0,9,30,4263,
+7,16,26,4263,
+10,21,21,4263,
+9,15,26,4263,
+1,9,30,4263,
+2,14,28,4263,
+10,20,22,4263,
+4,22,22,4263,
+10,10,28,4263,
+12,20,21,4273,
+6,7,30,4273,
+0,12,29,4273,
+6,18,25,4273,
+2,9,30,4273,
+0,16,27,4273,
+3,20,24,4273,
+8,9,29,4273,
+3,4,31,4273,
+7,19,24,4273,
+0,5,31,4273,
+4,21,23,4273,
+0,19,25,4273,
+9,11,28,4273,
+15,19,20,4299,
+16,17,21,4299,
+1,16,27,4299,
+11,17,24,4299,
+1,12,29,4299,
+1,5,31,4299,
+5,11,29,4299,
+1,19,25,4299,
+13,17,23,4299,
+2,12,29,4299,
+12,13,26,4299,
+12,19,22,4299,
+8,14,27,4299,
+6,13,28,4299,
+2,16,27,4299,
+8,21,22,4299,
+5,8,30,4299,
+3,14,28,4299,
+6,15,27,4299,
+2,5,31,4299,
+5,17,26,4299,
+2,19,25,4299,
+10,19,23,4299,
+7,10,29,4299,
+13,14,25,4299,
+3,9,30,4299,
+15,18,21,4315,
+8,12,28,4315,
+4,20,24,4315,
+4,4,31,4315,
+8,20,23,4315,
+11,14,26,4315,
+5,22,22,4315,
+3,12,29,4315,
+3,16,27,4315,
+12,15,25,4315,
+11,12,27,4315,
+5,21,23,4315,
+3,5,31,4315,
+9,17,25,4315,
+3,19,25,4315,
+8,16,26,4315,
+4,14,28,4315,
+14,20,20,4341,
+16,16,22,4341,
+14,15,24,4341,
+4,9,30,4341,
+0,6,31,4341,
+12,18,23,4341,
+14,19,21,4359,
+7,7,30,4359,
+6,11,29,4359,
+7,18,25,4359,
+10,13,27,4359,
+1,6,31,4359,
+15,17,22,4359,
+0,18,26,4359,
+0,10,30,4359,
+10,18,24,4359,
+6,8,30,4359,
+4,12,29,4359,
+8,19,24,4359,
+4,16,27,4359,
+5,20,24,4359,
+6,17,26,4359,
+10,15,26,4359,
+2,6,31,4359,
+1,18,26,4359,
+13,16,24,4359,
+1,10,30,4359,
+7,13,28,4359,
+4,19,25,4359,
+4,5,31,4359,
+11,16,25,4359,
+11,21,21,4362,
+7,15,27,4362,
+9,9,29,4362,
+2,10,30,4362,
+2,18,26,4362,
+14,18,22,4382,
+6,22,22,4382,
+8,10,29,4382,
+5,14,28,4382,
+11,20,22,4382,
+10,11,28,4382,
+3,6,31,4382,
+9,21,22,4382,
+9,14,27,4382,
+6,21,23,4382,
+5,9,30,4382,
+3,10,30,4382,
+0,15,28,4382,
+12,17,24,4390,
+9,12,28,4390,
+18,18,19,4433,
+3,18,26,4433,
+1,15,28,4433,
+9,20,23,4433,
+5,16,27,4433,
+0,13,29,4433,
+13,20,21,4433,
+15,16,23,4433,
+5,12,29,4433,
+0,7,31,4433,
+17,19,19,4444,
+5,5,31,4444,
+11,19,23,4444,
+5,19,25,4444,
+7,11,29,4444,
+1,13,29,4444,
+1,7,31,4444,
+6,20,24,4444,
+0,22,23,4444,
+17,18,20,4452,
+9,16,26,4452,
+2,15,28,4452,
+8,18,25,4452,
+4,6,31,4452,
+7,8,30,4452,
+10,17,25,4452,
+2,13,29,4452,
+14,17,23,4452,
+7,17,26,4452,
+1,22,23,4452,
+13,19,22,4452,
+13,13,26,4452,
+2,7,31,4452,
+4,10,30,4452,
+12,14,26,4452,
+4,18,26,4452,
+6,14,28,4452,
+12,12,27,4452,
+0,21,24,4452,
+7,22,22,4452,
+6,9,30,4452,
+2,22,23,4452,
+16,19,20,4466,
+8,13,28,4466,
+14,14,25,4466,
+8,15,27,4466,
+9,19,24,4466,
+1,21,24,4466,
+3,15,28,4466,
+0,17,27,4466,
+13,15,25,4466,
+3,7,31,4466,
+1,17,27,4466,
+17,17,21,4486,
+7,21,23,4486,
+11,13,27,4486,
+3,13,29,4486,
+6,12,29,4486,
+11,18,24,4486,
+16,18,21,4497,
+0,11,30,4497,
+2,21,24,4497,
+6,16,27,4497,
+11,15,26,4497,
+5,6,31,4497,
+1,11,30,4497,
+9,10,29,4497,
+2,17,27,4497,
+6,19,25,4497,
+3,22,23,4497,
+13,18,23,4497,
+0,0,32,4497,
+15,20,20,4518,
+2,11,30,4518,
+12,16,25,4518,
+10,21,22,4518,
+0,20,25,4518,
+0,1,32,4518,
+4,15,28,4518,
+7,20,24,4518,
+10,14,27,4518,
+5,18,26,4518,
+5,10,30,4518,
+0,8,31,4518,
+11,11,28,4518,
+1,8,31,4518,
+4,13,29,4518,
+1,20,25,4518,
+1,1,32,4518,
+12,21,21,4518,
+4,7,31,4518,
+15,15,24,4518,
+3,21,24,4518,
+8,11,29,4518,
+15,19,21,4530,
+3,17,27,4530,
+12,20,22,4530,
+8,8,30,4530,
+0,2,32,4530,
+10,12,28,4530,
+14,16,24,4530,
+10,20,23,4530,
+2,8,31,4530,
+16,17,22,4539,
+1,2,32,4539,
+8,17,26,4539,
+7,14,28,4539,
+4,22,23,4539,
+2,20,25,4539,
+9,18,25,4539,
+3,11,30,4539,
+7,9,30,4539,
+10,16,26,4539,
+8,22,22,4539,
+2,2,32,4539,
+15,18,22,4558,
+4,21,24,4558,
+6,6,31,4558,
+0,3,32,4558,
+9,13,28,4558,
+8,21,23,4558,
+13,17,24,4558,
+3,8,31,4558,
+5,15,28,4558,
+7,12,29,4558,
+4,17,27,4558,
+7,16,27,4558,
+1,3,32,4558,
+12,19,23,4558,
+3,20,25,4558,
+11,17,25,4558,
+7,19,25,4558,
+5,7,31,4558,
+5,13,29,4558,
+9,15,27,4558,
+6,18,26,4558,
+6,10,30,4558,
+0,14,29,4558,
+10,19,24,4558,
+2,3,32,4558,
+0,19,26,4558,
+4,11,30,4558,
+14,20,21,4581,
+5,22,23,4581,
+1,19,26,4581,
+1,14,29,4581,
+0,4,32,4581,
+0,16,28,4581,
+8,20,24,4581,
+2,14,29,4581,
+1,4,32,4581,
+4,8,31,4581,
+16,16,23,4595,
+13,14,26,4595,
+14,19,22,4595,
+2,19,26,4595,
+10,10,29,4595,
+4,20,25,4595,
+1,16,28,4595,
+12,13,27,4595,
+5,21,24,4595,
+3,3,32,4595,
+0,9,31,4595,
+1,9,31,4595,
+5,17,27,4595,
+9,11,29,4595,
+15,17,23,4612,
+12,18,24,4612,
+0,12,30,4612,
+2,4,32,4612,
+8,14,28,4612,
+2,16,28,4612,
+12,15,26,4612,
+6,15,28,4612,
+1,12,30,4612,
+8,9,30,4612,
+2,9,31,4612,
+11,21,22,4612,
+3,14,29,4612,
+9,17,26,4612,
+6,13,29,4612,
+18,19,19,4637,
+6,7,31,4637,
+11,14,27,4637,
+5,11,30,4637,
+14,15,25,4637,
+3,19,26,4637,
+18,18,20,4649,
+2,12,30,4649,
+11,12,28,4649,
+3,16,28,4649,
+0,5,32,4649,
+7,10,30,4649,
+14,18,23,4649,
+9,22,22,4649,
+8,16,27,4649,
+7,18,26,4649,
+3,4,32,4649,
+10,18,25,4649,
+6,22,23,4649,
+8,12,29,4649,
+13,16,25,4649,
+11,20,23,4649,
+17,19,20,4668,
+1,5,32,4668,
+5,8,31,4668,
+8,19,25,4668,
+5,20,25,4668,
+13,21,21,4668,
+3,9,31,4668,
+9,21,23,4668,
+13,20,22,4668,
+11,16,26,4668,
+2,5,32,4668,
+4,19,26,4668,
+3,12,30,4668,
+6,21,24,4668,
+4,14,29,4668,
+0,18,27,4668,
+10,13,28,4668,
+10,15,27,4668,
+1,18,27,4668,
+17,18,21,4684,
+6,17,27,4684,
+4,4,32,4684,
+4,16,28,4684,
+16,20,20,4692,
+2,18,27,4692,
+6,11,30,4692,
+9,20,24,4692,
+15,16,24,4692,
+16,19,21,4705,
+7,15,28,4705,
+3,5,32,4705,
+11,19,24,4705,
+4,9,31,4705,
+0,23,23,4705,
+12,17,25,4705,
+13,19,23,4705,
+7,7,31,4705,
+1,23,23,4705,
+7,13,29,4705,
+0,22,24,4705,
+4,12,30,4705,
+0,6,32,4705,
+14,17,24,4705,
+0,10,31,4705,
+6,20,25,4705,
+6,8,31,4705,
+9,14,28,4705,
+1,6,32,4705,
+1,22,24,4705,
+17,17,22,4722,
+10,11,29,4722,
+5,19,26,4722,
+5,14,29,4722,
+3,18,27,4722,
+1,10,31,4722,
+2,23,23,4722,
+9,9,30,4722,
+7,22,23,4722,
+2,6,32,4722,
+2,22,24,4722,
+8,10,30,4722,
+16,18,22,4732,
+8,18,26,4732,
+5,16,28,4732,
+2,10,31,4732,
+4,5,32,4732,
+10,17,26,4732,
+9,16,27,4732,
+7,21,24,4732,
+9,12,29,4732,
+15,20,21,4749,
+0,21,25,4749,
+0,15,29,4749,
+1,21,25,4749,
+7,17,27,4749,
+5,9,31,4749,
+3,23,23,4749,
+13,13,27,4749,
+9,19,25,4749,
+1,15,29,4749,
+10,22,22,4749,
+14,14,26,4749,
+3,6,32,4749,
+4,18,27,4749,
+12,21,22,4749,
+12,14,27,4749,
+0,13,30,4749,
+5,12,30,4749,
+3,22,24,4749,
+13,18,24,4749,
+13,15,26,4749,
+2,21,25,4749,
+3,10,31,4749,
+7,11,30,4749,
+11,18,25,4749,
+10,21,23,4749,
+15,19,22,4771,
+2,15,29,4771,
+1,13,30,4771,
+12,12,28,4771,
+8,15,28,4771,
+2,13,30,4771,
+0,7,32,4771,
+6,19,26,4771,
+12,20,23,4771,
+6,14,29,4771,
+0,17,28,4771,
+5,5,32,4771,
+1,7,32,4771,
+4,23,23,4771,
+7,20,25,4771,
+8,13,29,4771,
+16,17,23,4792,
+7,8,31,4792,
+1,17,28,4792,
+11,13,28,4792,
+11,15,27,4792,
+3,15,29,4792,
+15,15,25,4792,
+3,21,25,4792,
+4,22,24,4792,
+0,20,26,4792,
+4,6,32,4792,
+10,20,24,4792,
+12,16,26,4792,
+6,16,28,4792,
+1,20,26,4792,
+8,22,23,4792,
+2,17,28,4792,
+2,7,32,4792,
+4,10,31,4792,
+14,16,25,4792,
+15,18,23,4815,
+6,9,31,4815,
+3,13,30,4815,
+14,21,21,4815,
+5,18,27,4815,
+2,20,26,4815,
+10,14,28,4815,
+14,20,22,4824,
+6,12,30,4824,
+9,18,26,4824,
+9,10,30,4824,
+8,21,24,4824,
+12,19,24,4824,
+4,21,25,4824,
+3,17,28,4824,
+8,17,27,4824,
+4,15,29,4824,
+3,7,32,4824,
+0,11,31,4824,
+1,11,31,4824,
+11,11,29,4824,
+5,23,23,4824,
+13,17,25,4824,
+19,19,19,4858,
+5,6,32,4858,
+10,12,29,4858,
+3,20,26,4858,
+4,13,30,4858,
+18,19,20,4872,
+8,11,30,4872,
+10,16,27,4872,
+5,22,24,4872,
+10,19,25,4872,
+11,17,26,4872,
+7,14,29,4872,
+2,11,31,4872,
+5,10,31,4872,
+7,19,26,4872,
+14,19,23,4872,
+16,16,24,4872,
+0,8,32,4872,
+4,7,32,4872,
+7,16,28,4872,
+6,18,27,4872,
+8,8,31,4872,
+4,17,28,4872,
+18,18,21,4894,
+11,22,22,4894,
+0,0,33,4894,
+17,20,20,4894,
+8,20,25,4894,
+1,8,32,4894,
+9,15,28,4894,
+15,17,24,4894,
+0,1,33,4894,
+0,19,27,4894,
+5,21,25,4894,
+11,21,23,4894,
+9,13,29,4894,
+3,11,31,4894,
+5,15,29,4894,
+7,9,31,4894,
+1,1,33,4894,
+1,19,27,4894,
+17,19,21,4907,
+4,20,26,4907,
+2,8,32,4907,
+7,12,30,4907,
+12,18,25,4907,
+0,2,33,4907,
+1,2,33,4907,
+13,21,22,4907,
+5,13,30,4907,
+2,19,27,4907,
+9,22,23,4907,
+6,23,23,4907,
+13,14,27,4907,
+6,6,32,4907,
+0,14,30,4907,
+14,18,24,4910,
+6,22,24,4910,
+0,16,29,4910,
+6,10,31,4910,
+12,13,28,4910,
+1,14,30,4910,
+3,8,32,4910,
+2,2,33,4910,
+11,20,24,4910,
+16,20,21,4932,
+14,15,26,4932,
+17,18,22,4932,
+4,11,31,4932,
+9,21,24,4932,
+1,16,29,4932,
+5,7,32,4932,
+0,3,33,4932,
+5,17,28,4932,
+13,20,23,4932,
+12,15,27,4932,
+1,3,33,4932,
+3,19,27,4932,
+9,17,27,4932,
+2,14,30,4932,
+10,10,30,4932,
+10,18,26,4932,
+2,16,29,4932,
+11,14,28,4932,
+8,14,29,4932,
+13,16,26,4932,
+5,20,26,4932,
+8,19,26,4932,
+16,19,22,4952,
+2,3,33,4952,
+6,21,25,4952,
+7,18,27,4952,
+9,11,30,4952,
+6,15,29,4952,
+4,8,32,4952,
+8,16,28,4952,
+6,13,30,4952,
+3,14,30,4952,
+0,9,32,4952,
+0,23,24,4952,
+0,4,33,4952,
+0,12,31,4952,
+1,9,32,4952,
+15,16,25,4957,
+1,12,31,4957,
+13,19,24,4957,
+11,12,29,4957,
+8,9,31,4957,
+3,16,29,4957,
+9,20,25,4957,
+11,16,27,4957,
+1,4,33,4957,
+4,19,27,4957,
+1,23,24,4957,
+15,21,21,4975,
+5,11,31,4975,
+17,17,23,4975,
+3,3,33,4975,
+7,23,23,4975,
+11,19,25,4975,
+8,12,30,4975,
+0,18,28,4975,
+6,17,28,4975,
+15,20,22,4992,
+2,12,31,4992,
+0,22,25,4992,
+7,22,24,4992,
+2,23,24,4992,
+12,17,26,4992,
+2,4,33,4992,
+16,18,23,4992,
+10,15,28,4992,
+6,7,32,4992,
+1,18,28,4992,
+2,9,32,4992,
+1,22,25,4992,
+14,17,25,4992,
+10,13,29,4992,
+7,10,31,4992,
+6,20,26,4992,
+4,14,30,4992,
+2,18,28,4992,
+12,22,22,4992,
+5,8,32,4992,
+2,22,25,4992,
+4,16,29,4992,
+10,22,23,4992,
+3,4,33,4992,
+3,23,24,4992,
+12,21,23,5003,
+3,12,31,5003,
+3,9,32,5003,
+0,5,33,5003,
+7,21,25,5003,
+7,15,29,5003,
+15,19,23,5026,
+5,19,27,5026,
+1,5,33,5026,
+3,18,28,5026,
+10,21,24,5026,
+8,18,27,5026,
+0,21,26,5026,
+7,13,30,5026,
+2,5,33,5026,
+10,17,27,5026,
+1,21,26,5026,
+6,11,31,5026,
+9,19,26,5026,
+3,22,25,5026,
+9,14,29,5026,
+13,18,25,5026,
+12,20,24,5030,
+4,12,31,5030,
+5,14,30,5030,
+4,23,24,5030,
+10,11,30,5030,
+9,16,28,5030,
+16,17,24,5058,
+2,21,26,5058,
+14,14,27,5058,
+4,4,33,5058,
+4,9,32,5058,
+11,18,26,5058,
+14,21,22,5058,
+19,19,20,5084,
+8,23,23,5084,
+7,17,28,5084,
+13,13,28,5084,
+7,7,32,5084,
+5,16,29,5084,
+9,9,31,5084,
+3,5,33,5084,
+13,15,27,5084,
+0,10,32,5084,
+12,14,28,5084,
+6,8,32,5084,
+8,22,24,5084,
+18,20,20,5090,
+4,18,28,5090,
+0,6,33,5090,
+10,20,25,5090,
+4,22,25,5090,
+7,20,26,5090,
+0,15,30,5090,
+9,12,30,5090,
+15,18,24,5090,
+1,10,32,5090,
+8,10,31,5090,
+14,20,23,5090,
+1,15,30,5090,
+15,15,26,5090,
+6,19,27,5090,
+1,6,33,5090,
+3,21,26,5090,
+18,19,21,5108,
+2,10,32,5108,
+14,16,26,5108,
+12,16,27,5108,
+12,12,29,5108,
+0,20,27,5108,
+2,6,33,5108,
+2,15,30,5108,
+11,15,28,5108,
+1,20,27,5108,
+0,17,29,5108,
+5,23,24,5108,
+5,12,31,5108,
+4,5,33,5108,
+12,19,25,5108,
+8,15,29,5108,
+5,9,32,5108,
+17,20,21,5127,
+8,21,25,5127,
+0,13,31,5127,
+11,13,29,5127,
+1,17,29,5127,
+1,13,31,5127,
+7,11,31,5127,
+18,18,22,5130,
+6,14,30,5130,
+14,19,24,5130,
+3,10,32,5130,
+2,20,27,5130,
+5,18,28,5130,
+6,16,29,5130,
+8,13,30,5130,
+4,21,26,5130,
+3,6,33,5130,
+9,18,27,5130,
+3,15,30,5130,
+2,13,31,5130,
+13,17,26,5130,
+5,22,25,5130,
+17,19,22,5148,
+11,22,23,5148,
+2,17,29,5148,
+8,17,28,5148,
+7,8,32,5148,
+10,14,29,5148,
+10,19,26,5148,
+16,16,25,5148,
+13,22,22,5148,
+16,21,21,5175,
+0,7,33,5175,
+3,20,27,5175,
+11,21,24,5175,
+11,17,27,5175,
+9,23,23,5175,
+5,5,33,5175,
+15,17,25,5175,
+13,21,23,5175,
+3,13,31,5175,
+3,17,29,5175,
+1,7,33,5175,
+7,19,27,5175,
+10,16,28,5175,
+8,20,26,5175,
+4,10,32,5175,
+16,20,22,5178,
+9,22,24,5178,
+6,12,31,5178,
+6,23,24,5178,
+4,15,30,5178,
+6,9,32,5178,
+4,6,33,5178,
+11,11,30,5178,
+5,21,26,5178,
+9,10,31,5178,
+17,18,23,5201,
+2,7,33,5201,
+6,18,28,5201,
+10,12,30,5201,
+12,18,26,5201,
+7,14,30,5201,
+6,22,25,5201,
+0,19,28,5201,
+0,11,32,5201,
+13,20,24,5201,
+14,18,25,5201,
+4,20,27,5201,
+7,16,29,5201,
+1,11,32,5201,
+16,19,23,5219,
+8,11,31,5219,
+11,20,25,5219,
+1,19,28,5219,
+4,13,31,5219,
+4,17,29,5219,
+9,21,25,5219,
+9,15,29,5219,
+3,7,33,5219,
+2,19,28,5219,
+13,14,28,5219,
+5,10,32,5219,
+2,11,32,5219,
+5,6,33,5219,
+5,15,30,5219,
+15,21,22,5237,
+14,15,27,5237,
+9,13,30,5237,
+0,24,24,5237,
+8,8,32,5237,
+0,8,33,5237,
+6,21,26,5237,
+12,15,28,5237,
+1,24,24,5237,
+10,18,27,5237,
+17,17,24,5259,
+0,23,25,5259,
+8,19,27,5259,
+3,19,28,5259,
+7,12,31,5259,
+15,20,23,5259,
+12,13,29,5259,
+13,16,27,5259,
+3,11,32,5259,
+4,7,33,5259,
+1,8,33,5259,
+9,17,28,5259,
+7,23,24,5259,
+7,9,32,5259,
+5,20,27,5259,
+1,23,25,5259,
+13,19,25,5259,
+5,17,29,5259,
+5,13,31,5259,
+0,0,34,5259,
+2,24,24,5259,
+16,18,24,5264,
+0,16,30,5264,
+7,18,28,5264,
+15,16,26,5264,
+9,20,26,5264,
+12,22,23,5264,
+0,1,34,5264,
+2,8,33,5264,
+0,14,31,5264,
+1,16,30,5264,
+2,23,25,5264,
+11,19,26,5264,
+11,14,29,5264,
+7,22,25,5264,
+1,1,34,5264,
+10,23,23,5264,
+1,14,31,5264,
+8,14,30,5264,
+2,16,30,5264,
+0,22,26,5264,
+6,10,32,5264,
+10,22,24,5264,
+0,2,34,5264,
+4,11,32,5264,
+1,22,26,5264,
+8,16,29,5264,
+4,19,28,5264,
+2,14,31,5264,
+6,15,30,5264,
+19,20,20,5312,
+14,17,26,5312,
+12,21,24,5312,
+1,2,34,5312,
+6,6,33,5312,
+11,16,28,5312,
+10,10,31,5312,
+3,24,24,5312,
+3,8,33,5312,
+12,17,27,5312,
+15,19,24,5312,
+9,11,31,5312,
+19,19,21,5323,
+3,23,25,5323,
+5,7,33,5323,
+14,22,22,5323,
+2,2,34,5323,
+2,22,26,5323,
+3,16,30,5323,
+6,20,27,5323,
+0,3,34,5323,
+11,12,30,5323,
+0,18,29,5323,
+18,20,21,5336,
+7,21,26,5336,
+14,21,23,5336,
+1,3,34,5336,
+10,21,25,5336,
+6,13,31,5336,
+1,18,29,5336,
+3,14,31,5336,
+6,17,29,5336,
+10,15,29,5336,
+0,12,32,5336,
+4,24,24,5336,
+2,3,34,5336,
+8,9,32,5336,
+13,18,26,5336,
+2,18,29,5336,
+18,19,22,5353,
+8,12,31,5353,
+8,23,24,5353,
+1,12,32,5353,
+3,22,26,5353,
+10,13,30,5353,
+12,20,25,5353,
+4,8,33,5353,
+5,11,32,5353,
+0,9,33,5353,
+0,21,27,5353,
+16,17,25,5353,
+4,23,25,5353,
+5,19,28,5353,
+1,21,27,5353,
+9,19,27,5353,
+17,21,21,5370,
+1,9,33,5370,
+14,20,24,5370,
+8,18,28,5370,
+2,12,32,5370,
+0,4,34,5370,
+4,16,30,5370,
+4,14,31,5370,
+8,22,25,5370,
+1,4,34,5370,
+7,10,32,5370,
+17,20,22,5386,
+10,17,28,5386,
+3,18,29,5386,
+15,18,25,5386,
+2,21,27,5386,
+7,15,30,5386,
+6,7,33,5386,
+2,9,33,5386,
+11,18,27,5386,
+3,3,34,5386,
+10,20,26,5386,
+2,4,34,5386,
+4,22,26,5386,
+14,14,28,5386,
+18,18,23,5404,
+9,14,30,5404,
+3,12,32,5404,
+5,24,24,5404,
+7,20,27,5404,
+13,15,28,5404,
+9,16,29,5404,
+5,8,33,5404,
+13,13,29,5404,
+17,19,23,5420,
+15,15,27,5420,
+7,13,31,5420,
+11,23,23,5420,
+5,23,25,5420,
+7,17,29,5420,
+3,21,27,5420,
+3,9,33,5420,
+3,4,34,5420,
+16,21,22,5428,
+5,16,30,5428,
+8,21,26,5428,
+6,19,28,5428,
+12,14,29,5428,
+6,11,32,5428,
+12,19,26,5428,
+4,18,29,5428,
+14,16,27,5428,
+11,22,24,5428,
+0,5,34,5428,
+1,5,34,5428,
+13,22,23,5428,
+5,14,31,5428,
+14,19,25,5428,
+10,11,31,5428,
+12,16,28,5428,
+4,12,32,5428,
+0,20,28,5428,
+16,20,23,5448,
+1,20,28,5448,
+5,22,26,5448,
+2,5,34,5448,
+13,21,24,5448,
+0,15,31,5448,
+9,9,32,5448,
+9,12,31,5448,
+4,9,33,5448,
+4,21,27,5448,
+9,23,24,5448,
+7,7,33,5448,
+11,15,29,5448,
+11,21,25,5448,
+1,15,31,5448,
+13,17,27,5448,
+2,20,28,5448,
+6,24,24,5448,
+16,16,26,5448,
+8,10,32,5448,
+4,4,34,5448,
+12,12,30,5448,
+17,18,24,5464,
+6,8,33,5464,
+0,10,33,5464,
+0,17,30,5464,
+8,15,30,5464,
+9,18,28,5464,
+1,10,33,5464,
+11,13,30,5464,
+3,5,34,5464,
+2,15,31,5464,
+5,18,29,5464,
+9,22,25,5464,
+15,17,26,5464,
+10,19,27,5464,
+1,17,30,5464,
+6,23,25,5464,
+6,16,30,5464,
+0,6,34,5464,
+1,6,34,5464,
+16,19,24,5479,
+2,17,30,5479,
+5,12,32,5479,
+2,10,33,5479,
+6,14,31,5479,
+3,20,28,5479,
+0,13,32,5479,
+15,22,22,5479,
+8,20,27,5479,
+7,11,32,5479,
+8,13,31,5479,
+7,19,28,5479,
+1,13,32,5479,
+8,17,29,5479,
+11,17,28,5479,
+13,20,25,5479,
+5,21,27,5479,
+15,21,23,5489,
+5,9,33,5489,
+3,15,31,5489,
+6,22,26,5489,
+2,6,34,5489,
+14,18,26,5489,
+10,14,30,5489,
+2,13,32,5489,
+12,18,27,5489,
+11,20,26,5489,
+10,16,29,5489,
+4,5,34,5489,
+3,10,33,5489,
+3,17,30,5489,
+9,21,26,5489,
+20,20,20,5546,
+4,20,28,5546,
+7,24,24,5546,
+3,6,34,5546,
+0,24,25,5546,
+6,18,29,5546,
+15,20,24,5546,
+12,23,23,5546,
+4,15,31,5546,
+1,24,25,5546,
+19,20,21,5565,
+0,19,29,5565,
+7,8,33,5565,
+3,13,32,5565,
+11,11,31,5565,
+17,17,25,5565,
+7,23,25,5565,
+1,19,29,5565,
+6,12,32,5565,
+12,22,24,5565,
+14,15,28,5565,
+7,16,30,5565,
+10,23,24,5565,
+16,18,25,5565,
+10,12,31,5565,
+2,24,25,5565,
+4,10,33,5565,
+9,10,32,5565,
+0,23,26,5565,
+4,17,30,5565,
+0,7,34,5565,
+5,5,34,5565,
+7,14,31,5565,
+13,14,29,5565,
+13,19,26,5565,
+19,19,22,5581,
+6,9,33,5581,
+2,19,29,5581,
+6,21,27,5581,
+18,21,21,5581,
+1,7,34,5581,
+9,15,30,5581,
+1,23,26,5581,
+18,20,22,5593,
+10,18,28,5593,
+4,6,34,5593,
+2,23,26,5593,
+10,22,25,5593,
+7,22,26,5593,
+13,16,28,5593,
+8,11,32,5593,
+5,20,28,5593,
+14,22,23,5593,
+2,7,34,5593,
+8,19,28,5593,
+4,13,32,5593,
+3,24,25,5593,
+12,21,25,5593,
+15,16,27,5593,
+12,15,29,5593,
+0,11,33,5593,
+9,20,27,5593,
+1,11,33,5593,
+3,19,29,5593,
+15,19,25,5593,
+9,13,31,5593,
+5,15,31,5593,
+9,17,29,5593,
+11,19,27,5593,
+0,22,27,5593,
+12,13,30,5593,
+14,21,24,5600,
+5,17,30,5600,
+2,11,33,5600,
+18,19,23,5628,
+1,22,27,5628,
+7,18,29,5628,
+3,7,34,5628,
+17,21,22,5628,
+14,17,27,5628,
+5,10,33,5628,
+3,23,26,5628,
+8,24,24,5628,
+7,12,32,5628,
+8,8,33,5628,
+5,6,34,5628,
+2,22,27,5628,
+10,21,26,5628,
+12,17,28,5628,
+4,24,25,5628,
+0,16,31,5628,
+11,14,30,5628,
+17,20,23,5656,
+1,16,31,5656,
+4,19,29,5656,
+8,23,25,5656,
+5,13,32,5656,
+11,16,29,5656,
+7,21,27,5656,
+3,11,33,5656,
+7,9,33,5656,
+0,14,32,5656,
+12,20,26,5656,
+6,20,28,5656,
+8,16,30,5656,
+0,8,34,5656,
+4,7,34,5656,
+1,14,32,5656,
+14,20,25,5656,
+2,16,31,5656,
+8,14,31,5656,
+16,17,26,5656,
+1,8,34,5656,
+4,23,26,5656,
+13,18,27,5656,
+3,22,27,5656,
+6,15,31,5656,
+18,18,24,5685,
+0,18,30,5685,
+2,14,32,5685,
+10,10,32,5685,
+8,22,26,5685,
+2,8,34,5685,
+16,22,22,5685,
+0,21,28,5685,
+15,18,26,5685,
+6,10,33,5685,
+10,15,30,5685,
+1,18,30,5685,
+0,0,35,5685,
+6,17,30,5685,
+9,19,28,5685,
+1,21,28,5685,
+0,1,35,5685,
+16,21,23,5697,
+9,11,32,5697,
+3,16,31,5697,
+5,24,25,5697,
+4,11,33,5697,
+11,12,31,5697,
+11,23,24,5697,
+17,19,24,5697,
+1,1,35,5697,
+13,23,23,5697,
+5,19,29,5697,
+6,6,34,5697,
+2,18,30,5697,
+0,2,35,5697,
+6,13,32,5697,
+3,14,32,5697,
+11,18,28,5697,
+13,22,24,5697,
+10,20,27,5697,
+4,22,27,5697,
+3,8,34,5697,
+2,21,28,5697,
+8,18,29,5697,
+5,7,34,5697,
+5,23,26,5697,
+1,2,35,5697,
+10,17,29,5697,
+10,13,31,5697,
+11,22,25,5697,
+16,20,24,5729,
+8,12,32,5729,
+4,16,31,5729,
+9,24,24,5729,
+2,2,35,5729,
+0,12,33,5729,
+14,19,26,5729,
+3,18,30,5729,
+7,20,28,5729,
+14,14,29,5729,
+8,9,33,5729,
+0,3,35,5729,
+15,15,28,5729,
+3,21,28,5729,
+1,12,33,5729,
+12,19,27,5729,
+8,21,27,5729,
+1,3,35,5729,
+9,23,25,5729,
+5,11,33,5729,
+7,15,31,5729,
+13,21,25,5729,
+13,15,29,5729,
+4,8,34,5729,
+4,14,32,5729,
+14,16,28,5729,
+6,24,25,5729,
+9,16,30,5729,
+2,12,33,5729,
+0,9,34,5729,
+11,21,26,5729,
+9,14,31,5729,
+13,13,30,5729,
+15,22,23,5759,
+2,3,35,5759,
+7,17,30,5759,
+1,9,34,5759,
+6,19,29,5759,
+5,22,27,5759,
+7,10,33,5759,
+17,18,25,5759,
+12,14,30,5759,
+4,18,30,5759,
+16,16,27,5759,
+12,16,29,5759,
+0,4,35,5759,
+6,7,34,5759,
+4,21,28,5759,
+6,23,26,5759,
+2,9,34,5759,
+20,20,21,5802,
+0,20,29,5802,
+9,22,26,5802,
+13,17,28,5802,
+16,19,25,5802,
+5,16,31,5802,
+1,4,35,5802,
+1,20,29,5802,
+7,13,32,5802,
+15,21,24,5802,
+3,12,33,5802,
+19,21,21,5813,
+15,17,27,5813,
+3,3,35,5813,
+13,20,26,5813,
+10,19,28,5813,
+5,8,34,5813,
+2,20,29,5813,
+10,11,32,5813,
+19,20,22,5819,
+5,14,32,5819,
+2,4,35,5819,
+9,18,29,5819,
+11,15,30,5819,
+3,9,34,5819,
+6,11,33,5819,
+8,20,28,5819,
+18,21,22,5837,
+12,23,24,5837,
+5,18,30,5837,
+6,22,27,5837,
+0,15,32,5837,
+9,12,32,5837,
+14,18,27,5837,
+12,12,31,5837,
+4,12,33,5837,
+0,25,25,5837,
+15,20,25,5837,
+3,4,35,5837,
+11,20,27,5837,
+7,24,25,5837,
+0,17,31,5837,
+1,15,32,5837,
+0,5,35,5837,
+5,21,28,5837,
+3,20,29,5837,
+8,15,31,5837,
+9,9,33,5837,
+11,17,29,5837,
+1,5,35,5837,
+1,25,25,5837,
+7,19,29,5837,
+11,13,31,5837,
+1,17,31,5837,
+19,19,23,5847,
+9,21,27,5847,
+12,18,28,5847,
+10,24,24,5847,
+0,24,26,5847,
+4,9,34,5847,
+18,20,23,5862,
+8,10,33,5862,
+2,15,32,5862,
+1,24,26,5862,
+8,17,30,5862,
+6,16,31,5862,
+12,22,25,5862,
+10,23,25,5862,
+14,23,23,5862,
+7,23,26,5862,
+2,17,31,5862,
+2,5,35,5862,
+17,17,26,5862,
+2,25,25,5862,
+7,7,34,5862,
+6,8,34,5862,
+6,14,32,5862,
+16,18,26,5862,
+10,16,30,5862,
+14,22,24,5862,
+2,24,26,5862,
+0,10,34,5862,
+4,20,29,5862,
+1,10,34,5862,
+17,22,22,5876,
+4,4,35,5876,
+10,14,31,5876,
+8,13,32,5876,
+0,13,33,5876,
+3,15,32,5876,
+5,12,33,5876,
+0,23,27,5876,
+13,19,27,5876,
+7,11,33,5876,
+3,17,31,5876,
+3,25,25,5876,
+17,21,23,5895,
+1,13,33,5895,
+1,23,27,5895,
+3,5,35,5895,
+6,18,30,5895,
+10,22,26,5895,
+2,10,34,5895,
+18,19,24,5910,
+0,6,35,5910,
+6,21,28,5910,
+0,19,30,5910,
+3,24,26,5910,
+12,21,26,5910,
+7,22,27,5910,
+2,13,33,5910,
+1,19,30,5910,
+2,23,27,5910,
+1,6,35,5910,
+5,9,34,5910,
+14,15,29,5910,
+14,21,25,5910,
+15,19,26,5910,
+15,16,28,5910,
+2,19,30,5910,
+9,20,28,5910,
+2,6,35,5910,
+4,15,32,5910,
+3,10,34,5910,
+13,14,30,5910,
+8,24,25,5910,
+17,20,24,5926,
+10,18,29,5926,
+4,17,31,5926,
+4,25,25,5926,
+4,5,35,5926,
+11,19,28,5926,
+11,11,32,5926,
+5,20,29,5926,
+7,16,31,5926,
+13,16,29,5926,
+8,19,29,5926,
+9,15,31,5926,
+3,13,33,5926,
+3,23,27,5926,
+0,22,28,5926,
+4,24,26,5926,
+10,12,32,5926,
+6,12,33,5926,
+8,23,26,5926,
+14,17,28,5926,
+12,15,30,5926,
+16,22,23,5950,
+1,22,28,5950,
+7,8,34,5950,
+7,14,32,5950,
+3,6,35,5950,
+3,19,30,5950,
+10,21,27,5950,
+9,10,33,5950,
+9,17,30,5950,
+14,20,26,5950,
+4,10,34,5950,
+2,22,28,5950,
+6,9,34,5950,
+18,18,25,5978,
+16,21,24,5978,
+11,24,24,5978,
+12,20,27,5978,
+7,18,30,5978,
+13,23,24,5978,
+16,17,27,5978,
+7,21,28,5978,
+5,15,32,5978,
+0,7,35,5978,
+12,17,29,5978,
+8,11,33,5978,
+4,23,27,5978,
+12,13,31,5978,
+4,13,33,5978,
+9,13,32,5978,
+17,19,25,5994,
+1,7,35,5994,
+11,23,25,5994,
+5,25,25,5994,
+5,5,35,5994,
+5,17,31,5994,
+3,22,28,5994,
+8,22,27,5994,
+11,16,30,5994,
+13,18,28,5994,
+0,11,34,5994,
+5,24,26,5994,
+4,6,35,5994,
+6,20,29,5994,
+4,19,30,5994,
+11,14,31,5994,
+15,18,27,5994,
+1,11,34,5994,
+2,7,35,5994,
+13,22,25,5994,
+0,16,32,5994,
+16,20,25,6011,
+5,10,34,6011,
+1,16,32,6011,
+11,22,26,6011,
+8,16,31,6011,
+2,11,34,6011,
+0,21,29,6011,
+20,21,21,6051,
+7,12,33,6051,
+9,24,25,6051,
+1,21,29,6051,
+5,13,33,6051,
+3,7,35,6051,
+9,19,29,6051,
+5,23,27,6051,
+15,23,23,6051,
+2,16,32,6051,
+8,8,34,6051,
+10,20,28,6051,
+4,22,28,6051,
+20,20,22,6057,
+8,14,32,6057,
+15,22,24,6057,
+6,15,32,6057,
+0,14,33,6057,
+0,18,31,6057,
+2,21,29,6057,
+5,19,30,6057,
+13,21,26,6057,
+6,25,25,6057,
+3,11,34,6057,
+19,21,22,6072,
+6,17,31,6072,
+14,19,27,6072,
+1,14,33,6072,
+5,6,35,6072,
+10,15,31,6072,
+1,18,31,6072,
+7,9,34,6072,
+9,23,26,6072,
+11,18,29,6072,
+6,24,26,6072,
+8,18,30,6072,
+10,10,33,6072,
+12,19,28,6072,
+3,16,32,6072,
+10,17,30,6072,
+0,8,35,6072,
+17,18,26,6072,
+2,14,33,6072,
+11,12,32,6072,
+8,21,28,6072,
+2,18,31,6072,
+19,20,23,6101,
+1,8,35,6101,
+4,7,35,6101,
+7,20,29,6101,
+11,21,27,6101,
+15,21,25,6101,
+9,11,33,6101,
+3,21,29,6101,
+15,15,29,6101,
+18,22,22,6103,
+6,10,34,6103,
+14,14,30,6103,
+10,13,32,6103,
+2,8,35,6103,
+16,19,26,6103,
+5,22,28,6103,
+14,16,29,6103,
+4,11,34,6103,
+13,15,30,6103,
+18,21,23,6120,
+6,13,33,6120,
+3,18,31,6120,
+6,23,27,6120,
+3,14,33,6120,
+9,22,27,6120,
+12,24,24,6120,
+4,16,32,6120,
+0,0,36,6120,
+16,16,28,6120,
+6,19,30,6120,
+0,1,36,6120,
+6,6,35,6120,
+8,12,33,6120,
+19,19,24,6143,
+1,1,36,6143,
+9,16,31,6143,
+13,20,27,6143,
+3,8,35,6143,
+4,21,29,6143,
+12,23,25,6143,
+15,17,28,6143,
+7,15,32,6143,
+7,25,25,6143,
+13,17,29,6143,
+7,17,31,6143,
+5,7,35,6143,
+13,13,31,6143,
+12,16,30,6143,
+18,20,24,6147,
+0,12,34,6147,
+0,20,30,6147,
+0,2,36,6147,
+14,23,24,6147,
+15,20,26,6147,
+1,2,36,6147,
+10,24,25,6147,
+9,14,32,6147,
+8,9,34,6147,
+7,24,26,6147,
+12,14,31,6147,
+1,12,34,6147,
+0,25,26,6147,
+4,18,31,6147,
+1,20,30,6147,
+4,14,33,6147,
+5,11,34,6147,
+17,22,23,6162,
+10,19,29,6162,
+1,25,26,6162,
+2,12,34,6162,
+2,20,30,6162,
+14,18,28,6162,
+2,2,36,6162,
+6,22,28,6162,
+12,22,26,6162,
+0,24,27,6162,
+11,20,28,6162,
+14,22,25,6162,
+2,25,26,6162,
+10,23,26,6162,
+5,16,32,6162,
+8,20,29,6162,
+0,3,36,6162,
+7,10,34,6162,
+4,8,35,6162,
+9,18,30,6162,
+17,21,24,6186,
+1,3,36,6186,
+0,9,35,6186,
+9,21,28,6186,
+1,24,27,6186,
+5,21,29,6186,
+7,23,27,6186,
+1,9,35,6186,
+17,17,27,6186,
+7,13,33,6186,
+11,15,31,6186,
+16,18,27,6186,
+3,20,30,6186,
+2,3,36,6186,
+2,24,27,6186,
+3,12,34,6186,
+12,18,29,6186,
+7,19,30,6186,
+18,19,25,6203,
+11,17,30,6203,
+2,9,35,6203,
+10,11,33,6203,
+6,7,35,6203,
+3,25,26,6203,
+5,18,31,6203,
+5,14,33,6203,
+12,12,32,6203,
+0,4,36,6203,
+6,11,34,6203,
+14,21,26,6203,
+0,23,28,6203,
+1,4,36,6203,
+8,15,32,6203,
+0,17,32,6203,
+10,22,27,6203,
+3,3,36,6203,
+1,23,28,6203,
+8,25,25,6203,
+1,17,32,6203,
+3,24,27,6203,
+9,12,33,6203,
+13,19,28,6203,
+8,17,31,6203,
+11,13,32,6203,
+0,15,33,6203,
+12,21,27,6203,
+16,23,23,6236,
+5,8,35,6236,
+17,20,25,6236,
+3,9,35,6236,
+15,19,27,6236,
+1,15,33,6236,
+6,16,32,6236,
+16,22,24,6239,
+4,12,34,6239,
+4,20,30,6239,
+8,24,26,6239,
+2,4,36,6239,
+2,23,28,6239,
+2,17,32,6239,
+7,22,28,6239,
+4,25,26,6239,
+10,16,31,6239,
+6,21,29,6239,
+9,9,34,6239,
+2,15,33,6239,
+8,10,34,6239,
+10,14,32,6239,
+6,14,33,6239,
+6,18,31,6239,
+13,24,24,6247,
+14,15,30,6247,
+0,5,36,6247,
+4,24,27,6247,
+3,4,36,6247,
+11,24,25,6247,
+3,17,32,6247,
+16,21,25,6274,
+3,23,28,6274,
+4,9,35,6274,
+1,5,36,6274,
+9,20,29,6274,
+0,19,31,6274,
+15,16,29,6274,
+8,13,33,6274,
+8,23,27,6274,
+1,19,31,6274,
+3,15,33,6274,
+7,7,35,6274,
+11,19,29,6274,
+21,21,21,6301,
+13,23,25,6301,
+10,18,30,6301,
+18,18,26,6301,
+5,12,34,6301,
+2,5,36,6301,
+8,19,30,6301,
+14,20,27,6301,
+0,10,35,6301,
+6,8,35,6301,
+20,21,22,6316,
+0,13,34,6316,
+13,16,30,6316,
+5,20,30,6316,
+10,21,28,6316,
+0,22,29,6316,
+14,17,29,6316,
+1,10,35,6316,
+7,11,34,6316,
+1,22,29,6316,
+11,23,26,6316,
+17,19,26,6316,
+5,25,26,6316,
+13,14,31,6316,
+1,13,34,6316,
+2,19,31,6316,
+12,20,28,6316,
+4,4,36,6316,
+20,20,23,6335,
+19,22,22,6335,
+7,16,32,6335,
+13,22,26,6335,
+2,13,34,6335,
+2,22,29,6335,
+16,17,28,6335,
+4,17,32,6335,
+2,10,35,6335,
+4,23,28,6335,
+5,24,27,6335,
+4,15,33,6335,
+3,5,36,6335,
+15,23,24,6335,
+12,15,31,6335,
+9,15,32,6335,
+19,21,23,6352,
+5,9,35,6352,
+11,11,33,6352,
+7,21,29,6352,
+9,25,25,6352,
+3,19,31,6352,
+9,17,31,6352,
+0,6,36,6352,
+16,20,26,6352,
+8,22,28,6352,
+9,24,26,6352,
+12,17,30,6352,
+15,18,28,6352,
+1,6,36,6352,
+10,12,33,6352,
+15,22,25,6352,
+3,22,29,6352,
+11,22,27,6352,
+13,18,29,6352,
+3,13,34,6352,
+7,18,31,6352,
+3,10,35,6352,
+7,14,33,6352,
+6,20,30,6352,
+2,6,36,6352,
+6,12,34,6352,
+9,10,34,6352,
+19,20,24,6381,
+12,13,32,6381,
+18,22,23,6381,
+6,25,26,6381,
+4,5,36,6381,
+5,17,32,6381,
+11,16,31,6381,
+5,23,28,6381,
+4,19,31,6381,
+7,8,35,6381,
+9,23,27,6381,
+13,21,27,6381,
+5,15,33,6381,
+9,13,33,6381,
+10,20,29,6381,
+4,10,35,6381,
+6,24,27,6381,
+11,14,32,6381,
+4,13,34,6381,
+4,22,29,6381,
+8,11,34,6381,
+3,6,36,6381,
+14,19,28,6381,
+0,21,30,6381,
+18,21,24,6406,
+17,18,27,6406,
+15,21,26,6406,
+9,19,30,6406,
+1,21,30,6406,
+6,9,35,6406,
+8,16,32,6406,
+11,18,30,6406,
+2,21,30,6406,
+0,16,33,6406,
+12,24,25,6406,
+0,7,36,6406,
+0,11,35,6406,
+12,19,29,6406,
+16,19,27,6414,
+1,16,33,6414,
+5,5,36,6414,
+8,21,29,6414,
+11,21,28,6414,
+1,7,36,6414,
+1,11,35,6414,
+5,19,31,6414,
+19,19,25,6444,
+17,23,23,6444,
+4,6,36,6444,
+0,18,32,6444,
+14,24,24,6444,
+6,23,28,6444,
+17,22,24,6456,
+7,12,34,6456,
+12,23,26,6456,
+2,7,36,6456,
+1,18,32,6456,
+10,15,32,6456,
+6,17,32,6456,
+2,16,33,6456,
+7,20,30,6456,
+9,22,28,6456,
+18,20,25,6456,
+8,18,31,6456,
+8,14,33,6456,
+14,23,25,6456,
+5,22,29,6456,
+5,10,35,6456,
+15,15,30,6456,
+6,15,33,6456,
+10,25,25,6456,
+2,11,35,6456,
+10,17,31,6456,
+5,13,34,6456,
+7,25,26,6456,
+3,21,30,6456,
+2,18,32,6456,
+10,24,26,6456,
+0,14,34,6456,
+14,16,30,6456,
+0,26,26,6456,
+1,14,34,6456,
+8,8,35,6456,
+14,14,31,6456,
+16,16,29,6456,
+1,26,26,6456,
+13,20,28,6456,
+11,12,33,6456,
+7,24,27,6456,
+15,20,27,6463,
+3,7,36,6463,
+3,16,33,6463,
+0,25,27,6463,
+15,17,29,6463,
+1,25,27,6463,
+3,11,35,6463,
+7,9,35,6463,
+17,21,25,6487,
+13,15,31,6487,
+2,26,26,6487,
+10,10,34,6487,
+2,14,34,6487,
+14,22,26,6487,
+4,21,30,6487,
+3,18,32,6487,
+12,22,27,6487,
+5,6,36,6487,
+9,11,34,6487,
+10,23,27,6487,
+10,13,33,6487,
+2,25,27,6487,
+6,19,31,6487,
+13,17,30,6487,
+0,8,36,6487,
+0,24,28,6487,
+4,16,33,6487,
+0,20,31,6487,
+4,7,36,6487,
+9,16,32,6487,
+1,24,28,6487,
+6,10,35,6487,
+14,18,29,6487,
+1,8,36,6487,
+12,16,31,6487,
+6,13,34,6487,
+16,23,24,6523,
+10,19,30,6523,
+18,19,26,6523,
+3,14,34,6523,
+3,26,26,6523,
+6,22,29,6523,
+7,23,28,6523,
+17,17,28,6523,
+11,20,29,6523,
+4,11,35,6523,
+13,13,32,6523,
+1,20,31,6523,
+7,17,32,6523,
+9,21,29,6523,
+7,15,33,6523,
+3,25,27,6523,
+4,18,32,6523,
+16,18,28,6523,
+2,24,28,6523,
+8,20,30,6523,
+8,12,34,6523,
+2,8,36,6523,
+12,14,32,6523,
+8,25,26,6523,
+16,22,25,6545,
+2,20,31,6545,
+17,20,26,6545,
+5,21,30,6545,
+14,21,27,6545,
+21,21,22,6575,
+9,18,31,6575,
+9,14,33,6575,
+4,14,34,6575,
+12,18,30,6575,
+4,26,26,6575,
+20,22,22,6584,
+10,22,28,6584,
+6,6,36,6584,
+12,21,28,6584,
+0,0,37,6584,
+0,12,35,6584,
+8,24,27,6584,
+3,24,28,6584,
+3,8,36,6584,
+15,19,28,6584,
+13,24,25,6584,
+5,7,36,6584,
+20,21,23,6603,
+0,23,29,6603,
+5,16,33,6603,
+3,20,31,6603,
+0,1,37,6603,
+11,15,32,6603,
+4,25,27,6603,
+8,9,35,6603,
+1,12,35,6603,
+1,1,37,6603,
+1,23,29,6603,
+13,19,29,6603,
+11,17,31,6603,
+7,19,31,6603,
+5,11,35,6603,
+11,25,25,6603,
+11,24,26,6603,
+0,2,37,6603,
+5,18,32,6603,
+2,12,35,6603,
+16,21,26,6603,
+2,23,29,6603,
+1,2,37,6603,
+13,23,26,6603,
+7,10,35,6603,
+7,22,29,6603,
+19,22,23,6624,
+7,13,34,6624,
+4,8,36,6624,
+20,20,24,6633,
+4,24,28,6633,
+18,18,27,6633,
+10,11,34,6633,
+2,2,37,6633,
+5,26,26,6633,
+4,20,31,6633,
+15,24,24,6633,
+5,14,34,6633,
+12,12,33,6633,
+8,17,32,6633,
+6,21,30,6633,
+8,23,28,6633,
+0,9,36,6633,
+1,9,36,6633,
+0,17,33,6633,
+8,15,33,6633,
+19,21,24,6648,
+0,3,37,6648,
+3,12,35,6648,
+15,23,25,6648,
+5,25,27,6648,
+11,13,33,6648,
+17,19,27,6648,
+3,23,29,6648,
+11,23,27,6648,
+1,17,33,6648,
+1,3,37,6648,
+10,16,32,6648,
+14,20,28,6648,
+6,16,33,6648,
+2,9,36,6648,
+6,7,36,6648,
+9,12,34,6648,
+0,15,34,6648,
+9,20,30,6648,
+15,16,30,6648,
+2,17,33,6648,
+10,21,29,6648,
+18,23,23,6673,
+13,22,27,6673,
+9,25,26,6673,
+6,11,35,6673,
+2,3,37,6673,
+1,15,34,6673,
+11,19,30,6673,
+14,15,31,6673,
+18,22,24,6682,
+6,18,32,6682,
+0,22,30,6682,
+0,19,32,6682,
+1,22,30,6682,
+0,4,37,6682,
+2,15,34,6682,
+10,18,31,6682,
+4,12,35,6682,
+12,20,29,6682,
+16,20,27,6682,
+5,8,36,6682,
+10,14,33,6682,
+5,24,28,6682,
+14,17,30,6682,
+15,22,26,6682,
+1,4,37,6682,
+8,19,31,6682,
+3,9,36,6682,
+4,23,29,6682,
+19,20,25,6692,
+1,19,32,6692,
+5,20,31,6692,
+16,17,29,6692,
+13,16,31,6692,
+9,24,27,6692,
+3,17,33,6692,
+9,9,35,6692,
+3,3,37,6692,
+2,22,30,6692,
+6,14,34,6692,
+6,26,26,6692,
+8,10,35,6692,
+11,22,28,6692,
+2,4,37,6692,
+13,14,32,6692,
+2,19,32,6692,
+8,22,29,6692,
+8,13,34,6692,
+3,15,34,6692,
+7,21,30,6692,
+18,21,25,6713,
+6,25,27,6713,
+15,18,29,6713,
+12,15,32,6713,
+3,22,30,6713,
+13,18,30,6713,
+4,9,36,6713,
+9,23,28,6713,
+7,7,36,6713,
+13,21,28,6713,
+0,5,37,6713,
+4,17,33,6713,
+7,16,33,6713,
+0,13,35,6713,
+5,12,35,6713,
+9,17,32,6713,
+12,25,25,6713,
+3,19,32,6713,
+12,17,31,6713,
+17,23,24,6734,
+3,4,37,6734,
+7,11,35,6734,
+15,21,27,6734,
+9,15,33,6734,
+1,5,37,6734,
+5,23,29,6734,
+1,13,35,6734,
+0,10,36,6734,
+6,8,36,6734,
+12,24,26,6734,
+6,24,28,6734,
+4,15,34,6734,
+1,10,36,6734,
+14,24,25,6734,
+17,18,28,6734,
+7,18,32,6734,
+6,20,31,6734,
+19,19,26,6757,
+2,5,37,6757,
+11,11,34,6757,
+2,13,35,6757,
+14,19,29,6757,
+17,22,25,6757,
+10,20,30,6757,
+2,10,36,6757,
+4,22,30,6757,
+18,20,26,6768,
+10,12,34,6768,
+7,14,34,6768,
+16,19,28,6768,
+7,26,26,6768,
+4,4,37,6768,
+11,16,32,6768,
+10,25,26,6768,
+4,19,32,6768,
+14,23,26,6768,
+12,13,33,6768,
+5,9,36,6768,
+0,21,31,6768,
+12,23,27,6768,
+7,25,27,6768,
+5,17,33,6768,
+11,21,29,6768,
+1,21,31,6768,
+3,5,37,6768,
+9,19,31,6768,
+3,13,35,6768,
+6,12,35,6768,
+0,6,37,6768,
+10,24,27,6768,
+0,26,27,6768,
+12,19,30,6768,
+3,10,36,6768,
+8,21,30,6768,
+9,22,29,6768,
+1,6,37,6768,
+9,10,35,6768,
+11,18,31,6768,
+11,14,33,6768,
+6,23,29,6768,
+5,15,34,6768,
+2,21,31,6768,
+1,26,27,6768,
+17,21,26,6805,
+9,13,34,6805,
+16,24,24,6814,
+2,6,37,6814,
+21,22,22,6832,
+14,22,27,6832,
+15,20,28,6832,
+5,22,30,6832,
+0,25,28,6832,
+7,8,36,6832,
+2,26,27,6832,
+8,16,33,6832,
+7,24,28,6832,
+16,23,25,6832,
+4,5,37,6832,
+7,20,31,6832,
+5,19,32,6832,
+13,20,29,6832,
+4,13,35,6832,
+8,11,35,6832,
+1,25,28,6832,
+3,21,31,6832,
+15,15,31,6832,
+21,21,23,6849,
+16,16,30,6849,
+0,16,34,6849,
+4,10,36,6849,
+12,22,28,6849,
+8,18,32,6849,
+20,22,23,6866,
+2,25,28,6866,
+6,9,36,6866,
+10,17,32,6866,
+0,18,33,6866,
+10,23,28,6866,
+14,16,31,6866,
+1,16,34,6866,
+6,17,33,6866,
+10,15,33,6866,
+3,26,27,6866,
+3,6,37,6866,
+1,18,33,6866,
+15,17,30,6866,
+18,19,27,6866,
+2,16,34,6866,
+14,14,32,6866,
+8,26,26,6866,
+16,22,26,6866,
+8,14,34,6866,
+20,21,24,6891,
+0,11,36,6891,
+2,18,33,6891,
+6,15,34,6891,
+0,24,29,6891,
+7,12,35,6891,
+4,21,31,6891,
+0,7,37,6891,
+8,25,27,6891,
+17,20,27,6891,
+1,11,36,6891,
+3,25,28,6891,
+13,15,32,6891,
+1,24,29,6891,
+7,23,29,6891,
+17,17,29,6891,
+5,13,35,6891,
+13,17,31,6891,
+1,7,37,6891,
+13,25,25,6891,
+19,23,23,6909,
+5,5,37,6909,
+6,22,30,6909,
+14,18,30,6909,
+16,18,29,6909,
+5,10,36,6909,
+6,19,32,6909,
+4,26,27,6909,
+2,11,36,6909,
+14,21,28,6909,
+11,12,34,6909,
+2,24,29,6909,
+11,20,30,6909,
+3,16,34,6909,
+4,6,37,6909,
+13,24,26,6909,
+19,22,24,6915,
+0,14,35,6915,
+2,7,37,6915,
+1,14,35,6915,
+10,19,31,6915,
+3,18,33,6915,
+9,21,30,6915,
+11,25,26,6915,
+0,20,32,6915,
+12,16,32,6915,
+8,8,36,6915,
+8,24,28,6915,
+8,20,31,6915,
+1,20,32,6915,
+4,25,28,6915,
+10,13,34,6915,
+10,10,35,6915,
+20,20,25,6938,
+2,14,35,6938,
+10,22,29,6938,
+9,16,33,6938,
+11,24,27,6938,
+7,9,36,6938,
+3,24,29,6938,
+16,21,27,6938,
+12,21,29,6938,
+15,24,25,6938,
+3,11,36,6938,
+7,17,33,6938,
+13,13,33,6938,
+3,7,37,6938,
+15,19,29,6938,
+19,21,25,6949,
+13,23,27,6949,
+5,21,31,6949,
+9,11,35,6949,
+4,16,34,6949,
+2,20,32,6949,
+9,18,32,6949,
+0,23,30,6949,
+12,14,33,6949,
+12,18,31,6949,
+4,18,33,6949,
+18,23,24,6971,
+3,14,35,6971,
+6,13,35,6971,
+15,23,26,6971,
+5,26,27,6971,
+13,19,30,6971,
+7,15,34,6971,
+5,6,37,6971,
+1,23,30,6971,
+6,10,36,6971,
+18,18,28,6971,
+3,20,32,6971,
+18,22,25,6986,
+8,12,35,6986,
+2,23,30,6986,
+4,11,36,6986,
+9,26,26,6986,
+9,14,34,6986,
+4,24,29,6986,
+7,22,30,6986,
+0,8,37,6986,
+7,19,32,6986,
+11,23,28,6986,
+11,17,32,6986,
+1,8,37,6986,
+8,23,29,6986,
+5,25,28,6986,
+4,7,37,6986,
+17,19,28,6986,
+11,15,33,6986,
+9,25,27,6986,
+14,20,29,6986,
+2,8,37,6986,
+5,16,34,6986,
+13,22,28,6986,
+19,20,26,7019,
+4,14,35,7019,
+3,23,30,7019,
+5,18,33,7019,
+6,21,31,7019,
+15,22,27,7019,
+4,20,32,7019,
+0,12,36,7019,
+16,20,28,7019,
+6,26,27,7019,
+18,21,26,7036,
+10,21,30,7036,
+17,24,24,7036,
+1,12,36,7036,
+8,9,36,7036,
+9,24,28,7036,
+6,6,37,7036,
+8,17,33,7036,
+5,24,29,7036,
+3,8,37,7036,
+9,20,31,7036,
+5,11,36,7036,
+15,16,31,7036,
+11,19,31,7036,
+17,23,25,7050,
+7,13,35,7050,
+5,7,37,7050,
+12,20,30,7050,
+12,12,34,7050,
+0,0,38,7050,
+2,12,36,7050,
+8,15,34,7050,
+4,23,30,7050,
+0,17,34,7050,
+7,10,36,7050,
+12,25,26,7050,
+6,25,28,7050,
+16,17,30,7050,
+0,1,38,7050,
+0,22,31,7050,
+10,16,33,7050,
+14,15,32,7050,
+1,22,31,7050,
+1,17,34,7050,
+1,1,38,7050,
+11,13,34,7050,
+11,22,29,7050,
+14,25,25,7050,
+5,14,35,7050,
+10,11,35,7050,
+14,17,31,7050,
+0,2,38,7050,
+10,18,32,7050,
+14,24,26,7054,
+6,16,34,7054,
+8,22,30,7054,
+3,12,36,7054,
+2,22,31,7054,
+1,2,38,7054,
+12,24,27,7054,
+17,22,26,7088,
+8,19,32,7088,
+5,20,32,7088,
+13,16,32,7088,
+2,17,34,7088,
+15,18,30,7088,
+4,8,37,7088,
+6,18,33,7088,
+0,15,35,7088,
+15,21,28,7088,
+0,9,37,7088,
+9,12,35,7088,
+0,19,33,7088,
+19,19,27,7097,
+9,23,29,7097,
+13,21,29,7097,
+7,21,31,7097,
+1,9,37,7097,
+1,19,33,7097,
+1,15,35,7097,
+22,22,22,7115,
+2,2,38,7115,
+10,14,34,7115,
+10,26,26,7115,
+6,24,29,7115,
+18,20,27,7115,
+6,11,36,7115,
+0,3,38,7115,
+2,19,33,7115,
+10,25,27,7115,
+2,9,37,7115,
+14,23,27,7115,
+13,18,31,7115,
+13,14,33,7115,
+3,17,34,7115,
+6,7,37,7115,
+17,18,29,7115,
+2,15,35,7115,
+1,3,38,7115,
+3,22,31,7115,
+7,26,27,7115,
+21,22,23,7131,
+5,23,30,7131,
+4,12,36,7131,
+2,3,38,7131,
+14,19,30,7131,
+12,17,32,7131,
+6,14,35,7131,
+12,23,28,7131,
+16,24,25,7131,
+16,19,29,7131,
+12,15,33,7131,
+8,13,35,7131,
+20,23,23,7160,
+21,21,24,7160,
+5,8,37,7160,
+7,25,28,7160,
+0,27,27,7160,
+9,9,36,7160,
+3,15,35,7160,
+3,9,37,7160,
+3,19,33,7160,
+1,27,27,7160,
+9,17,33,7160,
+17,21,27,7160,
+0,4,38,7160,
+20,22,24,7166,
+10,24,28,7166,
+0,26,28,7166,
+6,20,32,7166,
+8,10,36,7166,
+1,26,28,7166,
+4,22,31,7166,
+1,4,38,7166,
+10,20,31,7166,
+16,23,26,7166,
+4,17,34,7166,
+7,16,34,7166,
+7,18,33,7166,
+2,27,27,7166,
+3,3,38,7166,
+9,15,34,7166,
+11,21,30,7166,
+2,26,28,7166,
+2,4,38,7166,
+14,22,28,7166,
+0,13,36,7166,
+0,21,32,7166,
+6,23,30,7166,
+9,22,30,7166,
+5,12,36,7166,
+0,25,29,7166,
+12,19,31,7166,
+4,15,35,7166,
+8,21,31,7166,
+4,19,33,7166,
+11,16,33,7166,
+15,20,29,7166,
+7,24,29,7166,
+7,11,36,7166,
+1,21,32,7166,
+9,19,32,7166,
+20,21,25,7207,
+1,13,36,7207,
+19,23,24,7207,
+4,9,37,7207,
+3,27,27,7207,
+11,11,35,7207,
+7,7,37,7207,
+1,25,29,7207,
+12,22,29,7207,
+2,13,36,7207,
+6,8,37,7207,
+3,26,28,7207,
+3,4,38,7207,
+18,19,28,7207,
+0,5,38,7207,
+16,22,27,7207,
+0,10,37,7207,
+2,21,32,7207,
+11,18,32,7207,
+12,13,34,7207,
+13,20,30,7207,
+8,26,27,7207,
+10,12,35,7207,
+5,22,31,7207,
+2,25,29,7207,
+7,14,35,7207,
+19,22,25,7237,
+1,5,38,7237,
+10,23,29,7237,
+1,10,37,7237,
+13,25,26,7237,
+5,17,34,7237,
+2,10,37,7237,
+8,25,28,7237,
+7,20,32,7237,
+17,20,28,7237,
+2,5,38,7237,
+11,14,34,7237,
+16,16,31,7237,
+11,26,26,7237,
+3,13,36,7237,
+3,21,32,7237,
+4,27,27,7237,
+13,24,27,7237,
+15,15,32,7237,
+5,9,37,7237,
+11,25,27,7237,
+9,13,35,7237,
+3,25,29,7237,
+15,17,31,7237,
+15,25,25,7240,
+5,15,35,7240,
+5,19,33,7240,
+4,26,28,7240,
+6,12,36,7240,
+8,16,34,7240,
+0,24,30,7240,
+4,4,38,7240,
+20,20,26,7264,
+14,16,32,7264,
+18,24,24,7264,
+1,24,30,7264,
+8,18,33,7264,
+9,10,36,7264,
+15,24,26,7264,
+17,17,30,7264,
+10,17,33,7264,
+3,5,38,7264,
+19,21,26,7280,
+7,23,30,7280,
+18,23,25,7280,
+3,10,37,7280,
+14,21,29,7280,
+16,18,30,7280,
+0,18,34,7280,
+2,24,30,7280,
+0,6,38,7280,
+14,18,31,7280,
+0,16,35,7280,
+6,17,34,7280,
+11,24,28,7280,
+4,21,32,7280,
+4,13,36,7280,
+1,18,34,7280,
+6,22,31,7280,
+14,14,33,7280,
+8,24,29,7280,
+8,11,36,7280,
+1,6,38,7280,
+10,15,34,7280,
+16,21,28,7280,
+1,16,35,7280,
+4,25,29,7280,
+11,20,31,7280,
+13,23,28,7280,
+7,8,37,7280,
+13,17,32,7280,
+13,15,33,7280,
+9,21,31,7280,
+5,27,27,7280,
+15,23,27,7288,
+2,18,34,7288,
+10,22,30,7288,
+2,6,38,7288,
+18,22,26,7303,
+3,24,30,7303,
+4,5,38,7303,
+5,26,28,7303,
+4,10,37,7303,
+2,16,35,7303,
+10,19,32,7303,
+12,21,30,7303,
+8,14,35,7303,
+15,19,30,7303,
+9,26,27,7303,
+6,9,37,7303,
+6,15,35,7303,
+6,19,33,7303,
+8,20,32,7303,
+18,18,29,7309,
+7,12,36,7309,
+3,18,34,7309,
+0,20,33,7309,
+12,16,33,7309,
+3,6,38,7309,
+11,12,35,7309,
+3,16,35,7309,
+5,21,32,7309,
+0,23,31,7309,
+0,11,37,7309,
+19,20,27,7349,
+17,24,25,7349,
+1,20,33,7349,
+5,13,36,7349,
+9,25,28,7349,
+17,19,29,7349,
+11,23,29,7349,
+1,23,31,7349,
+13,19,31,7349,
+5,25,29,7349,
+1,11,37,7349,
+12,18,32,7349,
+4,24,30,7349,
+0,14,36,7349,
+15,22,28,7349,
+1,14,36,7349,
+9,16,34,7349,
+0,7,38,7349,
+8,23,30,7349,
+2,20,33,7349,
+17,23,26,7379,
+18,21,27,7379,
+7,17,34,7379,
+5,10,37,7379,
+13,13,34,7379,
+2,11,37,7379,
+5,5,38,7379,
+10,13,35,7379,
+9,18,33,7379,
+2,23,31,7379,
+1,7,38,7379,
+7,22,31,7379,
+13,22,29,7379,
+6,27,27,7379,
+14,20,30,7379,
+12,26,26,7379,
+4,18,34,7379,
+12,14,34,7379,
+4,6,38,7379,
+6,26,28,7379,
+2,14,36,7379,
+10,10,36,7379,
+8,8,37,7379,
+2,7,38,7379,
+14,25,26,7379,
+16,20,29,7379,
+22,22,23,7406,
+4,16,35,7406,
+9,24,29,7406,
+12,25,27,7406,
+9,11,36,7406,
+3,20,33,7406,
+7,19,33,7406,
+3,23,31,7406,
+7,9,37,7406,
+21,23,23,7422,
+3,11,37,7422,
+11,17,33,7422,
+7,15,35,7422,
+5,24,30,7422,
+21,22,24,7443,
+14,24,27,7443,
+6,13,36,7443,
+6,21,32,7443,
+3,14,36,7443,
+3,7,38,7443,
+9,14,35,7443,
+17,22,27,7443,
+10,21,31,7443,
+6,25,29,7443,
+11,15,34,7443,
+8,12,36,7443,
+12,24,28,7443,
+9,20,32,7443,
+5,18,34,7443,
+5,6,38,7443,
+15,16,32,7443,
+6,10,37,7443,
+4,20,33,7443,
+10,26,27,7443,
+20,23,24,7470,
+11,22,30,7470,
+12,20,31,7470,
+5,16,35,7470,
+16,25,25,7470,
+16,17,31,7470,
+19,19,28,7470,
+4,11,37,7470,
+4,23,31,7470,
+11,19,32,7470,
+21,21,25,7479,
+7,27,27,7479,
+15,21,29,7479,
+0,8,38,7479,
+0,22,32,7479,
+4,14,36,7479,
+18,20,28,7479,
+16,24,26,7479,
+1,22,32,7479,
+20,22,25,7486,
+14,23,28,7486,
+8,17,34,7486,
+1,8,38,7486,
+8,22,31,7486,
+14,17,32,7486,
+7,26,28,7486,
+4,7,38,7486,
+10,25,28,7486,
+14,15,33,7486,
+13,21,30,7486,
+15,18,31,7486,
+9,23,30,7486,
+6,24,30,7486,
+2,22,32,7486,
+2,8,38,7486,
+10,16,34,7486,
+0,12,37,7486,
+19,24,24,7509,
+0,27,28,7509,
+17,18,30,7509,
+10,18,33,7509,
+12,12,35,7509,
+12,23,29,7509,
+13,16,33,7509,
+0,17,35,7509,
+17,21,28,7509,
+5,20,33,7509,
+1,27,28,7509,
+8,15,35,7509,
+1,12,37,7509,
+8,19,33,7509,
+7,21,32,7509,
+16,23,27,7509,
+7,13,36,7509,
+8,9,37,7509,
+7,25,29,7509,
+5,11,37,7509,
+11,13,35,7509,
+5,23,31,7509,
+19,23,25,7521,
+1,17,35,7521,
+6,18,34,7521,
+6,6,38,7521,
+6,16,35,7521,
+5,14,36,7521,
+2,12,37,7521,
+2,27,28,7521,
+3,22,32,7521,
+3,8,38,7521,
+20,21,26,7533,
+10,24,29,7533,
+0,19,34,7533,
+0,26,29,7533,
+16,19,30,7533,
+10,11,36,7533,
+13,18,32,7533,
+7,10,37,7533,
+2,17,35,7533,
+14,19,31,7533,
+1,19,34,7533,
+5,7,38,7533,
+1,26,29,7533,
+19,22,26,7553,
+9,12,36,7553,
+14,22,29,7553,
+2,19,34,7553,
+0,0,39,7553,
+13,26,26,7553,
+13,14,34,7553,
+0,15,36,7553,
+10,14,35,7553,
+2,26,29,7553,
+1,15,36,7553,
+12,17,33,7553,
+0,1,39,7553,
+8,27,27,7553,
+3,27,28,7553,
+3,12,37,7553,
+1,1,39,7553,
+3,17,35,7553,
+13,25,27,7553,
+11,21,31,7553,
+8,26,28,7553,
+10,20,32,7553,
+16,22,28,7553,
+4,22,32,7553,
+4,8,38,7553,
+7,24,30,7553,
+12,15,34,7553,
+6,20,33,7553,
+0,2,39,7553,
+2,15,36,7553,
+18,24,25,7582,
+0,9,38,7582,
+0,25,30,7582,
+15,20,30,7582,
+11,26,27,7582,
+1,9,38,7582,
+9,17,34,7582,
+1,2,39,7582,
+18,19,29,7582,
+6,23,31,7582,
+1,25,30,7582,
+6,11,37,7582,
+15,25,26,7582,
+9,22,31,7582,
+3,19,34,7582,
+3,26,29,7582,
+12,22,30,7582,
+6,14,36,7582,
+20,20,27,7609,
+7,18,34,7609,
+18,23,26,7609,
+2,25,30,7609,
+2,9,38,7609,
+2,2,39,7609,
+8,21,32,7609,
+12,19,32,7609,
+10,23,30,7609,
+6,7,38,7609,
+4,12,37,7609,
+4,27,28,7609,
+8,13,36,7609,
+13,24,28,7609,
+17,20,29,7609,
+15,24,27,7609,
+3,15,36,7609,
+11,25,28,7609,
+0,3,39,7609,
+0,21,33,7609,
+4,17,35,7609,
+7,16,35,7609,
+8,25,29,7609,
+13,20,31,7609,
+1,21,33,7609,
+19,21,27,7627,
+9,15,35,7627,
+1,3,39,7627,
+9,9,37,7627,
+9,19,33,7627,
+4,26,29,7627,
+11,16,34,7627,
+5,22,32,7627,
+8,10,37,7627,
+5,8,38,7627,
+4,19,34,7627,
+11,18,33,7627,
+2,3,39,7627,
+3,9,38,7627,
+2,21,33,7627,
+3,25,30,7627,
+16,16,32,7627,
+0,4,39,7627,
+18,22,27,7661,
+4,15,36,7661,
+14,21,30,7661,
+0,24,31,7661,
+11,24,29,7661,
+11,11,36,7661,
+15,23,28,7661,
+5,12,37,7661,
+15,17,32,7661,
+7,20,33,7661,
+1,4,39,7661,
+5,27,28,7661,
+0,13,37,7661,
+12,13,35,7661,
+1,24,31,7661,
+16,21,29,7661,
+1,13,37,7661,
+13,23,29,7661,
+5,17,35,7661,
+17,25,25,7675,
+9,27,27,7675,
+3,21,33,7675,
+17,17,31,7675,
+15,15,33,7675,
+7,11,37,7675,
+7,23,31,7675,
+3,3,39,7675,
+10,12,36,7675,
+8,24,30,7675,
+4,9,38,7675,
+17,24,26,7684,
+14,16,33,7684,
+2,4,39,7684,
+9,26,28,7684,
+7,14,36,7684,
+16,18,31,7684,
+4,25,30,7684,
+2,24,31,7684,
+5,19,34,7684,
+2,13,37,7684,
+7,7,38,7684,
+5,26,29,7684,
+11,14,35,7684,
+22,23,23,7715,
+6,8,38,7715,
+8,18,34,7715,
+22,22,24,7724,
+14,18,32,7724,
+6,22,32,7724,
+0,10,38,7724,
+19,20,28,7724,
+1,10,38,7724,
+8,16,35,7724,
+11,20,32,7724,
+10,22,31,7724,
+10,17,34,7724,
+9,21,32,7724,
+12,21,31,7724,
+9,13,36,7724,
+3,4,39,7724,
+3,24,31,7724,
+0,5,39,7724,
+21,23,24,7740,
+5,15,36,7740,
+4,21,33,7740,
+15,19,31,7740,
+1,5,39,7740,
+9,25,29,7740,
+3,13,37,7740,
+13,17,33,7740,
+17,23,27,7740,
+14,26,26,7740,
+18,18,30,7740,
+14,14,34,7740,
+2,10,38,7740,
+0,18,35,7740,
+6,27,28,7740,
+12,26,27,7740,
+18,21,28,7740,
+6,12,37,7740,
+10,15,35,7740,
+1,18,35,7740,
+15,22,29,7740,
+14,25,27,7740,
+5,25,30,7740,
+11,23,30,7740,
+21,22,25,7762,
+2,5,39,7762,
+9,10,37,7762,
+10,19,33,7762,
+13,15,34,7762,
+17,19,30,7762,
+5,9,38,7762,
+6,17,35,7762,
+0,16,36,7762,
+20,24,24,7773,
+4,4,39,7773,
+12,25,28,7773,
+13,22,30,7773,
+3,10,38,7773,
+2,18,35,7773,
+6,19,34,7773,
+4,24,31,7773,
+0,23,32,7773,
+1,16,36,7773,
+8,20,33,7773,
+6,26,29,7773,
+8,11,37,7773,
+20,23,25,7786,
+1,23,32,7786,
+4,13,37,7786,
+8,23,31,7786,
+13,19,32,7786,
+3,5,39,7786,
+5,21,33,7786,
+8,14,36,7786,
+14,24,28,7786,
+2,16,36,7786,
+0,20,34,7786,
+12,16,34,7786,
+16,20,30,7786,
+14,20,31,7786,
+9,24,30,7786,
+16,25,26,7786,
+0,6,39,7786,
+7,8,38,7786,
+12,18,33,7786,
+2,23,32,7786,
+7,22,32,7786,
+6,15,36,7786,
+1,20,34,7786,
+17,22,28,7786,
+10,27,27,7786,
+1,6,39,7786,
+21,21,26,7802,
+3,18,35,7802,
+4,10,38,7802,
+10,26,28,7802,
+2,20,34,7802,
+20,22,26,7814,
+6,9,38,7814,
+11,12,36,7814,
+6,25,30,7814,
+3,16,36,7814,
+9,18,34,7814,
+12,24,29,7814,
+16,24,27,7814,
+2,6,39,7814,
+5,24,31,7814,
+19,24,25,7832,
+9,16,35,7832,
+3,23,32,7832,
+7,12,37,7832,
+7,27,28,7832,
+4,5,39,7832,
+5,13,37,7832,
+7,17,35,7832,
+13,13,35,7832,
+19,19,29,7832,
+10,21,32,7832,
+18,20,29,7832,
+4,18,35,7832,
+0,11,38,7832,
+12,14,35,7832,
+0,14,37,7832,
+10,13,36,7832,
+3,20,34,7832,
+11,17,34,7832,
+11,22,31,7832,
+1,11,38,7832,
+7,19,34,7832,
+7,26,29,7832,
+3,6,39,7832,
+19,23,26,7855,
+15,21,30,7855,
+6,21,33,7855,
+1,14,37,7855,
+14,23,29,7855,
+10,25,29,7855,
+4,16,36,7855,
+0,28,28,7855,
+12,20,32,7855,
+4,23,32,7855,
+2,14,37,7855,
+2,11,38,7855,
+5,10,38,7855,
+16,17,32,7855,
+1,28,28,7855,
+10,10,37,7855,
+16,23,28,7855,
+15,16,33,7855,
+20,21,27,7888,
+9,20,33,7888,
+0,27,29,7888,
+0,7,39,7888,
+7,15,36,7888,
+1,7,39,7888,
+13,21,31,7888,
+11,19,33,7888,
+17,21,29,7888,
+5,5,39,7888,
+9,23,31,7888,
+11,15,35,7888,
+9,11,37,7888,
+1,27,29,7888,
+2,28,28,7888,
+8,22,32,7888,
+8,8,38,7888,
+4,20,34,7888,
+12,23,30,7888,
+6,24,31,7888,
+15,18,32,7888,
+0,22,33,7888,
+4,6,39,7888,
+9,14,36,7888,
+6,13,37,7888,
+7,9,38,7888,
+17,18,31,7888,
+18,25,25,7902,
+2,7,39,7902,
+14,17,33,7902,
+5,18,35,7902,
+13,26,27,7902,
+3,14,37,7902,
+3,11,38,7902,
+19,22,27,7902,
+2,27,29,7902,
+1,22,33,7902,
+7,25,30,7902,
+0,26,30,7902,
+18,24,26,7914,
+10,24,30,7914,
+8,12,37,7914,
+2,22,33,7914,
+15,26,26,7914,
+1,26,30,7914,
+3,28,28,7914,
+5,16,36,7914,
+8,27,28,7914,
+14,15,34,7914,
+16,19,31,7914,
+5,23,32,7914,
+13,25,28,7914,
+8,17,35,7914,
+3,27,29,7914,
+7,21,33,7914,
+3,7,39,7914,
+15,25,27,7914,
+11,27,27,7914,
+6,10,38,7914,
+14,22,30,7914,
+10,18,34,7914,
+2,26,30,7914,
+8,26,29,7914,
+11,26,28,7914,
+16,22,29,7924,
+13,16,34,7924,
+5,20,34,7924,
+4,11,38,7924,
+10,16,35,7924,
+4,14,37,7924,
+8,19,34,7924,
+14,19,32,7924,
+18,23,27,7959,
+3,22,33,7959,
+5,6,39,7959,
+13,18,33,7959,
+20,20,28,7966,
+12,12,36,7966,
+4,28,28,7966,
+15,24,28,7966,
+6,18,35,7966,
+18,19,30,7966,
+0,8,39,7966,
+0,17,36,7966,
+8,15,36,7966,
+3,26,30,7966,
+1,17,36,7966,
+11,13,36,7966,
+0,25,31,7966,
+13,24,29,7966,
+19,21,28,7980,
+1,8,39,7980,
+4,27,29,7980,
+11,21,32,7980,
+4,7,39,7980,
+15,20,31,7980,
+0,19,35,7980,
+7,24,31,7980,
+23,23,23,8009,
+11,25,29,8009,
+7,13,37,8009,
+1,19,35,8009,
+1,25,31,8009,
+0,12,38,8009,
+6,16,36,8009,
+12,22,31,8009,
+17,20,30,8009,
+4,22,33,8009,
+8,25,30,8009,
+6,23,32,8009,
+1,12,38,8009,
+22,23,24,8022,
+8,9,38,8022,
+9,22,32,8022,
+2,8,39,8022,
+12,17,34,8022,
+2,17,36,8022,
+10,20,33,8022,
+17,25,26,8022,
+10,23,31,8022,
+5,11,38,8022,
+13,14,35,8022,
+2,25,31,8022,
+5,14,37,8022,
+10,11,37,8022,
+2,19,35,8022,
+2,12,38,8022,
+10,14,36,8022,
+6,20,34,8022,
+18,22,28,8022,
+4,26,30,8022,
+7,10,38,8022,
+21,24,24,8052,
+6,6,39,8052,
+22,22,25,8052,
+5,28,28,8052,
+13,20,32,8052,
+8,21,33,8052,
+0,15,37,8052,
+9,27,28,8052,
+9,12,37,8052,
+12,15,35,8052,
+17,24,27,8052,
+12,19,33,8052,
+3,8,39,8052,
+3,17,36,8052,
+15,23,29,8052,
+3,19,35,8052,
+5,7,39,8052,
+3,25,31,8052,
+9,17,35,8052,
+21,23,25,8064,
+5,27,29,8064,
+1,15,37,8064,
+16,21,30,8064,
+3,12,38,8064,
+11,24,30,8064,
+0,21,34,8064,
+5,22,33,8064,
+2,15,37,8064,
+14,21,31,8064,
+13,23,30,8064,
+9,19,34,8064,
+9,26,29,8064,
+7,18,35,8064,
+1,21,34,8064,
+0,24,32,8064,
+0,0,40,8064,
+5,26,30,8064,
+11,18,34,8064,
+7,16,36,8064,
+2,21,34,8064,
+6,14,37,8064,
+0,1,40,8064,
+4,17,36,8064,
+21,22,26,8107,
+20,24,25,8107,
+4,8,39,8107,
+16,16,33,8107,
+6,11,38,8107,
+1,24,32,8107,
+14,26,27,8107,
+8,24,31,8107,
+11,16,35,8107,
+1,1,40,8107,
+19,20,29,8107,
+0,9,39,8107,
+8,13,37,8107,
+7,23,32,8107,
+4,25,31,8107,
+17,23,28,8107,
+4,19,35,8107,
+17,17,32,8107,
+12,27,27,8107,
+9,15,36,8107,
+15,17,33,8107,
+1,9,39,8107,
+3,15,37,8107,
+0,2,40,8107,
+12,26,28,8107,
+4,12,38,8107,
+2,24,32,8107,
+6,28,28,8107,
+16,18,32,8107,
+14,25,28,8107,
+1,2,40,8107,
+7,20,34,8107,
+20,23,26,8129,
+2,9,39,8129,
+6,7,39,8129,
+15,15,34,8129,
+3,21,34,8129,
+6,27,29,8129,
+18,21,29,8129,
+9,9,38,8129,
+9,25,30,8129,
+2,2,40,8129,
+14,16,34,8129,
+10,22,32,8129,
+8,10,38,8129,
+16,26,26,8129,
+0,3,40,8129,
+6,22,33,8129,
+18,18,31,8129,
+3,24,32,8129,
+14,18,33,8129,
+12,21,32,8129,
+15,22,30,8129,
+12,13,36,8129,
+15,19,32,8129,
+11,20,33,8129,
+5,8,39,8129,
+4,15,37,8129,
+1,3,40,8129,
+5,17,36,8129,
+12,25,29,8129,
+16,25,27,8137,
+5,25,31,8137,
+5,19,35,8137,
+11,23,31,8137,
+11,11,37,8137,
+21,21,27,8163,
+9,21,33,8163,
+19,25,25,8163,
+3,9,39,8163,
+17,19,31,8163,
+6,26,30,8163,
+10,27,28,8163,
+11,14,36,8163,
+19,24,26,8177,
+20,22,27,8177,
+5,12,38,8177,
+0,13,38,8177,
+2,3,40,8177,
+8,18,35,8177,
+4,21,34,8177,
+10,12,37,8177,
+14,24,29,8177,
+13,17,34,8177,
+7,11,38,8177,
+10,17,35,8177,
+7,14,37,8177,
+13,22,31,8177,
+1,13,38,8177,
+17,22,29,8177,
+8,16,36,8177,
+16,24,28,8177,
+4,24,32,8177,
+0,4,40,8177,
+2,13,38,8177,
+7,28,28,8177,
+10,19,34,8177,
+8,23,32,8177,
+10,26,29,8177,
+1,4,40,8177,
+14,14,35,8177,
+16,20,31,8177,
+0,23,33,8177,
+3,3,40,8177,
+9,24,31,8177,
+4,9,39,8177,
+19,23,27,8205,
+13,19,33,8205,
+9,13,37,8205,
+5,15,37,8205,
+1,23,33,8205,
+7,27,29,8205,
+13,15,35,8205,
+7,7,39,8205,
+14,20,32,8205,
+8,20,34,8205,
+12,24,30,8205,
+2,4,40,8205,
+0,18,36,8205,
+10,15,36,8205,
+1,18,36,8205,
+0,10,39,8205,
+6,17,36,8205,
+6,8,39,8205,
+6,19,35,8205,
+7,22,33,8205,
+2,23,33,8205,
+5,21,34,8205,
+3,13,38,8205,
+1,10,39,8205,
+19,19,30,8205,
+6,25,31,8205,
+12,18,34,8205,
+2,18,36,8205,
+6,12,38,8205,
+18,20,30,8210,
+5,24,32,8210,
+0,20,35,8210,
+10,25,30,8210,
+18,25,26,8243,
+0,28,29,8243,
+3,4,40,8243,
+12,16,35,8243,
+2,10,39,8243,
+14,23,30,8243,
+7,26,30,8243,
+0,5,40,8243,
+20,21,28,8243,
+0,16,37,8243,
+9,10,38,8243,
+1,20,35,8243,
+1,5,40,8243,
+1,28,29,8243,
+1,16,37,8243,
+16,23,29,8243,
+5,9,39,8243,
+3,23,33,8243,
+15,21,31,8243,
+13,27,27,8243,
+13,26,28,8243,
+8,14,37,8243,
+0,27,30,8243,
+8,11,38,8243,
+3,18,36,8243,
+2,28,29,8243,
+2,5,40,8243,
+11,22,32,8243,
+4,13,38,8243,
+2,16,37,8243,
+19,22,28,8266,
+18,24,27,8266,
+2,20,35,8266,
+6,15,37,8266,
+3,10,39,8266,
+9,18,35,8266,
+1,27,30,8266,
+15,26,27,8266,
+10,21,33,8266,
+17,21,30,8266,
+4,4,40,8266,
+8,28,28,8266,
+2,27,30,8266,
+6,21,34,8266,
+9,16,36,8266,
+12,20,33,8266,
+8,27,29,8266,
+3,16,37,8266,
+9,23,32,8266,
+4,23,33,8266,
+11,12,37,8266,
+16,17,33,8266,
+15,25,28,8270,
+3,5,40,8270,
+7,8,39,8270,
+7,17,36,8270,
+23,23,24,8326,
+3,28,29,8326,
+3,20,35,8326,
+13,13,36,8326,
+12,23,31,8326,
+11,27,28,8326,
+13,21,32,8326,
+7,25,31,8326,
+13,25,29,8326,
+11,17,35,8326,
+7,19,35,8326,
+12,14,36,8326,
+4,18,36,8326,
+0,6,40,8326,
+6,24,32,8326,
+22,24,24,8332,
+8,22,33,8332,
+15,16,34,8332,
+10,24,31,8332,
+17,18,32,8332,
+7,12,38,8332,
+9,20,34,8332,
+4,10,39,8332,
+18,23,28,8332,
+1,6,40,8332,
+0,26,31,8332,
+15,18,33,8332,
+10,13,37,8332,
+3,27,30,8332,
+22,23,25,8346,
+6,9,39,8346,
+11,19,34,8346,
+11,26,29,8346,
+1,26,31,8346,
+5,13,38,8346,
+16,22,30,8346,
+2,6,40,8346,
+8,26,30,8346,
+0,22,34,8346,
+0,14,38,8346,
+2,26,31,8346,
+1,22,34,8346,
+4,28,29,8346,
+20,20,29,8346,
+14,22,31,8346,
+14,17,34,8346,
+16,19,32,8346,
+4,20,35,8346,
+1,14,38,8346,
+17,26,26,8346,
+4,5,40,8346,
+4,16,37,8346,
+15,24,29,8346,
+21,24,25,8377,
+0,11,39,8377,
+11,15,36,8377,
+19,21,29,8377,
+7,15,37,8377,
+5,23,33,8377,
+1,11,39,8377,
+17,25,27,8377,
+2,14,38,8377,
+2,22,34,8377,
+22,22,26,8380,
+10,10,38,8380,
+3,6,40,8380,
+5,18,36,8380,
+4,27,30,8380,
+13,24,30,8380,
+18,19,31,8380,
+3,26,31,8380,
+5,10,39,8380,
+7,21,34,8380,
+2,11,39,8380,
+14,15,35,8380,
+21,23,26,8403,
+9,14,37,8403,
+11,25,30,8403,
+14,19,33,8403,
+9,11,38,8403,
+7,24,32,8403,
+17,24,28,8403,
+8,8,39,8403,
+0,25,32,8403,
+6,13,38,8403,
+18,22,29,8403,
+3,22,34,8403,
+0,7,40,8403,
+8,17,36,8403,
+15,20,32,8403,
+3,14,38,8403,
+10,18,35,8403,
+13,18,34,8403,
+9,28,28,8403,
+5,20,35,8403,
+1,25,32,8403,
+1,7,40,8403,
+17,20,31,8403,
+5,5,40,8403,
+5,16,37,8403,
+13,16,35,8403,
+8,25,31,8403,
+20,25,25,8425,
+8,19,35,8425,
+5,28,29,8425,
+7,9,39,8425,
+9,27,29,8425,
+3,11,39,8425,
+11,21,33,8425,
+20,24,26,8433,
+10,16,36,8433,
+12,22,32,8433,
+8,12,38,8433,
+4,6,40,8433,
+2,7,40,8433,
+4,26,31,8433,
+10,23,32,8433,
+2,25,32,8433,
+14,27,27,8433,
+21,22,27,8455,
+15,23,30,8455,
+5,27,30,8455,
+9,22,33,8455,
+6,23,33,8455,
+14,26,28,8455,
+10,20,34,8455,
+6,18,36,8455,
+4,14,38,8455,
+4,22,34,8455,
+6,10,39,8455,
+9,26,30,8455,
+12,12,37,8455,
+12,27,28,8455,
+0,19,36,8455,
+3,25,32,8455,
+16,21,31,8455,
+12,17,35,8455,
+4,11,39,8455,
+0,17,37,8455,
+13,20,33,8455,
+11,24,31,8455,
+20,23,27,8486,
+8,15,37,8486,
+3,7,40,8486,
+1,19,36,8486,
+11,13,37,8486,
+17,23,29,8486,
+1,17,37,8486,
+13,23,31,8486,
+12,26,29,8486,
+12,19,34,8486,
+19,20,30,8486,
+6,28,29,8486,
+6,16,37,8486,
+2,19,36,8486,
+13,14,36,8486,
+16,26,27,8486,
+8,21,34,8486,
+14,21,32,8486,
+5,6,40,8486,
+6,20,35,8486,
+19,25,26,8507,
+7,13,38,8507,
+2,17,37,8507,
+5,26,31,8507,
+14,25,29,8507,
+8,24,32,8507,
+0,8,40,8507,
+16,25,28,8507,
+4,7,40,8507,
+18,21,30,8507,
+10,14,37,8507,
+1,8,40,8507,
+5,22,34,8507,
+5,14,38,8507,
+0,12,39,8507,
+12,15,36,8507,
+6,27,30,8507,
+0,24,33,8507,
+4,25,32,8507,
+10,11,38,8507,
+1,12,39,8507,
+9,17,36,8507,
+19,24,27,8532,
+0,21,35,8532,
+8,9,39,8532,
+3,19,36,8532,
+1,24,33,8532,
+21,21,28,8532,
+3,17,37,8532,
+9,19,35,8532,
+9,25,31,8532,
+5,11,39,8532,
+17,17,33,8532,
+7,23,33,8532,
+1,21,35,8532,
+20,22,28,8536,
+10,28,28,8536,
+16,16,34,8536,
+2,8,40,8536,
+9,12,38,8536,
+2,12,39,8536,
+2,24,33,8536,
+16,18,33,8536,
+7,18,36,8536,
+0,15,38,8536,
+12,25,30,8536,
+15,22,31,8536,
+1,15,38,8536,
+10,27,29,8536,
+2,21,35,8536,
+11,18,35,8536,
+15,17,34,8536,
+7,10,39,8536,
+14,24,30,8536,
+18,18,32,8536,
+6,6,40,8536,
+16,24,29,8545,
+11,16,36,8545,
+6,26,31,8545,
+4,19,36,8545,
+17,22,30,8545,
+3,8,40,8545,
+2,15,38,8545,
+10,22,33,8545,
+5,25,32,8545,
+3,24,33,8545,
+5,7,40,8545,
+17,19,32,8545,
+7,16,37,8545,
+19,23,28,8580,
+7,28,29,8580,
+7,20,35,8580,
+4,17,37,8580,
+11,23,32,8580,
+3,12,39,8580,
+12,21,33,8580,
+9,15,37,8580,
+3,21,35,8580,
+15,15,35,8580,
+15,19,33,8580,
+10,26,30,8580,
+18,26,26,8582,
+14,18,34,8582,
+6,14,38,8582,
+6,22,34,8582,
+8,13,38,8582,
+11,20,34,8582,
+14,16,35,8582,
+13,22,32,8582,
+6,11,39,8582,
+3,15,38,8582,
+7,27,30,8582,
+9,21,34,8582,
+18,25,27,8602,
+16,20,32,8602,
+4,8,40,8602,
+4,24,33,8602,
+12,24,31,8602,
+9,24,32,8602,
+0,0,41,8602,
+0,9,40,8602,
+23,24,24,8652,
+4,12,39,8652,
+5,19,36,8652,
+20,21,29,8652,
+4,21,35,8652,
+13,27,28,8652,
+1,9,40,8652,
+0,29,29,8652,
+12,13,37,8652,
+8,23,33,8652,
+0,1,41,8652,
+13,17,35,8652,
+1,29,29,8652,
+15,27,27,8652,
+1,1,41,8652,
+9,9,39,8652,
+23,23,25,8667,
+19,19,31,8667,
+5,17,37,8667,
+18,24,28,8667,
+8,18,36,8667,
+0,28,30,8667,
+2,9,40,8667,
+1,28,30,8667,
+22,24,25,8672,
+15,26,28,8672,
+0,2,41,8672,
+14,20,33,8672,
+6,7,40,8672,
+4,15,38,8672,
+16,23,30,8672,
+6,25,32,8672,
+18,20,31,8672,
+0,23,34,8672,
+10,17,36,8672,
+8,10,39,8672,
+2,29,29,8672,
+1,2,41,8672,
+11,14,37,8672,
+11,11,38,8672,
+19,22,29,8672,
+1,23,34,8672,
+13,19,34,8672,
+10,25,31,8672,
+10,19,35,8672,
+7,26,31,8672,
+13,26,29,8672,
+14,23,31,8672,
+14,14,36,8672,
+10,12,38,8672,
+2,28,30,8672,
+8,16,37,8672,
+7,22,34,8672,
+8,20,35,8672,
+2,2,41,8672,
+7,14,38,8672,
+5,8,40,8672,
+11,28,28,8672,
+22,23,26,8689,
+2,23,34,8689,
+8,28,29,8689,
+15,21,32,8689,
+0,27,31,8689,
+13,15,36,8689,
+0,13,39,8689,
+5,24,33,8689,
+5,12,39,8689,
+0,3,41,8689,
+3,9,40,8689,
+1,13,39,8689,
+1,3,41,8689,
+1,27,31,8689,
+21,25,25,8706,
+3,29,29,8706,
+17,21,31,8706,
+15,25,29,8706,
+11,27,29,8706,
+5,21,35,8706,
+7,11,39,8706,
+21,24,26,8725,
+8,27,30,8725,
+6,19,36,8725,
+12,18,35,8725,
+0,18,37,8725,
+3,28,30,8725,
+9,13,38,8725,
+11,22,33,8725,
+2,27,31,8725,
+2,3,41,8725,
+3,23,34,8725,
+5,15,38,8725,
+13,25,30,8725,
+6,17,37,8725,
+10,15,37,8725,
+2,13,39,8725,
+18,23,29,8725,
+17,26,27,8725,
+1,18,37,8725,
+0,20,36,8725,
+12,16,36,8725,
+2,18,37,8725,
+0,4,41,8725,
+4,9,40,8725,
+11,26,30,8725,
+22,22,27,8741,
+10,21,34,8741,
+1,20,36,8741,
+12,23,32,8741,
+7,7,40,8741,
+1,4,41,8741,
+4,29,29,8741,
+7,25,32,8741,
+17,25,28,8741,
+3,27,31,8741,
+9,23,33,8741,
+3,13,39,8741,
+21,23,27,8759,
+13,21,33,8759,
+3,3,41,8759,
+2,20,36,8759,
+0,10,40,8759,
+12,20,34,8759,
+10,24,32,8759,
+20,20,30,8759,
+0,26,32,8759,
+0,16,38,8759,
+6,8,40,8759,
+4,28,30,8759,
+16,22,31,8759,
+15,24,30,8759,
+6,12,39,8759,
+16,17,34,8759,
+9,18,36,8759,
+2,4,41,8759,
+6,24,33,8759,
+8,26,31,8759,
+1,10,40,8759,
+1,16,38,8759,
+20,25,26,8772,
+1,26,32,8772,
+4,23,34,8772,
+6,21,35,8772,
+3,18,37,8772,
+9,10,39,8772,
+17,18,33,8772,
+19,21,30,8772,
+14,22,32,8772,
+8,14,38,8772,
+8,22,34,8772,
+2,26,32,8772,
+2,16,38,8772,
+2,10,40,8772,
+3,20,36,8772,
+15,18,34,8772,
+6,15,38,8772,
+20,24,27,8800,
+16,19,33,8800,
+9,28,29,8800,
+0,5,41,8800,
+7,19,36,8800,
+4,13,39,8800,
+5,9,40,8800,
+9,16,37,8800,
+8,11,39,8800,
+15,16,35,8800,
+11,17,36,8800,
+3,4,41,8800,
+9,20,35,8800,
+13,24,31,8800,
+4,27,31,8800,
+17,24,29,8800,
+13,13,37,8800,
+7,17,37,8800,
+11,19,35,8800,
+5,29,29,8800,
+11,25,31,8800,
+1,5,41,8800,
+18,22,30,8800,
+14,27,28,8800,
+0,22,35,8800,
+3,26,32,8800,
+4,18,37,8800,
+5,28,30,8800,
+21,22,28,8822,
+12,14,37,8822,
+18,19,32,8822,
+11,12,38,8822,
+3,16,38,8822,
+3,10,40,8822,
+9,27,30,8822,
+2,5,41,8822,
+5,23,34,8822,
+14,17,35,8822,
+1,22,35,8822,
+4,20,36,8822,
+12,28,28,8822,
+2,22,35,8822,
+19,26,26,8854,
+10,13,38,8854,
+14,26,29,8854,
+4,4,41,8854,
+14,19,34,8854,
+17,20,32,8854,
+8,25,32,8854,
+7,8,40,8854,
+20,23,28,8854,
+7,24,33,8854,
+16,27,27,8854,
+15,20,33,8854,
+0,25,33,8854,
+7,12,39,8854,
+12,27,29,8854,
+5,13,39,8854,
+11,15,37,8854,
+3,5,41,8854,
+7,21,35,8854,
+19,25,27,8866,
+5,27,31,8866,
+1,25,33,8866,
+15,23,31,8866,
+16,26,28,8866,
+4,16,38,8866,
+4,26,32,8866,
+4,10,40,8866,
+14,15,36,8866,
+12,22,33,8866,
+0,6,41,8866,
+6,9,40,8866,
+0,14,39,8866,
+7,15,38,8866,
+3,22,35,8866,
+6,29,29,8866,
+1,6,41,8866,
+17,23,30,8866,
+13,18,35,8866,
+10,23,33,8866,
+11,21,34,8866,
+2,25,33,8866,
+9,26,31,8866,
+5,18,37,8866,
+1,14,39,8866,
+10,18,36,8866,
+12,26,30,8866,
+6,28,30,8866,
+2,6,41,8866,
+0,11,40,8866,
+19,24,28,8886,
+6,23,34,8886,
+9,14,38,8886,
+10,10,39,8886,
+5,20,36,8886,
+16,21,32,8886,
+9,22,34,8886,
+14,25,30,8886,
+2,14,39,8886,
+8,19,36,8886,
+13,16,36,8886,
+11,24,32,8886,
+1,11,40,8886,
+8,17,37,8886,
+16,25,29,8886,
+13,23,32,8886,
+19,20,31,8886,
+4,5,41,8886,
+9,11,39,8886,
+21,21,29,8903,
+3,25,33,8903,
+2,11,40,8903,
+5,16,38,8903,
+13,20,34,8903,
+10,16,37,8903,
+20,22,29,8923,
+10,28,29,8923,
+5,10,40,8923,
+10,20,35,8923,
+4,22,35,8923,
+5,26,32,8923,
+6,13,39,8923,
+3,14,39,8923,
+14,21,33,8923,
+18,21,31,8923,
+6,27,31,8923,
+3,6,41,8923,
+24,24,24,8968,
+8,8,40,8968,
+6,18,37,8968,
+10,27,30,8968,
+8,12,39,8968,
+12,17,36,8968,
+18,26,27,8968,
+8,24,33,8968,
+3,11,40,8968,
+0,7,41,8968,
+7,9,40,8968,
+23,24,25,8987,
+12,19,35,8987,
+0,19,37,8987,
+12,25,31,8987,
+8,21,35,8987,
+4,25,33,8987,
+9,25,32,8987,
+5,5,41,8987,
+19,23,29,8987,
+1,19,37,8987,
+1,7,41,8987,
+7,29,29,8987,
+12,12,38,8987,
+6,20,36,8987,
+0,24,34,8987,
+16,24,30,8987,
+4,6,41,8987,
+8,15,38,8987,
+7,28,30,8987,
+4,14,39,8987,
+15,22,32,8987,
+0,17,38,8987,
+14,24,31,8987,
+1,24,34,8987,
+18,25,28,8987,
+2,7,41,8987,
+22,25,25,9007,
+17,22,31,9007,
+13,14,37,9007,
+17,17,34,9007,
+5,22,35,9007,
+1,17,38,9007,
+11,13,38,9007,
+2,19,37,9007,
+23,23,26,9007,
+7,23,34,9007,
+2,24,34,9007,
+6,10,40,9007,
+6,16,38,9007,
+16,18,34,9007,
+22,24,26,9019,
+6,26,32,9019,
+10,26,31,9019,
+13,28,28,9019,
+18,18,33,9019,
+0,21,36,9019,
+2,17,38,9019,
+4,11,40,9019,
+16,16,35,9019,
+12,15,37,9019,
+1,21,36,9019,
+9,19,36,9019,
+15,27,28,9019,
+17,19,33,9019,
+9,17,37,9019,
+7,13,39,9019,
+7,27,31,9019,
+3,19,37,9019,
+11,23,33,9019,
+3,7,41,9019,
+5,25,33,9019,
+13,27,29,9019,
+15,17,35,9019,
+10,14,38,9019,
+10,22,34,9019,
+11,18,36,9019,
+18,24,29,9025,
+2,21,36,9025,
+12,21,34,9025,
+20,21,30,9025,
+0,29,30,9025,
+3,24,34,9025,
+3,17,38,9025,
+1,29,30,9025,
+15,26,29,9025,
+7,18,37,9025,
+10,11,39,9025,
+13,22,33,9025,
+5,6,41,9025,
+22,23,27,9056,
+21,25,26,9056,
+5,14,39,9056,
+15,19,34,9056,
+0,12,40,9056,
+12,24,32,9056,
+0,8,41,9056,
+16,20,33,9056,
+13,26,30,9056,
+7,20,36,9056,
+19,22,30,9056,
+14,18,35,9056,
+1,12,40,9056,
+8,9,40,9056,
+0,28,31,9056,
+2,29,30,9056,
+6,22,35,9056,
+21,24,27,9086,
+15,15,36,9086,
+19,19,32,9086,
+1,28,31,9086,
+0,15,39,9086,
+3,21,36,9086,
+5,11,40,9086,
+16,23,31,9086,
+9,24,33,9086,
+4,19,37,9086,
+8,29,29,9086,
+11,16,37,9086,
+9,12,39,9086,
+4,7,41,9086,
+11,28,29,9086,
+1,8,41,9086,
+11,20,35,9086,
+17,27,27,9086,
+1,15,39,9086,
+9,21,35,9086,
+18,20,32,9086,
+4,24,34,9086,
+2,12,40,9086,
+8,28,30,9086,
+14,16,36,9086,
+4,17,38,9086,
+7,10,40,9086,
+2,28,31,9086,
+14,23,32,9086,
+10,25,32,9086,
+7,26,32,9086,
+17,26,28,9086,
+7,16,38,9086,
+2,8,41,9086,
+8,23,34,9086,
+3,29,30,9086,
+6,25,33,9086,
+11,27,30,9086,
+2,15,39,9086,
+9,15,38,9086,
+15,25,30,9086,
+20,26,26,9121,
+22,22,28,9121,
+14,20,34,9121,
+18,23,30,9121,
+6,14,39,9121,
+3,12,40,9121,
+0,27,32,9121,
+6,6,41,9121,
+4,21,36,9121,
+3,28,31,9121,
+17,21,32,9121,
+13,17,36,9121,
+8,13,39,9121,
+21,23,28,9144,
+3,8,41,9144,
+1,27,32,9144,
+0,23,35,9144,
+8,27,31,9144,
+20,25,27,9144,
+17,25,29,9144,
+15,21,33,9144,
+5,7,41,9144,
+5,19,37,9144,
+1,23,35,9144,
+3,15,39,9144,
+13,25,31,9144,
+13,19,35,9144,
+5,24,34,9144,
+8,18,37,9144,
+2,27,32,9144,
+4,29,30,9144,
+10,19,36,9144,
+12,13,38,9144,
+6,11,40,9144,
+2,23,35,9144,
+5,17,38,9144,
+7,22,35,9144,
+10,17,37,9144,
+11,26,31,9144,
+8,20,36,9144,
+4,12,40,9144,
+20,24,28,9177,
+14,14,37,9177,
+20,20,31,9177,
+4,8,41,9177,
+11,22,34,9177,
+11,14,38,9177,
+4,28,31,9177,
+0,9,41,9177,
+5,21,36,9177,
+12,23,33,9177,
+4,15,39,9177,
+9,9,40,9177,
+3,27,32,9177,
+15,24,31,9177,
+11,11,39,9177,
+13,15,37,9177,
+19,21,31,9177,
+3,23,35,9177,
+9,29,29,9177,
+1,9,41,9177,
+7,25,33,9177,
+16,22,32,9177,
+14,28,28,9177,
+0,0,42,9177,
+8,10,40,9177,
+12,18,36,9177,
+8,16,38,9177,
+8,26,32,9177,
+10,24,33,9177,
+10,12,39,9177,
+17,24,30,9190,
+9,28,30,9190,
+0,26,33,9190,
+0,1,42,9190,
+6,19,37,9190,
+6,7,41,9190,
+21,22,29,9218,
+5,29,30,9218,
+7,14,39,9218,
+19,26,27,9218,
+1,1,42,9218,
+1,26,33,9218,
+2,9,41,9218,
+14,27,29,9218,
+9,23,34,9218,
+13,21,34,9218,
+10,21,35,9218,
+0,18,38,9218,
+6,24,34,9218,
+0,2,42,9218,
+1,2,42,9218,
+0,20,37,9218,
+16,27,28,9218,
+2,26,33,9218,
+12,20,35,9218,
+6,17,38,9218,
+10,15,38,9218,
+18,22,31,9218,
+17,18,34,9218,
+4,27,32,9218,
+0,13,40,9218,
+13,24,32,9218,
+12,28,29,9218,
+14,22,33,9218,
+1,18,38,9218,
+5,12,40,9218,
+12,16,37,9218,
+1,13,40,9218,
+20,23,29,9250,
+7,11,40,9250,
+11,25,32,9250,
+4,23,35,9250,
+19,25,28,9250,
+5,28,31,9250,
+5,8,41,9250,
+16,17,35,9250,
+1,20,37,9250,
+3,9,41,9250,
+9,27,31,9250,
+5,15,39,9250,
+9,13,39,9250,
+2,2,42,9250,
+14,26,30,9250,
+2,18,38,9250,
+8,22,35,9250,
+0,3,42,9250,
+16,19,34,9250,
+2,20,37,9250,
+6,21,36,9250,
+2,13,40,9250,
+16,26,29,9250,
+12,27,30,9250,
+15,18,35,9250,
+3,26,33,9250,
+9,18,37,9250,
+18,19,33,9250,
+1,3,42,9250,
+6,29,30,9250,
+2,3,42,9250,
+9,20,36,9250,
+3,18,38,9250,
+15,16,36,9250,
+0,16,39,9250,
+24,24,25,9309,
+1,16,39,9309,
+17,20,33,9309,
+3,13,40,9309,
+4,9,41,9309,
+8,25,33,9309,
+19,24,29,9309,
+5,27,32,9309,
+15,23,32,9309,
+11,19,36,9309,
+3,20,37,9309,
+7,7,41,9309,
+17,23,31,9309,
+11,17,37,9309,
+7,19,37,9309,
+23,25,25,9320,
+5,23,35,9320,
+6,12,40,9320,
+0,22,36,9320,
+0,4,42,9320,
+9,26,32,9320,
+0,25,34,9320,
+8,14,39,9320,
+4,26,33,9320,
+6,8,41,9320,
+9,16,38,9320,
+2,16,39,9320,
+14,17,36,9320,
+1,22,36,9320,
+9,10,40,9320,
+6,28,31,9320,
+23,24,26,9337,
+16,25,30,9337,
+15,20,34,9337,
+7,24,34,9337,
+0,10,41,9337,
+12,26,31,9337,
+1,4,42,9337,
+1,10,41,9337,
+3,3,42,9337,
+14,19,35,9337,
+14,25,31,9337,
+7,17,38,9337,
+1,25,34,9337,
+21,21,30,9337,
+13,13,38,9337,
+18,27,27,9337,
+6,15,39,9337,
+10,29,29,9337,
+12,22,34,9337,
+2,22,36,9337,
+2,4,42,9337,
+12,14,38,9337,
+18,26,28,9337,
+10,28,30,9337,
+20,22,30,9337,
+4,18,38,9337,
+4,13,40,9337,
+19,20,32,9337,
+10,23,34,9337,
+22,25,26,9358,
+8,11,40,9358,
+4,20,37,9358,
+2,25,34,9358,
+2,10,41,9358,
+16,21,33,9358,
+3,16,39,9358,
+11,12,39,9358,
+11,24,33,9358,
+7,21,36,9358,
+13,23,33,9358,
+5,9,41,9358,
+23,23,27,9378,
+11,21,35,9378,
+18,21,32,9378,
+22,24,27,9391,
+0,5,42,9391,
+3,22,36,9391,
+3,4,42,9391,
+6,27,32,9391,
+13,18,36,9391,
+3,10,41,9391,
+10,13,39,9391,
+9,22,35,9391,
+7,29,30,9391,
+14,15,37,9391,
+3,25,34,9391,
+5,26,33,9391,
+11,15,38,9391,
+1,5,42,9391,
+19,23,30,9391,
+10,27,31,9391,
+6,23,35,9391,
+18,25,29,9391,
+14,21,34,9391,
+10,18,37,9391,
+16,24,31,9391,
+4,16,39,9391,
+7,12,40,9391,
+2,5,42,9391,
+5,18,38,9391,
+21,26,26,9412,
+15,28,28,9412,
+12,25,32,9412,
+5,20,37,9412,
+13,28,29,9412,
+7,28,31,9412,
+8,19,37,9412,
+13,16,37,9412,
+7,8,41,9412,
+5,13,40,9412,
+13,20,35,9412,
+9,25,33,9412,
+7,15,39,9412,
+15,27,29,9412,
+21,25,27,9429,
+8,24,34,9429,
+0,14,40,9429,
+4,22,36,9429,
+4,4,42,9429,
+10,20,36,9429,
+14,24,32,9429,
+17,22,32,9429,
+22,23,28,9439,
+1,14,40,9439,
+4,25,34,9439,
+8,17,38,9439,
+4,10,41,9439,
+9,14,39,9439,
+13,27,30,9439,
+15,22,33,9439,
+6,9,41,9439,
+3,5,42,9439,
+10,16,38,9439,
+2,14,40,9439,
+0,30,30,9439,
+10,10,40,9439,
+0,6,42,9439,
+10,26,32,9439,
+18,24,30,9439,
+21,24,28,9462,
+1,6,42,9462,
+1,30,30,9462,
+15,26,30,9462,
+12,19,36,9462,
+0,24,35,9462,
+8,21,36,9462,
+6,26,33,9462,
+17,27,28,9462,
+0,29,31,9462,
+0,11,41,9462,
+20,21,31,9462,
+1,24,35,9462,
+5,16,39,9462,
+7,27,32,9462,
+9,11,40,9462,
+12,17,37,9462,
+1,11,41,9462,
+11,29,29,9462,
+1,29,31,9462,
+7,23,35,9462,
+17,17,35,9462,
+18,18,34,9462,
+2,6,42,9462,
+2,30,30,9462,
+6,18,38,9462,
+8,29,30,9462,
+6,13,40,9462,
+11,28,30,9462,
+6,20,37,9462,
+16,18,35,9462,
+0,19,38,9462,
+2,24,35,9462,
+4,5,42,9462,
+20,26,27,9491,
+5,22,36,9491,
+3,14,40,9491,
+17,26,29,9491,
+2,29,31,9491,
+1,19,38,9491,
+5,10,41,9491,
+13,26,31,9491,
+11,23,34,9491,
+19,22,31,9491,
+17,19,34,9491,
+5,25,34,9491,
+2,11,41,9491,
+16,16,36,9491,
+0,28,32,9491,
+8,12,40,9491,
+3,30,30,9491,
+16,23,32,9491,
+8,8,41,9491,
+13,14,38,9491,
+10,22,35,9491,
+3,6,42,9491,
+2,19,38,9491,
+12,12,39,9491,
+22,22,29,9505,
+8,28,31,9505,
+1,28,32,9505,
+13,22,34,9505,
+12,24,33,9505,
+20,25,28,9505,
+0,21,37,9505,
+15,17,36,9505,
+3,24,35,9505,
+8,15,39,9505,
+0,17,39,9505,
+12,21,35,9505,
+21,23,29,9524,
+11,27,31,9524,
+19,19,33,9524,
+7,9,41,9524,
+11,13,39,9524,
+3,11,41,9524,
+15,25,31,9524,
+1,21,37,9524,
+9,19,37,9524,
+1,17,39,9524,
+15,19,35,9524,
+3,29,31,9524,
+4,14,40,9524,
+2,28,32,9524,
+16,20,34,9524,
+9,24,34,9524,
+6,16,39,9524,
+12,15,38,9524,
+0,7,42,9524,
+18,20,33,9524,
+18,23,31,9524,
+9,17,38,9524,
+7,26,33,9524,
+3,19,38,9524,
+10,25,33,9524,
+1,7,42,9524,
+2,21,37,9524,
+2,17,39,9524,
+5,5,42,9524,
+17,25,30,9524,
+14,23,33,9524,
+11,18,37,9524,
+6,22,36,9524,
+4,30,30,9524,
+14,18,36,9524,
+4,6,42,9524,
+6,10,41,9524,
+10,14,39,9524,
+6,25,34,9524,
+8,27,32,9524,
+3,28,32,9524,
+20,24,29,9562,
+4,24,35,9562,
+2,7,42,9562,
+7,18,38,9562,
+11,20,36,9562,
+4,11,41,9562,
+7,20,37,9562,
+8,23,35,9562,
+13,25,32,9562,
+0,27,33,9562,
+4,29,31,9562,
+7,13,40,9562,
+9,21,36,9562,
+15,15,37,9562,
+19,27,27,9575,
+17,21,33,9575,
+3,21,37,9575,
+1,27,33,9575,
+3,17,39,9575,
+14,20,35,9575,
+14,16,37,9575,
+10,11,40,9575,
+14,28,29,9575,
+5,14,40,9575,
+11,26,32,9575,
+4,19,38,9575,
+11,16,38,9575,
+19,26,28,9589,
+15,21,34,9589,
+3,7,42,9589,
+9,29,30,9589,
+2,27,33,9589,
+16,28,28,9589,
+4,28,32,9589,
+20,20,32,9589,
+15,24,32,9589,
+5,6,42,9589,
+0,23,36,9589,
+14,27,30,9589,
+5,30,30,9589,
+9,12,40,9589,
+0,12,41,9589,
+21,22,30,9620,
+0,15,40,9620,
+19,21,32,9620,
+7,16,39,9620,
+17,24,31,9620,
+24,25,25,9660,
+12,29,29,9660,
+4,21,37,9660,
+16,27,29,9660,
+9,28,31,9660,
+1,23,36,9660,
+1,15,40,9660,
+1,12,41,9660,
+4,17,39,9660,
+5,24,35,9660,
+13,19,36,9660,
+8,9,41,9660,
+5,29,31,9660,
+9,15,39,9660,
+13,17,37,9660,
+3,27,33,9660,
+19,25,29,9660,
+5,11,41,9660,
+0,8,42,9660,
+24,24,26,9666,
+12,28,30,9666,
+7,22,36,9666,
+2,12,41,9666,
+2,23,36,9666,
+1,8,42,9666,
+2,15,40,9666,
+8,26,33,9666,
+4,7,42,9666,
+20,23,30,9666,
+16,22,33,9666,
+12,23,34,9666,
+10,19,37,9666,
+11,22,35,9666,
+23,25,26,9682,
+7,25,34,9682,
+7,10,41,9682,
+5,19,38,9682,
+2,8,42,9682,
+6,14,40,9682,
+18,22,32,9682,
+0,26,34,9682,
+10,24,34,9682,
+8,18,38,9682,
+16,26,30,9682,
+8,20,37,9682,
+10,17,38,9682,
+1,26,34,9682,
+14,26,31,9682,
+5,28,32,9682,
+8,13,40,9682,
+12,27,31,9682,
+3,12,41,9682,
+9,27,32,9682,
+3,15,40,9682,
+12,13,39,9682,
+23,24,27,9716,
+4,27,33,9716,
+13,24,33,9716,
+3,23,36,9716,
+9,23,35,9716,
+13,21,35,9716,
+5,21,37,9716,
+5,17,39,9716,
+11,25,33,9716,
+6,6,42,9716,
+6,30,30,9716,
+14,22,34,9716,
+22,26,26,9720,
+14,14,38,9720,
+2,26,34,9720,
+6,24,35,9720,
+18,27,28,9720,
+12,18,37,9720,
+3,8,42,9720,
+10,21,36,9720,
+19,24,30,9720,
+6,29,31,9720,
+6,11,41,9720,
+17,18,35,9720,
+13,15,38,9720,
+5,7,42,9720,
+11,14,39,9720,
+22,25,27,9736,
+12,20,36,9736,
+8,16,39,9736,
+10,29,30,9736,
+6,19,38,9736,
+3,26,34,9736,
+4,23,36,9736,
+18,19,34,9736,
+4,12,41,9736,
+4,15,40,9736,
+18,26,29,9736,
+16,17,36,9736,
+16,19,35,9736,
+17,23,32,9736,
+23,23,28,9768,
+11,11,40,9768,
+16,25,31,9768,
+15,23,33,9768,
+5,27,33,9768,
+21,21,31,9768,
+9,9,41,9768,
+6,28,32,9768,
+8,22,36,9768,
+22,24,28,9771,
+12,26,32,9771,
+4,8,42,9771,
+12,16,38,9771,
+10,12,40,9771,
+0,20,38,9771,
+0,18,39,9771,
+8,25,34,9771,
+20,22,31,9771,
+0,9,42,9771,
+15,18,36,9771,
+14,25,32,9771,
+1,20,38,9771,
+8,10,41,9771,
+17,20,34,9771,
+7,14,40,9771,
+10,28,31,9771,
+1,18,39,9771,
+9,26,33,9771,
+6,21,37,9771,
+1,9,42,9771,
+6,17,39,9771,
+10,15,39,9771,
+21,26,27,9790,
+4,26,34,9790,
+2,20,38,9790,
+2,18,39,9790,
+6,7,42,9790,
+2,9,42,9790,
+7,30,30,9790,
+18,25,30,9790,
+0,0,43,9790,
+9,18,38,9790,
+5,15,40,9790,
+0,1,43,9790,
+0,13,41,9790,
+9,20,37,9790,
+0,25,35,9790,
+15,28,29,9790,
+7,24,35,9790,
+15,16,37,9790,
+21,25,28,9812,
+5,23,36,9812,
+5,12,41,9812,
+9,13,40,9812,
+19,20,33,9812,
+15,20,35,9812,
+19,23,31,9812,
+1,25,35,9812,
+7,11,41,9812,
+1,13,41,9812,
+1,1,43,9812,
+11,19,37,9812,
+13,29,29,9812,
+7,29,31,9812,
+3,20,38,9812,
+0,2,43,9812,
+11,24,34,9812,
+0,22,37,9812,
+10,27,32,9812,
+12,22,35,9812,
+14,19,36,9812,
+16,21,34,9812,
+13,28,30,9812,
+5,8,42,9812,
+2,13,41,9812,
+3,9,42,9812,
+15,27,30,9812,
+6,27,33,9812,
+11,17,38,9812,
+18,21,33,9812,
+1,2,43,9812,
+2,25,35,9812,
+13,23,34,9812,
+1,22,37,9812,
+22,23,29,9836,
+3,18,39,9836,
+7,19,38,9836,
+10,23,35,9836,
+14,17,37,9836,
+16,24,32,9836,
+0,16,40,9836,
+5,26,34,9836,
+2,2,43,9836,
+7,28,32,9836,
+17,28,28,9836,
+2,22,37,9836,
+1,16,40,9836,
+21,24,29,9863,
+0,3,43,9863,
+20,27,27,9863,
+12,25,33,9863,
+11,21,36,9863,
+9,16,39,9863,
+7,17,39,9863,
+7,21,37,9863,
+17,27,29,9863,
+13,13,39,9863,
+3,13,41,9863,
+1,3,43,9863,
+3,25,35,9863,
+13,27,31,9863,
+20,26,28,9869,
+4,20,38,9869,
+2,16,40,9869,
+8,14,40,9869,
+9,22,36,9869,
+4,9,42,9869,
+6,15,40,9869,
+4,18,39,9869,
+12,14,39,9869,
+0,30,31,9869,
+18,24,31,9869,
+6,23,36,9869,
+6,12,41,9869,
+14,24,33,9869,
+17,22,33,9869,
+7,7,42,9869,
+15,26,31,9869,
+9,10,41,9869,
+1,30,31,9869,
+11,29,30,9869,
+14,21,35,9869,
+3,22,37,9869,
+2,3,43,9869,
+9,25,34,9869,
+13,18,37,9869,
+0,10,42,9869,
+6,8,42,9869,
+8,30,30,9869,
+11,12,40,9869,
+0,4,43,9869,
+10,26,33,9869,
+13,20,36,9869,
+3,16,40,9869,
+20,21,32,9886,
+8,24,35,9886,
+14,15,38,9886,
+1,10,42,9886,
+0,29,32,9886,
+15,22,34,9886,
+2,30,31,9886,
+17,26,30,9886,
+1,29,32,9886,
+1,4,43,9886,
+4,13,41,9886,
+4,25,35,9886,
+8,29,31,9886,
+11,28,31,9886,
+8,11,41,9886,
+20,25,29,9919,
+7,27,33,9919,
+11,15,39,9919,
+3,3,43,9919,
+2,10,42,9919,
+22,22,30,9921,
+10,18,38,9921,
+6,26,34,9921,
+5,20,38,9921,
+10,20,37,9921,
+2,4,43,9921,
+4,22,37,9921,
+19,22,32,9921,
+8,19,38,9921,
+13,16,38,9921,
+2,29,32,9921,
+13,26,32,9921,
+10,13,40,9921,
+5,9,42,9921,
+3,30,31,9921,
+5,18,39,9921,
+21,23,30,9942,
+4,16,40,9942,
+8,28,32,9942,
+0,24,36,9942,
+0,28,33,9942,
+3,10,42,9942,
+1,24,36,9942,
+18,18,35,9942,
+11,27,32,9942,
+8,17,39,9942,
+3,29,32,9942,
+12,19,37,9942,
+17,17,36,9942,
+7,12,41,9942,
+7,23,36,9942,
+15,25,32,9942,
+1,28,33,9942,
+8,21,37,9942,
+7,15,40,9942,
+16,23,33,9942,
+3,4,43,9942,
+19,27,28,9970,
+0,5,43,9970,
+11,23,35,9970,
+25,25,25,10002,
+17,19,35,10002,
+5,25,35,10002,
+17,25,31,10002,
+1,5,43,10002,
+5,13,41,10002,
+20,24,30,10002,
+12,24,34,10002,
+16,18,36,10002,
+2,24,36,10002,
+0,14,41,10002,
+12,17,38,10002,
+9,14,40,10002,
+18,23,32,10002,
+4,30,31,10002,
+2,28,33,10002,
+24,25,26,10019,
+7,8,42,10019,
+10,16,39,10019,
+19,19,34,10019,
+2,5,43,10019,
+19,26,29,10019,
+13,22,35,10019,
+5,22,37,10019,
+1,14,41,10019,
+14,29,29,10019,
+10,22,36,10019,
+18,20,34,10019,
+6,20,38,10019,
+4,10,42,10019,
+14,28,30,10019,
+12,21,36,10019,
+3,24,36,10019,
+6,9,42,10019,
+4,4,43,10019,
+23,26,26,10036,
+16,20,35,10036,
+10,25,34,10036,
+24,24,27,10036,
+5,16,40,10036,
+7,26,34,10036,
+2,14,41,10036,
+16,28,29,10036,
+6,18,39,10036,
+14,23,34,10036,
+4,29,32,10036,
+9,30,30,10036,
+16,16,37,10036,
+10,10,41,10036,
+0,19,39,10036,
+3,28,33,10036,
+8,27,33,10036,
+9,24,35,10036,
+15,19,36,10036,
+1,19,39,10036,
+9,11,41,10036,
+9,29,31,10036,
+13,25,33,10036,
+23,25,27,10053,
+15,17,37,10053,
+3,5,43,10053,
+0,11,42,10053,
+0,27,34,10053,
+0,21,38,10053,
+0,6,43,10053,
+16,27,30,10053,
+12,29,30,10053,
+17,21,34,10053,
+5,30,31,10053,
+11,26,33,10053,
+6,25,35,10053,
+13,14,39,10053,
+2,19,39,10053,
+3,14,41,10053,
+19,25,30,10053,
+6,13,41,10053,
+9,19,38,10053,
+1,27,34,10053,
+1,21,38,10053,
+21,22,31,10053,
+1,6,43,10053,
+1,11,42,10053,
+14,27,31,10053,
+12,12,40,10053,
+4,24,36,10053,
+22,26,27,10098,
+4,28,33,10098,
+9,28,32,10098,
+5,10,42,10098,
+8,23,36,10098,
+23,24,28,10098,
+11,18,38,10098,
+2,11,42,10098,
+2,27,34,10098,
+6,22,37,10098,
+12,28,31,10098,
+20,20,33,10098,
+0,17,40,10098,
+8,15,40,10098,
+17,24,32,10098,
+2,21,38,10098,
+8,12,41,10098,
+14,18,37,10098,
+2,6,43,10098,
+12,15,39,10098,
+20,23,31,10098,
+1,17,40,10098,
+15,24,33,10098,
+5,29,32,10098,
+4,5,43,10098,
+11,13,40,10098,
+11,20,37,10098,
+9,21,37,10098,
+9,17,39,10098,
+19,21,33,10098,
+15,21,35,10098,
+3,19,39,10098,
+18,28,28,10098,
+8,8,42,10098,
+6,16,40,10098,
+14,20,36,10098,
+16,26,31,10098,
+4,14,41,10098,
+22,25,28,10117,
+2,17,40,10117,
+7,20,38,10117,
+18,27,29,10117,
+3,27,34,10117,
+3,6,43,10117,
+7,9,42,10117,
+3,21,38,10117,
+3,11,42,10117,
+15,15,38,10117,
+7,18,39,10117,
+8,26,34,10117,
+14,26,32,10117,
+16,22,34,10117,
+10,14,40,10117,
+14,16,38,10117,
+12,27,32,10117,
+5,24,36,10117,
+18,22,33,10117,
+6,30,31,10117,
+0,23,37,10117,
+19,24,31,10125,
+0,7,43,10125,
+3,17,40,10125,
+5,28,33,10125,
+12,23,35,10125,
+11,16,39,10125,
+4,19,39,10125,
+7,25,35,10125,
+1,23,37,10125,
+23,23,29,10160,
+1,7,43,10160,
+7,13,41,10160,
+5,5,43,10160,
+13,19,37,10160,
+21,27,27,10160,
+9,27,33,10160,
+18,26,30,10160,
+6,10,42,10160,
+10,30,30,10160,
+0,26,35,10160,
+13,24,34,10160,
+21,26,28,10173,
+11,22,36,10173,
+22,24,29,10173,
+4,6,43,10173,
+4,21,38,10173,
+6,29,32,10173,
+4,11,42,10173,
+4,27,34,10173,
+10,24,35,10173,
+13,17,38,10173,
+11,25,34,10173,
+7,22,37,10173,
+2,23,37,10173,
+10,29,31,10173,
+1,26,35,10173,
+5,14,41,10173,
+2,7,43,10173,
+10,11,41,10173,
+16,25,32,10173,
+4,17,40,10173,
+14,22,35,10173,
+10,19,38,10173,
+2,26,35,10173,
+7,16,40,10173,
+13,21,36,10173,
+9,15,40,10173,
+9,12,41,10173,
+0,15,41,10173,
+21,21,32,10187,
+9,23,36,10187,
+3,7,43,10187,
+1,15,41,10187,
+15,29,29,10187,
+17,23,33,10187,
+21,25,29,10220,
+3,23,37,10220,
+5,19,39,10220,
+0,12,42,10220,
+20,22,32,10220,
+8,20,38,10220,
+6,24,36,10220,
+10,28,32,10220,
+12,26,33,10220,
+17,18,36,10220,
+8,9,42,10220,
+15,28,30,10220,
+1,12,42,10220,
+8,18,39,10220,
+6,28,33,10220,
+5,21,38,10220,
+5,6,43,10220,
+5,11,42,10220,
+15,23,34,10220,
+18,25,31,10220,
+14,25,33,10220,
+10,21,37,10220,
+2,15,41,10220,
+5,27,34,10220,
+13,29,30,10220,
+7,30,31,10220,
+18,19,35,10220,
+10,17,39,10220,
+3,26,35,10220,
+12,18,38,10220,
+2,12,42,10220,
+12,13,40,10220,
+20,27,28,10259,
+6,14,41,10259,
+12,20,37,10259,
+0,8,43,10259,
+16,19,36,10259,
+14,14,39,10259,
+7,10,42,10259,
+9,26,34,10259,
+22,23,30,10259,
+8,25,35,10259,
+4,7,43,10259,
+13,28,31,10259,
+19,23,32,10259,
+4,23,37,10259,
+17,20,35,10259,
+5,17,40,10259,
+8,13,41,10259,
+17,28,29,10259,
+1,8,43,10259,
+7,29,32,10259,
+16,17,37,10259,
+15,27,31,10259,
+3,15,41,10259,
+13,15,39,10259,
+2,8,43,10259,
+3,12,42,10259,
+11,14,40,10259,
+4,26,35,10259,
+19,20,34,10259,
+20,26,29,10290,
+21,24,30,10290,
+8,22,37,10290,
+15,18,37,10290,
+6,19,39,10290,
+17,27,30,10290,
+10,27,33,10290,
+8,16,40,10290,
+6,21,38,10290,
+0,25,36,10290,
+6,11,42,10290,
+15,20,36,10290,
+6,27,34,10290,
+18,21,34,10290,
+0,20,39,10290,
+12,16,39,10290,
+6,6,43,10290,
+16,24,33,10290,
+7,24,36,10290,
+11,30,30,10290,
+0,31,31,10290,
+4,15,41,10290,
+1,20,39,10290,
+3,8,43,10290,
+13,27,32,10290,
+16,21,35,10290,
+7,28,33,10290,
+11,24,35,10290,
+1,25,36,10290,
+13,23,35,10290,
+11,29,31,10290,
+5,7,43,10290,
+1,31,31,10290,
+5,23,37,10290,
+11,11,41,10290,
+0,30,32,10290,
+12,22,36,10290,
+4,12,42,10290,
+0,18,40,10290,
+18,24,32,10301,
+15,26,32,10301,
+12,25,34,10301,
+8,30,31,10301,
+10,15,40,10301,
+2,25,36,10301,
+1,30,32,10301,
+2,20,39,10301,
+15,16,38,10301,
+10,12,41,10301,
+1,18,40,10301,
+10,23,36,10301,
+9,20,38,10301,
+20,25,30,10328,
+6,17,40,10328,
+25,25,26,10355,
+7,14,41,10355,
+11,19,38,10355,
+9,9,42,10355,
+9,18,39,10355,
+14,19,37,10355,
+17,26,31,10355,
+2,31,31,10355,
+5,26,35,10355,
+2,18,40,10355,
+14,24,34,10355,
+2,30,32,10355,
+0,22,38,10355,
+24,26,26,10369,
+8,10,42,10369,
+14,17,38,10369,
+19,28,28,10369,
+8,29,32,10369,
+1,22,38,10369,
+4,8,43,10369,
+22,22,31,10369,
+17,22,34,10369,
+11,28,32,10369,
+3,20,39,10369,
+0,29,33,10369,
+20,21,33,10369,
+24,25,27,10398,
+3,25,36,10398,
+0,9,43,10398,
+21,23,31,10398,
+11,17,39,10398,
+19,27,29,10398,
+5,15,41,10398,
+11,21,37,10398,
+1,9,43,10398,
+7,19,39,10398,
+1,29,33,10398,
+3,31,31,10398,
+9,25,35,10398,
+9,13,41,10398,
+2,22,38,10398,
+10,26,34,10398,
+3,30,32,10398,
+3,18,40,10398,
+14,21,36,10398,
+0,13,42,10398,
+5,12,42,10398,
+7,11,42,10398,
+23,26,27,10428,
+7,21,38,10428,
+19,22,33,10428,
+15,22,35,10428,
+1,13,42,10428,
+9,22,37,10428,
+6,7,43,10428,
+2,9,43,10428,
+2,29,33,10428,
+7,27,34,10428,
+13,26,33,10428,
+6,23,37,10428,
+24,24,28,10437,
+8,24,36,10437,
+0,0,44,10437,
+20,24,31,10437,
+4,25,36,10437,
+9,16,40,10437,
+4,20,39,10437,
+14,29,30,10437,
+3,22,38,10437,
+6,26,35,10437,
+8,28,33,10437,
+0,16,41,10437,
+0,1,44,10437,
+13,18,38,10437,
+2,13,42,10437,
+19,26,30,10437,
+13,13,40,10437,
+1,1,44,10437,
+13,20,37,10437,
+17,25,32,10437,
+5,8,43,10437,
+1,16,41,10437,
+4,31,31,10437,
+7,17,40,10437,
+23,25,28,10455,
+16,29,29,10455,
+15,25,33,10455,
+3,9,43,10455,
+11,27,33,10455,
+3,29,33,10455,
+4,30,32,10455,
+16,28,30,10455,
+0,2,44,10455,
+4,18,40,10455,
+0,28,34,10455,
+12,14,40,10455,
+14,28,31,10455,
+1,2,44,10455,
+8,14,41,10455,
+1,28,34,10455,
+2,16,41,10455,
+16,23,34,10455,
+6,15,41,10455,
+9,30,31,10455,
+14,15,39,10455,
+3,13,42,10455,
+22,27,27,10472,
+18,23,33,10472,
+12,30,30,10472,
+2,28,34,10472,
+4,22,38,10472,
+18,18,36,10472,
+2,2,44,10472,
+22,26,28,10488,
+10,20,38,10488,
+6,12,42,10488,
+9,10,42,10488,
+0,3,44,10488,
+0,24,37,10488,
+12,24,35,10488,
+10,18,39,10488,
+3,16,41,10488,
+5,20,39,10488,
+8,19,39,10488,
+1,24,37,10488,
+9,29,32,10488,
+17,19,36,10488,
+1,3,44,10488,
+16,27,31,10488,
+13,16,39,10488,
+23,24,29,10512,
+12,29,31,10512,
+4,29,33,10512,
+4,9,43,10512,
+11,12,41,10512,
+11,15,40,10512,
+5,25,36,10512,
+11,23,36,10512,
+7,23,37,10512,
+17,17,37,10512,
+7,7,43,10512,
+19,25,31,10512,
+5,31,31,10512,
+19,19,35,10512,
+14,27,32,10512,
+2,24,37,10512,
+8,11,42,10512,
+5,18,40,10512,
+18,20,35,10512,
+4,13,42,10512,
+8,21,38,10512,
+0,10,43,10512,
+3,28,34,10512,
+21,22,32,10512,
+12,19,38,10512,
+8,27,34,10512,
+2,3,44,10512,
+6,8,43,10512,
+13,22,36,10512,
+18,28,29,10512,
+5,30,32,10512,
+16,18,37,10512,
+13,25,34,10512,
+1,10,43,10512,
+7,26,35,10512,
+10,25,35,10512,
+22,25,29,10537,
+14,23,35,10537,
+10,13,41,10537,
+12,28,32,10537,
+16,20,36,10537,
+0,4,44,10537,
+11,26,34,10537,
+1,4,44,10537,
+2,10,43,10537,
+8,17,40,10537,
+5,22,38,10537,
+9,24,36,10537,
+4,16,41,10537,
+10,22,37,10537,
+18,27,30,10537,
+20,23,32,10537,
+9,28,33,10537,
+12,21,37,10537,
+3,3,44,10537,
+0,27,35,10537,
+12,17,39,10537,
+17,24,33,10537,
+3,24,37,10537,
+21,27,28,10558,
+5,29,33,10558,
+5,9,43,10558,
+1,27,35,10558,
+15,19,37,10558,
+17,21,35,10558,
+7,15,41,10558,
+16,26,32,10558,
+20,20,34,10558,
+2,4,44,10558,
+4,28,34,10558,
+10,16,40,10558,
+16,16,38,10558,
+6,25,36,10558,
+6,20,39,10558,
+7,12,42,10558,
+15,24,34,10558,
+21,26,29,10587,
+23,23,30,10587,
+9,14,41,10587,
+3,10,43,10587,
+6,31,31,10587,
+19,21,34,10587,
+5,13,42,10587,
+15,17,38,10587,
+2,27,35,10587,
+6,18,40,10587,
+0,14,42,10587,
+22,24,30,10601,
+6,30,32,10601,
+0,5,44,10601,
+4,24,37,10601,
+14,26,33,10601,
+1,14,42,10601,
+3,4,44,10601,
+0,19,40,10601,
+18,26,31,10601,
+10,30,31,10601,
+19,24,32,10601,
+8,23,37,10601,
+1,5,44,10601,
+15,21,36,10601,
+7,8,43,10601,
+1,19,40,10601,
+12,27,33,10601,
+0,21,39,10601,
+5,16,41,10601,
+3,27,35,10601,
+1,21,39,10601,
+9,19,39,10601,
+10,10,42,10601,
+6,22,38,10601,
+2,14,42,10601,
+14,18,38,10601,
+18,22,34,10601,
+8,26,35,10601,
+13,14,40,10601,
+14,20,37,10601,
+2,19,40,10601,
+11,20,38,10601,
+2,5,44,10601,
+5,28,34,10601,
+10,29,32,10601,
+16,22,35,10601,
+4,10,43,10601,
+2,21,39,10601,
+6,9,43,10601,
+6,29,33,10601,
+9,11,42,10601,
+9,21,38,10601,
+21,25,30,10633,
+15,29,30,10633,
+9,27,34,10633,
+11,18,39,10633,
+20,28,28,10640,
+4,4,44,10640,
+12,12,41,10640,
+3,14,42,10640,
+12,15,40,10640,
+13,30,30,10640,
+12,23,36,10640,
+6,13,42,10640,
+7,20,39,10640,
+3,5,44,10640,
+20,27,29,10668,
+5,24,37,10668,
+3,19,40,10668,
+8,15,41,10668,
+0,17,41,10668,
+0,11,43,10668,
+15,28,31,10668,
+4,27,35,10668,
+7,25,36,10668,
+16,25,33,10668,
+9,17,40,10668,
+13,24,35,10668,
+17,29,29,10668,
+7,31,31,10668,
+13,29,31,10668,
+15,15,39,10668,
+11,13,41,10668,
+1,17,41,10668,
+1,11,43,10668,
+21,21,33,10668,
+11,25,35,10668,
+3,21,39,10668,
+0,6,44,10668,
+10,24,36,10668,
+8,12,42,10668,
+0,26,36,10668,
+6,16,41,10668,
+7,30,32,10668,
+10,28,33,10668,
+18,25,32,10668,
+7,18,40,10668,
+1,6,44,10668,
+0,23,38,10668,
+1,26,36,10668,
+14,16,39,10668,
+17,28,30,10668,
+20,22,33,10668,
+22,23,31,10682,
+2,11,43,10682,
+2,17,41,10682,
+11,22,37,10682,
+1,23,38,10682,
+13,19,38,10682,
+5,10,43,10682,
+17,23,34,10682,
+12,26,34,10682,
+2,6,44,10682,
+2,26,36,10682,
+14,22,36,10682,
+4,14,42,10682,
+6,28,34,10682,
+20,26,30,10695,
+13,28,32,10695,
+14,25,34,10695,
+10,14,41,10695,
+11,16,40,10695,
+2,23,38,10695,
+7,22,38,10695,
+25,26,26,10733,
+8,8,43,10733,
+4,5,44,10733,
+4,19,40,10733,
+4,21,39,10733,
+15,27,32,10733,
+21,24,31,10733,
+3,17,41,10733,
+15,23,35,10733,
+7,9,43,10733,
+13,21,37,10733,
+3,11,43,10733,
+9,23,37,10733,
+17,27,31,10733,
+7,29,33,10733,
+13,17,39,10733,
+25,25,27,10748,
+19,23,33,10748,
+5,27,35,10748,
+24,26,27,10760,
+6,24,37,10760,
+18,19,36,10760,
+3,26,36,10760,
+3,6,44,10760,
+3,23,38,10760,
+17,18,37,10760,
+11,30,31,10760,
+9,26,35,10760,
+7,13,42,10760,
+10,19,39,10760,
+6,10,43,10760,
+10,27,34,10760,
+24,25,28,10773,
+17,20,36,10773,
+10,21,38,10773,
+0,7,44,10773,
+8,25,36,10773,
+5,14,42,10773,
+0,31,32,10773,
+10,11,42,10773,
+8,20,39,10773,
+4,17,41,10773,
+1,31,32,10773,
+19,20,35,10773,
+16,19,37,10773,
+8,31,31,10773,
+5,19,40,10773,
+5,5,44,10773,
+11,29,32,10773,
+4,11,43,10773,
+20,25,31,10773,
+19,28,29,10773,
+1,7,44,10773,
+7,16,41,10773,
+9,15,41,10773,
+5,21,39,10773,
+13,27,33,10773,
+23,27,27,10795,
+8,30,32,10795,
+16,24,34,10795,
+4,26,36,10795,
+8,18,40,10795,
+12,20,38,10795,
+4,6,44,10795,
+10,17,40,10795,
+4,23,38,10795,
+2,7,44,10795,
+7,28,34,10795,
+16,17,38,10795,
+23,26,28,10815,
+17,26,32,10815,
+12,18,39,10815,
+2,31,32,10815,
+18,24,33,10815,
+0,15,42,10815,
+0,30,33,10815,
+9,12,42,10815,
+15,26,33,10815,
+19,27,30,10815,
+1,15,42,10815,
+6,27,35,10815,
+1,30,33,10815,
+18,21,35,10815,
+22,22,32,10815,
+8,22,38,10815,
+14,14,40,10815,
+11,24,36,10815,
+0,12,43,10815,
+24,24,29,10843,
+2,30,33,10843,
+16,21,36,10843,
+2,15,42,10843,
+15,18,38,10843,
+21,23,32,10843,
+8,9,43,10843,
+15,20,37,10843,
+13,15,40,10843,
+13,23,36,10843,
+3,7,44,10843,
+12,25,35,10843,
+3,31,32,10843,
+1,12,43,10843,
+7,24,37,10843,
+12,13,41,10843,
+8,29,33,10843,
+0,25,37,10843,
+11,28,33,10843,
+23,25,29,10860,
+1,25,37,10860,
+5,17,41,10860,
+5,11,43,10860,
+14,30,30,10860,
+6,14,42,10860,
+20,21,34,10860,
+5,26,36,10860,
+16,29,30,10860,
+14,24,35,10860,
+0,29,34,10860,
+22,27,28,10871,
+5,6,44,10871,
+6,19,40,10871,
+2,12,43,10871,
+12,22,37,10871,
+8,13,42,10871,
+17,22,35,10871,
+14,29,31,10871,
+19,26,31,10871,
+6,21,39,10871,
+3,30,33,10871,
+11,14,41,10871,
+7,10,43,10871,
+3,15,42,10871,
+5,23,38,10871,
+10,23,37,10871,
+1,29,34,10871,
+2,25,37,10871,
+12,16,40,10871,
+20,24,32,10871,
+0,20,40,10871,
+0,8,44,10871,
+10,26,35,10871,
+13,26,34,10871,
+4,31,32,10871,
+22,26,29,10899,
+1,20,40,10899,
+4,7,44,10899,
+19,22,34,10899,
+16,28,31,10899,
+2,29,34,10899,
+8,16,41,10899,
+1,8,44,10899,
+14,19,38,10899,
+15,16,39,10899,
+9,20,39,10899,
+9,25,36,10899,
+3,12,43,10899,
+11,19,39,10899,
+3,25,37,10899,
+7,27,35,10899,
+9,31,31,10899,
+17,25,33,10899,
+8,28,34,10899,
+2,8,44,10899,
+2,20,40,10899,
+14,28,32,10899,
+0,22,39,10899,
+23,24,30,10927,
+12,30,31,10927,
+4,15,42,10927,
+4,30,33,10927,
+0,18,41,10927,
+15,22,36,10927,
+9,30,32,10927,
+9,18,40,10927,
+1,18,41,10927,
+6,11,43,10927,
+14,17,39,10927,
+11,27,34,10927,
+11,11,42,10927,
+6,17,41,10927,
+11,21,38,10927,
+14,21,37,10927,
+15,25,34,10927,
+18,29,29,10927,
+10,15,41,10927,
+1,22,39,10927,
+3,29,34,10927,
+6,6,44,10927,
+18,28,30,10927,
+6,26,36,10927,
+10,12,42,10927,
+6,23,38,10927,
+3,20,40,10927,
+16,27,32,10927,
+4,12,43,10927,
+2,18,41,10927,
+2,22,39,10927,
+0,28,35,10927,
+22,25,30,10948,
+12,29,32,10948,
+8,24,37,10948,
+21,28,28,10948,
+7,14,42,10948,
+9,22,38,10948,
+3,8,44,10948,
+18,23,34,10948,
+4,25,37,10948,
+11,17,40,10948,
+5,31,32,10948,
+5,7,44,10948,
+7,19,40,10948,
+19,25,32,10948,
+1,28,35,10948,
+16,23,35,10948,
+7,21,39,10948,
+9,29,33,10948,
+21,27,29,10974,
+9,9,43,10974,
+2,28,35,10974,
+8,10,43,10974,
+4,29,34,10974,
+13,20,38,10974,
+21,22,33,10974,
+13,18,39,10974,
+14,27,33,10974,
+3,22,39,10974,
+5,15,42,10974,
+18,27,31,10974,
+3,18,41,10974,
+9,13,42,10974,
+5,30,33,10974,
+12,24,36,10974,
+4,20,40,10974,
+4,8,44,10974,
+0,9,44,10974,
+18,18,37,10974,
+21,26,30,11009,
+12,28,33,11009,
+19,19,36,11009,
+20,23,33,11009,
+9,16,41,11009,
+3,28,35,11009,
+1,9,44,11009,
+5,12,43,11009,
+0,13,43,11009,
+8,27,35,11009,
+13,25,35,11009,
+11,23,37,11009,
+1,13,43,11009,
+13,13,41,11009,
+17,19,37,11009,
+7,17,41,11009,
+23,23,31,11025,
+7,11,43,11025,
+5,25,37,11025,
+18,20,36,11025,
+0,24,38,11025,
+0,16,42,11025,
+7,26,36,11025,
+16,26,33,11025,
+10,25,36,11025,
+12,14,41,11025,
+6,31,32,11025,
+14,23,36,11025,
+1,16,42,11025,
+10,20,39,11025,
+1,24,38,11025,
+17,24,34,11025,
+4,18,41,11025,
+2,9,44,11025,
+6,7,44,11025,
+14,15,40,11025,
+4,22,39,11025,
+22,24,31,11040,
+9,28,34,11040,
+5,29,34,11040,
+17,17,38,11040,
+10,31,31,11040,
+13,22,37,11040,
+2,13,43,11040,
+11,26,35,11040,
+7,23,38,11040,
+8,14,42,11040,
+16,18,38,11040,
+2,16,42,11040,
+10,18,40,11040,
+10,30,32,11040,
+2,24,38,11040,
+18,26,32,11040,
+5,8,44,11040,
+0,0,45,11040,
+15,30,30,11040,
+5,20,40,11040,
+20,20,35,11040,
+4,28,35,11040,
+16,20,37,11040,
+6,15,42,11040,
+8,19,40,11040,
+20,28,29,11070,
+6,30,33,11070,
+0,27,36,11070,
+13,16,40,11070,
+19,24,33,11070,
+0,1,45,11070,
+17,21,36,11070,
+3,9,44,11070,
+15,24,35,11070,
+8,21,39,11070,
+1,27,36,11070,
+9,24,37,11070,
+12,19,39,11070,
+11,15,41,11070,
+19,21,35,11070,
+21,25,31,11079,
+1,1,45,11079,
+15,29,31,11079,
+3,13,43,11079,
+10,22,38,11079,
+14,26,34,11079,
+26,26,26,11109,
+3,24,38,11109,
+0,2,45,11109,
+12,21,38,11109,
+12,27,34,11109,
+11,12,42,11109,
+3,16,42,11109,
+6,12,43,11109,
+20,27,30,11109,
+2,27,36,11109,
+5,22,39,11109,
+13,30,31,11109,
+1,2,45,11109,
+6,25,37,11109,
+9,10,43,11109,
+5,18,41,11109,
+10,29,33,11109,
+15,19,38,11109,
+17,29,30,11109,
+25,26,27,11129,
+16,16,39,11129,
+4,9,44,11129,
+2,2,45,11129,
+12,17,40,11129,
+10,13,42,11129,
+18,22,35,11129,
+6,29,34,11129,
+15,28,32,11129,
+3,27,36,11129,
+8,11,43,11129,
+5,28,35,11129,
+17,28,31,11129,
+13,29,32,11129,
+0,3,45,11129,
+25,25,28,11159,
+7,31,32,11159,
+24,27,27,11159,
+4,13,43,11159,
+7,7,44,11159,
+8,17,41,11159,
+15,17,39,11159,
+1,3,45,11159,
+9,27,35,11159,
+15,21,37,11159,
+4,24,38,11159,
+24,26,28,11164,
+8,26,36,11164,
+4,16,42,11164,
+16,22,36,11164,
+6,20,40,11164,
+6,8,44,11164,
+0,10,44,11164,
+1,10,44,11164,
+8,23,38,11164,
+22,23,32,11164,
+10,16,41,11164,
+20,26,31,11164,
+16,25,34,11164,
+21,21,34,11164,
+7,15,42,11164,
+7,30,33,11164,
+18,25,33,11164,
+2,3,45,11164,
+2,10,44,11164,
+20,22,34,11164,
+10,28,34,11164,
+14,20,38,11164,
+6,18,41,11164,
+13,24,36,11164,
+21,24,32,11174,
+9,14,42,11174,
+0,4,45,11174,
+4,27,36,11174,
+0,21,40,11174,
+14,18,39,11174,
+6,22,39,11174,
+23,27,28,11208,
+0,19,41,11208,
+24,25,29,11208,
+7,12,43,11208,
+17,27,32,11208,
+11,20,39,11208,
+13,28,33,11208,
+5,9,44,11208,
+11,25,36,11208,
+9,19,40,11208,
+12,23,37,11208,
+1,4,45,11208,
+1,21,40,11208,
+3,3,45,11208,
+19,29,29,11208,
+17,23,35,11208,
+9,21,39,11208,
+15,27,33,11208,
+11,31,31,11208,
+5,13,43,11208,
+1,19,41,11208,
+7,25,37,11208,
+3,10,44,11208,
+2,4,45,11208,
+5,16,42,11208,
+2,21,40,11208,
+11,18,40,11208,
+11,30,32,11208,
+0,26,37,11208,
+10,24,37,11208,
+19,28,30,11208,
+5,24,38,11208,
+12,26,35,11208,
+0,14,43,11208,
+6,28,35,11208,
+1,14,43,11208,
+2,19,41,11208,
+23,26,29,11233,
+1,26,37,11233,
+19,23,34,11233,
+14,25,35,11233,
+13,14,41,11233,
+7,29,34,11233,
+0,32,32,11233,
+2,26,37,11233,
+11,22,38,11233,
+2,14,43,11233,
+14,22,37,11233,
+8,31,32,11233,
+20,25,32,11233,
+7,20,40,11233,
+10,10,43,11233,
+7,8,44,11233,
+1,32,32,11233,
+0,31,33,11233,
+3,21,40,11233,
+15,15,40,11233,
+0,23,39,11233,
+12,15,41,11233,
+3,4,45,11233,
+0,5,45,11233,
+15,23,36,11233,
+5,27,36,11233,
+9,17,41,11233,
+13,19,39,11233,
+1,23,39,11233,
+19,27,31,11240,
+9,11,43,11240,
+1,31,33,11240,
+11,29,33,11240,
+1,5,45,11240,
+3,19,41,11240,
+22,28,28,11269,
+24,24,30,11269,
+2,32,32,11269,
+14,16,40,11269,
+12,12,42,11269,
+4,10,44,11269,
+9,26,36,11269,
+6,9,44,11269,
+8,30,33,11269,
+8,15,42,11269,
+0,17,42,11269,
+18,19,37,11269,
+13,27,34,11269,
+6,13,43,11269,
+2,31,33,11269,
+3,14,43,11269,
+9,23,38,11269,
+17,26,33,11269,
+2,23,39,11269,
+3,26,37,11269,
+7,22,39,11269,
+1,17,42,11269,
+2,5,45,11269,
+11,13,42,11269,
+22,27,29,11290,
+7,18,41,11290,
+10,27,35,11290,
+13,21,38,11290,
+23,25,30,11290,
+16,30,30,11290,
+0,30,34,11290,
+6,16,42,11290,
+18,24,34,11290,
+6,24,38,11290,
+19,20,36,11290,
+1,30,34,11290,
+0,11,44,11290,
+4,4,45,11290,
+3,32,32,11290,
+4,21,40,11290,
+15,26,34,11290,
+17,18,38,11290,
+16,24,35,11290,
+14,30,31,11290,
+2,17,42,11290,
+8,12,43,11290,
+22,22,33,11290,
+16,29,31,11290,
+1,11,44,11290,
+8,25,37,11290,
+13,17,40,11290,
+7,28,35,11290,
+4,19,41,11290,
+11,16,41,11290,
+17,20,37,11290,
+3,23,39,11290,
+3,5,45,11290,
+3,31,33,11290,
+21,23,33,11298,
+2,30,34,11298,
+10,14,42,11298,
+22,26,30,11321,
+14,29,32,11321,
+2,11,44,11321,
+11,28,34,11321,
+10,19,40,11321,
+18,21,36,11321,
+16,19,38,11321,
+4,14,43,11321,
+6,27,36,11321,
+5,10,44,11321,
+8,29,34,11321,
+19,26,32,11321,
+4,26,37,11321,
+0,6,45,11321,
+3,17,42,11321,
+1,6,45,11321,
+10,21,39,11321,
+8,8,44,11321,
+8,20,40,11321,
+4,32,32,11321,
+16,28,32,11321,
+12,20,39,11321,
+12,25,36,11321,
+2,6,45,11321,
+20,24,33,11332,
+3,30,34,11332,
+18,29,30,11332,
+20,21,35,11332,
+23,24,31,11371,
+7,9,44,11371,
+16,17,39,11371,
+4,31,33,11371,
+21,28,29,11371,
+5,21,40,11371,
+16,21,37,11371,
+0,29,35,11371,
+3,11,44,11371,
+4,23,39,11371,
+12,31,31,11371,
+4,5,45,11371,
+9,31,32,11371,
+11,24,37,11371,
+7,13,43,11371,
+1,29,35,11371,
+5,19,41,11371,
+13,23,37,11371,
+12,30,32,11371,
+12,18,40,11371,
+14,24,36,11371,
+14,28,33,11371,
+0,25,38,11371,
+7,24,38,11371,
+18,28,31,11371,
+8,22,39,11371,
+17,22,36,11371,
+7,16,42,11371,
+15,20,38,11371,
+8,18,41,11371,
+4,17,42,11371,
+2,29,35,11371,
+1,25,38,11371,
+21,27,30,11404,
+5,26,37,11404,
+17,25,34,11404,
+10,11,43,11404,
+5,14,43,11404,
+22,25,31,11404,
+15,18,39,11404,
+10,17,41,11404,
+9,15,42,11404,
+9,30,33,11404,
+3,6,45,11404,
+19,22,35,11404,
+13,26,35,11404,
+6,10,44,11404,
+12,22,38,11404,
+4,30,34,11404,
+10,26,36,11404,
+5,32,32,11404,
+8,28,35,11404,
+10,23,38,11404,
+4,11,44,11404,
+14,14,41,11404,
+2,25,38,11404,
+16,27,33,11404,
+0,15,43,11404,
+7,27,36,11404,
+0,7,45,11404,
+12,29,33,11404,
+9,12,43,11404,
+5,5,45,11404,
+9,25,37,11404,
+1,7,45,11404,
+3,29,35,11404,
+19,25,33,11408,
+5,31,33,11408,
+1,15,43,11408,
+15,25,35,11408,
+11,27,35,11408,
+13,15,41,11408,
+5,23,39,11408,
+6,21,40,11408,
+12,13,42,11408,
+4,6,45,11408,
+18,27,32,11416,
+2,15,43,11416,
+21,26,31,11444,
+18,23,35,11444,
+2,7,45,11444,
+6,19,41,11444,
+9,29,34,11444,
+5,17,42,11444,
+3,25,38,11444,
+15,22,37,11444,
+14,19,39,11444,
+0,12,44,11444,
+0,28,36,11444,
+14,21,38,11444,
+8,9,44,11444,
+21,22,34,11444,
+5,30,34,11444,
+14,27,34,11444,
+1,12,44,11444,
+15,16,40,11444,
+0,20,41,11444,
+12,16,41,11444,
+26,26,27,11502,
+9,20,40,11502,
+6,14,43,11502,
+6,26,37,11502,
+1,28,36,11502,
+11,14,42,11502,
+16,23,36,11502,
+11,19,40,11502,
+1,20,41,11502,
+4,29,35,11502,
+8,13,43,11502,
+5,11,44,11502,
+23,23,32,11502,
+20,29,29,11502,
+3,7,45,11502,
+11,21,39,11502,
+3,15,43,11502,
+25,27,27,11519,
+12,28,34,11519,
+6,32,32,11519,
+8,24,38,11519,
+8,16,42,11519,
+22,24,32,11519,
+0,22,40,11519,
+20,28,30,11519,
+2,12,44,11519,
+2,28,36,11519,
+10,31,32,11519,
+25,26,28,11529,
+7,10,44,11529,
+1,22,40,11529,
+14,17,40,11529,
+2,20,41,11529,
+20,23,34,11529,
+4,25,38,11529,
+6,31,33,11529,
+6,23,39,11529,
+9,18,41,11529,
+9,22,39,11529,
+5,6,45,11529,
+15,30,31,11529,
+16,26,34,11529,
+0,18,42,11529,
+2,22,40,11529,
+8,27,36,11529,
+17,30,30,11529,
+10,30,33,11529,
+10,15,42,11529,
+18,26,33,11529,
+1,18,42,11529,
+12,24,37,11529,
+24,27,28,11557,
+0,8,45,11557,
+3,12,44,11557,
+3,28,36,11557,
+6,17,42,11557,
+7,21,40,11557,
+15,29,32,11557,
+13,25,36,11557,
+21,25,32,11557,
+4,15,43,11557,
+17,24,35,11557,
+4,7,45,11557,
+20,27,31,11557,
+1,8,45,11557,
+13,20,39,11557,
+3,20,41,11557,
+9,28,35,11557,
+5,29,35,11557,
+17,29,31,11557,
+19,19,37,11557,
+11,17,41,11557,
+13,31,31,11557,
+25,25,29,11568,
+11,11,43,11568,
+7,19,41,11568,
+2,18,42,11568,
+6,30,34,11568,
+18,18,38,11568,
+11,26,36,11568,
+24,26,29,11592,
+13,18,40,11592,
+10,12,43,11592,
+3,22,40,11592,
+19,24,34,11592,
+13,30,32,11592,
+18,20,37,11592,
+6,11,44,11592,
+2,8,45,11592,
+7,14,43,11592,
+17,19,38,11592,
+11,23,38,11592,
+10,25,37,11592,
+14,23,37,11592,
+5,25,38,11592,
+7,26,37,11592,
+4,28,36,11592,
+4,12,44,11592,
+20,20,36,11592,
+14,26,35,11592,
+6,6,45,11592,
+0,24,39,11592,
+15,24,36,11592,
+3,18,42,11592,
+10,29,34,11592,
+13,22,38,11592,
+4,20,41,11592,
+23,28,28,11609,
+7,32,32,11609,
+17,28,32,11609,
+1,24,39,11609,
+15,28,33,11609,
+3,8,45,11609,
+0,27,37,11609,
+19,21,36,11609,
+9,9,44,11609,
+12,27,35,11609,
+13,29,33,11609,
+5,15,43,11609,
+7,31,33,11609,
+5,7,45,11609,
+17,17,39,11609,
+17,21,37,11609,
+1,27,37,11609,
+7,23,39,11609,
+9,13,43,11609,
+23,27,29,11631,
+4,22,40,11631,
+20,26,32,11631,
+8,10,44,11631,
+16,20,38,11631,
+10,20,40,11631,
+2,24,39,11631,
+16,18,39,11631,
+9,24,38,11631,
+9,16,42,11631,
+24,25,30,11645,
+19,29,30,11645,
+2,27,37,11645,
+13,13,42,11645,
+22,23,33,11645,
+7,17,42,11645,
+14,15,41,11645,
+6,29,35,11645,
+12,14,42,11645,
+4,18,42,11645,
+18,22,36,11645,
+7,30,34,11645,
+5,28,36,11645,
+10,18,41,11645,
+10,22,39,11645,
+4,8,45,11645,
+8,21,40,11645,
+0,16,43,11645,
+5,12,44,11645,
+6,25,38,11645,
+23,26,30,11666,
+18,25,34,11666,
+0,13,44,11666,
+12,19,40,11666,
+11,31,32,11666,
+1,16,43,11666,
+3,24,39,11666,
+13,16,41,11666,
+12,21,39,11666,
+19,28,31,11666,
+0,9,45,11666,
+16,25,35,11666,
+7,11,44,11666,
+8,19,41,11666,
+21,24,33,11666,
+9,27,36,11666,
+1,13,44,11666,
+5,20,41,11666,
+17,27,33,11666,
+15,19,39,11666,
+3,27,37,11666,
+21,21,35,11666,
+1,9,45,11666,
+20,22,35,11666,
+2,16,43,11666,
+16,22,37,11666,
+8,14,43,11666,
+8,26,37,11666,
+2,13,44,11666,
+10,28,35,11666,
+22,28,29,11695,
+5,22,40,11695,
+13,28,34,11695,
+15,27,34,11695,
+2,9,45,11695,
+11,15,42,11695,
+6,15,43,11695,
+6,7,45,11695,
+11,30,33,11695,
+15,21,38,11695,
+8,32,32,11695,
+16,16,40,11695,
+0,32,33,11695,
+24,24,31,11726,
+5,18,42,11726,
+4,24,39,11726,
+22,27,30,11726,
+8,23,39,11726,
+5,8,45,11726,
+19,27,32,11726,
+12,17,41,11726,
+13,24,37,11726,
+17,23,36,11726,
+3,13,44,11726,
+3,16,43,11726,
+20,25,33,11726,
+1,32,33,11726,
+11,12,43,11726,
+8,31,33,11726,
+15,17,40,11726,
+4,27,37,11726,
+23,25,31,11737,
+19,23,35,11737,
+7,29,35,11737,
+3,9,45,11737,
+11,25,37,11737,
+0,0,46,11737,
+6,28,36,11737,
+6,12,44,11737,
+12,26,36,11737,
+9,10,44,11737,
+2,32,33,11737,
+0,31,34,11737,
+0,1,46,11737,
+12,23,38,11737,
+14,20,39,11737,
+6,20,41,11737,
+8,17,42,11737,
+16,30,31,11737,
+14,25,36,11737,
+7,25,38,11737,
+10,13,43,11737,
+1,1,46,11737,
+11,29,34,11737,
+14,31,31,11737,
+1,31,34,11737,
+0,26,38,11737,
+14,30,32,11737,
+8,30,34,11737,
+10,24,38,11737,
+0,2,46,11737,
+14,18,40,11737,
+6,22,40,11737,
+10,16,42,11737,
+22,26,31,11772,
+4,16,43,11772,
+11,20,40,11772,
+16,29,32,11772,
+1,26,38,11772,
+1,2,46,11772,
+8,11,44,11772,
+17,26,34,11772,
+4,13,44,11772,
+2,31,34,11772,
+9,21,40,11772,
+4,9,45,11772,
+0,21,41,11772,
+5,24,39,11772,
+3,32,33,11772,
+7,15,43,11772,
+7,7,45,11772,
+5,27,37,11772,
+21,29,29,11795,
+13,27,35,11795,
+1,21,41,11795,
+15,23,37,11795,
+9,19,41,11795,
+2,26,38,11795,
+22,22,34,11795,
+18,30,30,11795,
+14,22,38,11795,
+2,2,46,11795,
+6,18,42,11795,
+0,19,42,11795,
+18,24,35,11795,
+21,28,30,11811,
+0,3,46,11811,
+0,30,35,11811,
+10,27,36,11811,
+0,10,45,11811,
+6,8,45,11811,
+1,3,46,11811,
+11,22,39,11811,
+21,23,34,11811,
+14,29,33,11811,
+1,19,42,11811,
+2,21,41,11811,
+1,30,35,11811,
+11,18,41,11811,
+9,14,43,11811,
+18,29,31,11811,
+1,10,45,11811,
+19,26,33,11811,
+9,26,37,11811,
+3,31,34,11811,
+15,26,35,11811,
+16,24,36,11811,
+12,31,32,11811,
+2,3,46,11811,
+16,28,33,11811,
+7,12,44,11811,
+23,24,32,11837,
+2,10,45,11837,
+2,30,35,11837,
+3,26,38,11837,
+9,32,32,11837,
+0,23,40,11837,
+2,19,42,11837,
+13,14,42,11837,
+18,19,38,11837,
+4,32,33,11837,
+7,28,36,11837,
+19,20,37,11837,
+13,19,40,11837,
+8,29,35,11837,
+1,23,40,11837,
+11,28,35,11837,
+7,20,41,11837,
+5,13,44,11837,
+5,16,43,11837,
+21,27,31,11852,
+13,21,39,11852,
+9,31,33,11852,
+3,21,41,11852,
+5,9,45,11852,
+15,15,41,11852,
+9,23,39,11852,
+18,28,32,11852,
+20,24,34,11852,
+0,4,46,11852,
+0,14,44,11852,
+4,31,34,11852,
+14,16,41,11852,
+6,24,39,11852,
+12,30,33,11852,
+17,20,38,11852,
+7,22,40,11852,
+2,23,40,11852,
+1,14,44,11852,
+22,25,32,11861,
+8,25,38,11861,
+1,4,46,11861,
+12,15,42,11861,
+9,17,42,11861,
+3,3,46,11861,
+6,27,37,11861,
+18,21,37,11861,
+26,27,27,11898,
+17,18,39,11898,
+3,10,45,11898,
+3,19,42,11898,
+3,30,35,11898,
+4,26,38,11898,
+2,14,44,11898,
+2,4,46,11898,
+26,26,28,11906,
+10,10,44,11906,
+14,28,34,11906,
+20,21,36,11906,
+9,30,34,11906,
+12,12,43,11906,
+0,29,36,11906,
+7,18,42,11906,
+9,11,44,11906,
+0,17,43,11906,
+5,32,33,11906,
+7,8,45,11906,
+25,27,28,11927,
+4,21,41,11927,
+8,15,43,11927,
+1,29,36,11927,
+16,19,39,11927,
+12,25,37,11927,
+3,23,40,11927,
+1,17,43,11927,
+13,17,41,11927,
+17,25,35,11927,
+11,13,43,11927,
+4,19,42,11927,
+13,26,36,11927,
+3,4,46,11927,
+2,29,36,11927,
+11,16,42,11927,
+3,14,44,11927,
+14,24,37,11927,
+16,21,38,11927,
+21,26,32,11927,
+12,29,34,11927,
+16,27,34,11927,
+4,10,45,11927,
+6,13,44,11927,
+6,16,43,11927,
+19,22,36,11927,
+11,24,38,11927,
+10,21,40,11927,
+20,29,30,11927,
+4,30,35,11927,
+0,5,46,11927,
+25,26,29,11956,
+18,27,33,11956,
+10,19,41,11956,
+1,5,46,11956,
+19,25,34,11956,
+13,23,38,11956,
+2,17,43,11956,
+6,9,45,11956,
+17,22,37,11956,
+5,31,34,11956,
+8,12,44,11956,
+24,28,28,11968,
+12,20,40,11968,
+8,28,36,11968,
+20,28,31,11968,
+8,20,41,11968,
+4,23,40,11968,
+2,5,46,11968,
+5,26,38,11968,
+10,26,37,11968,
+10,14,43,11968,
+16,17,40,11968,
+24,27,29,11986,
+7,24,39,11986,
+0,11,45,11986,
+15,25,36,11986,
+0,25,39,11986,
+11,27,36,11986,
+15,20,39,11986,
+3,29,36,11986,
+7,27,37,11986,
+1,11,45,11986,
+5,21,41,11986,
+9,29,35,11986,
+1,25,39,11986,
+15,31,31,11986,
+3,17,43,11986,
+23,23,33,11986,
+10,32,32,11986,
+4,14,44,11986,
+8,22,40,11986,
+4,4,46,11986,
+12,22,39,11986,
+6,32,33,11986,
+12,18,41,11986,
+15,30,32,11986,
+18,23,36,11986,
+22,24,33,11986,
+15,18,40,11986,
+17,30,31,11986,
+10,23,39,11986,
+3,5,46,11986,
+25,25,30,12010,
+2,25,39,12010,
+2,11,45,12010,
+5,10,45,12010,
+9,25,38,12010,
+14,27,35,12010,
+5,19,42,12010,
+10,31,33,12010,
+21,22,35,12010,
+5,30,35,12010,
+24,26,30,12028,
+0,6,46,12028,
+8,18,42,12028,
+12,28,35,12028,
+8,8,45,12028,
+4,29,36,12028,
+6,31,34,12028,
+0,28,37,12028,
+10,17,42,12028,
+20,27,32,12028,
+1,6,46,12028,
+15,22,38,12028,
+17,29,32,12028,
+7,16,43,12028,
+13,31,32,12028,
+5,23,40,12028,
+20,23,35,12028,
+7,13,44,12028,
+23,28,29,12049,
+16,23,37,12049,
+4,17,43,12049,
+1,28,37,12049,
+15,29,33,12049,
+9,15,43,12049,
+3,11,45,12049,
+3,25,39,12049,
+21,25,33,12049,
+7,9,45,12049,
+2,6,46,12049,
+14,14,42,12049,
+18,26,34,12049,
+10,30,34,12049,
+6,26,38,12049,
+14,19,40,12049,
+2,28,37,12049,
+10,11,44,12049,
+5,14,44,12049,
+16,26,35,12049,
+4,5,46,12049,
+14,21,39,12049,
+6,21,41,12049,
+23,27,30,12072,
+13,15,42,12072,
+13,30,33,12072,
+17,24,36,12072,
+19,30,30,12072,
+0,15,44,12072,
+6,19,42,12072,
+6,30,35,12072,
+8,24,39,12072,
+6,10,45,12072,
+3,6,46,12072,
+9,12,44,12072,
+9,28,36,12072,
+8,27,37,12072,
+19,24,35,12072,
+1,15,44,12072,
+7,32,33,12072,
+12,13,43,12072,
+15,16,41,12072,
+24,25,31,12091,
+11,21,40,12091,
+9,20,41,12091,
+5,29,36,12091,
+17,28,33,12091,
+4,11,45,12091,
+4,25,39,12091,
+3,28,37,12091,
+11,19,41,12091,
+5,17,43,12091,
+19,29,31,12091,
+13,25,37,12091,
+12,24,38,12091,
+12,16,42,12091,
+0,20,42,12091,
+2,15,44,12091,
+9,22,40,12091,
+6,23,40,12091,
+1,20,42,12091,
+20,26,33,12091,
+0,22,41,12091,
+15,28,34,12091,
+0,7,46,12091,
+22,29,29,12110,
+7,31,34,12110,
+1,7,46,12110,
+10,29,35,12110,
+23,26,31,12110,
+5,5,46,12110,
+13,29,34,12110,
+11,14,43,12110,
+1,22,41,12110,
+11,26,37,12110,
+14,17,41,12110,
+19,19,38,12110,
+22,28,30,12125,
+14,26,36,12125,
+6,14,44,12125,
+4,6,46,12125,
+2,20,42,12125,
+18,20,38,12125,
+9,18,42,12125,
+2,22,41,12125,
+7,26,38,12125,
+11,32,32,12125,
+22,23,34,12125,
+13,20,40,12125,
+8,13,44,12125,
+10,25,38,12125,
+20,20,37,12125,
+18,18,39,12125,
+8,16,43,12125,
+0,12,45,12125,
+2,7,46,12125,
+12,27,36,12125,
+14,23,38,12125,
+19,28,32,12125,
+4,28,37,12125,
+1,12,45,12125,
+15,24,37,12125,
+8,9,45,12125,
+3,15,44,12125,
+5,11,45,12125,
+19,21,37,12125,
+5,25,39,12125,
+11,31,33,12125,
+17,19,39,12125,
+11,23,39,12125,
+7,21,41,12125,
+3,20,42,12125,
+21,24,34,12140,
+6,29,36,12140,
+0,27,38,12140,
+2,12,45,12140,
+0,18,43,12140,
+17,27,34,12140,
+7,30,35,12140,
+11,17,42,12140,
+3,7,46,12140,
+10,15,43,12140,
+17,21,38,12140,
+1,27,38,12140,
+18,25,35,12140,
+6,17,43,12140,
+7,10,45,12140,
+13,22,39,12140,
+3,22,41,12140,
+1,18,43,12140,
+7,19,42,12140,
+13,18,41,12140,
+22,27,31,12180,
+0,24,40,12180,
+24,24,32,12191,
+5,6,46,12191,
+4,15,44,12191,
+18,22,37,12191,
+2,18,43,12191,
+1,24,40,12191,
+2,27,38,12191,
+8,32,33,12191,
+11,30,34,12191,
+16,20,39,12191,
+16,25,36,12191,
+11,11,44,12191,
+23,25,32,12212,
+7,23,40,12212,
+17,17,40,12212,
+21,21,36,12212,
+0,33,33,12212,
+5,28,37,12212,
+16,31,31,12212,
+13,28,35,12212,
+9,24,39,12212,
+3,12,45,12212,
+9,27,37,12212,
+19,27,33,12212,
+1,33,33,12212,
+15,27,35,12212,
+0,8,46,12212,
+16,18,40,12212,
+0,32,34,12212,
+20,22,36,12212,
+2,24,40,12212,
+10,28,36,12212,
+16,30,32,12212,
+4,20,42,12212,
+10,12,44,12212,
+1,32,34,12212,
+20,25,34,12212,
+8,31,34,12212,
+4,22,41,12212,
+14,31,32,12212,
+4,7,46,12212,
+7,14,44,12212,
+1,8,46,12212,
+10,20,41,12212,
+3,18,43,12212,
+6,25,39,12212,
+3,27,38,12212,
+21,29,30,12233,
+2,33,33,12233,
+6,11,45,12233,
+2,32,34,12233,
+8,26,38,12233,
+22,26,32,12246,
+2,8,46,12246,
+10,22,40,12246,
+16,22,38,12246,
+4,12,45,12246,
+14,15,42,12246,
+14,30,33,12246,
+3,24,40,12246,
+18,30,31,12246,
+12,21,40,12246,
+19,23,36,12246,
+9,16,43,12246,
+12,19,41,12246,
+8,21,41,12246,
+16,29,33,12246,
+5,15,44,12246,
+15,19,40,12246,
+0,31,35,12246,
+9,13,44,12246,
+21,28,31,12260,
+7,29,36,12260,
+9,9,45,12260,
+11,29,35,12260,
+1,31,35,12260,
+7,17,43,12260,
+17,23,37,12260,
+27,27,27,12290,
+3,33,33,12290,
+15,21,39,12290,
+13,13,43,12290,
+10,18,42,12290,
+6,6,46,12290,
+8,19,42,12290,
+3,8,46,12290,
+13,24,38,12290,
+8,10,45,12290,
+3,32,34,12290,
+5,20,42,12290,
+18,29,32,12290,
+12,14,43,12290,
+12,26,37,12290,
+4,27,38,12290,
+6,28,37,12290,
+13,16,42,12290,
+8,30,35,12290,
+26,27,28,12309,
+4,18,43,12309,
+14,25,37,12309,
+5,22,41,12309,
+11,25,38,12309,
+17,26,35,12309,
+2,31,35,12309,
+5,7,46,12309,
+0,16,44,12309,
+12,32,32,12309,
+4,24,40,12309,
+26,26,29,12343,
+19,26,34,12343,
+8,23,40,12343,
+14,29,34,12343,
+16,16,41,12343,
+25,28,28,12343,
+22,22,35,12343,
+1,16,44,12343,
+5,12,45,12343,
+13,27,36,12343,
+12,23,39,12343,
+23,24,33,12343,
+4,33,33,12343,
+12,31,33,12343,
+9,32,33,12343,
+21,27,32,12343,
+0,13,45,12343,
+7,25,39,12343,
+1,13,45,12343,
+11,15,43,12343,
+15,17,41,12343,
+25,27,29,12358,
+21,23,35,12358,
+3,31,35,12358,
+7,11,45,12358,
+4,32,34,12358,
+8,14,44,12358,
+18,24,36,12358,
+14,20,40,12358,
+16,28,34,12358,
+4,8,46,12358,
+2,16,44,12358,
+0,30,36,12358,
+15,26,36,12358,
+0,9,46,12358,
+18,28,33,12358,
+1,30,36,12358,
+12,17,42,12358,
+6,15,44,12358,
+10,24,39,12358,
+0,26,39,12358,
+22,25,33,12358,
+1,26,39,12358,
+15,23,38,12358,
+1,9,46,12358,
+5,18,43,12358,
+9,31,34,12358,
+5,27,38,12358,
+10,27,37,12358,
+2,13,45,12358,
+20,30,30,12364,
+12,30,34,12364,
+2,30,36,12364,
+6,20,42,12364,
+2,9,46,12364,
+5,24,40,12364,
+14,18,41,12364,
+6,7,46,12364,
+9,26,38,12364,
+11,12,44,12364,
+2,26,39,12364,
+11,28,36,12364,
+24,28,29,12404,
+14,22,39,12404,
+6,22,41,12404,
+25,26,30,12404,
+16,24,37,12404,
+20,24,35,12404,
+8,29,36,12404,
+3,16,44,12404,
+20,29,31,12404,
+7,28,37,12404,
+8,17,43,12404,
+4,31,35,12404,
+11,20,41,12404,
+5,33,33,12404,
+3,13,45,12404,
+9,21,41,12404,
+14,28,35,12404,
+6,12,45,12404,
+0,21,42,12404,
+10,13,44,12404,
+5,8,46,12404,
+11,22,40,12404,
+10,16,43,12404,
+5,32,34,12404,
+19,20,38,12404,
+3,30,36,12404,
+24,27,30,12434,
+9,19,42,12434,
+3,26,39,12434,
+18,19,39,12434,
+1,21,42,12434,
+9,30,35,12434,
+3,9,46,12434,
+21,26,33,12434,
+9,10,45,12434,
+20,28,32,12434,
+4,16,44,12434,
+18,21,38,12434,
+6,27,38,12434,
+0,0,47,12434,
+2,21,42,12434,
+11,18,42,12434,
+18,27,34,12434,
+6,18,43,12434,
+0,29,37,12434,
+13,21,40,12434,
+17,25,36,12434,
+20,21,37,12434,
+9,23,40,12434,
+8,25,39,12434,
+12,29,35,12434,
+17,20,39,12434,
+0,23,41,12434,
+0,1,47,12434,
+8,11,45,12434,
+4,13,45,12434,
+7,15,44,12434,
+16,27,35,12434,
+15,31,32,12434,
+0,19,43,12434,
+5,31,35,12434,
+23,29,29,12471,
+17,31,31,12471,
+19,25,35,12471,
+1,23,41,12471,
+1,29,37,12471,
+1,1,47,12471,
+1,19,43,12471,
+25,25,31,12471,
+13,19,41,12471,
+4,30,36,12471,
+6,24,40,12471,
+10,32,33,12471,
+4,26,39,12471,
+17,18,40,12471,
+7,20,42,12471,
+24,26,31,12493,
+23,28,30,12493,
+17,30,32,12493,
+4,9,46,12493,
+12,25,38,12493,
+0,2,47,12493,
+9,14,44,12493,
+13,14,43,12493,
+2,29,37,12493,
+15,30,33,12493,
+3,21,42,12493,
+15,15,42,12493,
+1,2,47,12493,
+7,22,41,12493,
+2,19,43,12493,
+23,23,34,12493,
+6,33,33,12493,
+7,7,46,12493,
+2,23,41,12493,
+13,26,37,12493,
+19,22,37,12493,
+14,24,38,12493,
+6,8,46,12493,
+22,24,34,12493,
+6,32,34,12493,
+14,16,42,12493,
+0,10,46,12493,
+8,28,37,12493,
+10,31,34,12493,
+5,16,44,12493,
+1,10,46,12493,
+16,19,40,12493,
+17,22,38,12493,
+2,2,47,12493,
+13,32,32,12493,
+20,27,33,12501,
+12,15,43,12501,
+11,24,39,12501,
+0,3,47,12501,
+16,21,39,12501,
+9,29,36,12501,
+7,12,45,12501,
+5,13,45,12501,
+23,27,31,12528,
+17,29,33,12528,
+13,23,39,12528,
+11,27,37,12528,
+15,25,37,12528,
+3,23,41,12528,
+9,17,43,12528,
+13,31,33,12528,
+3,29,37,12528,
+1,3,47,12528,
+3,19,43,12528,
+2,10,46,12528,
+10,26,38,12528,
+4,21,42,12528,
+0,14,45,12528,
+21,22,36,12528,
+14,27,36,12528,
+5,30,36,12528,
+5,26,39,12528,
+18,23,37,12528,
+10,21,41,12528,
+2,3,47,12528,
+19,30,31,12528,
+7,27,38,12528,
+6,31,35,12528,
+13,17,42,12528,
+5,9,46,12528,
+7,18,43,12528,
+15,29,34,12528,
+1,14,45,12528,
+21,25,34,12528,
+12,12,44,12528,
+12,28,36,12528,
+12,20,41,12528,
+0,17,44,12528,
+8,15,44,12528,
+0,4,47,12528,
+13,30,34,12528,
+15,20,40,12528,
+7,24,40,12528,
+0,25,40,12528,
+3,10,46,12528,
+20,23,36,12528,
+2,14,45,12528,
+18,26,35,12528,
+10,10,45,12528,
+10,19,42,12528,
+22,29,30,12567,
+10,30,35,12567,
+24,25,32,12567,
+4,19,43,12567,
+4,23,41,12567,
+16,17,41,12567,
+1,17,44,12567,
+1,4,47,12567,
+4,29,37,12567,
+11,13,44,12567,
+11,16,43,12567,
+19,29,32,12567,
+1,25,40,12567,
+7,33,33,12567,
+3,3,47,12567,
+9,25,39,12567,
+9,11,45,12567,
+16,26,36,12567,
+8,20,42,12567,
+12,22,40,12567,
+6,16,44,12567,
+0,28,38,12567,
+7,8,46,12567,
+1,28,38,12567,
+2,25,40,12567,
+22,28,31,12601,
+2,4,47,12601,
+2,17,44,12601,
+23,26,32,12601,
+17,28,34,12601,
+8,22,41,12601,
+10,23,40,12601,
+7,32,34,12601,
+16,23,38,12601,
+5,21,42,12601,
+15,22,39,12601,
+6,13,45,12601,
+15,18,41,12601,
+3,14,45,12601,
+12,18,42,12601,
+10,14,44,12601,
+4,10,46,12601,
+20,26,34,12601,
+6,30,36,12601,
+2,28,38,12601,
+6,9,46,12601,
+6,26,39,12601,
+8,12,45,12601,
+19,24,36,12601,
+9,28,37,12601,
+0,5,47,12601,
+17,24,37,12601,
+3,25,40,12601,
+3,17,44,12601,
+3,4,47,12601,
+11,32,33,12601,
+19,28,33,12606,
+15,28,35,12606,
+7,31,35,12606,
+5,29,37,12606,
+1,5,47,12606,
+5,19,43,12606,
+13,29,35,12606,
+5,23,41,12606,
+4,14,45,12606,
+22,27,32,12652,
+10,29,36,12652,
+8,18,43,12652,
+3,28,38,12652,
+8,27,38,12652,
+0,11,46,12652,
+14,21,40,12652,
+13,25,38,12652,
+1,11,46,12652,
+22,23,35,12652,
+10,17,43,12652,
+11,31,34,12652,
+2,5,47,12652,
+14,19,41,12652,
+8,24,40,12652,
+24,24,33,12677,
+6,21,42,12677,
+21,30,30,12677,
+7,16,44,12677,
+14,14,43,12677,
+14,26,37,12677,
+5,10,46,12677,
+4,17,44,12677,
+4,4,47,12677,
+2,11,46,12677,
+4,25,40,12677,
+16,31,32,12677,
+11,26,38,12677,
+12,24,39,12677,
+8,33,33,12677,
+27,27,28,12720,
+9,15,44,12720,
+12,27,37,12720,
+21,24,35,12720,
+3,5,47,12720,
+21,29,31,12720,
+13,15,43,12720,
+17,27,35,12720,
+7,13,45,12720,
+11,21,41,12720,
+23,25,33,12720,
+19,19,39,12720,
+4,28,38,12720,
+26,28,28,12725,
+20,20,38,12725,
+14,32,32,12725,
+8,32,34,12725,
+8,8,46,12725,
+18,20,39,12725,
+9,20,42,12725,
+18,25,36,12725,
+0,6,47,12725,
+7,30,36,12725,
+0,33,34,12725,
+15,16,42,12725,
+15,24,38,12725,
+16,30,33,12725,
+1,33,34,12725,
+3,11,46,12725,
+14,23,39,12725,
+6,29,37,12725,
+1,6,47,12725,
+10,25,39,12725,
+19,27,34,12725,
+11,30,35,12725,
+6,23,41,12725,
+26,27,29,12749,
+19,21,38,12749,
+18,31,31,12749,
+7,26,39,12749,
+11,19,42,12749,
+6,19,43,12749,
+14,31,33,12749,
+9,22,41,12749,
+5,14,45,12749,
+7,9,46,12749,
+10,11,45,12749,
+18,30,32,12749,
+18,18,40,12749,
+0,22,42,12749,
+2,6,47,12749,
+1,22,42,12749,
+14,17,42,12749,
+12,13,44,12749,
+0,20,43,12749,
+0,32,35,12749,
+21,28,32,12749,
+2,33,34,12749,
+22,26,33,12749,
+13,28,36,12749,
+12,16,43,12749,
+15,27,36,12749,
+1,20,43,12749,
+0,15,45,12749,
+11,23,40,12749,
+5,17,44,12749,
+20,25,35,12749,
+8,31,35,12749,
+1,32,35,12749,
+4,5,47,12749,
+0,27,39,12749,
+16,25,37,12749,
+13,20,41,12749,
+17,19,40,12749,
+9,12,45,12749,
+25,28,29,12767,
+5,25,40,12767,
+21,21,37,12767,
+1,15,45,12767,
+1,27,39,12767,
+17,21,39,12767,
+6,10,46,12767,
+14,30,34,12767,
+2,22,42,12767,
+26,26,30,12771,
+18,22,38,12771,
+20,22,37,12771,
+11,14,44,12771,
+16,29,34,12771,
+13,22,40,12771,
+4,11,46,12771,
+2,32,35,12771,
+10,28,37,12771,
+5,28,38,12771,
+2,20,43,12771,
+18,29,33,12771,
+3,33,34,12771,
+2,27,39,12771,
+9,18,43,12771,
+3,6,47,12771,
+7,21,42,12771,
+9,27,38,12771,
+25,27,30,12790,
+2,15,45,12790,
+16,20,40,12790,
+8,16,44,12790,
+9,24,40,12790,
+12,32,33,12790,
+3,22,42,12790,
+0,24,41,12790,
+6,14,45,12790,
+13,18,42,12790,
+0,31,36,12790,
+1,31,36,12790,
+8,13,45,12790,
+3,32,35,12790,
+1,24,41,12790,
+0,7,47,12790,
+24,29,29,12823,
+3,20,43,12823,
+11,29,36,12823,
+9,33,33,12823,
+21,27,33,12823,
+17,17,41,12823,
+3,27,39,12823,
+19,23,37,12823,
+7,23,41,12823,
+11,17,43,12823,
+7,19,43,12823,
+3,15,45,12823,
+5,5,47,12823,
+7,29,37,12823,
+1,7,47,12823,
+0,18,44,12823,
+24,28,30,12832,
+0,12,46,12832,
+8,30,36,12832,
+8,9,46,12832,
+1,12,46,12832,
+8,26,39,12832,
+4,33,34,12832,
+23,24,34,12832,
+2,31,36,12832,
+9,32,34,12832,
+10,15,44,12832,
+4,6,47,12832,
+16,18,41,12832,
+2,24,41,12832,
+6,17,44,12832,
+6,25,40,12832,
+12,31,34,12832,
+20,30,31,12832,
+1,18,44,12832,
+17,26,36,12832,
+16,22,39,12832,
+25,26,31,12853,
+17,23,38,12853,
+14,29,35,12853,
+2,7,47,12853,
+19,26,35,12853,
+5,11,46,12853,
+10,20,42,12853,
+6,28,38,12853,
+18,28,34,12853,
+12,26,38,12853,
+2,12,46,12853,
+2,18,44,12853,
+4,22,42,12853,
+22,22,36,12853,
+16,28,35,12853,
+22,25,34,12853,
+14,25,38,12853,
+4,32,35,12853,
+4,20,43,12853,
+7,10,46,12853,
+20,29,32,12853,
+10,22,41,12853,
+12,21,41,12853,
+13,24,39,12853,
+15,21,40,12853,
+3,24,41,12853,
+4,15,45,12853,
+24,27,31,12888,
+4,27,39,12888,
+21,23,36,12888,
+3,31,36,12888,
+13,27,37,12888,
+15,19,41,12888,
+11,25,39,12888,
+11,11,45,12888,
+9,31,35,12888,
+3,7,47,12888,
+8,21,42,12888,
+3,12,46,12888,
+10,12,45,12888,
+3,18,44,12888,
+18,24,37,12888,
+0,30,37,12888,
+12,30,35,12888,
+12,19,42,12888,
+1,30,37,12888,
+14,15,43,12888,
+5,6,47,12888,
+7,14,45,12888,
+5,33,34,12888,
+23,29,30,12927,
+15,26,37,12927,
+20,24,36,12927,
+21,26,34,12927,
+0,8,47,12927,
+10,18,43,12927,
+2,30,37,12927,
+5,22,42,12927,
+10,27,38,12927,
+20,28,33,12927,
+4,31,36,12927,
+12,23,40,12927,
+4,24,41,12927,
+6,11,46,12927,
+15,32,32,12927,
+9,16,44,12927,
+5,32,35,12927,
+1,8,47,12927,
+17,31,32,12927,
+11,28,37,12927,
+7,25,40,12927,
+23,28,31,12953,
+5,20,43,12953,
+7,17,44,12953,
+4,7,47,12953,
+8,29,37,12953,
+8,23,41,12953,
+13,13,44,12953,
+25,25,32,12953,
+13,16,43,12953,
+8,19,43,12953,
+5,15,45,12953,
+9,13,45,12953,
+5,27,39,12953,
+15,23,39,12953,
+15,31,33,12953,
+14,28,36,12953,
+24,26,32,12960,
+16,24,38,12960,
+4,12,46,12960,
+16,16,42,12960,
+10,24,40,12960,
+12,14,44,12960,
+0,26,40,12960,
+4,18,44,12960,
+9,30,36,12960,
+14,20,41,12960,
+2,8,47,12960,
+7,28,38,12960,
+1,26,40,12960,
+18,27,35,12960,
+9,9,46,12960,
+3,30,37,12960,
+9,26,39,12960,
+15,17,42,12960,
+17,30,33,12960,
+10,33,33,12960,
+2,26,40,12960,
+8,10,46,12960,
+14,22,40,12960,
+10,32,34,12960,
+15,30,34,12960,
+16,27,36,12960,
+6,33,34,12960,
+6,6,47,12960,
+0,16,45,12960,
+12,29,36,12960,
+19,20,39,12960,
+5,24,41,12960,
+3,8,47,12960,
+11,15,44,12960,
+12,17,43,12960,
+13,32,33,12960,
+5,31,36,12960,
+1,16,45,12960,
+23,27,32,13011,
+19,25,36,13011,
+5,7,47,13011,
+23,23,35,13011,
+19,31,31,13011,
+17,25,37,13011,
+22,30,30,13014,
+14,18,42,13014,
+6,22,42,13014,
+4,30,37,13014,
+5,18,44,13014,
+20,21,38,13014,
+0,29,38,13014,
+18,19,40,13014,
+3,26,40,13014,
+2,16,45,13014,
+20,27,34,13014,
+6,20,43,13014,
+22,24,35,13014,
+5,12,46,13014,
+0,13,46,13014,
+11,20,42,13014,
+8,14,45,13014,
+19,30,32,13014,
+6,32,35,13014,
+6,27,39,13014,
+1,13,46,13014,
+13,31,34,13014,
+11,22,41,13014,
+22,29,31,13036,
+18,21,39,13036,
+10,31,35,13036,
+6,15,45,13036,
+17,29,34,13036,
+9,21,42,13036,
+7,11,46,13036,
+1,29,38,13036,
+8,25,40,13036,
+17,20,40,13036,
+13,26,38,13036,
+19,22,38,13036,
+2,13,46,13036,
+4,8,47,13036,
+2,29,38,13036,
+8,17,44,13036,
+11,12,45,13036,
+0,21,43,13036,
+24,25,33,13070,
+3,16,45,13070,
+0,9,47,13070,
+12,25,39,13070,
+9,23,41,13070,
+19,29,33,13070,
+13,21,41,13070,
+9,19,43,13070,
+9,29,37,13070,
+21,25,35,13070,
+1,21,43,13070,
+1,9,47,13070,
+15,29,35,13070,
+4,26,40,13070,
+10,16,44,13070,
+22,28,32,13072,
+8,28,38,13072,
+14,24,39,13072,
+0,23,42,13072,
+6,31,36,13072,
+6,24,41,13072,
+14,27,37,13072,
+6,7,47,13072,
+11,18,43,13072,
+15,25,38,13072,
+17,22,39,13072,
+13,30,35,13072,
+13,19,42,13072,
+1,23,42,13072,
+23,26,33,13090,
+21,22,37,13090,
+7,33,34,13090,
+10,13,45,13090,
+3,29,38,13090,
+11,27,38,13090,
+5,30,37,13090,
+2,9,47,13090,
+2,21,43,13090,
+17,18,41,13090,
+3,13,46,13090,
+10,30,36,13090,
+6,12,46,13090,
+18,26,36,13090,
+6,18,44,13090,
+11,24,40,13090,
+9,10,46,13090,
+2,23,42,13090,
+12,28,37,13090,
+4,16,45,13090,
+0,19,44,13090,
+18,23,38,13090,
+16,21,40,13090,
+7,22,42,13090,
+27,28,28,13129,
+10,26,39,13129,
+7,32,35,13129,
+17,28,35,13129,
+13,23,40,13129,
+1,19,44,13129,
+5,8,47,13129,
+16,19,41,13129,
+7,20,43,13129,
+20,23,37,13129,
+7,15,45,13129,
+11,33,33,13129,
+15,15,43,13129,
+3,9,47,13129,
+7,27,39,13129,
+3,21,43,13129,
+27,27,29,13149,
+13,14,44,13149,
+20,26,35,13149,
+5,26,40,13149,
+19,28,34,13149,
+2,19,44,13149,
+26,28,29,13166,
+4,29,38,13166,
+8,11,46,13166,
+14,16,43,13166,
+11,32,34,13166,
+16,26,37,13166,
+4,13,46,13166,
+3,23,42,13166,
+22,27,33,13166,
+9,14,45,13166,
+21,30,31,13166,
+0,0,48,13166,
+16,32,32,13166,
+10,21,42,13166,
+26,27,30,13199,
+0,1,48,13199,
+15,28,36,13199,
+6,30,37,13199,
+12,15,44,13199,
+0,28,39,13199,
+7,31,36,13199,
+1,28,39,13199,
+0,25,41,13199,
+9,17,44,13199,
+7,24,41,13199,
+13,29,36,13199,
+1,1,48,13199,
+16,23,39,13199,
+9,25,40,13199,
+21,29,32,13199,
+19,24,37,13199,
+16,31,33,13199,
+5,16,45,13199,
+4,9,47,13199,
+4,21,43,13199,
+3,19,44,13199,
+15,20,41,13199,
+13,17,43,13199,
+25,29,29,13222,
+11,31,35,13222,
+1,25,41,13222,
+7,7,47,13222,
+0,2,48,13222,
+12,20,42,13222,
+24,24,34,13222,
+15,22,40,13222,
+7,12,46,13222,
+12,22,41,13222,
+22,23,36,13222,
+9,28,38,13222,
+7,18,44,13222,
+17,24,38,13222,
+1,2,48,13222,
+8,33,34,13222,
+0,10,47,13222,
+16,17,42,13222,
+6,8,47,13222,
+2,28,39,13222,
+4,23,42,13222,
+18,31,32,13222,
+14,32,33,13222,
+25,28,30,13228,
+1,10,47,13228,
+10,29,37,13228,
+10,19,43,13228,
+10,23,41,13228,
+23,25,34,13228,
+5,29,38,13228,
+5,13,46,13228,
+2,25,41,13228,
+2,2,48,13228,
+8,22,42,13228,
+0,14,46,13228,
+16,30,34,13228,
+6,26,40,13228,
+0,34,34,13228,
+1,34,34,13228,
+15,18,42,13228,
+8,20,43,13228,
+4,19,44,13228,
+14,31,34,13228,
+1,14,46,13228,
+26,26,31,13252,
+21,24,36,13252,
+2,10,47,13252,
+18,30,33,13252,
+0,3,48,13252,
+11,16,44,13252,
+12,12,45,13252,
+8,32,35,13252,
+8,27,39,13252,
+17,27,36,13252,
+8,15,45,13252,
+0,17,45,13252,
+0,33,35,13252,
+3,28,39,13252,
+21,28,33,13252,
+1,3,48,13252,
+5,9,47,13252,
+1,17,45,13252,
+3,25,41,13252,
+5,21,43,13252,
+13,25,39,13252,
+19,27,35,13252,
+1,33,35,13252,
+25,27,31,13266,
+11,13,45,13266,
+2,34,34,13266,
+2,14,46,13266,
+14,26,38,13266,
+22,26,34,13266,
+10,10,46,13266,
+12,18,43,13266,
+24,29,30,13284,
+2,3,48,13284,
+6,16,45,13284,
+11,30,36,13284,
+12,27,38,13284,
+7,30,37,13284,
+14,21,41,13284,
+3,10,47,13284,
+2,17,45,13284,
+2,33,35,13284,
+18,25,37,13284,
+11,26,39,13284,
+5,23,42,13284,
+9,11,46,13284,
+0,4,48,13284,
+0,32,36,13284,
+12,24,40,13284,
+3,34,34,13284,
+8,24,41,13284,
+14,19,42,13284,
+3,14,46,13284,
+6,13,46,13284,
+20,20,39,13284,
+6,29,38,13284,
+1,32,36,13284,
+20,25,36,13284,
+10,14,45,13284,
+1,4,48,13284,
+24,28,31,13309,
+8,31,36,13309,
+14,30,35,13309,
+18,29,34,13309,
+4,28,39,13309,
+19,19,40,13309,
+7,8,47,13309,
+5,19,44,13309,
+15,24,39,13309,
+16,29,35,13309,
+3,3,48,13309,
+20,31,31,13309,
+12,33,33,13309,
+4,25,41,13309,
+13,28,37,13309,
+15,27,37,13309,
+19,21,39,13309,
+3,17,45,13309,
+3,33,35,13309,
+12,32,34,13309,
+20,30,32,13309,
+2,4,48,13309,
+8,18,44,13309,
+8,12,46,13309,
+18,20,40,13309,
+2,32,36,13309,
+10,25,40,13309,
+7,26,40,13309,
+4,10,47,13309,
+10,17,44,13309,
+25,26,32,13349,
+14,23,40,13349,
+16,25,38,13349,
+21,21,38,13349,
+21,27,34,13349,
+9,33,34,13349,
+6,21,43,13349,
+11,21,42,13349,
+6,9,47,13349,
+4,34,34,13349,
+4,14,46,13349,
+14,14,44,13349,
+20,22,38,13349,
+10,28,38,13349,
+6,23,42,13349,
+18,22,39,13349,
+9,22,42,13349,
+0,5,48,13349,
+24,27,32,13375,
+3,4,48,13375,
+18,18,41,13375,
+0,27,40,13375,
+3,32,36,13375,
+23,30,30,13375,
+5,28,39,13375,
+1,27,40,13375,
+23,24,35,13375,
+15,16,43,13375,
+9,32,35,13375,
+7,16,45,13375,
+13,15,44,13375,
+9,20,43,13375,
+12,31,35,13375,
+0,11,47,13375,
+4,33,35,13375,
+1,5,48,13375,
+17,21,40,13375,
+4,17,45,13375,
+20,29,33,13375,
+0,31,37,13375,
+9,15,45,13375,
+11,29,37,13375,
+5,25,41,13375,
+17,19,41,13375,
+11,23,41,13375,
+1,31,37,13375,
+11,19,43,13375,
+9,27,39,13375,
+1,11,47,13375,
+23,29,31,13394,
+2,27,40,13394,
+13,20,42,13394,
+18,28,35,13394,
+6,19,44,13394,
+0,22,43,13394,
+2,5,48,13394,
+14,29,36,13394,
+8,30,37,13394,
+19,26,36,13394,
+1,22,43,13394,
+7,13,46,13394,
+14,17,43,13394,
+22,25,35,13394,
+19,23,38,13394,
+17,26,37,13394,
+13,22,41,13394,
+7,29,38,13394,
+2,11,47,13394,
+2,31,37,13394,
+5,10,47,13394,
+16,28,36,13394,
+4,32,36,13394,
+4,4,48,13394,
+12,16,44,13394,
+0,20,44,13394,
+2,22,43,13394,
+10,11,46,13394,
+22,22,37,13394,
+5,14,46,13394,
+17,32,32,13394,
+1,20,44,13394,
+8,8,47,13394,
+5,34,34,13394,
+16,20,41,13394,
+23,28,32,13434,
+15,32,33,13434,
+3,27,40,13434,
+9,24,41,13434,
+3,5,48,13434,
+9,31,36,13434,
+12,13,45,13434,
+17,23,39,13434,
+7,21,43,13434,
+3,31,37,13434,
+21,23,37,13434,
+7,9,47,13434,
+25,25,33,13445,
+3,11,47,13445,
+17,31,33,13445,
+5,17,45,13445,
+5,33,35,13445,
+2,20,44,13445,
+0,24,42,13445,
+12,30,36,13445,
+0,6,48,13445,
+16,22,40,13445,
+8,26,40,13445,
+20,28,34,13445,
+6,28,39,13445,
+1,6,48,13445,
+24,26,33,13451,
+9,12,46,13451,
+12,26,39,13451,
+9,18,44,13451,
+1,24,42,13451,
+0,15,46,13451,
+15,31,34,13451,
+14,25,39,13451,
+17,17,42,13451,
+11,14,45,13451,
+1,15,46,13451,
+13,18,43,13451,
+6,25,41,13451,
+7,23,42,13451,
+21,26,35,13451,
+13,27,38,13451,
+3,22,43,13451,
+2,6,48,13451,
+18,24,38,13451,
+0,30,38,13451,
+16,18,42,13451,
+2,24,42,13451,
+4,27,40,13451,
+15,26,38,13451,
+1,30,38,13451,
+22,30,31,13467,
+6,10,47,13467,
+8,16,45,13467,
+20,24,37,13467,
+10,33,34,13467,
+2,15,46,13467,
+5,32,36,13467,
+17,30,34,13467,
+4,5,48,13467,
+13,24,40,13467,
+3,20,44,13467,
+4,11,47,13467,
+19,31,32,13467,
+7,19,44,13467,
+11,25,40,13467,
+4,31,37,13467,
+11,17,44,13467,
+23,27,33,13495,
+15,21,41,13495,
+13,33,33,13495,
+6,34,34,13495,
+2,30,38,13495,
+10,22,42,13495,
+6,14,46,13495,
+10,20,43,13495,
+12,21,42,13495,
+0,18,45,13495,
+18,27,36,13495,
+8,13,46,13495,
+11,28,38,13495,
+8,29,38,13495,
+3,24,42,13495,
+22,29,32,13510,
+14,28,37,13510,
+4,22,43,13510,
+3,6,48,13510,
+10,32,35,13510,
+13,32,34,13510,
+10,15,45,13510,
+3,15,46,13510,
+6,17,45,13510,
+9,30,37,13510,
+19,30,33,13510,
+1,18,45,13510,
+15,19,42,13510,
+15,30,35,13510,
+6,33,35,13510,
+10,27,39,13510,
+4,20,44,13510,
+28,28,28,13559,
+0,12,47,13559,
+0,7,48,13559,
+3,30,38,13559,
+16,24,39,13559,
+2,18,45,13559,
+12,23,41,13559,
+15,23,40,13559,
+20,27,35,13559,
+8,21,43,13559,
+12,29,37,13559,
+16,27,37,13559,
+23,23,36,13559,
+12,19,43,13559,
+8,9,47,13559,
+7,28,39,13559,
+1,12,47,13559,
+5,5,48,13559,
+1,7,48,13559,
+27,28,29,13584,
+5,27,40,13584,
+7,25,41,13584,
+13,31,35,13584,
+17,29,35,13584,
+19,25,37,13584,
+5,31,37,13584,
+5,11,47,13584,
+6,32,36,13584,
+4,6,48,13584,
+4,24,42,13584,
+22,24,36,13584,
+10,24,41,13584,
+22,28,33,13584,
+10,31,36,13584,
+8,23,42,13584,
+2,12,47,13584,
+2,7,48,13584,
+14,15,44,13584,
+24,25,34,13584,
+0,26,41,13584,
+9,26,40,13584,
+4,15,46,13584,
+5,22,43,13584,
+27,27,30,13616,
+26,29,29,13616,
+19,29,34,13616,
+17,25,38,13616,
+3,18,45,13616,
+7,10,47,13616,
+11,11,46,13616,
+1,26,41,13616,
+10,12,46,13616,
+10,18,44,13616,
+14,20,42,13616,
+26,28,30,13628,
+4,30,38,13628,
+14,22,41,13628,
+16,16,43,13628,
+8,19,44,13628,
+7,14,46,13628,
+23,26,34,13628,
+13,16,44,13628,
+2,26,41,13628,
+5,20,44,13628,
+19,20,40,13628,
+7,34,34,13628,
+20,21,39,13628,
+21,25,36,13628,
+15,29,36,13628,
+3,7,48,13628,
+0,29,39,13628,
+9,16,45,13628,
+3,12,47,13628,
+13,13,45,13628,
+7,33,35,13628,
+1,29,39,13628,
+7,17,45,13628,
+15,17,43,13628,
+21,31,31,13628,
+13,30,36,13628,
+5,24,42,13628,
+6,27,40,13628,
+4,18,45,13628,
+12,14,45,13628,
+5,6,48,13628,
+18,21,40,13628,
+21,30,32,13638,
+11,33,34,13638,
+26,27,31,13677,
+6,11,47,13677,
+6,31,37,13677,
+13,26,39,13677,
+19,22,39,13677,
+2,29,39,13677,
+9,29,38,13677,
+9,13,46,13677,
+25,29,30,13677,
+5,15,46,13677,
+18,19,41,13677,
+3,26,41,13677,
+0,8,48,13677,
+6,22,43,13677,
+16,32,33,13677,
+18,26,37,13677,
+4,7,48,13677,
+11,22,42,13677,
+21,22,38,13677,
+4,12,47,13677,
+12,17,44,13677,
+7,32,36,13677,
+22,27,34,13677,
+17,28,36,13677,
+8,28,39,13677,
+5,30,38,13677,
+1,8,48,13677,
+14,27,38,13677,
+12,25,40,13677,
+10,30,37,13677,
+14,18,43,13677,
+25,28,31,13698,
+8,25,41,13698,
+17,20,41,13698,
+11,32,35,13698,
+11,20,43,13698,
+19,28,35,13698,
+3,29,39,13698,
+9,21,43,13698,
+15,25,39,13698,
+11,27,39,13698,
+11,15,45,13698,
+21,29,33,13698,
+9,9,47,13698,
+12,28,38,13698,
+18,32,32,13698,
+14,24,40,13698,
+2,8,48,13698,
+0,16,46,13698,
+20,26,36,13698,
+6,20,44,13698,
+1,16,46,13698,
+4,26,41,13698,
+20,23,38,13698,
+8,10,47,13698,
+16,31,34,13698,
+17,22,40,13698,
+13,21,42,13698,
+14,33,33,13698,
+18,23,39,13698,
+9,23,42,13698,
+5,18,45,13698,
+18,31,33,13698,
+8,34,34,13698,
+8,14,46,13698,
+2,16,46,13698,
+14,32,34,13698,
+6,24,42,13698,
+16,26,38,13698,
+6,6,48,13698,
+10,26,40,13698,
+26,26,32,13734,
+24,30,30,13734,
+6,15,46,13734,
+0,21,44,13734,
+17,18,42,13734,
+24,24,35,13734,
+3,8,48,13734,
+11,31,36,13734,
+24,29,31,13760,
+1,21,44,13760,
+25,27,32,13760,
+5,7,48,13760,
+5,12,47,13760,
+8,17,45,13760,
+15,28,37,13760,
+4,29,39,13760,
+0,13,47,13760,
+11,24,41,13760,
+16,21,41,13760,
+0,23,43,13760,
+7,27,40,13760,
+8,33,35,13760,
+9,19,44,13760,
+7,11,47,13760,
+23,25,35,13760,
+1,23,43,13760,
+13,29,37,13760,
+7,31,37,13760,
+1,13,47,13760,
+13,23,41,13760,
+13,19,43,13760,
+18,30,34,13760,
+6,30,38,13760,
+16,30,35,13760,
+11,18,44,13760,
+19,24,38,13760,
+16,19,42,13760,
+21,28,34,13760,
+11,12,46,13760,
+3,16,46,13760,
+10,16,45,13760,
+2,21,44,13760,
+0,34,35,13760,
+14,31,35,13760,
+2,23,43,13760,
+7,22,43,13760,
+5,26,41,13760,
+1,34,35,13760,
+2,13,47,13760,
+22,23,37,13760,
+4,8,48,13760,
+8,32,36,13760,
+24,28,32,13801,
+0,28,40,13801,
+1,28,40,13801,
+10,13,46,13801,
+7,20,44,13801,
+0,33,36,13801,
+6,18,45,13801,
+10,29,38,13801,
+20,31,32,13801,
+0,9,48,13801,
+16,23,40,13801,
+2,34,35,13801,
+22,26,35,13801,
+9,28,39,13801,
+1,9,48,13801,
+21,24,37,13801,
+0,19,45,13801,
+19,27,36,13801,
+1,33,36,13801,
+15,15,44,13801,
+17,24,39,13801,
+3,21,44,13801,
+17,27,37,13801,
+1,19,45,13801,
+3,23,43,13801,
+3,13,47,13801,
+5,29,39,13801,
+9,25,41,13801,
+14,16,44,13801,
+4,16,46,13801,
+2,28,40,13801,
+6,7,48,13801,
+7,24,42,13801,
+2,9,48,13801,
+6,12,47,13801,
+20,30,33,13809,
+15,20,42,13809,
+0,25,42,13809,
+2,33,36,13809,
+12,33,34,13809,
+10,21,43,13809,
+2,19,45,13809,
+25,26,33,13835,
+11,30,37,13835,
+13,14,45,13835,
+3,34,35,13835,
+1,25,42,13835,
+23,30,31,13835,
+7,15,46,13835,
+18,29,35,13835,
+15,22,41,13835,
+9,10,47,13835,
+12,22,42,13835,
+14,30,36,13835,
+14,26,39,13835,
+18,25,38,13835,
+3,28,40,13835,
+12,20,43,13835,
+9,14,46,13835,
+9,34,34,13835,
+16,29,36,13835,
+7,30,38,13835,
+6,26,41,13835,
+5,8,48,13835,
+0,32,37,13835,
+4,21,44,13835,
+12,32,35,13835,
+8,27,40,13835,
+10,23,42,13835,
+2,25,42,13835,
+8,11,47,13835,
+20,25,37,13835,
+23,29,32,13873,
+16,17,43,13873,
+12,15,45,13873,
+8,31,37,13873,
+1,32,37,13873,
+12,27,39,13873,
+13,25,40,13873,
+13,17,44,13873,
+4,13,47,13873,
+3,33,36,13873,
+3,9,48,13873,
+24,27,33,13873,
+4,23,43,13873,
+21,27,35,13873,
+3,19,45,13873,
+9,33,35,13873,
+9,17,45,13873,
+5,16,46,13873,
+20,29,34,13873,
+13,28,38,13873,
+2,32,37,13873,
+10,19,44,13873,
+4,34,35,13873,
+11,26,40,13873,
+8,22,43,13873,
+7,18,45,13873,
+3,25,42,13873,
+15,18,43,13873,
+15,27,38,13873,
+6,29,39,13873,
+4,28,40,13873,
+8,20,44,13873,
+20,20,40,13873,
+12,31,36,13873,
+0,0,49,13873,
+4,9,48,13873,
+23,24,36,13894,
+4,33,36,13894,
+15,24,40,13894,
+9,32,36,13894,
+14,21,42,13894,
+12,24,41,13894,
+17,32,33,13894,
+5,21,44,13894,
+4,19,45,13894,
+23,28,33,13943,
+11,16,45,13943,
+7,12,47,13943,
+19,21,40,13943,
+3,32,37,13943,
+16,25,39,13943,
+7,7,48,13943,
+0,1,49,13943,
+21,21,39,13943,
+19,19,41,13943,
+5,13,47,13943,
+1,1,49,13943,
+5,23,43,13943,
+15,33,33,13943,
+12,18,44,13943,
+0,10,48,13943,
+6,8,48,13943,
+18,28,36,13943,
+8,24,42,13943,
+12,12,46,13943,
+10,28,39,13943,
+4,25,42,13943,
+1,10,48,13943,
+0,17,46,13943,
+0,2,49,13943,
+0,14,47,13943,
+15,32,34,13943,
+18,20,41,13943,
+0,31,38,13943,
+20,22,39,13943,
+22,25,36,13943,
+8,15,46,13943,
+22,31,31,13972,
+1,14,47,13972,
+10,25,41,13972,
+5,34,35,13972,
+19,26,37,13972,
+14,19,43,13972,
+7,26,41,13972,
+25,25,34,13972,
+1,17,46,13972,
+17,31,34,13972,
+1,2,49,13972,
+14,23,41,13972,
+11,13,46,13972,
+11,29,38,13972,
+1,31,38,13972,
+14,29,37,13972,
+18,22,40,13972,
+2,10,48,13972,
+6,16,46,13972,
+24,26,34,13987,
+22,30,32,13987,
+8,30,38,13987,
+4,32,37,13987,
+19,32,32,13987,
+17,26,38,13987,
+2,31,38,13987,
+2,17,46,13987,
+20,28,35,13987,
+10,10,47,13987,
+2,14,47,13987,
+5,28,40,13987,
+16,28,37,13987,
+2,2,49,13987,
+28,28,29,14016,
+0,3,49,14016,
+5,33,36,14016,
+9,27,40,14016,
+5,9,48,14016,
+0,27,41,14016,
+7,29,39,14016,
+17,21,41,14016,
+5,19,45,14016,
+11,21,43,14016,
+27,29,29,14032,
+1,27,41,14032,
+9,31,37,14032,
+19,23,39,14032,
+15,31,35,14032,
+1,3,49,14032,
+19,31,33,14032,
+9,11,47,14032,
+22,22,38,14032,
+18,18,42,14032,
+10,34,34,14032,
+10,14,46,14032,
+21,26,36,14032,
+8,18,45,14032,
+27,28,30,14049,
+6,21,44,14049,
+3,10,48,14049,
+12,30,37,14049,
+13,33,34,14049,
+6,13,47,14049,
+3,17,46,14049,
+10,17,45,14049,
+3,14,47,14049,
+17,19,42,14049,
+11,23,42,14049,
+17,30,35,14049,
+21,23,38,14049,
+23,27,34,14049,
+5,25,42,14049,
+6,23,43,14049,
+9,22,43,14049,
+2,27,41,14049,
+22,29,33,14049,
+2,3,49,14049,
+3,31,38,14049,
+10,33,35,14049,
+19,30,34,14049,
+15,16,44,14049,
+14,14,45,14049,
+7,8,48,14049,
+8,12,47,14049,
+6,34,35,14049,
+0,4,49,14049,
+26,29,30,14070,
+13,22,42,14070,
+9,20,44,14070,
+5,32,37,14070,
+11,19,44,14070,
+13,32,35,14070,
+17,23,40,14070,
+13,20,43,14070,
+1,4,49,14070,
+3,27,41,14070,
+27,27,31,14094,
+13,27,39,14094,
+13,15,45,14094,
+3,3,49,14094,
+6,28,40,14094,
+16,20,42,14094,
+12,26,40,14094,
+4,10,48,14094,
+20,24,38,14094,
+0,22,44,14094,
+10,32,36,14094,
+0,30,39,14094,
+8,26,41,14094,
+4,31,38,14094,
+14,25,40,14094,
+26,28,31,14104,
+14,17,44,14104,
+15,30,36,14104,
+18,24,39,14104,
+2,4,49,14104,
+4,14,47,14104,
+6,33,36,14104,
+6,9,48,14104,
+1,22,44,14104,
+4,17,46,14104,
+16,22,41,14104,
+7,16,46,14104,
+9,24,42,14104,
+15,26,39,14104,
+1,30,39,14104,
+18,27,37,14104,
+6,19,45,14104,
+9,15,46,14104,
+22,28,34,14104,
+14,28,38,14104,
+2,22,44,14104,
+0,11,48,14104,
+2,30,39,14104,
+25,30,30,14133,
+12,16,45,14133,
+20,27,36,14133,
+6,25,42,14133,
+0,20,45,14133,
+9,30,38,14133,
+0,24,43,14133,
+7,21,44,14133,
+4,27,41,14133,
+13,24,41,14133,
+3,4,49,14133,
+1,11,48,14133,
+0,5,49,14133,
+8,29,39,14133,
+1,20,45,14133,
+21,31,32,14133,
+17,29,36,14133,
+24,25,35,14133,
+1,24,43,14133,
+11,28,39,14133,
+13,31,36,14133,
+25,29,31,14149,
+23,23,37,14149,
+7,23,43,14149,
+17,17,43,14149,
+7,13,47,14149,
+11,25,41,14149,
+1,5,49,14149,
+19,29,35,14149,
+16,27,38,14149,
+13,18,44,14149,
+12,29,38,14149,
+16,18,43,14149,
+5,10,48,14149,
+12,13,46,14149,
+6,32,37,14149,
+3,22,44,14149,
+2,24,43,14149,
+10,27,40,14149,
+26,27,32,14161,
+2,20,45,14161,
+22,24,37,14161,
+2,11,48,14161,
+19,25,38,14161,
+3,30,39,14161,
+23,26,35,14161,
+21,30,33,14161,
+10,11,47,14161,
+10,31,37,14161,
+5,14,47,14161,
+5,31,38,14161,
+7,34,35,14161,
+9,18,45,14161,
+15,21,42,14161,
+2,5,49,14161,
+5,17,46,14161,
+8,8,48,14161,
+16,24,40,14161,
+4,4,49,14161,
+25,28,32,14180,
+11,14,46,14180,
+7,28,40,14180,
+11,34,34,14180,
+10,22,43,14180,
+3,11,48,14180,
+3,24,43,14180,
+9,12,47,14180,
+0,15,47,14180,
+7,9,48,14180,
+16,33,33,14180,
+3,20,45,14180,
+7,33,36,14180,
+12,21,43,14180,
+17,25,39,14180,
+1,15,47,14180,
+3,5,49,14180,
+21,25,37,14180,
+15,29,37,14180,
+5,27,41,14180,
+15,19,43,14180,
+7,19,45,14180,
+11,17,45,14180,
+15,23,41,14180,
+11,33,35,14180,
+16,32,34,14180,
+10,20,44,14180,
+4,22,44,14180,
+8,16,46,14180,
+24,30,31,14227,
+12,23,42,14227,
+4,30,39,14227,
+0,6,49,14227,
+18,32,33,14227,
+9,26,41,14227,
+21,29,34,14227,
+2,15,47,14227,
+7,25,42,14227,
+1,6,49,14227,
+13,30,37,14227,
+22,27,35,14227,
+10,24,42,14227,
+0,26,42,14227,
+6,10,48,14227,
+0,18,46,14227,
+4,11,48,14227,
+6,14,47,14227,
+11,32,36,14227,
+20,21,40,14227,
+4,24,43,14227,
+24,29,32,14254,
+12,19,44,14254,
+1,26,42,14254,
+1,18,46,14254,
+18,31,34,14254,
+14,33,34,14254,
+19,28,36,14254,
+6,17,46,14254,
+26,26,33,14254,
+4,20,45,14254,
+2,6,49,14254,
+0,29,40,14254,
+8,21,44,14254,
+10,15,46,14254,
+6,31,38,14254,
+16,31,35,14254,
+8,13,47,14254,
+4,5,49,14254,
+19,20,41,14254,
+8,23,43,14254,
+17,28,37,14254,
+7,32,37,14254,
+1,29,40,14254,
+9,29,39,14254,
+3,15,47,14254,
+25,27,33,14266,
+2,26,42,14266,
+2,18,46,14266,
+14,22,42,14266,
+18,26,38,14266,
+10,30,38,14266,
+20,26,37,14266,
+2,29,40,14266,
+13,26,40,14266,
+5,22,44,14266,
+14,20,43,14266,
+8,34,35,14266,
+19,22,40,14266,
+14,32,35,14266,
+14,27,39,14266,
+21,22,39,14266,
+6,27,41,14266,
+18,21,41,14266,
+3,6,49,14266,
+14,15,45,14266,
+5,30,39,14266,
+20,32,32,14272,
+8,28,40,14272,
+16,16,44,14272,
+0,12,48,14272,
+24,24,36,14272,
+3,18,46,14272,
+3,26,42,14272,
+18,19,42,14272,
+8,33,36,14272,
+10,18,45,14272,
+8,9,48,14272,
+1,12,48,14272,
+12,28,39,14272,
+24,28,33,14304,
+18,30,35,14304,
+4,15,47,14304,
+8,19,45,14304,
+13,16,45,14304,
+20,31,33,14304,
+5,24,43,14304,
+15,17,44,14304,
+21,28,35,14304,
+0,35,35,14304,
+20,23,39,14304,
+0,7,49,14304,
+15,25,40,14304,
+3,29,40,14304,
+11,27,40,14304,
+12,25,41,14304,
+5,20,45,14304,
+5,11,48,14304,
+23,25,36,14304,
+23,31,31,14316,
+11,31,37,14316,
+1,35,35,14316,
+5,5,49,14316,
+11,11,47,14316,
+1,7,49,14316,
+0,34,36,14316,
+16,30,36,14316,
+2,12,48,14316,
+8,25,42,14316,
+1,34,36,14316,
+15,28,38,14316,
+10,12,47,14316,
+23,30,32,14337,
+9,16,46,14337,
+17,20,42,14337,
+16,26,39,14337,
+14,24,41,14337,
+14,31,36,14337,
+7,10,48,14337,
+4,6,49,14337,
+18,23,40,14337,
+7,31,38,14337,
+7,17,46,14337,
+11,22,43,14337,
+2,35,35,14337,
+17,22,41,14337,
+7,14,47,14337,
+13,13,46,14337,
+13,29,38,14337,
+2,7,49,14337,
+14,18,44,14337,
+22,26,36,14337,
+2,34,36,14337,
+20,30,34,14337,
+4,18,46,14337,
+6,22,44,14337,
+12,14,46,14337,
+12,34,34,14337,
+4,26,42,14337,
+22,23,38,14337,
+6,30,39,14337,
+8,32,37,14337,
+10,26,41,14337,
+4,29,40,14337,
+11,20,44,14337,
+25,26,34,14358,
+3,12,48,14358,
+12,17,45,14358,
+0,33,37,14358,
+9,21,44,14358,
+12,33,35,14358,
+19,24,39,14358,
+13,21,43,14358,
+7,27,41,14358,
+9,13,47,14358,
+9,23,43,14358,
+5,15,47,14358,
+3,7,49,14358,
+1,33,37,14358,
+19,27,37,14358,
+23,29,33,14378,
+3,35,35,14378,
+24,27,34,14394,
+11,24,42,14394,
+3,34,36,14394,
+21,24,38,14394,
+18,29,36,14394,
+6,20,45,14394,
+6,24,43,14394,
+6,11,48,14394,
+16,21,42,14394,
+9,34,35,14394,
+13,23,42,14394,
+5,6,49,14394,
+11,15,46,14394,
+17,27,38,14394,
+10,29,39,14394,
+17,18,43,14394,
+2,33,37,14394,
+12,32,36,14394,
+4,12,48,14394,
+5,26,42,14394,
+9,28,40,14394,
+17,24,40,14394,
+0,23,44,14394,
+5,18,46,14394,
+0,16,47,14394,
+0,8,49,14394,
+0,28,41,14394,
+14,30,37,14394,
+11,30,38,14394,
+4,7,49,14394,
+1,28,41,14394,
+13,19,44,14394,
+16,19,43,14394,
+28,29,29,14461,
+20,29,35,14461,
+5,29,40,14461,
+1,8,49,14461,
+16,23,41,14461,
+9,9,48,14461,
+9,33,36,14461,
+1,16,47,14461,
+21,27,36,14461,
+0,21,45,14461,
+4,35,35,14461,
+16,29,37,14461,
+1,23,44,14461,
+17,33,33,14461,
+3,33,37,14461,
+1,21,45,14461,
+9,19,45,14461,
+8,10,48,14461,
+4,34,36,14461,
+28,28,30,14468,
+0,32,38,14468,
+20,25,38,14468,
+23,28,34,14468,
+22,31,32,14468,
+2,28,41,14468,
+2,8,49,14468,
+8,31,38,14468,
+2,16,47,14468,
+2,23,44,14468,
+17,32,34,14468,
+8,17,46,14468,
+8,14,47,14468,
+7,22,44,14468,
+1,32,38,14468,
+9,25,42,14468,
+18,25,39,14468,
+27,29,30,14504,
+2,21,45,14504,
+7,30,39,14504,
+15,33,34,14504,
+11,18,45,14504,
+6,15,47,14504,
+10,16,46,14504,
+2,32,38,14504,
+14,26,40,14504,
+0,13,48,14504,
+15,22,42,14504,
+5,12,48,14504,
+22,30,33,14504,
+6,6,49,14504,
+12,27,40,14504,
+3,8,49,14504,
+7,20,45,14504,
+11,12,47,14504,
+7,24,43,14504,
+27,28,31,14525,
+12,31,37,14525,
+4,33,37,14525,
+19,32,33,14525,
+8,27,41,14525,
+3,23,44,14525,
+23,24,37,14525,
+15,32,35,14525,
+3,16,47,14525,
+1,13,48,14525,
+0,25,43,14525,
+3,28,41,14525,
+7,11,48,14525,
+15,20,43,14525,
+13,28,39,14525,
+9,32,37,14525,
+1,25,43,14525,
+13,25,41,14525,
+5,7,49,14525,
+3,21,45,14525,
+5,35,35,14525,
+25,25,35,14525,
+17,31,35,14525,
+15,27,39,14525,
+15,15,45,14525,
+6,26,42,14525,
+26,30,30,14527,
+6,18,46,14527,
+2,13,48,14527,
+3,32,38,14527,
+6,29,40,14527,
+14,16,45,14527,
+0,19,46,14527,
+5,34,36,14527,
+18,28,37,14527,
+10,21,44,14527,
+12,22,43,14527,
+24,26,35,14527,
+10,13,47,14527,
+11,26,41,14527,
+19,31,34,14527,
+26,29,31,14558,
+10,23,43,14558,
+2,25,43,14558,
+22,25,37,14558,
+1,19,46,14558,
+20,28,36,14558,
+12,20,44,14558,
+16,17,44,14558,
+4,8,49,14558,
+20,20,41,14558,
+19,26,38,14558,
+13,14,46,14558,
+4,23,44,14558,
+4,16,47,14558,
+16,25,40,14558,
+4,28,41,14558,
+10,34,35,14558,
+2,19,46,14558,
+14,29,38,14558,
+22,29,34,14558,
+13,34,34,14558,
+15,31,36,14558,
+27,27,32,14594,
+0,9,49,14594,
+4,21,45,14594,
+0,31,39,14594,
+21,21,40,14594,
+3,13,48,14594,
+15,24,41,14594,
+3,25,43,14594,
+5,33,37,14594,
+13,33,35,14594,
+19,21,41,14594,
+13,17,45,14594,
+7,15,47,14594,
+1,31,39,14594,
+11,29,39,14594,
+23,27,35,14594,
+1,9,49,14594,
+26,28,32,14602,
+8,22,44,14602,
+4,32,38,14602,
+12,24,42,14602,
+20,22,40,14602,
+10,28,40,14602,
+16,28,38,14602,
+6,12,48,14602,
+17,30,36,14602,
+9,10,48,14602,
+15,18,44,14602,
+8,30,39,14602,
+10,33,36,14602,
+12,15,46,14602,
+9,14,47,14602,
+14,21,43,14602,
+21,26,37,14602,
+6,35,35,14602,
+2,31,39,14602,
+9,17,46,14602,
+19,19,42,14602,
+2,9,49,14602,
+25,30,31,14619,
+10,19,45,14619,
+3,19,46,14619,
+6,7,49,14619,
+17,26,39,14619,
+9,31,38,14619,
+19,30,35,14619,
+6,34,36,14619,
+18,20,42,14619,
+12,30,38,14619,
+7,18,46,14619,
+8,24,43,14619,
+8,20,45,14619,
+21,32,32,14619,
+10,25,42,14619,
+14,23,42,14619,
+4,13,48,14619,
+18,22,41,14619,
+13,32,36,14619,
+7,26,42,14619,
+8,11,48,14619,
+22,22,39,14619,
+5,16,47,14619,
+19,23,40,14619,
+4,25,43,14619,
+5,23,44,14619,
+5,28,41,14619,
+7,29,40,14619,
+5,8,49,14619,
+25,29,32,14654,
+5,21,45,14654,
+21,23,39,14654,
+9,27,41,14654,
+21,31,33,14654,
+3,31,39,14654,
+3,9,49,14654,
+12,18,45,14654,
+14,19,44,14654,
+4,19,46,14654,
+5,32,38,14654,
+10,32,37,14654,
+0,27,42,14654,
+22,28,35,14654,
+11,16,46,14654,
+17,21,42,14654,
+1,27,42,14654,
+15,30,37,14654,
+26,27,33,14684,
+6,33,37,14684,
+12,12,47,14684,
+21,30,34,14684,
+24,25,36,14684,
+20,24,39,14684,
+18,27,38,14684,
+2,27,42,14684,
+18,18,43,14684,
+7,12,48,14684,
+19,29,36,14684,
+20,27,37,14684,
+0,17,47,14684,
+11,21,44,14684,
+25,28,33,14711,
+4,9,49,14711,
+24,31,31,14711,
+4,31,39,14711,
+8,15,47,14711,
+13,27,40,14711,
+5,13,48,14711,
+5,25,43,14711,
+7,7,49,14711,
+11,23,43,14711,
+17,29,37,14711,
+17,19,43,14711,
+11,13,47,14711,
+7,35,35,14711,
+1,17,47,14711,
+13,31,37,14711,
+17,23,41,14711,
+0,14,48,14711,
+0,30,40,14711,
+24,30,32,14717,
+18,24,40,14717,
+0,0,50,14717,
+0,10,49,14717,
+6,23,44,14717,
+12,26,41,14717,
+16,33,34,14717,
+1,30,40,14717,
+9,22,44,14717,
+6,16,47,14717,
+7,34,36,14717,
+1,14,48,14717,
+14,28,39,14717,
+23,26,36,14717,
+15,26,40,14717,
+6,28,41,14717,
+0,1,50,14717,
+6,8,49,14717,
+14,25,41,14717,
+23,23,38,14717,
+2,17,47,14717,
+6,21,45,14717,
+1,10,49,14717,
+5,19,46,14717,
+13,22,43,14717,
+11,34,35,14717,
+18,33,33,14717,
+9,30,39,14717,
+1,1,50,14717,
+3,27,42,14717,
+8,18,46,14717,
+10,10,48,14717,
+18,32,34,14717,
+8,26,42,14717,
+2,30,40,14717,
+16,22,42,14717,
+22,24,38,14717,
+0,2,50,14717,
+6,32,38,14717,
+2,14,48,14717,
+13,20,44,14717,
+1,2,50,14717,
+10,17,46,14717,
+2,10,49,14717,
+16,32,35,14717,
+10,14,47,14717,
+16,20,43,14717,
+8,29,40,14717,
+10,31,38,14717,
+11,28,40,14717,
+24,29,33,14774,
+9,11,48,14774,
+15,16,45,14774,
+12,29,39,14774,
+16,27,39,14774,
+9,24,43,14774,
+11,33,36,14774,
+9,20,45,14774,
+7,33,37,14774,
+11,19,45,14774,
+19,25,39,14774,
+21,29,35,14774,
+3,17,47,14774,
+5,31,39,14774,
+5,9,49,14774,
+14,34,34,14774,
+14,14,46,14774,
+26,26,34,14777,
+2,2,50,14777,
+0,3,50,14777,
+22,27,36,14777,
+3,30,40,14777,
+6,13,48,14777,
+4,27,42,14777,
+3,14,48,14777,
+0,22,45,14777,
+13,24,42,14777,
+3,10,49,14777,
+1,3,50,14777,
+6,25,43,14777,
+14,33,35,14777,
+1,22,45,14777,
+15,29,38,14777,
+25,27,34,14796,
+13,15,46,14796,
+11,25,42,14796,
+10,27,41,14796,
+14,17,45,14796,
+18,31,35,14796,
+21,25,38,14796,
+8,12,48,14796,
+0,24,44,14796,
+6,19,46,14796,
+13,30,38,14796,
+1,24,44,14796,
+16,24,41,14796,
+2,22,45,14796,
+2,3,50,14796,
+20,32,33,14796,
+16,31,36,14796,
+8,35,35,14796,
+11,32,37,14796,
+23,31,32,14830,
+19,28,37,14830,
+7,8,49,14830,
+17,25,40,14830,
+4,17,47,14830,
+17,17,44,14830,
+7,28,41,14830,
+7,23,44,14830,
+7,16,47,14830,
+7,21,45,14830,
+9,15,47,14830,
+15,21,43,14830,
+14,32,36,14830,
+0,20,46,14830,
+0,4,50,14830,
+24,28,34,14833,
+2,24,44,14833,
+16,18,44,14833,
+8,34,36,14833,
+12,16,46,14833,
+4,30,40,14833,
+4,14,48,14833,
+4,10,49,14833,
+1,4,50,14833,
+20,31,34,14833,
+7,32,38,14833,
+1,20,46,14833,
+17,28,38,14833,
+3,22,45,14833,
+6,9,49,14833,
+13,18,45,14833,
+5,27,42,14833,
+3,3,50,14833,
+6,31,39,14833,
+15,23,42,14833,
+23,30,33,14858,
+2,4,50,14858,
+10,22,44,14858,
+18,30,36,14858,
+2,20,46,14858,
+20,26,38,14858,
+24,24,37,14858,
+0,35,36,14858,
+10,30,39,14858,
+3,24,44,14858,
+21,28,36,14858,
+9,26,42,14858,
+9,18,46,14858,
+12,21,44,14858,
+18,26,39,14858,
+12,13,47,14858,
+0,29,41,14858,
+8,33,37,14858,
+7,13,48,14858,
+1,35,36,14858,
+0,11,49,14858,
+15,19,44,14858,
+12,23,43,14858,
+9,29,40,14858,
+20,21,41,14858,
+5,17,47,14858,
+1,29,41,14858,
+7,25,43,14858,
+1,11,49,14858,
+29,29,29,14911,
+23,25,37,14911,
+2,35,36,14911,
+5,30,40,14911,
+19,20,42,14911,
+12,34,35,14911,
+10,24,43,14911,
+5,14,48,14911,
+28,29,30,14925,
+4,22,45,14925,
+21,22,40,14925,
+3,4,50,14925,
+20,30,35,14925,
+0,34,37,14925,
+16,30,37,14925,
+0,5,50,14925,
+0,26,43,14925,
+10,11,48,14925,
+10,20,45,14925,
+14,27,40,14925,
+3,20,46,14925,
+11,31,38,14925,
+19,22,41,14925,
+14,31,37,14925,
+1,26,43,14925,
+11,14,47,14925,
+1,34,37,14925,
+7,19,46,14925,
+2,11,49,14925,
+5,10,49,14925,
+23,29,34,14925,
+1,5,50,14925,
+13,26,41,14925,
+25,26,35,14925,
+2,29,41,14925,
+11,17,46,14925,
+12,28,40,14925,
+4,24,44,14925,
+22,26,37,14925,
+27,30,30,14963,
+6,27,42,14963,
+14,22,43,14963,
+8,23,44,14963,
+9,12,48,14963,
+0,15,48,14963,
+2,5,50,14963,
+8,28,41,14963,
+12,33,36,14963,
+8,8,49,14963,
+2,34,37,14963,
+20,23,40,14963,
+18,21,42,14963,
+2,26,43,14963,
+8,16,47,14963,
+28,28,31,14963,
+8,21,45,14963,
+1,15,48,14963,
+15,28,39,14963,
+12,19,45,14963,
+24,27,35,14963,
+3,35,36,14963,
+11,27,41,14963,
+27,29,31,14985,
+7,31,39,14985,
+3,29,41,14985,
+13,29,39,14985,
+9,35,35,14985,
+15,25,41,14985,
+3,11,49,14985,
+7,9,49,14985,
+4,4,50,14985,
+8,32,38,14985,
+14,20,44,14985,
+16,26,40,14985,
+4,20,46,14985,
+22,32,32,14985,
+9,34,36,14985,
+12,25,42,14985,
+0,33,38,14985,
+0,18,47,14985,
+2,15,48,14985,
+22,23,39,14985,
+1,33,38,14985,
+3,26,43,14985,
+18,29,37,14985,
+18,19,43,14985,
+1,18,47,14985,
+3,34,37,14985,
+5,22,45,14985,
+17,33,34,14985,
+6,17,47,14985,
+22,31,33,14985,
+19,27,38,14985,
+10,15,47,14985,
+3,5,50,14985,
+18,23,41,14985,
+6,30,40,14985,
+14,24,42,14985,
+0,6,50,14985,
+6,14,48,14985,
+4,35,36,14985,
+2,18,47,14985,
+15,34,34,14985,
+26,30,31,15022,
+5,24,44,15022,
+6,10,49,15022,
+12,32,37,15022,
+16,16,45,15022,
+2,33,38,15022,
+1,6,50,15022,
+27,28,32,15022,
+20,29,36,15022,
+8,13,48,15022,
+14,15,46,15022,
+19,24,40,15022,
+17,22,42,15022,
+17,32,35,15022,
+4,29,41,15022,
+23,28,35,15022,
+21,24,39,15022,
+3,15,48,15022,
+8,25,43,15022,
+4,11,49,15022,
+17,20,43,15022,
+15,17,45,15022,
+19,33,33,15022,
+15,33,35,15022,
+21,27,37,15022,
+9,33,37,15022,
+17,27,39,15022,
+10,26,42,15022,
+22,30,34,15022,
+2,6,50,15022,
+14,30,38,15022,
+10,18,46,15022,
+4,26,43,15022,
+4,34,37,15022,
+19,32,34,15022,
+11,22,44,15022,
+16,29,38,15022,
+8,19,46,15022,
+26,29,32,15059,
+13,16,46,15059,
+10,29,40,15059,
+5,20,46,15059,
+4,5,50,15059,
+11,30,39,15059,
+3,18,47,15059,
+3,33,38,15059,
+7,27,42,15059,
+0,32,39,15059,
+14,18,45,15059,
+3,6,50,15059,
+0,12,49,15059,
+4,15,48,15059,
+6,22,45,15059,
+15,32,36,15059,
+17,31,36,15059,
+11,20,45,15059,
+16,21,43,15059,
+5,35,36,15059,
+9,23,44,15059,
+8,9,49,15059,
+8,31,39,15059,
+20,25,39,15059,
+9,16,47,15059,
+1,12,49,15059,
+13,21,44,15059,
+25,25,36,15064,
+11,24,43,15064,
+1,32,39,15064,
+9,28,41,15064,
+17,24,41,15064,
+11,11,48,15064,
+25,31,31,15103,
+5,29,41,15103,
+13,13,47,15103,
+9,21,45,15103,
+19,31,35,15103,
+5,11,49,15103,
+27,27,33,15103,
+13,23,43,15103,
+7,17,47,15103,
+24,26,36,15103,
+6,24,44,15103,
+0,28,42,15103,
+10,12,48,15103,
+2,12,49,15103,
+12,31,38,15103,
+23,24,38,15103,
+0,7,50,15103,
+9,32,38,15103,
+1,28,42,15103,
+12,14,47,15103,
+26,28,33,15121,
+2,32,39,15121,
+7,14,48,15121,
+17,18,44,15121,
+12,17,46,15121,
+18,25,40,15121,
+16,23,42,15121,
+4,33,38,15121,
+25,30,32,15121,
+4,18,47,15121,
+7,30,40,15121,
+7,10,49,15121,
+5,26,43,15121,
+22,29,35,15121,
+10,35,35,15121,
+5,34,37,15121,
+5,5,50,15121,
+13,34,35,15121,
+1,7,50,15121,
+2,28,42,15121,
+18,28,38,15121,
+10,34,36,15121,
+4,6,50,15121,
+6,20,46,15121,
+22,25,38,15121,
+14,26,41,15121,
+13,28,40,15121,
+2,7,50,15121,
+20,28,37,15121,
+16,19,44,15121,
+21,32,33,15131,
+15,27,40,15131,
+0,23,45,15131,
+12,27,41,15131,
+9,13,48,15131,
+3,12,49,15131,
+13,33,36,15131,
+23,27,36,15131,
+3,32,39,15131,
+5,15,48,15131,
+13,19,45,15131,
+9,25,43,15131,
+11,15,47,15131,
+1,23,45,15131,
+15,31,37,15131,
+25,29,33,15160,
+8,27,42,15160,
+19,30,36,15160,
+0,21,46,15160,
+6,35,36,15160,
+3,28,42,15160,
+3,7,50,15160,
+15,22,43,15160,
+10,33,37,15160,
+2,23,45,15160,
+14,29,39,15160,
+17,30,37,15160,
+5,33,38,15160,
+13,25,42,15160,
+9,19,46,15160,
+1,21,46,15160,
+6,29,41,15160,
+7,22,45,15160,
+6,11,49,15160,
+21,31,34,15160,
+5,18,47,15160,
+19,26,39,15160,
+0,16,48,15160,
+24,31,32,15204,
+6,26,43,15204,
+21,26,38,15204,
+4,12,49,15204,
+15,20,44,15204,
+0,25,44,15204,
+26,27,34,15204,
+11,18,46,15204,
+5,6,50,15204,
+16,28,39,15204,
+1,16,48,15204,
+4,32,39,15204,
+0,31,40,15204,
+7,24,44,15204,
+2,21,46,15204,
+11,26,42,15204,
+6,34,37,15204,
+1,25,44,15204,
+1,31,40,15204,
+11,29,40,15204,
+13,32,37,15204,
+16,25,41,15204,
+8,17,47,15204,
+9,31,39,15204,
+21,21,41,15204,
+9,9,49,15204,
+3,23,45,15204,
+22,28,36,15204,
+20,20,42,15204,
+2,16,48,15204,
+0,8,50,15204,
+8,30,40,15204,
+12,22,44,15204,
+4,28,42,15204,
+8,14,48,15204,
+2,25,44,15204,
+2,31,40,15204,
+15,24,42,15204,
+20,22,41,15204,
+12,30,39,15204,
+17,26,40,15204,
+24,30,33,15244,
+7,20,46,15244,
+4,7,50,15244,
+10,23,44,15244,
+25,28,34,15244,
+10,28,41,15244,
+10,16,47,15244,
+6,15,48,15244,
+8,10,49,15244,
+1,8,50,15244,
+3,21,46,15244,
+21,30,35,15244,
+19,21,42,15244,
+15,15,46,15244,
+10,21,45,15244,
+14,16,46,15244,
+22,22,40,15244,
+10,32,38,15244,
+16,34,34,15244,
+2,8,50,15244,
+3,16,48,15244,
+15,30,38,15244,
+11,12,48,15244,
+18,33,34,15244,
+6,18,47,15244,
+12,24,43,15244,
+6,33,38,15244,
+12,20,45,15244,
+0,13,49,15244,
+7,35,36,15244,
+16,33,35,15244,
+4,23,45,15244,
+24,25,37,15254,
+21,23,40,15254,
+16,17,45,15254,
+3,31,40,15254,
+5,12,49,15254,
+0,19,47,15254,
+5,32,39,15254,
+3,25,44,15254,
+11,35,35,15254,
+19,23,41,15254,
+7,29,41,15254,
+19,29,37,15254,
+19,19,43,15254,
+1,19,47,15254,
+1,13,49,15254,
+7,11,49,15254,
+6,6,50,15254,
+18,22,42,15254,
+10,13,48,15254,
+20,27,38,15254,
+3,8,50,15254,
+14,21,44,15254,
+18,32,35,15254,
+5,28,42,15254,
+18,20,43,15254,
+8,22,45,15254,
+24,29,34,15296,
+4,21,46,15296,
+11,34,36,15296,
+13,31,38,15296,
+23,26,37,15296,
+2,13,49,15296,
+14,23,43,15296,
+2,19,47,15296,
+7,26,43,15296,
+17,29,38,15296,
+18,27,39,15296,
+10,25,43,15296,
+7,34,37,15296,
+15,18,45,15296,
+9,27,42,15296,
+13,14,47,15296,
+5,7,50,15296,
+13,17,46,15296,
+16,32,36,15296,
+20,24,40,15296,
+8,24,44,15296,
+4,16,48,15296,
+14,34,35,15296,
+4,25,44,15296,
+10,19,46,15296,
+23,32,32,15332,
+26,26,35,15332,
+4,31,40,15332,
+21,29,36,15332,
+12,15,47,15332,
+7,15,48,15332,
+20,33,33,15332,
+0,27,43,15332,
+17,21,43,15332,
+23,31,33,15354,
+5,23,45,15354,
+3,13,49,15354,
+3,19,47,15354,
+25,27,35,15354,
+9,17,47,15354,
+23,23,39,15354,
+13,27,41,15354,
+11,33,37,15354,
+1,27,43,15354,
+14,28,40,15354,
+4,8,50,15354,
+20,32,34,15354,
+8,20,46,15354,
+14,33,36,15354,
+0,30,41,15354,
+22,24,39,15354,
+0,9,50,15354,
+18,24,41,15354,
+6,12,49,15354,
+9,14,48,15354,
+6,32,39,15354,
+18,31,36,15354,
+9,30,40,15354,
+14,19,45,15354,
+7,18,47,15354,
+1,9,50,15354,
+7,33,38,15354,
+2,27,43,15354,
+15,26,41,15354,
+17,23,42,15354,
+22,27,37,15354,
+29,29,30,15398,
+9,10,49,15398,
+5,21,46,15398,
+1,30,41,15398,
+10,31,39,15398,
+18,18,44,15398,
+28,30,30,15408,
+12,18,46,15408,
+6,28,42,15408,
+12,26,42,15408,
+23,30,34,15408,
+2,30,41,15408,
+12,29,40,15408,
+24,28,35,15408,
+16,27,40,15408,
+2,9,50,15408,
+5,16,48,15408,
+14,25,42,15408,
+6,7,50,15408,
+8,35,36,15408,
+5,31,40,15408,
+11,23,44,15408,
+4,13,49,15408,
+19,25,40,15408,
+28,29,31,15427,
+8,29,41,15427,
+17,19,44,15427,
+11,16,47,15427,
+20,31,35,15427,
+5,25,44,15427,
+16,31,37,15427,
+11,28,41,15427,
+8,11,49,15427,
+4,19,47,15427,
+3,27,43,15427,
+15,29,39,15427,
+11,21,45,15427,
+21,25,39,15427,
+11,32,38,15427,
+8,26,43,15427,
+13,22,44,15427,
+8,34,37,15427,
+5,8,50,15427,
+16,22,43,15427,
+14,32,37,15427,
+19,28,38,15427,
+3,9,50,15427,
+3,30,41,15427,
+9,22,45,15427,
+6,23,45,15427,
+27,30,31,15461,
+13,30,39,15461,
+12,12,48,15461,
+16,20,44,15461,
+0,36,36,15461,
+28,28,32,15470,
+8,15,48,15470,
+1,36,36,15470,
+9,24,44,15470,
+18,30,37,15470,
+10,27,42,15470,
+0,17,48,15470,
+6,21,46,15470,
+13,20,45,15470,
+0,35,37,15470,
+7,32,39,15470,
+17,28,39,15470,
+21,28,37,15470,
+7,12,49,15470,
+1,17,48,15470,
+13,24,43,15470,
+4,27,43,15470,
+27,29,32,15492,
+12,35,35,15492,
+11,13,48,15492,
+23,29,35,15492,
+17,25,41,15492,
+11,25,43,15492,
+5,19,47,15492,
+1,35,37,15492,
+5,13,49,15492,
+24,24,38,15492,
+12,34,36,15492,
+16,24,42,15492,
+6,16,48,15492,
+2,36,36,15492,
+20,30,36,15492,
+0,14,49,15492,
+6,31,40,15492,
+7,28,42,15492,
+4,9,50,15492,
+15,16,46,15492,
+6,25,44,15492,
+25,26,36,15492,
+20,26,39,15492,
+4,30,41,15492,
+9,20,46,15492,
+8,33,38,15492,
+2,17,48,15492,
+22,32,33,15492,
+8,18,47,15492,
+11,19,46,15492,
+1,14,49,15492,
+7,7,50,15492,
+26,31,31,15520,
+2,35,37,15520,
+10,17,47,15520,
+23,25,38,15520,
+0,34,38,15520,
+6,8,50,15520,
+18,26,40,15520,
+26,30,32,15533,
+10,14,48,15533,
+0,10,50,15533,
+10,30,40,15533,
+16,30,38,15533,
+0,22,46,15533,
+14,31,38,15533,
+1,10,50,15533,
+10,10,49,15533,
+0,24,45,15533,
+24,27,36,15533,
+1,34,38,15533,
+22,31,34,15533,
+17,34,34,15533,
+2,14,49,15533,
+14,14,47,15533,
+1,22,46,15533,
+3,36,36,15533,
+0,0,51,15533,
+14,17,46,15533,
+0,1,51,15533,
+9,35,36,15533,
+15,21,44,15533,
+12,33,37,15533,
+27,28,33,15561,
+1,24,45,15561,
+3,17,48,15561,
+15,23,43,15561,
+1,1,51,15561,
+17,33,35,15561,
+9,11,49,15561,
+17,17,45,15561,
+5,27,43,15561,
+9,29,41,15561,
+11,31,39,15561,
+13,15,47,15561,
+3,35,37,15561,
+7,23,45,15561,
+2,34,38,15561,
+2,22,46,15561,
+22,26,38,15561,
+2,10,50,15561,
+16,18,45,15561,
+0,29,42,15561,
+20,21,42,15561,
+0,2,51,15561,
+2,24,45,15561,
+9,26,43,15561,
+6,19,47,15561,
+19,33,34,15561,
+9,34,37,15561,
+1,29,42,15561,
+5,9,50,15561,
+7,21,46,15561,
+5,30,41,15561,
+26,29,33,15585,
+21,22,41,15585,
+1,2,51,15585,
+15,34,35,15585,
+6,13,49,15585,
+14,27,41,15585,
+3,14,49,15585,
+4,36,36,15585,
+3,10,50,15585,
+8,32,39,15585,
+13,26,42,15585,
+15,28,40,15585,
+2,2,51,15585,
+12,28,41,15585,
+4,17,48,15585,
+18,29,38,15585,
+7,16,48,15585,
+23,28,36,15585,
+3,34,38,15585,
+0,20,47,15585,
+12,16,47,15585,
+13,18,46,15585,
+2,29,42,15585,
+19,22,42,15585,
+17,32,36,15585,
+22,30,35,15585,
+3,22,46,15585,
+8,12,49,15585,
+10,22,45,15585,
+12,23,44,15585,
+3,24,45,15585,
+7,25,44,15585,
+13,29,40,15585,
+15,33,36,15585,
+9,15,48,15585,
+19,20,43,15585,
+19,32,35,15585,
+20,23,41,15585,
+4,35,37,15585,
+25,31,32,15610,
+7,31,40,15610,
+12,21,45,15610,
+0,33,39,15610,
+0,3,51,15610,
+1,20,47,15610,
+20,29,37,15610,
+15,19,45,15610,
+1,33,39,15610,
+19,27,39,15610,
+1,3,51,15610,
+10,24,44,15610,
+8,28,42,15610,
+12,32,38,15610,
+0,26,44,15610,
+1,26,44,15610,
+7,8,50,15610,
+22,23,40,15610,
+4,14,49,15610,
+16,26,41,15610,
+2,20,47,15610,
+25,30,33,15636,
+15,25,42,15636,
+18,21,43,15636,
+9,18,47,15636,
+21,27,38,15636,
+2,3,51,15636,
+27,27,34,15636,
+3,29,42,15636,
+2,33,39,15636,
+9,33,38,15636,
+11,27,42,15636,
+6,27,43,15636,
+14,22,44,15636,
+10,20,46,15636,
+2,26,44,15636,
+26,28,34,15650,
+4,22,46,15650,
+4,10,50,15650,
+4,34,38,15650,
+21,24,40,15650,
+6,30,41,15650,
+18,23,42,15650,
+5,36,36,15650,
+4,24,45,15650,
+12,13,48,15650,
+0,4,51,15650,
+14,30,39,15650,
+6,9,50,15650,
+16,29,39,15650,
+8,23,45,15650,
+5,17,48,15650,
+17,27,40,15650,
+3,20,47,15650,
+19,31,36,15650,
+15,32,37,15650,
+1,4,51,15650,
+12,25,43,15650,
+19,24,41,15650,
+11,17,47,15650,
+5,35,37,15650,
+7,19,47,15650,
+3,33,39,15650,
+21,33,33,15650,
+3,3,51,15650,
+25,25,37,15650,
+13,35,35,15650,
+7,13,49,15650,
+17,31,37,15650,
+14,20,45,15650,
+11,30,40,15650,
+4,29,42,15650,
+8,21,46,15650,
+18,19,44,15650,
+13,34,36,15650,
+11,14,48,15650,
+2,4,51,15650,
+0,11,50,15650,
+24,26,37,15670,
+10,35,36,15670,
+3,26,44,15670,
+12,19,46,15670,
+14,24,43,15670,
+21,32,34,15670,
+22,29,36,15670,
+25,29,34,15699,
+1,11,50,15699,
+10,29,41,15699,
+17,22,43,15699,
+10,11,49,15699,
+5,14,49,15699,
+0,32,40,15699,
+24,32,32,15715,
+8,16,48,15715,
+2,11,50,15715,
+10,26,43,15715,
+8,31,40,15715,
+1,32,40,15715,
+10,34,37,15715,
+5,10,50,15715,
+20,25,40,15715,
+4,20,47,15715,
+17,20,44,15715,
+8,25,44,15715,
+5,22,46,15715,
+5,34,38,15715,
+24,31,33,15736,
+12,31,39,15736,
+0,15,49,15736,
+9,32,39,15736,
+23,24,39,15736,
+5,24,45,15736,
+3,4,51,15736,
+9,12,49,15736,
+0,5,51,15736,
+4,33,39,15736,
+1,15,49,15736,
+1,5,51,15736,
+7,27,43,15736,
+21,31,35,15736,
+23,27,37,15736,
+13,33,37,15736,
+6,36,36,15736,
+16,16,46,15736,
+20,28,38,15736,
+4,26,44,15736,
+2,32,40,15736,
+8,8,50,15736,
+0,18,48,15736,
+10,15,48,15736,
+9,28,42,15736,
+1,18,48,15736,
+17,24,42,15736,
+18,28,39,15736,
+6,17,48,15736,
+14,15,47,15736,
+18,25,41,15736,
+5,29,42,15736,
+22,25,39,15736,
+6,35,37,15736,
+26,27,35,15769,
+11,22,45,15769,
+2,5,51,15769,
+19,30,37,15769,
+15,17,46,15769,
+15,31,38,15769,
+3,11,50,15769,
+7,30,41,15769,
+7,9,50,15769,
+2,15,49,15769,
+24,30,34,15781,
+2,18,48,15781,
+10,33,38,15781,
+17,30,38,15781,
+6,14,49,15781,
+16,21,44,15781,
+4,4,51,15781,
+0,28,43,15781,
+11,24,44,15781,
+10,18,47,15781,
+3,32,40,15781,
+8,13,49,15781,
+13,16,47,15781,
+8,19,47,15781,
+16,23,43,15781,
+1,28,43,15781,
+13,23,44,15781,
+13,28,41,15781,
+5,20,47,15781,
+25,28,35,15795,
+3,5,51,15795,
+15,27,41,15795,
+5,33,39,15795,
+3,15,49,15795,
+13,21,45,15795,
+9,23,45,15795,
+6,34,38,15795,
+6,22,46,15795,
+18,34,34,15795,
+14,26,42,15795,
+14,18,46,15795,
+6,10,50,15795,
+0,6,51,15795,
+12,27,42,15795,
+16,34,35,15795,
+19,26,40,15795,
+2,28,43,15795,
+11,20,46,15795,
+5,26,44,15795,
+4,11,50,15795,
+21,30,36,15795,
+22,28,37,15795,
+13,32,38,15795,
+14,29,40,15795,
+3,18,48,15795,
+6,24,45,15795,
+9,21,46,15795,
+21,26,39,15795,
+17,18,45,15795,
+18,33,35,15795,
+1,6,51,15795,
+4,32,40,15795,
+16,28,40,15795,
+7,36,36,15795,
+9,16,48,15795,
+2,6,51,15795,
+6,29,42,15795,
+16,33,36,15795,
+29,30,30,15876,
+16,19,45,15876,
+23,32,33,15876,
+4,5,51,15876,
+12,17,47,15876,
+9,31,40,15876,
+9,25,44,15876,
+3,28,43,15876,
+13,13,48,15876,
+8,27,43,15876,
+11,35,36,15876,
+4,15,49,15876,
+24,29,35,15876,
+7,17,48,15876,
+0,31,41,15876,
+29,29,31,15895,
+1,31,41,15895,
+11,11,49,15895,
+7,35,37,15895,
+13,25,43,15895,
+11,29,41,15895,
+12,14,48,15895,
+18,32,36,15895,
+4,18,48,15895,
+0,12,50,15895,
+12,30,40,15895,
+10,12,49,15895,
+8,30,41,15895,
+24,25,38,15895,
+20,33,34,15895,
+8,9,50,15895,
+16,25,42,15895,
+15,22,44,15895,
+1,12,50,15895,
+6,20,47,15895,
+0,23,46,15895,
+10,32,39,15895,
+28,30,31,15907,
+1,23,46,15907,
+23,31,34,15907,
+3,6,51,15907,
+13,19,46,15907,
+5,11,50,15907,
+6,33,39,15907,
+14,35,35,15907,
+21,21,42,15907,
+19,29,38,15907,
+11,26,43,15907,
+17,26,41,15907,
+11,34,37,15907,
+15,30,39,15907,
+7,14,49,15907,
+2,31,41,15907,
+2,12,50,15907,
+26,26,36,15907,
+14,34,36,15907,
+10,28,42,15907,
+20,22,42,15907,
+6,26,44,15907,
+16,32,37,15907,
+20,32,35,15907,
+7,34,38,15907,
+4,28,43,15907,
+20,20,43,15907,
+2,23,46,15907,
+22,22,41,15907,
+7,22,46,15907,
+5,32,40,15907,
+28,29,32,15938,
+23,26,38,15938,
+7,10,50,15938,
+0,21,47,15938,
+7,24,45,15938,
+15,24,43,15938,
+11,15,48,15938,
+15,20,45,15938,
+0,25,45,15938,
+20,27,39,15938,
+0,7,51,15938,
+25,27,36,15938,
+19,21,43,15938,
+17,29,39,15938,
+9,19,47,15938,
+1,7,51,15938,
+21,23,41,15938,
+21,29,37,15938,
+1,25,45,15938,
+5,15,49,15938,
+13,31,39,15938,
+1,21,47,15938,
+9,13,49,15938,
+3,31,41,15938,
+5,5,51,15938,
+27,31,31,15948,
+27,30,32,15962,
+18,27,40,15962,
+12,22,45,15962,
+3,12,50,15962,
+5,18,48,15962,
+4,6,51,15962,
+2,7,51,15962,
+14,33,37,15962,
+2,25,45,15962,
+11,18,47,15962,
+19,23,42,15962,
+11,33,38,15962,
+10,23,45,15962,
+2,21,47,15962,
+23,30,35,15962,
+18,31,37,15962,
+3,23,46,15962,
+7,29,42,15962,
+24,28,36,15962,
+8,36,36,15962,
+12,24,44,15962,
+6,11,50,15962,
+18,22,43,15962,
+28,28,33,15983,
+22,27,38,15983,
+20,31,36,15983,
+8,17,48,15983,
+10,21,46,15983,
+0,16,49,15983,
+20,24,41,15983,
+23,23,40,15983,
+4,31,41,15983,
+7,20,47,15983,
+1,16,49,15983,
+19,19,44,15983,
+8,35,37,15983,
+5,28,43,15983,
+3,25,45,15983,
+27,29,33,16004,
+3,7,51,16004,
+3,21,47,16004,
+15,15,47,16004,
+7,33,39,16004,
+9,27,43,16004,
+22,24,40,16004,
+6,32,40,16004,
+10,16,48,16004,
+4,12,50,16004,
+18,20,44,16004,
+12,20,46,16004,
+14,16,47,16004,
+14,28,41,16004,
+10,25,44,16004,
+14,23,44,16004,
+10,31,40,16004,
+4,23,46,16004,
+16,31,38,16004,
+2,16,49,16004,
+8,14,49,16004,
+16,17,46,16004,
+7,26,44,16004,
+26,31,32,16026,
+13,27,42,16026,
+9,30,41,16026,
+14,21,45,16026,
+6,15,49,16026,
+5,6,51,16026,
+9,9,50,16026,
+22,33,33,16026,
+8,22,46,16026,
+18,24,42,16026,
+22,32,34,16026,
+14,32,38,16026,
+0,30,42,16026,
+8,10,50,16026,
+8,34,38,16026,
+6,18,48,16026,
+26,30,33,16056,
+0,27,44,16056,
+15,18,46,16056,
+0,19,48,16056,
+12,35,36,16056,
+15,26,42,16056,
+0,8,51,16056,
+1,30,42,16056,
+0,36,37,16056,
+8,24,45,16056,
+17,21,44,16056,
+23,29,36,16056,
+21,25,40,16056,
+16,27,41,16056,
+1,36,37,16056,
+11,12,49,16056,
+4,21,47,16056,
+1,8,51,16056,
+1,27,44,16056,
+3,16,49,16056,
+19,28,39,16056,
+11,32,39,16056,
+1,19,48,16056,
+12,29,41,16056,
+4,7,51,16056,
+15,29,40,16056,
+4,25,45,16056,
+19,25,41,16056,
+13,17,47,16056,
+5,31,41,16056,
+17,23,43,16056,
+2,30,42,16056,
+18,30,38,16056,
+2,8,51,16056,
+2,36,37,16056,
+13,30,40,16056,
+20,30,37,16056,
+2,19,48,16056,
+2,27,44,16056,
+0,35,38,16056,
+11,28,42,16056,
+0,13,50,16056,
+8,29,42,16056,
+27,28,34,16081,
+5,12,50,16081,
+6,28,43,16081,
+12,26,43,16081,
+12,34,37,16081,
+13,14,48,16081,
+21,28,38,16081,
+25,26,37,16081,
+22,31,35,16081,
+10,13,49,16081,
+1,35,38,16081,
+5,23,46,16081,
+1,13,50,16081,
+10,19,47,16081,
+14,25,43,16081,
+17,34,35,16081,
+7,11,50,16081,
+9,36,36,16081,
+8,20,47,16081,
+2,13,50,16081,
+17,28,40,16081,
+25,32,32,16118,
+14,19,46,16118,
+7,32,40,16118,
+24,24,39,16118,
+26,29,34,16118,
+12,15,48,16118,
+19,34,34,16118,
+6,6,51,16118,
+2,35,38,16118,
+18,18,45,16118,
+3,30,42,16118,
+4,16,49,16118,
+3,8,51,16118,
+3,27,44,16118,
+8,33,39,16118,
+3,36,37,16118,
+24,27,37,16118,
+17,33,36,16118,
+9,17,48,16118,
+3,19,48,16118,
+9,35,37,16118,
+7,15,49,16118,
+5,21,47,16118,
+19,33,35,16118,
+25,31,33,16138,
+17,19,45,16138,
+5,7,51,16138,
+15,35,35,16138,
+11,23,45,16138,
+23,25,39,16138,
+5,25,45,16138,
+8,26,44,16138,
+20,26,40,16138,
+16,22,44,16138,
+12,33,38,16138,
+7,18,48,16138,
+16,30,39,16138,
+15,34,36,16138,
+0,34,39,16138,
+12,18,47,16138,
+17,25,42,16138,
+13,22,45,16138,
+3,35,38,16138,
+3,13,50,16138,
+11,21,46,16138,
+9,14,49,16138,
+14,31,39,16138,
+10,27,43,16138,
+1,34,39,16138,
+6,31,41,16138,
+22,30,36,16149,
+6,12,50,16149,
+4,30,42,16149,
+9,22,46,16149,
+9,34,38,16149,
+22,26,39,16149,
+16,20,45,16149,
+25,30,34,16177,
+2,34,39,16177,
+6,23,46,16177,
+4,36,37,16177,
+4,19,48,16177,
+18,26,41,16177,
+9,10,50,16177,
+4,27,44,16177,
+4,8,51,16177,
+19,32,36,16177,
+16,24,43,16177,
+10,30,41,16177,
+13,24,44,16177,
+11,16,48,16177,
+9,24,45,16177,
+5,16,49,16177,
+7,28,43,16177,
+17,32,37,16177,
+11,25,44,16177,
+0,9,51,16177,
+23,28,37,16177,
+11,31,40,16177,
+27,27,35,16210,
+15,33,37,16210,
+1,9,51,16210,
+8,11,50,16210,
+26,28,35,16222,
+13,20,46,16222,
+4,35,38,16222,
+4,13,50,16222,
+20,29,38,16222,
+6,21,47,16222,
+6,7,51,16222,
+6,25,45,16222,
+9,29,42,16222,
+18,29,39,16222,
+3,34,39,16222,
+2,9,51,16222,
+21,33,34,16222,
+8,32,40,16222,
+24,32,33,16241,
+12,32,39,16241,
+5,30,42,16241,
+14,27,42,16241,
+21,22,42,16241,
+12,12,49,16241,
+0,33,40,16241,
+20,21,43,16241,
+13,35,36,16241,
+1,33,40,16241,
+0,17,49,16241,
+15,28,41,16241,
+8,15,49,16241,
+5,8,51,16241,
+21,32,35,16241,
+15,23,44,16241,
+5,36,37,16241,
+19,27,40,16241,
+5,27,44,16241,
+15,16,47,16241,
+5,19,48,16241,
+0,29,43,16241,
+9,20,47,16241,
+11,19,47,16241,
+1,17,49,16241,
+1,29,43,16241,
+21,27,39,16241,
+7,31,41,16241,
+15,21,45,16241,
+19,31,37,16241,
+3,9,51,16241,
+13,29,41,16241,
+25,29,35,16262,
+9,33,39,16262,
+11,13,49,16262,
+0,24,46,16262,
+12,28,42,16262,
+8,18,48,16262,
+10,36,36,16262,
+4,34,39,16262,
+0,22,47,16262,
+20,23,42,16262,
+2,33,40,16262,
+24,31,34,16276,
+15,32,38,16276,
+9,26,44,16276,
+6,16,49,16276,
+7,12,50,16276,
+1,24,46,16276,
+10,17,48,16276,
+2,29,43,16276,
+13,34,37,16276,
+5,35,38,16276,
+7,23,46,16276,
+13,26,43,16276,
+22,29,37,16276,
+17,31,38,16276,
+5,13,50,16276,
+17,17,46,16276,
+1,22,47,16276,
+25,25,38,16276,
+2,17,49,16276,
+22,23,41,16276,
+19,22,43,16276,
+14,17,47,16276,
+10,35,37,16276,
+14,14,48,16276,
+2,24,46,16276,
+24,26,38,16276,
+0,14,50,16276,
+16,26,42,16276,
+16,18,46,16276,
+14,30,40,16276,
+10,14,49,16276,
+8,28,43,16276,
+1,14,50,16276,
+16,29,40,16276,
+19,20,44,16276,
+2,22,47,16276,
+21,31,36,16288,
+21,24,41,16288,
+13,15,48,16288,
+3,33,40,16288,
+4,9,51,16288,
+12,23,45,16288,
+15,25,43,16288,
+7,21,47,16288,
+17,27,41,16288,
+3,29,43,16288,
+7,25,45,16288,
+3,17,49,16288,
+7,7,51,16288,
+11,27,43,16288,
+10,34,38,16288,
+2,14,50,16288,
+10,22,46,16288,
+6,30,42,16288,
+30,30,30,16354,
+10,10,50,16354,
+6,27,44,16354,
+10,24,45,16354,
+19,24,42,16354,
+3,24,46,16354,
+6,19,48,16354,
+0,10,51,16354,
+18,21,44,16354,
+6,8,51,16354,
+0,26,45,16354,
+12,21,46,16354,
+26,27,36,16354,
+6,36,37,16354,
+24,30,35,16354,
+13,33,38,16354,
+1,26,45,16354,
+18,23,43,16354,
+11,30,41,16354,
+3,22,47,16354,
+15,19,46,16354,
+23,27,38,16354,
+13,18,47,16354,
+5,34,39,16354,
+29,30,31,16374,
+9,11,50,16374,
+1,10,51,16374,
+0,0,52,16374,
+0,20,48,16374,
+12,16,48,16374,
+10,29,42,16374,
+20,28,39,16374,
+1,20,48,16374,
+19,30,38,16374,
+6,35,38,16374,
+0,1,52,16374,
+25,28,36,16374,
+23,24,40,16374,
+12,31,40,16374,
+6,13,50,16374,
+0,32,41,16374,
+14,22,45,16374,
+3,14,50,16374,
+2,10,51,16374,
+18,34,35,16374,
+4,33,40,16374,
+9,32,40,16374,
+12,25,44,16374,
+2,26,45,16374,
+4,17,49,16374,
+4,29,43,16374,
+20,25,41,16374,
+7,16,49,16374,
+1,1,52,16374,
+28,31,31,16416,
+29,29,32,16416,
+8,31,41,16416,
+16,35,35,16416,
+1,32,41,16416,
+15,31,39,16416,
+23,33,33,16416,
+9,15,49,16416,
+5,9,51,16416,
+14,24,44,16416,
+2,20,48,16416,
+16,34,36,16416,
+18,28,40,16416,
+8,12,50,16416,
+28,30,32,16424,
+0,2,52,16424,
+4,24,46,16424,
+9,18,48,16424,
+8,23,46,16424,
+17,22,44,16424,
+4,22,47,16424,
+23,32,34,16424,
+22,25,40,16424,
+2,32,41,16424,
+10,20,47,16424,
+1,2,52,16424,
+18,33,36,16424,
+3,10,51,16424,
+3,26,45,16424,
+10,33,39,16424,
+17,30,39,16424,
+18,19,45,16424,
+21,30,37,16424,
+22,28,38,16424,
+10,26,44,16424,
+2,2,52,16424,
+14,20,46,16424,
+20,34,34,16424,
+4,14,50,16424,
+0,3,52,16424,
+18,25,42,16424,
+7,30,42,16424,
+11,36,36,16424,
+3,20,48,16424,
+24,29,36,16436,
+6,34,39,16436,
+9,28,43,16436,
+7,36,37,16436,
+13,32,39,16436,
+8,25,45,16436,
+27,31,32,16481,
+17,24,43,16481,
+20,33,35,16481,
+3,32,41,16481,
+7,19,48,16481,
+16,33,37,16481,
+28,29,33,16481,
+8,21,47,16481,
+12,13,49,16481,
+5,33,40,16481,
+1,3,52,16481,
+11,17,48,16481,
+17,20,45,16481,
+7,27,44,16481,
+12,19,47,16481,
+7,8,51,16481,
+23,31,35,16481,
+5,29,43,16481,
+5,17,49,16481,
+11,35,37,16481,
+2,3,52,16481,
+18,32,37,16481,
+5,24,46,16481,
+13,28,42,16481,
+4,10,51,16481,
+14,35,36,16481,
+4,26,45,16481,
+21,26,40,16481,
+7,35,38,16481,
+11,14,49,16481,
+14,29,41,16481,
+27,30,33,16508,
+7,13,50,16508,
+6,9,51,16508,
+5,22,47,16508,
+19,26,41,16508,
+15,27,42,16508,
+0,4,52,16508,
+4,20,48,16508,
+0,28,44,16508,
+20,32,36,16508,
+5,14,50,16508,
+14,34,37,16508,
+8,16,49,16508,
+1,4,52,16508,
+11,34,38,16508,
+1,28,44,16508,
+16,23,44,16508,
+26,26,37,16508,
+11,22,46,16508,
+14,26,43,16508,
+16,28,41,16508,
+4,32,41,16508,
+10,11,50,16508,
+16,16,47,16508,
+24,25,39,16508,
+3,3,52,16508,
+0,11,51,16508,
+11,24,45,16508,
+12,27,43,16508,
+16,21,45,16508,
+1,11,51,16508,
+25,27,37,16514,
+9,31,41,16514,
+13,23,45,16514,
+19,29,39,16514,
+15,17,47,16514,
+26,32,32,16548,
+28,28,34,16548,
+10,32,40,16548,
+2,4,52,16548,
+16,32,38,16548,
+2,28,44,16548,
+14,15,48,16548,
+6,33,40,16548,
+0,18,49,16548,
+9,12,50,16548,
+0,15,50,16548,
+12,30,41,16548,
+0,31,42,16548,
+23,30,36,16548,
+15,30,40,16548,
+10,15,49,16548,
+9,23,46,16548,
+6,17,49,16548,
+5,10,51,16548,
+11,29,42,16548,
+7,34,39,16548,
+5,26,45,16548,
+1,31,42,16548,
+6,29,43,16548,
+2,11,51,16548,
+13,21,46,16548,
+1,15,50,16548,
+21,29,38,16548,
+26,31,33,16570,
+23,26,39,16570,
+1,18,49,16570,
+27,29,34,16570,
+8,30,42,16570,
+6,24,46,16570,
+10,18,48,16570,
+8,36,37,16570,
+3,28,44,16570,
+17,18,46,16570,
+17,26,42,16570,
+24,28,37,16570,
+14,18,47,16570,
+5,20,48,16570,
+20,27,40,16570,
+0,5,52,16570,
+14,33,38,16570,
+3,4,52,16570,
+2,15,50,16570,
+2,18,49,16570,
+8,19,48,16570,
+8,8,51,16570,
+22,33,34,16570,
+2,31,42,16570,
+13,16,48,16570,
+18,31,38,16570,
+6,22,47,16570,
+8,27,44,16570,
+16,25,43,16570,
+11,20,47,16570,
+1,5,52,16570,
+13,31,40,16570,
+5,32,41,16570,
+17,29,40,16570,
+20,31,37,16570,
+13,25,44,16570,
+9,21,47,16570,
+9,25,45,16570,
+3,11,51,16570,
+7,9,51,16570,
+21,21,43,16570,
+11,33,39,16570,
+26,30,34,16609,
+22,22,42,16609,
+6,14,50,16609,
+8,35,38,16609,
+22,32,35,16609,
+8,13,50,16609,
+10,28,43,16609,
+16,19,46,16609,
+20,22,43,16609,
+11,26,44,16609,
+2,5,52,16609,
+15,22,45,16609,
+18,27,41,16609,
+3,18,49,16609,
+21,23,42,16609,
+3,31,42,16609,
+3,15,50,16609,
+22,27,39,16609,
+12,36,36,16609,
+4,28,44,16609,
+20,20,44,16609,
+4,4,52,16609,
+6,26,45,16609,
+6,10,51,16609,
+12,17,48,16609,
+15,24,44,16609,
+7,33,40,16609,
+3,5,52,16609,
+12,35,37,16609,
+0,23,47,16609,
+25,32,33,16663,
+19,21,44,16663,
+0,37,37,16663,
+16,31,39,16663,
+27,28,35,16663,
+4,11,51,16663,
+9,16,49,16663,
+13,19,47,16663,
+7,29,43,16663,
+17,35,35,16663,
+13,13,49,16663,
+7,17,49,16663,
+23,29,37,16663,
+19,23,43,16663,
+1,23,47,16663,
+23,23,41,16663,
+1,37,37,16663,
+20,24,42,16663,
+6,20,48,16663,
+0,6,52,16663,
+0,36,38,16663,
+17,34,36,16663,
+8,34,39,16663,
+15,20,46,16663,
+22,24,41,16663,
+22,31,36,16663,
+14,32,39,16663,
+4,18,49,16663,
+4,31,42,16663,
+6,32,41,16663,
+7,24,46,16663,
+0,25,46,16663,
+1,6,52,16663,
+1,36,38,16663,
+12,14,49,16663,
+4,15,50,16663,
+11,11,50,16663,
+2,37,37,16663,
+2,23,47,16663,
+10,31,41,16663,
+7,22,47,16663,
+1,25,46,16663,
+25,31,34,16692,
+26,29,35,16692,
+19,34,35,16692,
+20,30,38,16692,
+10,12,50,16692,
+2,6,52,16692,
+12,22,46,16692,
+14,28,42,16692,
+12,34,38,16692,
+18,22,44,16692,
+2,36,38,16692,
+12,24,45,16692,
+11,32,40,16692,
+25,26,38,16692,
+19,28,40,16692,
+9,30,42,16692,
+0,12,51,16692,
+5,28,44,16692,
+7,14,50,16692,
+10,23,46,16692,
+2,25,46,16692,
+4,5,52,16692,
+18,30,39,16692,
+0,21,48,16692,
+19,33,36,16692,
+9,19,48,16692,
+21,28,39,16692,
+1,21,48,16692,
+8,9,51,16692,
+9,36,37,16692,
+1,12,51,16692,
+15,35,36,16692,
+9,27,44,16692,
+0,35,39,16692,
+5,11,51,16692,
+21,25,41,16692,
+3,23,47,16692,
+15,29,41,16692,
+1,35,39,16692,
+19,19,45,16692,
+13,27,43,16692,
+3,37,37,16692,
+11,15,49,16692,
+17,33,37,16692,
+12,29,42,16692,
+3,36,38,16692,
+18,24,43,16692,
+11,18,48,16692,
+2,21,48,16692,
+2,12,51,16692,
+24,27,38,16709,
+0,30,43,16709,
+18,20,45,16709,
+3,6,52,16709,
+16,27,42,16709,
+15,34,37,16709,
+1,30,43,16709,
+5,18,49,16709,
+13,30,41,16709,
+15,26,43,16709,
+7,26,45,16709,
+14,23,45,16709,
+5,15,50,16709,
+10,25,45,16709,
+9,13,50,16709,
+3,25,46,16709,
+7,10,51,16709,
+19,25,42,16709,
+9,35,38,16709,
+25,30,35,16735,
+2,35,39,16735,
+10,21,47,16735,
+5,31,42,16735,
+24,24,40,16735,
+2,30,43,16735,
+8,33,40,16735,
+7,20,48,16735,
+12,20,47,16735,
+14,21,46,16735,
+21,34,34,16735,
+0,7,52,16735,
+22,30,37,16735,
+4,37,37,16735,
+8,17,49,16735,
+4,23,47,16735,
+23,25,40,16735,
+15,15,48,16735,
+5,5,52,16735,
+11,28,43,16735,
+1,7,52,16735,
+7,32,41,16735,
+3,21,48,16735,
+24,33,33,16780,
+17,28,41,16780,
+17,23,44,16780,
+3,12,51,16780,
+0,27,45,16780,
+19,32,37,16780,
+12,33,39,16780,
+8,29,43,16780,
+16,17,47,16780,
+27,27,36,16780,
+21,33,35,16780,
+3,35,39,16780,
+17,21,45,16780,
+1,27,45,16780,
+14,16,48,16780,
+16,30,40,16780,
+8,24,46,16780,
+6,28,44,16780,
+26,28,36,16786,
+4,6,52,16786,
+4,36,38,16786,
+0,16,50,16786,
+12,26,44,16786,
+24,32,34,16786,
+0,34,40,16786,
+20,26,41,16786,
+1,16,50,16786,
+23,28,38,16786,
+14,31,40,16786,
+1,34,40,16786,
+10,16,49,16786,
+14,25,44,16786,
+8,22,47,16786,
+2,7,52,16786,
+17,32,38,16786,
+4,25,46,16786,
+15,33,38,16786,
+2,27,45,16786,
+9,34,39,16786,
+3,30,43,16786,
+6,11,51,16786,
+15,18,47,16786,
+8,14,50,16786,
+2,16,50,16786,
+22,26,40,16786,
+2,34,40,16786,
+6,15,50,16786,
+21,32,36,16798,
+6,31,42,16798,
+30,30,31,16861,
+13,36,36,16861,
+4,21,48,16861,
+6,18,49,16861,
+4,12,51,16861,
+3,7,52,16861,
+0,19,49,16861,
+13,17,48,16861,
+20,29,39,16861,
+4,35,39,16861,
+25,29,36,16861,
+24,31,35,16861,
+1,19,49,16861,
+11,31,41,16861,
+5,23,47,16861,
+13,35,37,16861,
+3,27,45,16861,
+9,9,51,16861,
+5,37,37,16861,
+17,25,43,16861,
+29,31,31,16874,
+18,26,42,16874,
+10,30,42,16874,
+18,18,46,16874,
+4,30,43,16874,
+18,29,40,16874,
+11,12,50,16874,
+8,26,45,16874,
+10,19,48,16874,
+8,10,51,16874,
+3,34,40,16874,
+5,36,38,16874,
+10,27,44,16874,
+5,6,52,16874,
+10,36,37,16874,
+29,30,32,16897,
+3,16,50,16897,
+16,22,45,16897,
+14,19,47,16897,
+2,19,49,16897,
+11,23,46,16897,
+13,14,49,16897,
+19,31,38,16897,
+17,19,46,16897,
+5,25,46,16897,
+12,32,40,16897,
+16,24,44,16897,
+8,20,48,16897,
+0,8,52,16897,
+10,35,38,16897,
+28,31,32,16920,
+7,28,44,16920,
+4,7,52,16920,
+10,13,50,16920,
+1,8,52,16920,
+13,34,38,16920,
+8,32,41,16920,
+13,22,46,16920,
+22,29,38,16920,
+5,12,51,16920,
+12,15,49,16920,
+9,33,40,16920,
+15,32,39,16920,
+21,27,40,16920,
+0,33,41,16920,
+0,13,51,16920,
+5,21,48,16920,
+4,27,45,16920,
+13,24,45,16920,
+21,31,37,16920,
+11,25,45,16920,
+19,27,41,16920,
+7,11,51,16920,
+9,29,43,16920,
+5,35,39,16920,
+29,29,33,16946,
+1,13,51,16946,
+25,25,39,16946,
+11,21,47,16946,
+3,19,49,16946,
+17,31,39,16946,
+1,33,41,16946,
+9,17,49,16946,
+16,20,46,16946,
+12,18,48,16946,
+2,8,52,16946,
+4,16,50,16946,
+24,30,36,16946,
+4,34,40,16946,
+15,28,42,16946,
+9,24,46,16946,
+24,26,39,16946,
+28,30,33,16970,
+7,18,49,16970,
+14,27,43,16970,
+7,31,42,16970,
+23,33,34,16970,
+7,15,50,16970,
+26,27,37,16970,
+2,33,41,16970,
+6,23,47,16970,
+21,22,43,16970,
+5,30,43,16970,
+2,13,51,16970,
+6,37,37,16970,
+13,29,42,16970,
+9,22,47,16970,
+18,35,35,16970,
+18,34,36,16970,
+6,36,38,16970,
+6,6,52,16970,
+6,25,46,16970,
+27,32,32,16998,
+20,21,44,16998,
+3,8,52,16998,
+22,23,42,16998,
+0,29,44,16998,
+9,14,50,16998,
+10,34,39,16998,
+14,30,41,16998,
+16,35,36,16998,
+12,28,43,16998,
+11,16,49,16998,
+20,23,43,16998,
+13,20,47,16998,
+16,29,41,16998,
+23,32,35,16998,
+4,19,49,16998,
+25,28,37,16998,
+5,7,52,16998,
+1,29,44,16998,
+3,13,51,16998,
+15,23,45,16998,
+23,27,39,16998,
+3,33,41,16998,
+13,33,39,16998,
+5,27,45,16998,
+27,31,33,17017,
+13,26,44,17017,
+20,34,35,17017,
+6,21,48,17017,
+16,34,37,17017,
+16,26,43,17017,
+6,12,51,17017,
+5,34,40,17017,
+5,16,50,17017,
+21,24,42,17017,
+19,22,44,17017,
+2,29,44,17017,
+28,29,34,17031,
+19,30,39,17031,
+6,35,39,17031,
+15,21,46,17031,
+17,27,42,17031,
+18,33,37,17031,
+9,10,51,17031,
+9,26,45,17031,
+20,28,40,17031,
+8,28,44,17031,
+4,8,52,17031,
+0,9,52,17031,
+9,20,48,17031,
+27,30,34,17061,
+6,30,43,17061,
+20,33,36,17061,
+21,30,38,17061,
+11,30,42,17061,
+15,16,48,17061,
+0,24,47,17061,
+24,29,37,17061,
+9,32,41,17061,
+11,36,37,17061,
+23,31,36,17061,
+8,11,51,17061,
+19,20,45,17061,
+11,19,48,17061,
+15,25,44,17061,
+11,27,44,17061,
+19,24,43,17061,
+1,9,52,17061,
+12,31,41,17061,
+15,31,40,17061,
+1,24,47,17061,
+4,33,41,17061,
+23,24,41,17061,
+3,29,44,17061,
+4,13,51,17061,
+5,19,49,17061,
+7,37,37,17061,
+17,17,47,17061,
+7,23,47,17061,
+0,22,48,17061,
+0,32,42,17061,
+12,12,50,17061,
+14,36,36,17061,
+16,18,47,17061,
+10,33,40,17061,
+2,9,52,17061,
+8,18,49,17061,
+18,23,44,17061,
+6,7,52,17061,
+20,25,42,17061,
+1,22,48,17061,
+7,36,38,17061,
+14,17,48,17061,
+8,31,42,17061,
+17,30,40,17061,
+0,17,50,17061,
+2,24,47,17061,
+8,15,50,17061,
+1,32,42,17061,
+16,33,38,17061,
+22,28,39,17061,
+18,28,41,17061,
+26,32,33,17084,
+12,23,46,17084,
+1,17,50,17084,
+18,21,45,17084,
+22,25,41,17084,
+7,25,46,17084,
+10,17,49,17084,
+11,13,50,17084,
+11,35,38,17084,
+14,35,37,17084,
+6,27,45,17084,
+10,29,43,17084,
+10,24,46,17084,
+6,34,40,17084,
+6,16,50,17084,
+2,22,48,17084,
+18,32,38,17084,
+2,32,42,17084,
+0,26,46,17084,
+13,32,40,17084,
+10,22,47,17084,
+2,17,50,17084,
+1,26,46,17084,
+5,8,52,17084,
+20,32,37,17084,
+26,31,34,17106,
+4,29,44,17106,
+28,28,35,17106,
+14,14,49,17106,
+3,9,52,17106,
+12,21,47,17106,
+7,21,48,17106,
+7,12,51,17106,
+12,25,45,17106,
+3,24,47,17106,
+13,15,49,17106,
+5,13,51,17106,
+15,19,47,17106,
+5,33,41,17106,
+7,35,39,17106,
+27,29,35,17132,
+22,34,34,17132,
+14,34,38,17132,
+10,14,50,17132,
+14,22,46,17132,
+26,26,38,17132,
+2,26,46,17132,
+13,18,48,17132,
+14,24,45,17132,
+0,14,51,17132,
+3,22,48,17132,
+3,32,42,17132,
+17,22,45,17132,
+23,30,37,17132,
+7,30,43,17132,
+1,14,51,17132,
+25,27,38,17132,
+21,26,41,17132,
+6,19,49,17132,
+18,25,43,17132,
+22,33,35,17132,
+3,17,50,17132,
+11,34,39,17132,
+9,28,44,17132,
+12,16,49,17132,
+4,24,47,17132,
+16,32,39,17132,
+10,26,45,17132,
+18,19,46,17132,
+24,25,40,17132,
+10,10,51,17132,
+0,20,49,17132,
+14,29,42,17132,
+3,26,46,17132,
+4,9,52,17132,
+2,14,51,17132,
+17,24,44,17132,
+26,30,35,17183,
+19,26,42,17183,
+5,29,44,17183,
+8,23,47,17183,
+19,29,40,17183,
+1,20,49,17183,
+8,37,37,17183,
+13,28,43,17183,
+7,7,52,17183,
+7,27,45,17183,
+25,33,33,17199,
+21,29,39,17199,
+9,11,51,17199,
+15,27,43,17199,
+0,10,52,17199,
+4,32,42,17199,
+22,32,36,17199,
+6,8,52,17199,
+16,28,42,17199,
+10,20,48,17199,
+8,36,38,17199,
+4,22,48,17199,
+24,28,38,17199,
+7,16,50,17199,
+7,34,40,17199,
+8,25,46,17199,
+17,20,46,17199,
+25,32,34,17215,
+1,10,52,17215,
+14,20,47,17215,
+10,32,41,17215,
+4,17,50,17215,
+23,26,40,17215,
+2,20,49,17215,
+20,31,38,17215,
+9,31,42,17215,
+3,14,51,17215,
+14,33,39,17215,
+6,13,51,17215,
+9,15,50,17215,
+9,18,49,17215,
+18,31,39,17215,
+6,33,41,17215,
+15,30,41,17215,
+2,10,52,17215,
+12,30,42,17215,
+14,26,44,17215,
+4,26,46,17215,
+0,0,53,17215,
+27,28,36,17241,
+12,36,37,17241,
+8,12,51,17241,
+8,21,48,17241,
+0,28,45,17241,
+12,27,44,17241,
+12,19,48,17241,
+17,35,36,17241,
+8,35,39,17241,
+0,31,43,17241,
+11,33,40,17241,
+5,24,47,17241,
+1,28,45,17241,
+20,27,41,17241,
+16,23,45,17241,
+3,20,49,17241,
+0,1,53,17241,
+5,9,52,17241,
+13,31,41,17241,
+1,1,53,17241,
+11,17,49,17241,
+7,19,49,17241,
+19,35,35,17241,
+17,29,41,17241,
+1,31,43,17241,
+25,31,35,17263,
+11,29,43,17263,
+19,34,36,17263,
+26,29,36,17284,
+12,13,50,17284,
+3,10,52,17284,
+0,37,38,17284,
+4,14,51,17284,
+0,2,53,17284,
+6,29,44,17284,
+2,28,45,17284,
+12,35,38,17284,
+5,32,42,17284,
+16,21,46,17284,
+5,22,48,17284,
+11,24,46,17284,
+22,27,40,17284,
+8,30,43,17284,
+23,29,38,17284,
+13,23,46,17284,
+2,31,43,17284,
+1,2,53,17284,
+11,22,47,17284,
+17,34,37,17284,
+17,26,43,17284,
+1,37,38,17284,
+22,31,37,17284,
+5,17,50,17284,
+16,16,48,17284,
+7,8,52,17284,
+2,2,53,17284,
+18,27,42,17284,
+2,37,38,17284,
+15,36,36,17284,
+22,22,43,17284,
+5,26,46,17284,
+4,20,49,17284,
+11,14,50,17284,
+16,31,40,17284,
+16,25,44,17284,
+0,36,39,17284,
+8,27,45,17284,
+21,21,44,17284,
+3,28,45,17284,
+15,17,48,17284,
+0,3,53,17284,
+1,36,39,17284,
+3,31,43,17284,
+9,23,47,17284,
+7,13,51,17284,
+7,33,41,17284,
+15,35,37,17284,
+19,33,37,17284,
+13,25,45,17284,
+13,21,47,17284,
+21,23,43,17284,
+1,3,53,17284,
+9,37,37,17284,
+8,34,40,17284,
+10,28,44,17284,
+8,16,50,17284,
+14,32,40,17284,
+20,22,44,17284,
+4,10,52,17284,
+12,34,39,17284,
+25,30,36,17343,
+24,33,34,17343,
+6,9,52,17343,
+9,36,38,17343,
+2,36,39,17343,
+6,24,47,17343,
+20,30,39,17343,
+5,14,51,17343,
+9,25,46,17343,
+2,3,53,17343,
+10,11,51,17343,
+25,26,39,17343,
+17,33,38,17343,
+21,34,35,17343,
+3,37,38,17343,
+11,26,45,17343,
+17,18,47,17343,
+30,31,31,17371,
+14,15,49,17371,
+23,23,42,17371,
+6,22,48,17371,
+30,30,32,17388,
+18,30,40,17388,
+0,18,50,17388,
+22,24,42,17388,
+14,18,48,17388,
+6,32,42,17388,
+15,34,38,17388,
+10,18,49,17388,
+0,11,52,17388,
+0,35,40,17388,
+11,20,48,17388,
+21,28,40,17388,
+20,24,43,17388,
+0,4,53,17388,
+24,32,35,17388,
+10,31,42,17388,
+4,28,45,17388,
+6,17,50,17388,
+15,22,46,17388,
+1,18,50,17388,
+10,15,50,17388,
+20,20,45,17388,
+13,16,49,17388,
+5,20,49,17388,
+1,35,40,17388,
+1,4,53,17388,
+1,11,52,17388,
+3,36,39,17388,
+21,33,36,17388,
+7,29,44,17388,
+0,15,51,17388,
+9,21,48,17388,
+24,27,39,17388,
+15,24,45,17388,
+29,31,32,17410,
+8,19,49,17410,
+11,32,41,17410,
+19,28,41,17410,
+4,31,43,17410,
+16,19,47,17410,
+19,23,44,17410,
+9,12,51,17410,
+3,3,53,17410,
+1,15,51,17410,
+19,21,45,17410,
+27,27,37,17410,
+9,35,39,17410,
+2,18,50,17410,
+22,30,38,17410,
+6,26,46,17410,
+26,28,37,17410,
+2,11,52,17410,
+4,37,38,17410,
+2,35,40,17410,
+5,10,52,17410,
+2,4,53,17410,
+19,32,38,17410,
+14,28,43,17410,
+21,25,42,17410,
+15,29,42,17410,
+9,30,43,17410,
+29,30,33,17443,
+2,15,51,17443,
+28,32,32,17457,
+8,8,52,17457,
+24,31,36,17457,
+4,36,39,17457,
+18,22,45,17457,
+24,24,41,17457,
+13,30,42,17457,
+6,14,51,17457,
+12,33,40,17457,
+0,23,48,17457,
+3,18,50,17457,
+7,9,52,17457,
+0,25,47,17457,
+15,20,47,17457,
+28,31,33,17476,
+13,36,37,17476,
+3,4,53,17476,
+8,33,41,17476,
+23,28,39,17476,
+8,13,51,17476,
+13,19,48,17476,
+13,27,44,17476,
+7,24,47,17476,
+21,32,37,17476,
+1,23,48,17476,
+12,29,43,17476,
+12,17,49,17476,
+3,35,40,17476,
+17,32,39,17476,
+0,5,53,17476,
+5,28,45,17476,
+3,11,52,17476,
+16,27,43,17476,
+23,25,41,17476,
+1,25,47,17476,
+25,29,37,17476,
+9,27,45,17476,
+19,25,43,17476,
+5,31,43,17476,
+3,15,51,17476,
+1,5,53,17476,
+15,33,39,17476,
+18,24,44,17476,
+12,24,46,17476,
+0,30,44,17476,
+6,20,49,17476,
+16,30,41,17476,
+1,30,44,17476,
+17,28,42,17476,
+12,22,47,17476,
+7,22,48,17476,
+7,32,42,17476,
+9,16,50,17476,
+2,23,48,17476,
+15,26,44,17476,
+9,34,40,17476,
+0,34,41,17476,
+2,5,53,17476,
+10,37,37,17476,
+29,29,34,17500,
+19,19,46,17500,
+13,13,50,17500,
+13,35,38,17500,
+14,31,41,17500,
+5,37,38,17500,
+10,23,47,17500,
+1,34,41,17500,
+2,25,47,17500,
+7,17,50,17500,
+2,30,44,17500,
+18,20,46,17500,
+12,14,50,17500,
+10,36,38,17500,
+28,30,34,17514,
+6,10,52,17514,
+4,18,50,17514,
+20,26,42,17514,
+4,35,40,17514,
+14,23,46,17514,
+23,34,34,17514,
+8,29,44,17514,
+22,26,41,17514,
+10,25,46,17514,
+7,26,46,17514,
+4,4,53,17514,
+11,28,44,17514,
+2,34,41,17514,
+4,11,52,17514,
+20,29,40,17514,
+5,36,39,17514,
+0,21,49,17514,
+3,23,48,17514,
+27,32,33,17539,
+4,15,51,17539,
+3,25,47,17539,
+17,23,45,17539,
+19,31,39,17539,
+9,19,49,17539,
+3,5,53,17539,
+23,33,35,17539,
+11,11,51,17539,
+1,21,49,17539,
+0,27,46,17539,
+0,6,53,17539,
+10,12,51,17539,
+6,28,45,17539,
+12,26,45,17539,
+24,30,37,17539,
+18,35,36,17539,
+10,21,48,17539,
+3,30,44,17539,
+1,6,53,17539,
+13,34,39,17539,
+18,29,41,17539,
+27,31,34,17572,
+7,14,51,17572,
+14,21,47,17572,
+6,31,43,17572,
+11,31,42,17572,
+1,27,46,17572,
+11,15,50,17572,
+3,34,41,17572,
+11,18,49,17572,
+21,31,38,17572,
+2,21,49,17572,
+17,21,46,17572,
+22,29,39,17572,
+14,25,45,17572,
+10,35,39,17572,
+12,20,48,17572,
+16,36,36,17572,
+0,12,52,17572,
+2,27,46,17572,
+18,34,37,17572,
+1,12,52,17572,
+8,24,47,17572,
+23,32,36,17572,
+8,9,52,17572,
+5,18,50,17572,
+6,37,38,17572,
+10,30,43,17572,
+2,6,53,17572,
+26,27,38,17572,
+16,17,48,17572,
+15,32,40,17572,
+12,32,41,17572,
+4,23,48,17572,
+18,26,43,17572,
+28,29,35,17606,
+17,31,40,17606,
+5,11,52,17606,
+5,35,40,17606,
+20,35,35,17606,
+17,25,44,17606,
+4,25,47,17606,
+16,35,37,17606,
+4,5,53,17606,
+25,25,40,17606,
+7,20,49,17606,
+9,13,51,17606,
+3,21,49,17606,
+9,33,41,17606,
+5,15,51,17606,
+15,15,49,17606,
+21,27,41,17606,
+20,34,36,17606,
+2,12,52,17606,
+8,22,48,17606,
+8,32,42,17606,
+4,30,44,17606,
+24,26,40,17606,
+15,18,48,17606,
+4,34,41,17606,
+0,33,42,17606,
+14,16,49,17606,
+8,17,50,17606,
+7,10,52,17606,
+6,36,39,17606,
+25,28,38,17606,
+3,27,46,17606,
+3,6,53,17606,
+1,33,42,17606,
+26,33,33,17638,
+27,30,35,17638,
+10,27,45,17638,
+19,27,42,17638,
+10,34,40,17638,
+16,22,46,17638,
+10,16,50,17638,
+26,32,34,17650,
+8,26,46,17650,
+16,34,38,17650,
+18,18,47,17650,
+2,33,42,17650,
+0,16,51,17650,
+3,12,52,17650,
+18,33,38,17650,
+16,24,45,17650,
+15,28,43,17650,
+5,23,48,17650,
+1,16,51,17650,
+13,33,40,17650,
+20,33,37,17650,
+23,27,40,17650,
+7,28,45,17650,
+0,7,53,17650,
+9,29,44,17650,
+4,21,49,17650,
+1,7,53,17650,
+11,37,37,17650,
+11,23,47,17650,
+5,25,47,17650,
+5,5,53,17650,
+13,29,43,17650,
+7,31,43,17650,
+13,17,49,17650,
+17,19,47,17650,
+23,31,37,17650,
+6,18,50,17650,
+14,30,42,17650,
+11,36,38,17650,
+6,35,40,17650,
+14,19,48,17650,
+16,29,42,17650,
+0,19,50,17650,
+2,16,51,17650,
+6,11,52,17650,
+4,6,53,17650,
+8,14,51,17650,
+13,24,46,17650,
+19,30,40,17650,
+21,22,44,17650,
+14,27,44,17650,
+4,27,46,17650,
+24,29,38,17658,
+14,36,37,17658,
+5,30,44,17658,
+21,30,39,17658,
+10,19,49,17658,
+2,7,53,17658,
+5,34,41,17658,
+11,25,46,17658,
+7,37,38,17658,
+3,33,42,17658,
+6,15,51,17658,
+1,19,50,17658,
+13,22,47,17658,
+26,31,35,17693,
+22,23,43,17693,
+4,12,52,17693,
+28,28,36,17701,
+12,28,44,17701,
+20,28,41,17701,
+13,14,50,17701,
+2,19,50,17701,
+22,34,35,17701,
+20,23,44,17701,
+16,20,47,17701,
+8,20,49,17701,
+14,35,38,17701,
+20,21,45,17701,
+3,16,51,17701,
+11,21,48,17701,
+9,9,52,17701,
+9,24,47,17701,
+7,36,39,17701,
+27,29,36,17726,
+21,24,43,17726,
+16,33,39,17726,
+0,29,45,17726,
+11,12,51,17726,
+11,35,39,17726,
+5,21,49,17726,
+1,29,45,17726,
+17,27,43,17726,
+15,31,41,17726,
+3,7,53,17726,
+22,28,40,17726,
+8,10,52,17726,
+20,32,38,17726,
+16,26,44,17726,
+9,22,48,17726,
+18,32,39,17726,
+9,32,42,17726,
+12,15,50,17726,
+22,33,36,17726,
+4,33,42,17726,
+23,24,42,17726,
+12,18,49,17726,
+6,23,48,17726,
+12,31,42,17726,
+25,33,34,17752,
+5,27,46,17752,
+9,17,50,17752,
+6,25,47,17752,
+11,30,43,17752,
+13,26,45,17752,
+5,6,53,17752,
+19,22,45,17752,
+3,19,50,17752,
+10,33,41,17752,
+17,30,41,17752,
+15,23,46,17752,
+2,29,45,17752,
+10,13,51,17752,
+18,28,42,17752,
+26,30,36,17771,
+6,30,44,17771,
+26,26,39,17771,
+7,18,50,17771,
+22,25,42,17771,
+6,34,41,17771,
+0,13,52,17771,
+14,34,39,17771,
+4,16,51,17771,
+0,8,53,17771,
+9,26,46,17771,
+0,32,43,17771,
+5,12,52,17771,
+13,20,48,17771,
+19,24,44,17771,
+8,28,45,17771,
+23,30,38,17771,
+20,25,43,17771,
+7,11,52,17771,
+4,7,53,17771,
+8,31,43,17771,
+7,35,40,17771,
+1,32,43,17771,
+25,32,35,17800,
+1,13,52,17800,
+1,8,53,17800,
+13,32,41,17800,
+15,25,45,17800,
+15,21,47,17800,
+25,27,39,17800,
+11,27,45,17800,
+3,29,45,17800,
+7,15,51,17800,
+4,19,50,17800,
+2,32,43,17800,
+11,34,40,17800,
+2,13,52,17800,
+19,20,46,17800,
+8,37,38,17800,
+22,32,37,17800,
+11,16,50,17800,
+2,8,53,17800,
+10,29,44,17800,
+5,33,42,17800,
+18,23,45,17800,
+6,21,49,17800,
+9,14,51,17800,
+16,32,40,17800,
+0,24,48,17800,
+6,27,46,17800,
+21,26,42,17800,
+18,21,46,17800,
+8,36,39,17800,
+17,36,36,17800,
+24,28,39,17813,
+1,24,48,17813,
+6,6,53,17813,
+12,23,47,17813,
+20,31,39,17813,
+27,28,37,17851,
+3,13,52,17851,
+19,35,36,17851,
+17,17,48,17851,
+21,29,40,17851,
+5,16,51,17851,
+25,31,36,17851,
+12,37,37,17851,
+3,32,43,17851,
+15,16,49,17851,
+24,25,41,17851,
+3,8,53,17851,
+9,20,49,17851,
+4,29,45,17851,
+7,23,48,17851,
+11,19,49,17851,
+7,25,47,17851,
+5,7,53,17851,
+17,35,37,17851,
+31,31,31,17890,
+19,29,41,17890,
+2,24,48,17890,
+12,36,38,17890,
+6,12,52,17890,
+16,18,48,17890,
+7,30,44,17890,
+10,24,47,17890,
+14,33,40,17890,
+30,31,32,17909,
+9,10,52,17909,
+12,25,46,17909,
+0,26,47,17909,
+0,22,49,17909,
+18,25,44,17909,
+18,31,40,17909,
+1,22,49,17909,
+7,34,41,17909,
+19,34,37,17909,
+5,19,50,17909,
+14,29,43,17909,
+19,26,43,17909,
+14,17,49,17909,
+23,26,41,17909,
+1,26,47,17909,
+26,29,37,17909,
+8,18,50,17909,
+0,38,38,17909,
+10,32,42,17909,
+10,22,48,17909,
+24,34,34,17909,
+14,24,46,17909,
+15,30,42,17909,
+12,12,51,17909,
+30,30,33,17933,
+17,34,38,17933,
+4,8,53,17933,
+6,33,42,17933,
+29,32,32,17933,
+8,11,52,17933,
+3,24,48,17933,
+17,22,46,17933,
+10,17,50,17933,
+8,35,40,17933,
+12,21,48,17933,
+22,31,38,17933,
+4,32,43,17933,
+2,26,47,17933,
+4,13,52,17933,
+13,28,44,17933,
+14,22,47,17933,
+1,38,38,17933,
+2,22,49,17933,
+16,28,43,17933,
+17,24,45,17933,
+15,19,48,17933,
+15,27,44,17933,
+12,35,39,17933,
+0,17,51,17933,
+24,33,35,17933,
+8,15,51,17933,
+0,9,53,17933,
+9,28,45,17933,
+15,36,37,17933,
+0,37,39,17933,
+9,31,43,17933,
+1,17,51,17933,
+23,29,39,17933,
+7,21,49,17933,
+29,31,33,17954,
+1,37,39,17954,
+21,35,35,17954,
+1,9,53,17954,
+5,29,45,17954,
+11,13,51,17954,
+11,33,41,17954,
+10,26,46,17954,
+2,38,38,17954,
+14,14,50,17954,
+20,27,42,17954,
+21,34,36,17954,
+12,30,43,17954,
+6,16,51,17954,
+13,18,49,17954,
+2,37,39,17954,
+2,17,51,17954,
+22,27,41,17954,
+13,31,42,17954,
+18,19,47,17954,
+3,22,49,17954,
+7,27,46,17954,
+13,15,50,17954,
+15,35,38,17954,
+17,29,42,17954,
+19,33,38,17954,
+6,7,53,17954,
+3,26,47,17954,
+2,9,53,17954,
+25,30,37,17954,
+9,37,38,17954,
+24,32,36,17959,
+0,36,40,17959,
+4,24,48,17959,
+29,30,34,18001,
+14,26,45,18001,
+6,19,50,18001,
+0,31,44,18001,
+1,36,40,18001,
+10,14,51,18001,
+28,32,33,18001,
+7,12,52,18001,
+3,38,38,18001,
+8,23,48,18001,
+11,29,44,18001,
+5,13,52,18001,
+12,27,45,18001,
+5,32,43,18001,
+1,31,44,18001,
+9,36,39,18001,
+5,8,53,18001,
+16,31,41,18001,
+17,20,47,18001,
+8,25,47,18001,
+3,17,51,18001,
+3,37,39,18001,
+21,33,37,18001,
+3,9,53,18001,
+17,33,39,18001,
+14,20,48,18001,
+0,20,50,18001,
+8,30,44,18001,
+20,30,40,18001,
+0,14,52,18001,
+12,34,40,18001,
+2,36,40,18001,
+0,28,46,18001,
+12,16,50,18001,
+4,26,47,18001,
+17,26,44,18001,
+10,20,49,18001,
+1,20,50,18001,
+1,28,46,18001,
+2,31,44,18001,
+4,22,49,18001,
+14,32,41,18001,
+16,23,46,18001,
+28,31,34,18041,
+25,26,40,18041,
+1,14,52,18041,
+8,34,41,18041,
+7,33,42,18041,
+27,27,38,18041,
+15,34,39,18041,
+6,29,45,18041,
+18,27,43,18041,
+2,20,50,18041,
+22,22,44,18041,
+26,28,38,18041,
+10,10,52,18041,
+4,38,38,18041,
+2,28,46,18041,
+2,14,52,18041,
+24,27,40,18041,
+18,30,41,18041,
+22,30,39,18041,
+3,36,40,18041,
+5,24,48,18041,
+9,18,50,18041,
+12,19,49,18041,
+4,17,51,18041,
+19,32,39,18041,
+16,25,45,18041,
+9,35,40,18041,
+4,37,39,18041,
+3,31,44,18041,
+9,11,52,18041,
+21,28,41,18041,
+0,35,41,18041,
+4,9,53,18041,
+8,21,49,18041,
+21,23,44,18041,
+24,31,37,18054,
+7,16,51,18054,
+11,24,47,18054,
+16,21,47,18054,
+29,29,35,18094,
+21,21,45,18094,
+1,35,41,18094,
+13,37,37,18094,
+13,23,47,18094,
+9,15,51,18094,
+7,7,53,18094,
+23,23,43,18094,
+27,33,33,18094,
+20,22,45,18094,
+8,27,46,18094,
+22,24,43,18094,
+11,22,48,18094,
+11,32,42,18094,
+28,30,35,18106,
+3,28,46,18106,
+21,32,38,18106,
+6,32,43,18106,
+13,36,38,18106,
+3,14,52,18106,
+19,28,42,18106,
+10,28,45,18106,
+27,32,34,18106,
+3,20,50,18106,
+6,8,53,18106,
+0,10,53,18106,
+6,13,52,18106,
+25,29,38,18106,
+1,10,53,18106,
+23,34,35,18106,
+7,19,50,18106,
+13,25,46,18106,
+11,17,50,18106,
+5,26,47,18106,
+5,22,49,18106,
+10,31,43,18106,
+2,35,41,18106,
+20,24,44,18106,
+4,36,40,18106,
+8,12,52,18106,
+23,28,40,18106,
+17,32,40,18106,
+10,37,38,18106,
+5,38,38,18106,
+4,31,44,18106,
+11,26,46,18106,
+2,10,53,18106,
+16,16,49,18106,
+13,21,48,18106,
+9,23,48,18106,
+15,33,40,18106,
+23,33,36,18118,
+12,13,51,18118,
+12,33,41,18118,
+3,35,41,18118,
+7,29,45,18118,
+21,25,43,18118,
+19,23,45,18118,
+9,25,47,18118,
+5,9,53,18118,
+13,35,39,18118,
+15,29,43,18118,
+15,17,49,18118,
+5,17,51,18118,
+27,31,35,18153,
+5,37,39,18153,
+20,20,46,18153,
+4,20,50,18153,
+0,0,54,18153,
+4,28,46,18153,
+4,14,52,18153,
+18,36,36,18153,
+24,24,42,18153,
+6,24,48,18153,
+14,28,44,18153,
+9,30,44,18153,
+15,24,46,18153,
+0,1,54,18153,
+17,18,48,18153,
+10,36,39,18153,
+8,33,42,18153,
+18,35,37,18153,
+11,14,51,18153,
+23,25,42,18153,
+9,34,41,18153,
+3,10,53,18153,
+19,21,46,18153,
+13,30,43,18153,
+1,1,54,18153,
+15,22,47,18153,
+0,34,42,18153,
+24,30,38,18161,
+0,2,54,18161,
+16,30,42,18161,
+16,27,44,18161,
+6,26,47,18161,
+16,36,37,18161,
+14,15,50,18161,
+1,34,42,18161,
+16,19,48,18161,
+20,35,36,18161,
+14,18,49,18161,
+28,29,36,18202,
+6,22,49,18202,
+26,33,34,18202,
+5,36,40,18202,
+1,2,54,18202,
+8,16,51,18202,
+14,31,42,18202,
+12,29,44,18202,
+17,28,43,18202,
+23,32,37,18202,
+5,31,44,18202,
+11,20,49,18202,
+19,31,40,18202,
+7,32,43,18202,
+20,29,41,18202,
+19,25,44,18202,
+7,8,53,18202,
+7,13,52,18202,
+4,35,41,18202,
+13,27,45,18202,
+9,21,49,18202,
+21,31,39,18202,
+18,22,46,18202,
+18,34,38,18202,
+22,26,42,18202,
+2,34,42,18202,
+10,18,50,18202,
+6,38,38,18202,
+2,2,54,18202,
+0,30,45,18202,
+5,28,46,18202,
+27,30,36,18235,
+10,35,40,18235,
+0,18,51,18235,
+22,29,40,18235,
+18,24,45,18235,
+16,35,38,18235,
+0,3,54,18235,
+13,16,50,18235,
+26,32,35,18235,
+13,34,40,18235,
+20,34,37,18235,
+4,10,53,18235,
+10,11,52,18235,
+8,19,50,18235,
+5,20,50,18235,
+5,14,52,18235,
+20,26,43,18235,
+1,30,45,18235,
+1,3,54,18235,
+6,17,51,18235,
+15,26,45,18235,
+6,9,53,18235,
+6,37,39,18235,
+10,15,51,18235,
+1,18,51,18235,
+26,27,39,18235,
+9,27,46,18235,
+15,20,48,18235,
+0,25,48,18235,
+9,12,52,18235,
+2,3,54,18235,
+3,34,42,18235,
+0,15,52,18235,
+2,30,45,18235,
+18,29,42,18235,
+12,24,47,18235,
+2,18,51,18235,
+7,24,48,18235,
+1,25,48,18235,
+25,28,39,18244,
+0,23,49,18244,
+11,28,45,18244,
+15,32,41,18244,
+0,11,53,18244,
+1,15,52,18244,
+8,29,45,18244,
+1,11,53,18244,
+17,31,41,18244,
+11,31,43,18244,
+13,19,49,18244,
+25,25,41,18244,
+19,19,47,18244,
+5,35,41,18244,
+1,23,49,18244,
+12,22,48,18244,
+12,32,42,18244,
+6,36,40,18244,
+0,4,54,18244,
+18,20,47,18244,
+24,26,41,18244,
+2,25,48,18244,
+12,17,50,18244,
+26,31,36,18297,
+1,4,54,18297,
+16,34,39,18297,
+2,15,52,18297,
+6,31,44,18297,
+20,33,38,18297,
+10,23,48,18297,
+14,23,47,18297,
+3,18,51,18297,
+10,25,47,18297,
+5,10,53,18297,
+3,30,45,18297,
+18,33,39,18297,
+17,23,46,18297,
+14,37,37,18297,
+21,27,42,18297,
+2,11,53,18297,
+2,23,49,18297,
+23,31,38,18297,
+22,35,35,18297,
+11,37,38,18297,
+9,33,42,18297,
+7,22,49,18297,
+3,3,54,18297,
+7,26,47,18297,
+10,30,44,18297,
+22,34,36,18297,
+14,36,38,18297,
+6,14,52,18297,
+6,20,50,18297,
+2,4,54,18297,
+18,26,44,18297,
+12,26,46,18297,
+6,28,46,18297,
+4,34,42,18297,
+10,34,41,18297,
+14,25,46,18297,
+28,28,37,18331,
+8,32,43,18331,
+8,8,53,18331,
+25,34,34,18331,
+7,38,38,18331,
+8,13,52,18331,
+3,25,48,18331,
+24,29,39,18331,
+3,15,52,18331,
+0,33,43,18331,
+11,36,39,18331,
+9,16,51,18331,
+0,27,47,18331,
+13,13,51,18331,
+3,11,53,18331,
+17,21,47,18331,
+19,27,43,18331,
+13,33,41,18331,
+17,25,45,18331,
+7,17,51,18331,
+3,23,49,18331,
+1,33,43,18331,
+27,29,37,18344,
+7,37,39,18344,
+7,9,53,18344,
+23,27,41,18344,
+25,33,35,18344,
+1,27,47,18344,
+0,21,50,18344,
+12,14,51,18344,
+3,4,54,18344,
+21,30,40,18344,
+0,5,54,18344,
+4,30,45,18344,
+14,21,48,18344,
+4,18,51,18344,
+6,35,41,18344,
+2,27,47,18344,
+10,21,49,18344,
+1,5,54,18344,
+22,33,37,18344,
+19,30,41,18344,
+14,35,39,18344,
+1,21,50,18344,
+9,19,50,18344,
+2,33,43,18344,
+8,24,48,18344,
+26,30,37,18384,
+2,21,50,18384,
+7,36,40,18384,
+2,5,54,18384,
+4,25,48,18384,
+20,32,39,18384,
+10,27,46,18384,
+25,32,36,18384,
+15,28,44,18384,
+6,10,53,18384,
+12,20,49,18384,
+11,18,50,18384,
+4,15,52,18384,
+16,33,40,18384,
+14,30,43,18384,
+5,34,42,18384,
+16,29,43,18384,
+11,35,40,18384,
+31,31,32,18432,
+4,11,53,18432,
+4,23,49,18432,
+11,11,52,18432,
+13,29,44,18432,
+16,17,49,18432,
+7,31,44,18432,
+3,33,43,18432,
+3,27,47,18432,
+11,15,51,18432,
+9,29,45,18432,
+18,32,40,18432,
+4,4,54,18432,
+10,12,52,18432,
+20,28,42,18432,
+30,32,32,18437,
+16,24,46,18437,
+7,14,52,18437,
+16,22,47,18437,
+7,20,50,18437,
+7,28,46,18437,
+8,26,47,18437,
+22,23,44,18437,
+8,22,49,18437,
+22,28,41,18437,
+5,30,45,18437,
+21,22,45,18437,
+30,31,33,18456,
+15,15,50,18456,
+14,27,45,18456,
+23,30,39,18456,
+5,18,51,18456,
+15,18,49,18456,
+3,5,54,18456,
+15,31,42,18456,
+3,21,50,18456,
+22,32,38,18456,
+14,34,40,18456,
+26,26,40,18456,
+8,38,38,18456,
+18,18,48,18456,
+0,6,54,18456,
+14,16,50,18456,
+12,28,45,18456,
+10,33,42,18456,
+0,12,53,18456,
+17,30,42,18456,
+1,6,54,18456,
+21,24,44,18456,
+19,36,36,18456,
+8,37,39,18456,
+5,25,48,18456,
+11,23,48,18456,
+23,24,43,18456,
+5,15,52,18456,
+8,9,53,18456,
+9,13,52,18456,
+4,27,47,18456,
+29,32,33,18499,
+9,32,43,18499,
+20,23,45,18499,
+13,24,47,18499,
+8,17,51,18499,
+25,27,40,18499,
+17,27,44,18499,
+4,33,43,18499,
+12,31,43,18499,
+1,12,53,18499,
+17,36,37,18499,
+17,19,48,18499,
+25,31,37,18499,
+11,25,47,18499,
+19,35,37,18499,
+7,35,41,18499,
+5,11,53,18499,
+5,23,49,18499,
+6,34,42,18499,
+30,30,34,18505,
+2,6,54,18505,
+4,5,54,18505,
+13,22,48,18505,
+18,28,43,18505,
+12,37,38,18505,
+11,30,44,18505,
+4,21,50,18505,
+20,21,46,18505,
+13,32,42,18505,
+27,28,38,18505,
+0,29,46,18505,
+24,34,35,18505,
+16,26,45,18505,
+2,12,53,18505,
+10,16,51,18505,
+17,35,38,18505,
+11,34,41,18505,
+14,19,49,18505,
+13,17,50,18505,
+29,31,34,18525,
+1,29,46,18525,
+22,25,43,18525,
+7,10,53,18525,
+0,16,52,18525,
+16,20,48,18525,
+24,28,40,18525,
+0,32,44,18525,
+8,36,40,18525,
+24,33,36,18525,
+10,19,50,18525,
+26,29,38,18525,
+1,16,52,18525,
+16,32,41,18525,
+20,25,44,18525,
+19,22,46,18525,
+19,34,38,18525,
+9,24,48,18525,
+3,6,54,18525,
+13,26,46,18525,
+12,36,39,18525,
+1,32,44,18525,
+20,31,40,18525,
+6,30,45,18525,
+8,31,44,18525,
+2,29,46,18525,
+6,18,51,18525,
+0,19,51,18525,
+21,35,36,18525,
+19,24,45,18525,
+3,12,53,18525,
+28,33,33,18561,
+21,29,41,18561,
+11,21,49,18561,
+15,37,37,18561,
+15,23,47,18561,
+1,19,51,18561,
+5,33,43,18561,
+5,27,47,18561,
+2,16,52,18561,
+8,14,52,18561,
+2,32,44,18561,
+8,20,50,18561,
+8,28,46,18561,
+28,32,34,18565,
+6,15,52,18565,
+0,7,54,18565,
+6,25,48,18565,
+15,36,38,18565,
+24,25,42,18565,
+0,38,39,18565,
+19,29,42,18565,
+2,19,51,18565,
+5,21,50,18565,
+18,31,41,18565,
+1,38,39,18565,
+9,22,49,18565,
+3,29,46,18565,
+29,30,35,18587,
+9,26,47,18587,
+1,7,54,18587,
+21,34,37,18587,
+10,29,45,18587,
+17,34,39,18587,
+6,11,53,18587,
+11,27,46,18587,
+6,23,49,18587,
+15,25,46,18587,
+21,26,43,18587,
+13,14,51,18587,
+14,33,41,18587,
+22,31,39,18587,
+5,5,54,18587,
+4,6,54,18587,
+12,18,50,18587,
+9,38,38,18587,
+4,12,53,18587,
+24,32,37,18587,
+0,37,40,18587,
+3,16,52,18587,
+25,30,38,18587,
+2,7,54,18587,
+23,26,42,18587,
+7,34,42,18587,
+11,12,52,18587,
+3,32,44,18587,
+2,38,39,18587,
+12,35,40,18587,
+18,23,46,18587,
+8,35,41,18587,
+12,15,51,18587,
+28,31,35,18612,
+13,20,49,18612,
+19,20,47,18612,
+15,21,48,18612,
+23,29,40,18612,
+1,37,40,18612,
+9,9,53,18612,
+9,37,39,18612,
+3,19,51,18612,
+15,35,39,18612,
+9,17,51,18612,
+19,33,39,18612,
+10,32,43,18612,
+10,13,52,18612,
+19,26,44,18612,
+8,10,53,18612,
+14,29,44,18612,
+4,29,46,18612,
+2,37,40,18612,
+21,33,38,18612,
+7,18,51,18612,
+3,7,54,18612,
+11,33,42,18612,
+3,38,39,18612,
+6,33,43,18612,
+18,21,47,18612,
+18,25,45,18612,
+27,33,34,18633,
+7,30,45,18633,
+15,30,43,18633,
+6,27,47,18633,
+16,28,44,18633,
+4,32,44,18633,
+4,16,52,18633,
+22,27,42,18633,
+5,6,54,18633,
+0,24,49,18633,
+0,36,41,18633,
+6,21,50,18633,
+12,23,48,18633,
+9,36,40,18633,
+27,32,35,18692,
+17,33,40,18692,
+5,12,53,18692,
+9,31,44,18692,
+11,16,51,18692,
+1,24,49,18692,
+0,13,53,18692,
+1,36,41,18692,
+4,19,51,18692,
+29,29,36,18692,
+13,28,45,18692,
+20,27,43,18692,
+12,25,47,18692,
+3,37,40,18692,
+7,15,52,18692,
+7,25,48,18692,
+13,31,43,18692,
+7,23,49,18692,
+1,13,53,18692,
+17,29,43,18692,
+15,27,45,18692,
+7,11,53,18692,
+17,17,49,18692,
+27,27,39,18692,
+23,35,35,18692,
+0,26,48,18692,
+0,8,54,18692,
+28,30,36,18699,
+12,30,44,18699,
+10,24,48,18699,
+20,30,41,18699,
+9,14,52,18699,
+14,24,47,18699,
+2,36,41,18699,
+23,34,36,18699,
+9,28,46,18699,
+1,8,54,18699,
+15,34,40,18699,
+17,24,46,18699,
+26,28,39,18699,
+9,20,50,18699,
+1,26,48,18699,
+24,31,38,18699,
+4,7,54,18699,
+16,18,49,18699,
+12,34,41,18699,
+16,31,42,18699,
+2,24,49,18699,
+4,38,39,18699,
+15,16,50,18699,
+5,29,46,18699,
+2,13,53,18699,
+25,26,41,18699,
+17,22,47,18699,
+13,37,38,18699,
+11,19,50,18699,
+2,26,48,18699,
+2,8,54,18699,
+14,22,48,18699,
+0,22,50,18699,
+22,30,40,18699,
+14,32,42,18699,
+8,34,42,18699,
+14,17,50,18699,
+5,32,44,18699,
+4,37,40,18699,
+19,32,40,18699,
+1,22,50,18699,
+5,16,52,18699,
+10,22,49,18699,
+10,26,47,18699,
+0,31,45,18699,
+3,36,41,18699,
+27,31,36,18757,
+12,21,49,18757,
+24,27,41,18757,
+21,32,39,18757,
+3,24,49,18757,
+13,36,39,18757,
+23,33,37,18757,
+7,33,43,18757,
+25,29,39,18757,
+15,19,49,18757,
+11,29,45,18757,
+3,13,53,18757,
+7,27,47,18757,
+5,19,51,18757,
+1,31,45,18757,
+9,35,41,18757,
+14,26,46,18757,
+6,6,54,18757,
+18,30,42,18757,
+26,34,34,18759,
+10,38,38,18759,
+2,22,50,18759,
+18,36,37,18759,
+3,26,48,18759,
+12,27,46,18759,
+0,35,42,18759,
+21,28,42,18759,
+18,27,44,18759,
+3,8,54,18759,
+8,30,45,18759,
+6,12,53,18759,
+8,18,51,18759,
+18,19,48,18759,
+5,7,54,18759,
+7,21,50,18759,
+2,31,45,18759,
+17,26,45,18759,
+26,33,35,18784,
+10,17,51,18784,
+1,35,42,18784,
+9,10,53,18784,
+10,37,39,18784,
+5,38,39,18784,
+12,12,52,18784,
+20,36,36,18784,
+8,15,52,18784,
+2,35,42,18784,
+22,22,45,18784,
+14,14,51,18784,
+0,28,47,18784,
+8,25,48,18784,
+17,20,48,18784,
+4,36,41,18784,
+6,29,46,18784,
+3,22,50,18784,
+4,24,49,18784,
+18,35,38,18784,
+0,17,52,18784,
+13,18,50,18784,
+19,28,43,18784,
+1,17,52,18784,
+5,37,40,18784,
+28,29,37,18821,
+17,32,41,18821,
+8,11,53,18821,
+11,32,43,18821,
+4,13,53,18821,
+1,28,47,18821,
+11,13,52,18821,
+16,37,37,18821,
+16,23,47,18821,
+13,35,40,18821,
+23,28,41,18821,
+8,23,49,18821,
+20,35,37,18821,
+23,23,44,18821,
+15,33,41,18821,
+13,15,51,18821,
+21,23,45,18821,
+3,31,45,18821,
+16,36,38,18821,
+6,16,52,18821,
+26,32,36,18831,
+4,26,48,18831,
+6,32,44,18831,
+10,36,40,18831,
+4,8,54,18831,
+22,24,44,18831,
+23,32,38,18831,
+24,30,39,18831,
+12,33,42,18831,
+0,9,54,18831,
+10,31,44,18831,
+14,20,49,18831,
+16,25,46,18831,
+2,28,47,18831,
+2,17,52,18831,
+6,19,51,18831,
+3,35,42,18831,
+27,30,37,18855,
+21,21,46,18855,
+1,9,54,18855,
+4,22,50,18855,
+10,28,46,18855,
+10,14,52,18855,
+10,20,50,18855,
+20,34,38,18855,
+20,22,46,18855,
+2,9,54,18855,
+12,16,51,18855,
+16,21,48,18855,
+6,7,54,18855,
+9,34,42,18855,
+6,38,39,18855,
+18,34,39,18855,
+11,24,48,18855,
+24,24,43,18855,
+20,24,45,18855,
+0,20,51,18855,
+21,25,44,18855,
+13,23,48,18855,
+3,28,47,18855,
+3,17,52,18855,
+5,24,49,18855,
+1,20,51,18855,
+4,31,45,18855,
+5,36,41,18855,
+7,12,53,18855,
+8,27,47,18855,
+21,31,40,18855,
+16,35,39,18855,
+8,33,43,18855,
+15,29,44,18855,
+19,31,41,18855,
+13,25,47,18855,
+5,13,53,18855,
+23,25,43,18855,
+12,19,50,18855,
+2,20,51,18855,
+6,37,40,18855,
+8,21,50,18855,
+5,8,54,18855,
+16,30,43,18855,
+13,30,44,18855,
+0,14,53,18855,
+5,26,48,18855,
+20,29,42,18855,
+0,34,43,18855,
+26,27,40,18875,
+22,35,36,18875,
+14,28,45,18875,
+4,35,42,18875,
+9,30,45,18875,
+26,31,37,18912,
+3,9,54,18912,
+7,29,46,18912,
+1,14,53,18912,
+25,34,35,18912,
+9,18,51,18912,
+13,34,41,18912,
+14,31,43,18912,
+1,34,43,18912,
+10,35,41,18912,
+19,23,46,18912,
+11,26,47,18912,
+22,29,41,18912,
+11,22,49,18912,
+22,34,37,18912,
+7,32,44,18912,
+2,14,53,18912,
+4,28,47,18912,
+22,26,43,18912,
+10,10,53,18912,
+17,28,44,18912,
+25,28,40,18912,
+20,20,47,18912,
+4,17,52,18912,
+7,16,52,18912,
+5,22,50,18912,
+31,32,32,18981,
+14,37,38,18981,
+2,34,43,18981,
+11,38,38,18981,
+9,15,52,18981,
+20,33,39,18981,
+3,20,51,18981,
+16,27,45,18981,
+15,24,47,18981,
+25,33,36,18981,
+9,25,48,18981,
+12,29,45,18981,
+11,17,51,18981,
+13,21,49,18981,
+23,31,39,18981,
+31,31,33,18999,
+7,19,51,18999,
+5,31,45,18999,
+19,21,47,18999,
+19,25,45,18999,
+11,37,39,18999,
+9,11,53,18999,
+9,23,49,18999,
+16,16,50,18999,
+20,26,44,18999,
+16,34,40,18999,
+28,28,38,18999,
+6,36,41,18999,
+6,24,49,18999,
+18,33,40,18999,
+14,36,39,18999,
+30,32,33,19016,
+15,22,48,19016,
+15,32,42,19016,
+4,9,54,19016,
+7,7,54,19016,
+3,34,43,19016,
+25,25,42,19016,
+3,14,53,19016,
+27,29,38,19016,
+13,27,46,19016,
+7,38,39,19016,
+17,18,49,19016,
+18,29,43,19016,
+6,13,53,19016,
+17,31,42,19016,
+15,17,50,19016,
+5,35,42,19016,
+24,26,42,19016,
+6,26,48,19016,
+0,10,54,19016,
+18,24,46,19016,
+6,8,54,19016,
+0,30,46,19016,
+8,12,53,19016,
+1,10,54,19016,
+12,32,43,19016,
+24,29,40,19016,
+4,20,51,19016,
+18,22,47,19016,
+11,36,40,19016,
+30,31,34,19037,
+15,26,46,19037,
+12,13,52,19037,
+1,30,46,19037,
+22,33,38,19037,
+5,28,47,19037,
+11,31,44,19037,
+7,37,40,19037,
+25,32,37,19037,
+16,19,49,19037,
+5,17,52,19037,
+9,27,47,19037,
+9,33,43,19037,
+21,27,43,19037,
+29,33,33,19056,
+2,10,54,19056,
+2,30,46,19056,
+6,22,50,19056,
+10,34,42,19056,
+26,30,38,19056,
+14,18,50,19056,
+11,14,52,19056,
+29,32,34,19070,
+11,28,46,19070,
+4,14,53,19070,
+8,29,46,19070,
+14,35,40,19070,
+4,34,43,19070,
+11,20,50,19070,
+6,31,45,19070,
+9,21,50,19070,
+5,9,54,19070,
+21,30,41,19070,
+14,15,51,19070,
+23,27,42,19070,
+13,33,42,19070,
+20,32,40,19070,
+12,24,48,19070,
+8,32,44,19070,
+8,16,52,19070,
+6,35,42,19070,
+3,10,54,19070,
+19,30,42,19070,
+10,30,45,19070,
+3,30,46,19070,
+30,30,35,19101,
+10,18,51,19101,
+0,0,55,19101,
+18,26,45,19101,
+0,33,44,19101,
+16,33,41,19101,
+19,19,48,19101,
+0,1,55,19101,
+0,25,49,19101,
+7,24,49,19101,
+24,35,35,19101,
+7,36,41,19101,
+19,36,37,19101,
+15,20,49,19101,
+5,20,51,19101,
+8,19,51,19101,
+19,27,44,19101,
+1,33,44,19101,
+13,16,51,19101,
+1,1,55,19101,
+1,25,49,19101,
+7,13,53,19101,
+17,37,37,19101,
+11,35,41,19101,
+29,31,35,19121,
+17,23,47,19121,
+18,20,48,19121,
+0,18,52,19121,
+24,34,36,19121,
+2,33,44,19121,
+12,22,49,19121,
+22,32,39,19121,
+14,23,48,19121,
+0,23,50,19121,
+6,28,47,19121,
+12,26,47,19121,
+17,36,38,19121,
+1,18,52,19121,
+7,26,48,19121,
+23,30,40,19121,
+0,2,55,19121,
+18,32,41,19121,
+6,17,52,19121,
+8,38,39,19121,
+28,33,34,19132,
+10,25,48,19132,
+7,8,54,19132,
+10,15,52,19132,
+1,2,55,19132,
+17,25,46,19132,
+1,23,50,19132,
+10,11,53,19132,
+13,19,50,19132,
+2,25,49,19132,
+19,35,38,19132,
+14,25,47,19132,
+5,34,43,19132,
+25,31,38,19132,
+10,23,49,19132,
+5,14,53,19132,
+4,10,54,19132,
+22,28,42,19132,
+4,30,46,19132,
+12,38,38,19132,
+2,18,52,19132,
+14,30,44,19132,
+2,2,55,19132,
+8,37,40,19132,
+28,32,35,19163,
+20,28,43,19163,
+16,29,44,19163,
+14,34,41,19163,
+26,26,41,19163,
+6,9,54,19163,
+7,22,50,19163,
+0,27,48,19163,
+2,23,50,19163,
+21,36,36,19163,
+12,37,39,19163,
+17,21,48,19163,
+1,27,48,19163,
+12,17,51,19163,
+24,33,37,19163,
+3,33,44,19163,
+0,15,53,19163,
+0,3,55,19163,
+9,12,53,19163,
+27,28,39,19163,
+15,28,45,19163,
+3,25,49,19163,
+17,35,39,19163,
+7,31,45,19163,
+15,31,43,19163,
+25,27,41,19163,
+1,15,53,19163,
+13,29,45,19163,
+1,3,55,19163,
+21,35,37,19163,
+3,18,52,19163,
+2,27,48,19163,
+0,11,54,19163,
+29,30,36,19208,
+6,20,51,19208,
+10,33,43,19208,
+1,11,54,19208,
+19,34,39,19208,
+3,23,50,19208,
+14,21,49,19208,
+26,29,39,19208,
+2,15,53,19208,
+9,29,46,19208,
+22,23,45,19208,
+2,3,55,19208,
+15,37,38,19208,
+7,35,42,19208,
+17,30,43,19208,
+10,27,47,19208,
+12,36,40,19208,
+9,32,44,19208,
+5,30,46,19208,
+21,22,46,19208,
+9,16,52,19208,
+23,24,44,19208,
+8,24,49,19208,
+28,31,36,19227,
+12,31,44,19227,
+5,10,54,19227,
+8,36,41,19227,
+16,24,47,19227,
+6,14,53,19227,
+4,33,44,19227,
+10,21,50,19227,
+21,34,38,19227,
+27,34,34,19227,
+6,34,43,19227,
+24,28,41,19227,
+14,27,46,19227,
+11,34,42,19227,
+2,11,54,19227,
+0,4,55,19227,
+13,13,52,19227,
+0,21,51,19227,
+15,36,39,19227,
+7,17,52,19227,
+13,32,43,19227,
+1,4,55,19227,
+0,39,39,19227,
+4,25,49,19227,
+21,24,45,19227,
+3,27,48,19227,
+7,28,47,19227,
+20,31,41,19227,
+8,13,53,19227,
+3,3,55,19227,
+1,39,39,19227,
+17,27,45,19227,
+3,15,53,19227,
+27,33,35,19254,
+9,19,51,19254,
+1,21,51,19254,
+12,28,46,19254,
+12,20,50,19254,
+24,32,38,19254,
+4,18,52,19254,
+16,22,48,19254,
+16,32,42,19254,
+12,14,52,19254,
+8,26,48,19254,
+0,38,40,19254,
+8,8,54,19254,
+18,28,44,19254,
+20,23,46,19254,
+22,25,44,19254,
+4,23,50,19254,
+17,34,40,19254,
+22,31,40,19254,
+1,38,40,19254,
+2,4,55,19254,
+16,17,50,19254,
+11,18,51,19254,
+21,29,42,19254,
+3,11,54,19254,
+25,30,39,19254,
+7,9,54,19254,
+2,21,51,19254,
+2,39,39,19254,
+11,30,45,19254,
+9,38,39,19254,
+16,26,46,19254,
+2,38,40,19254,
+8,22,50,19254,
+27,32,36,19286,
+4,27,48,19286,
+14,33,42,19286,
+13,24,48,19286,
+15,18,50,19286,
+0,32,45,19286,
+18,31,42,19286,
+18,18,49,19286,
+23,35,36,19286,
+5,33,44,19286,
+20,25,45,19286,
+20,21,47,19286,
+3,4,55,19286,
+4,15,53,19286,
+24,25,43,19286,
+1,32,45,19286,
+11,25,48,19286,
+19,33,40,19286,
+0,29,47,19286,
+0,5,55,19286,
+0,37,41,19286,
+8,31,45,19286,
+11,15,52,19286,
+15,35,40,19286,
+7,20,51,19286,
+12,35,41,19286,
+9,37,40,19286,
+3,39,39,19286,
+1,37,41,19286,
+5,25,49,19286,
+11,11,53,19286,
+23,29,41,19286,
+1,29,47,19286,
+1,5,55,19286,
+29,29,37,19306,
+11,23,49,19306,
+21,33,39,19306,
+17,19,49,19306,
+15,15,51,19306,
+19,29,43,19306,
+3,21,51,19306,
+6,10,54,19306,
+6,30,46,19306,
+28,30,37,19320,
+3,38,40,19320,
+10,12,53,19320,
+5,18,52,19320,
+14,16,51,19320,
+8,35,42,19320,
+19,24,46,19320,
+21,26,44,19320,
+2,32,45,19320,
+4,11,54,19320,
+2,5,55,19320,
+13,22,49,19320,
+5,23,50,19320,
+23,34,37,19320,
+7,34,43,19320,
+23,26,43,19320,
+13,26,47,19320,
+7,14,53,19320,
+19,22,47,19320,
+2,29,47,19320,
+2,37,41,19320,
+13,38,38,19320,
+26,34,35,19363,
+16,20,49,19363,
+4,4,55,19363,
+14,19,50,19363,
+8,17,52,19363,
+10,29,46,19363,
+8,28,47,19363,
+4,39,39,19363,
+27,27,40,19363,
+15,23,48,19363,
+24,31,39,19363,
+4,21,51,19363,
+9,24,49,19363,
+3,32,45,19363,
+9,36,41,19363,
+5,27,48,19363,
+3,29,47,19363,
+17,33,41,19363,
+11,33,43,19363,
+27,31,37,19383,
+3,37,41,19383,
+15,25,47,19383,
+9,13,53,19383,
+5,15,53,19383,
+11,27,47,19383,
+3,5,55,19383,
+13,17,51,19383,
+13,37,39,19383,
+4,38,40,19383,
+26,28,40,19383,
+10,16,52,19383,
+0,36,42,19383,
+0,12,54,19383,
+10,32,44,19383,
+1,36,42,19383,
+1,12,54,19383,
+15,30,44,19383,
+8,9,54,19383,
+6,33,44,19383,
+9,26,48,19383,
+26,33,36,19391,
+0,6,55,19391,
+11,21,50,19391,
+1,6,55,19391,
+15,34,41,19391,
+5,11,54,19391,
+18,23,47,19391,
+18,37,37,19391,
+14,29,45,19391,
+22,27,43,19391,
+23,33,38,19391,
+10,19,51,19391,
+19,26,45,19391,
+6,25,49,19391,
+6,18,52,19391,
+2,12,54,19391,
+18,36,38,19391,
+12,34,42,19391,
+2,36,42,19391,
+20,30,42,19391,
+21,32,40,19391,
+25,26,42,19391,
+2,6,55,19391,
+0,16,53,19391,
+10,38,39,19391,
+22,30,41,19391,
+19,20,48,19391,
+18,25,46,19391,
+9,22,50,19391,
+0,19,52,19391,
+20,36,37,19391,
+13,36,40,19391,
+6,23,50,19391,
+8,20,51,19391,
+16,28,45,19391,
+7,30,46,19391,
+20,27,44,19391,
+4,32,45,19391,
+7,10,54,19391,
+4,37,41,19391,
+25,29,40,19402,
+1,19,52,19402,
+4,29,47,19402,
+4,5,55,19402,
+17,29,44,19402,
+16,31,43,19402,
+19,32,41,19402,
+1,16,53,19402,
+13,31,44,19402,
+5,21,51,19402,
+5,39,39,19402,
+15,21,49,19402,
+9,31,45,19402,
+13,28,46,19402,
+6,27,48,19402,
+8,34,43,19402,
+3,12,54,19402,
+24,27,42,19402,
+26,32,37,19459,
+12,30,45,19459,
+8,14,53,19459,
+12,18,51,19459,
+3,36,42,19459,
+28,29,38,19459,
+10,37,40,19459,
+14,32,43,19459,
+20,35,38,19459,
+13,20,50,19459,
+13,14,52,19459,
+5,38,40,19459,
+18,21,48,19459,
+2,19,52,19459,
+2,16,53,19459,
+16,37,38,19459,
+9,35,42,19459,
+6,15,53,19459,
+3,6,55,19459,
+15,27,46,19459,
+18,35,39,19459,
+32,32,32,19512,
+12,15,52,19512,
+12,25,48,19512,
+6,11,54,19512,
+18,30,43,19512,
+16,36,39,19512,
+27,30,38,19512,
+21,28,43,19512,
+3,16,53,19512,
+12,23,49,19512,
+0,7,55,19512,
+23,32,39,19512,
+17,24,47,19512,
+9,17,52,19512,
+3,19,52,19512,
+5,32,45,19512,
+9,28,47,19512,
+31,32,33,19539,
+11,12,53,19539,
+7,33,44,19539,
+0,35,43,19539,
+7,25,49,19539,
+1,7,55,19539,
+25,35,35,19539,
+1,35,43,19539,
+13,35,41,19539,
+5,37,41,19539,
+5,29,47,19539,
+5,5,55,19539,
+0,24,50,19539,
+4,36,42,19539,
+24,30,40,19539,
+14,24,48,19539,
+4,12,54,19539,
+22,36,36,19539,
+20,34,39,19539,
+1,24,50,19539,
+0,31,46,19539,
+17,22,48,19539,
+10,36,41,19539,
+25,34,36,19539,
+4,6,55,19539,
+7,18,52,19539,
+23,28,42,19539,
+17,32,42,19539,
+0,26,49,19539,
+10,24,49,19539,
+15,33,42,19539,
+6,39,39,19539,
+17,17,50,19539,
+7,23,50,19539,
+22,35,37,19539,
+18,27,45,19539,
+6,21,51,19539,
+30,33,33,19568,
+1,31,46,19568,
+31,31,34,19568,
+10,13,53,19568,
+11,29,46,19568,
+9,9,54,19568,
+2,7,55,19568,
+2,35,43,19568,
+1,26,49,19568,
+2,24,50,19568,
+10,26,48,19568,
+30,32,34,19584,
+6,38,40,19584,
+18,34,40,19584,
+8,10,54,19584,
+8,30,46,19584,
+16,18,50,19584,
+4,19,52,19584,
+19,28,44,19584,
+11,32,44,19584,
+2,31,46,19584,
+26,31,38,19584,
+17,26,46,19584,
+14,22,49,19584,
+11,16,52,19584,
+16,35,40,19584,
+2,26,49,19584,
+4,16,53,19584,
+14,26,47,19584,
+7,27,48,19584,
+12,33,43,19584,
+15,16,51,19584,
+9,20,51,19584,
+12,27,47,19584,
+21,31,41,19584,
+3,35,43,19584,
+25,33,37,19584,
+7,15,53,19584,
+23,23,45,19584,
+3,7,55,19584,
+11,19,51,19584,
+10,22,50,19584,
+22,34,38,19584,
+14,38,38,19584,
+22,22,46,19584,
+12,21,50,19584,
+5,36,42,19584,
+6,32,45,19584,
+22,24,45,19584,
+0,22,51,19584,
+3,24,50,19584,
+0,13,54,19584,
+5,12,54,19584,
+1,13,54,19584,
+29,33,34,19623,
+26,27,41,19623,
+9,14,53,19623,
+30,31,35,19623,
+5,6,55,19623,
+6,37,41,19623,
+7,11,54,19623,
+10,31,45,19623,
+1,22,51,19623,
+19,31,42,19623,
+14,17,51,19623,
+6,29,47,19623,
+21,23,46,19623,
+9,34,43,19623,
+18,19,49,19623,
+15,19,50,19623,
+3,26,49,19623,
+11,38,39,19623,
+14,37,39,19623,
+3,31,46,19623,
+0,28,48,19623,
+24,24,44,19623,
+0,8,55,19623,
+10,35,42,19623,
+2,22,51,19623,
+8,33,44,19623,
+2,13,54,19623,
+22,29,42,19623,
+16,23,48,19623,
+28,28,39,19623,
+20,33,40,19623,
+1,28,48,19623,
+13,34,42,19623,
+23,31,40,19623,
+11,37,40,19623,
+20,29,43,19623,
+5,16,53,19623,
+17,20,49,19623,
+5,19,52,19623,
+23,25,44,19623,
+8,25,49,19623,
+4,7,55,19623,
+4,35,43,19623,
+1,8,55,19623,
+25,28,41,19623,
+16,25,47,19623,
+29,32,35,19666,
+27,29,39,19666,
+7,21,51,19666,
+7,39,39,19666,
+21,25,45,19666,
+21,21,47,19666,
+15,29,45,19666,
+16,30,44,19666,
+4,24,50,19666,
+20,24,46,19666,
+2,28,48,19666,
+14,36,40,19666,
+0,34,44,19666,
+8,18,52,19666,
+4,31,46,19666,
+10,17,52,19666,
+4,26,49,19666,
+25,32,38,19666,
+16,34,41,19666,
+2,8,55,19666,
+7,38,40,19666,
+10,28,47,19666,
+14,31,44,19666,
+20,22,47,19666,
+1,34,44,19666,
+8,23,50,19666,
+3,22,51,19666,
+13,30,45,19666,
+18,33,41,19666,
+13,18,51,19666,
+3,13,54,19666,
+22,33,39,19666,
+28,34,34,19712,
+14,14,52,19712,
+30,30,36,19712,
+6,12,54,19712,
+14,28,46,19712,
+6,36,42,19712,
+2,34,44,19712,
+14,20,50,19712,
+22,26,44,19712,
+8,27,48,19712,
+3,28,48,19712,
+9,30,46,19712,
+9,10,54,19712,
+6,6,55,19712,
+24,35,36,19712,
+12,12,53,19712,
+26,30,39,19712,
+11,24,49,19712,
+13,25,48,19712,
+8,15,53,19712,
+17,28,45,19712,
+7,32,45,19712,
+16,21,49,19712,
+0,17,53,19712,
+28,33,35,19740,
+29,31,36,19740,
+15,32,43,19740,
+11,36,41,19740,
+3,8,55,19740,
+13,15,52,19740,
+24,29,41,19740,
+1,17,53,19740,
+7,29,47,19740,
+13,23,49,19740,
+11,13,53,19740,
+5,7,55,19740,
+17,31,43,19740,
+25,25,43,19740,
+19,23,47,19740,
+5,35,43,19740,
+19,37,37,19740,
+7,37,41,19740,
+6,19,52,19740,
+4,13,54,19740,
+19,36,38,19740,
+11,26,48,19740,
+10,20,51,19740,
+8,11,54,19740,
+24,26,43,19740,
+5,24,50,19740,
+24,34,37,19740,
+20,26,45,19740,
+6,16,53,19740,
+12,29,46,19740,
+18,29,44,19740,
+3,34,44,19740,
+4,22,51,19740,
+16,27,46,19740,
+14,35,41,19740,
+2,17,53,19740,
+17,37,38,19740,
+19,25,46,19740,
+5,26,49,19740,
+5,31,46,19740,
+4,28,48,19740,
+12,32,44,19740,
+0,20,52,19740,
+12,16,52,19740,
+20,20,48,19740,
+28,32,36,19776,
+15,24,48,19776,
+11,22,50,19776,
+1,20,52,19776,
+10,14,53,19776,
+20,32,41,19776,
+10,34,43,19776,
+4,8,55,19776,
+21,30,42,19776,
+8,21,51,19776,
+0,9,55,19776,
+17,36,39,19776,
+8,39,39,19776,
+21,27,44,19776,
+21,36,37,19776,
+12,19,51,19776,
+9,33,44,19776,
+19,21,48,19776,
+19,35,39,19776,
+1,9,55,19776,
+25,31,39,19776,
+13,27,47,19776,
+11,31,45,19776,
+9,25,49,19776,
+13,33,43,19776,
+23,27,43,19776,
+3,17,53,19776,
+4,34,44,19776,
+22,32,40,19776,
+8,38,40,19776,
+2,20,52,19776,
+12,38,39,19776,
+7,36,42,19776,
+24,33,38,19793,
+16,33,42,19793,
+0,30,47,19793,
+9,18,52,19793,
+18,24,47,19793,
+7,12,54,19793,
+6,35,43,19793,
+15,22,49,19793,
+1,30,47,19793,
+13,21,50,19793,
+5,22,51,19793,
+9,23,50,19793,
+5,13,54,19793,
+6,7,55,19793,
+27,34,35,19836,
+15,26,47,19836,
+23,30,41,19836,
+21,35,38,19836,
+2,9,55,19836,
+19,30,43,19836,
+29,30,37,19836,
+11,35,42,19836,
+0,14,54,19836,
+6,24,50,19836,
+18,32,42,19836,
+18,22,48,19836,
+5,28,48,19836,
+1,14,54,19836,
+3,20,52,19836,
+6,26,49,19836,
+16,16,51,19836,
+12,37,40,19836,
+6,31,46,19836,
+17,18,50,19836,
+15,38,38,19836,
+2,30,47,19836,
+8,32,45,19836,
+27,28,40,19836,
+9,27,48,19836,
+0,33,45,19836,
+4,17,53,19836,
+7,16,53,19836,
+11,17,52,19836,
+5,8,55,19836,
+28,31,37,19876,
+27,33,36,19876,
+8,37,41,19876,
+17,35,40,19876,
+11,28,47,19876,
+8,29,47,19876,
+7,19,52,19876,
+15,37,39,19876,
+3,9,55,19876,
+19,27,45,19876,
+15,17,51,19876,
+9,15,53,19876,
+1,33,45,19876,
+10,10,54,19876,
+18,26,46,19876,
+26,26,42,19876,
+10,30,46,19876,
+14,34,42,19876,
+2,14,54,19876,
+16,19,50,19876,
+22,28,43,19876,
+19,34,40,19876,
+26,29,40,19876,
+5,34,44,19876,
+2,33,45,19876,
+21,34,39,19876,
+3,30,47,19876,
+25,27,42,19876,
+9,11,54,19876,
+20,28,44,19876,
+4,20,52,19876,
+6,22,51,19876,
+15,36,40,19876,
+12,24,49,19876,
+3,14,54,19876,
+24,32,39,19891,
+14,30,45,19891,
+0,39,40,19891,
+12,36,41,19891,
+14,18,51,19891,
+6,13,54,19891,
+23,36,36,19891,
+11,20,51,19891,
+12,13,53,19891,
+4,9,55,19891,
+27,32,37,19930,
+17,23,48,19930,
+1,39,40,19930,
+16,29,45,19930,
+15,31,44,19930,
+3,33,45,19930,
+9,39,39,19930,
+23,35,37,19930,
+19,19,49,19930,
+7,7,55,19930,
+5,17,53,19930,
+7,35,43,19930,
+9,21,51,19930,
+17,25,47,19930,
+6,28,48,19930,
+8,12,54,19930,
+24,28,42,19930,
+12,26,48,19930,
+8,36,42,19930,
+2,39,40,19930,
+15,28,46,19930,
+6,8,55,19930,
+0,10,55,19930,
+10,33,44,19930,
+7,24,50,19930,
+20,31,42,19930,
+0,38,41,19930,
+18,20,49,19930,
+15,20,50,19930,
+4,30,47,19930,
+14,15,52,19930,
+17,30,44,19930,
+0,25,50,19930,
+25,30,40,19930,
+9,38,40,19930,
+14,25,48,19930,
+17,34,41,19930,
+7,26,49,19930,
+1,38,41,19930,
+13,29,46,19930,
+26,35,35,19953,
+1,10,55,19953,
+1,25,50,19953,
+7,31,46,19953,
+14,23,49,19953,
+22,31,41,19953,
+29,29,38,19953,
+11,34,43,19953,
+11,14,53,19953,
+10,25,49,19953,
+6,34,44,19953,
+26,34,36,19967,
+4,14,54,19967,
+10,18,52,19967,
+28,30,38,19967,
+12,22,50,19967,
+13,16,52,19967,
+5,20,52,19967,
+2,38,41,19967,
+2,25,50,19967,
+16,32,43,19967,
+2,10,55,19967,
+23,34,38,19967,
+13,32,44,19967,
+8,16,53,19967,
+10,23,50,19967,
+22,23,46,19967,
+8,19,52,19967,
+4,33,45,19967,
+23,24,45,19967,
+0,27,49,19967,
+0,23,51,19967,
+3,39,40,19967,
+12,31,45,19967,
+9,32,45,19967,
+21,33,40,19967,
+13,19,51,19967,
+21,29,43,19967,
+9,37,41,19967,
+17,21,49,19967,
+5,9,55,19967,
+19,33,41,19967,
+15,35,41,19967,
+1,23,51,19967,
+1,27,49,19967,
+9,29,47,19967,
+12,35,42,19967,
+18,28,45,19967,
+0,18,53,19967,
+0,37,42,19967,
+21,24,46,19967,
+10,27,48,19967,
+1,37,42,19967,
+21,22,47,19967,
+14,33,43,19967,
+2,27,49,19967,
+27,31,38,20020,
+13,38,39,20020,
+17,27,46,20020,
+26,33,37,20020,
+3,25,50,20020,
+3,38,41,20020,
+10,15,53,20020,
+18,31,43,20020,
+22,25,45,20020,
+1,18,53,20020,
+3,10,55,20020,
+7,22,51,20020,
+5,30,47,20020,
+23,29,42,20020,
+7,13,54,20020,
+2,23,51,20020,
+6,17,53,20020,
+14,27,47,20020,
+0,0,56,20020,
+16,24,48,20020,
+14,21,50,20020,
+2,37,42,20020,
+24,31,40,20020,
+24,25,44,20020,
+32,32,33,20083,
+18,37,38,20083,
+11,30,46,20083,
+2,18,53,20083,
+12,28,47,20083,
+4,39,40,20083,
+5,14,54,20083,
+12,17,52,20083,
+10,11,54,20083,
+7,28,48,20083,
+0,1,56,20083,
+20,23,47,20083,
+8,35,43,20083,
+7,8,55,20083,
+20,37,37,20083,
+19,29,44,20083,
+1,1,56,20083,
+13,37,40,20083,
+27,27,41,20083,
+5,33,45,20083,
+3,27,49,20083,
+31,33,33,20103,
+23,33,39,20103,
+3,23,51,20103,
+6,20,52,20103,
+20,36,38,20103,
+0,32,46,20103,
+0,2,56,20103,
+8,24,50,20103,
+31,32,34,20119,
+1,32,46,20119,
+4,25,50,20119,
+16,22,49,20119,
+7,34,44,20119,
+20,25,46,20119,
+0,15,54,20119,
+1,2,56,20119,
+8,26,49,20119,
+26,28,41,20119,
+9,36,42,20119,
+8,31,46,20119,
+16,26,47,20119,
+4,10,55,20119,
+4,38,41,20119,
+18,36,39,20119,
+9,12,54,20119,
+23,26,44,20119,
+17,33,42,20119,
+10,39,39,20119,
+6,9,55,20119,
+3,37,42,20119,
+10,21,51,20119,
+1,15,54,20119,
+3,18,53,20119,
+21,26,45,20119,
+16,38,38,20119,
+2,2,56,20119,
+10,38,40,20119,
+26,32,38,20119,
+2,32,46,20119,
+15,34,42,20119,
+12,20,51,20119,
+20,21,48,20119,
+0,36,43,20119,
+30,33,34,20155,
+2,15,54,20155,
+0,21,52,20155,
+0,3,56,20155,
+6,30,47,20155,
+0,29,48,20155,
+1,3,56,20155,
+9,19,52,20155,
+9,16,53,20155,
+4,23,51,20155,
+13,36,41,20155,
+1,36,43,20155,
+4,27,49,20155,
+28,29,39,20155,
+21,32,41,20155,
+13,24,49,20155,
+1,29,48,20155,
+5,39,40,20155,
+20,35,39,20155,
+25,35,36,20155,
+1,21,52,20155,
+16,17,51,20155,
+0,11,55,20155,
+16,37,39,20155,
+11,33,44,20155,
+19,24,47,20155,
+7,17,53,20155,
+25,29,41,20155,
+13,13,53,20155,
+11,25,49,20155,
+1,11,55,20155,
+31,31,35,20173,
+6,14,54,20173,
+22,30,42,20173,
+18,18,50,20173,
+10,32,45,20173,
+8,13,54,20173,
+2,3,56,20173,
+19,22,48,20173,
+13,26,48,20173,
+2,29,48,20173,
+18,35,40,20173,
+3,32,46,20173,
+4,37,42,20173,
+4,18,53,20173,
+2,36,43,20173,
+30,32,35,20188,
+20,30,43,20188,
+22,36,37,20188,
+12,34,43,20188,
+11,18,52,20188,
+12,14,53,20188,
+2,21,52,20188,
+19,32,42,20188,
+22,27,44,20188,
+8,22,51,20188,
+2,11,55,20188,
+17,19,50,20188,
+5,25,50,20188,
+10,29,47,20188,
+5,10,55,20188,
+6,33,45,20188,
+3,15,54,20188,
+10,37,41,20188,
+11,23,50,20188,
+25,26,43,20188,
+5,38,41,20188,
+25,34,37,20188,
+15,30,45,20188,
+27,30,39,20188,
+15,18,51,20188,
+0,4,56,20188,
+8,28,48,20188,
+16,36,40,20188,
+7,20,52,20188,
+19,26,46,20188,
+8,8,55,20188,
+1,4,56,20188,
+23,32,40,20188,
+16,31,44,20188,
+29,34,34,20206,
+13,22,50,20206,
+22,35,38,20206,
+14,29,46,20206,
+3,36,43,20206,
+3,21,52,20206,
+3,29,48,20206,
+24,27,43,20206,
+15,25,48,20206,
+20,27,45,20206,
+15,15,52,20206,
+3,3,56,20206,
+11,27,48,20206,
+29,33,35,20237,
+9,35,43,20237,
+13,31,45,20237,
+17,29,45,20237,
+5,23,51,20237,
+15,23,49,20237,
+5,27,49,20237,
+11,15,53,20237,
+7,9,55,20237,
+3,11,55,20237,
+2,4,56,20237,
+4,32,46,20237,
+14,32,44,20237,
+20,34,40,20237,
+14,16,52,20237,
+8,34,44,20237,
+16,20,50,20237,
+16,28,46,20237,
+24,30,41,20237,
+6,39,40,20237,
+4,15,54,20237,
+9,24,50,20237,
+30,31,36,20250,
+18,23,48,20250,
+25,33,38,20250,
+5,18,53,20250,
+26,31,39,20250,
+18,25,47,20250,
+11,11,54,20250,
+13,35,42,20250,
+14,19,51,20250,
+5,37,42,20250,
+9,26,49,20250,
+9,31,46,20250,
+7,30,47,20250,
+12,30,46,20250,
+10,12,54,20250,
+18,30,44,20250,
+10,36,42,20250,
+7,14,54,20250,
+21,28,44,20250,
+6,10,55,20250,
+3,4,56,20250,
+4,21,52,20250,
+0,5,56,20250,
+18,34,41,20250,
+4,36,43,20250,
+6,25,50,20250,
+14,38,39,20250,
+29,32,36,20285,
+4,29,48,20285,
+6,38,41,20285,
+0,35,44,20285,
+22,34,39,20285,
+16,35,41,20285,
+8,17,53,20285,
+1,35,44,20285,
+13,17,52,20285,
+1,5,56,20285,
+13,28,47,20285,
+4,11,55,20285,
+19,20,49,20285,
+23,28,43,20285,
+17,32,43,20285,
+7,33,45,20285,
+11,39,39,20285,
+15,33,43,20285,
+15,27,47,20285,
+11,21,51,20285,
+10,19,52,20285,
+2,5,56,20285,
+2,35,44,20285,
+28,34,35,20317,
+5,32,46,20317,
+10,16,53,20317,
+14,37,40,20317,
+11,38,40,20317,
+18,21,49,20317,
+9,13,54,20317,
+15,21,50,20317,
+5,15,54,20317,
+6,23,51,20317,
+6,27,49,20317,
+9,22,51,20317,
+21,31,42,20317,
+8,20,52,20317,
+24,36,36,20317,
+4,4,56,20317,
+28,28,40,20317,
+6,37,42,20317,
+17,24,48,20317,
+28,33,36,20360,
+6,18,53,20360,
+12,33,44,20360,
+9,28,48,20360,
+30,30,37,20360,
+26,27,42,20360,
+18,27,46,20360,
+0,12,55,20360,
+5,21,52,20360,
+25,32,39,20360,
+20,33,41,20360,
+5,36,43,20360,
+19,28,45,20360,
+5,29,48,20360,
+0,31,47,20360,
+24,35,37,20360,
+27,29,40,20360,
+8,9,55,20360,
+3,35,44,20360,
+3,5,56,20360,
+12,25,49,20360,
+0,19,53,20360,
+7,39,40,20360,
+11,32,45,20360,
+13,20,51,20360,
+1,12,55,20360,
+5,11,55,20360,
+23,31,41,20360,
+11,37,41,20360,
+1,19,53,20360,
+29,31,37,20376,
+19,31,43,20376,
+11,29,47,20376,
+1,31,47,20376,
+0,6,56,20376,
+12,18,52,20376,
+0,16,54,20376,
+14,36,41,20376,
+9,34,44,20376,
+1,6,56,20376,
+2,12,55,20376,
+8,30,47,20376,
+25,28,42,20376,
+22,33,40,20376,
+1,16,54,20376,
+14,24,49,20376,
+12,23,50,20376,
+17,22,49,20376,
+10,35,43,20376,
+23,23,46,20376,
+22,29,43,20376,
+7,38,41,20376,
+19,37,38,20376,
+7,25,50,20376,
+2,31,47,20376,
+17,26,47,20376,
+13,34,43,20376,
+2,19,53,20376,
+7,10,55,20376,
+13,14,53,20376,
+14,26,48,20376,
+22,24,46,20376,
+24,34,38,20383,
+2,6,56,20383,
+2,16,54,20383,
+10,24,50,20383,
+26,30,40,20383,
+6,32,46,20383,
+0,26,50,20383,
+16,34,42,20383,
+8,14,54,20383,
+28,32,37,20416,
+12,27,48,20416,
+18,33,42,20416,
+6,15,54,20416,
+4,5,56,20416,
+4,35,44,20416,
+20,29,44,20416,
+17,38,38,20416,
+22,22,47,20416,
+1,26,50,20416,
+10,26,49,20416,
+0,24,51,20416,
+24,24,45,20416,
+10,31,46,20416,
+19,36,39,20416,
+3,12,55,20416,
+1,24,51,20416,
+12,15,53,20416,
+8,33,45,20416,
+23,25,45,20416,
+3,19,53,20416,
+7,27,49,20416,
+21,37,37,20416,
+21,23,47,20416,
+7,23,51,20416,
+27,35,35,20434,
+17,37,39,20434,
+3,31,47,20434,
+17,17,51,20434,
+9,17,53,20434,
+14,22,50,20434,
+2,26,50,20434,
+11,12,54,20434,
+6,29,48,20434,
+16,30,45,20434,
+11,36,42,20434,
+2,24,51,20434,
+27,34,36,20447,
+6,36,43,20447,
+3,16,54,20447,
+16,18,51,20447,
+3,6,56,20447,
+0,34,45,20447,
+21,36,38,20447,
+6,21,52,20447,
+24,29,42,20447,
+21,25,46,20447,
+7,37,42,20447,
+14,31,45,20447,
+6,11,55,20447,
+1,34,45,20447,
+15,29,46,20447,
+7,18,53,20447,
+20,24,47,20447,
+13,30,46,20447,
+4,12,55,20447,
+0,28,49,20447,
+15,32,44,20447,
+18,19,50,20447,
+29,30,38,20475,
+3,26,50,20475,
+14,35,42,20475,
+16,25,48,20475,
+2,34,45,20475,
+22,26,45,20475,
+10,22,51,20475,
+8,39,40,20475,
+9,20,52,20475,
+17,36,40,20475,
+10,13,54,20475,
+0,7,56,20475,
+15,16,52,20475,
+25,31,40,20475,
+12,21,51,20475,
+3,24,51,20475,
+11,16,53,20475,
+19,35,40,20475,
+5,5,56,20475,
+24,33,39,20475,
+5,35,44,20475,
+12,39,39,20475,
+11,19,52,20475,
+16,23,49,20475,
+4,19,53,20475,
+21,21,48,20475,
+17,31,44,20475,
+1,7,56,20475,
+4,31,47,20475,
+1,28,49,20475,
+25,25,44,20475,
+9,9,55,20475,
+15,19,51,20475,
+21,35,39,20475,
+27,33,37,20496,
+4,6,56,20496,
+12,38,40,20496,
+4,16,54,20496,
+10,28,48,20496,
+20,22,48,20496,
+24,26,44,20496,
+20,32,42,20496,
+0,22,52,20496,
+28,31,38,20512,
+2,7,56,20512,
+8,10,55,20512,
+2,28,49,20512,
+14,28,47,20512,
+22,32,41,20512,
+7,32,46,20512,
+8,25,50,20512,
+14,17,52,20512,
+17,20,50,20512,
+8,38,41,20512,
+1,22,52,20512,
+17,28,46,20512,
+18,29,45,20512,
+9,30,47,20512,
+21,30,43,20512,
+15,38,39,20512,
+7,15,54,20512,
+3,34,45,20512,
+4,26,50,20512,
+20,26,46,20512,
+2,22,52,20512,
+10,34,44,20512,
+12,32,45,20512,
+23,30,42,20512,
+4,24,51,20512,
+9,14,54,20512,
+7,29,48,20512,
+3,28,49,20512,
+13,33,44,20512,
+7,36,43,20512,
+23,27,44,20512,
+15,37,40,20512,
+5,12,55,20512,
+16,33,43,20512,
+8,23,51,20512,
+16,27,47,20512,
+23,36,37,20526,
+3,7,56,20526,
+12,37,41,20526,
+27,28,41,20526,
+0,13,55,20526,
+7,21,52,20526,
+19,23,48,20526,
+8,27,49,20526,
+12,29,47,20526,
+21,27,45,20526,
+7,11,55,20526,
+5,19,53,20526,
+17,35,41,20526,
+9,33,45,20526,
+13,25,49,20526,
+11,35,43,20526,
+1,13,55,20526,
+5,31,47,20526,
+19,25,47,20526,
+18,32,43,20526,
+5,16,54,20526,
+4,34,45,20526,
+26,35,36,20574,
+5,6,56,20574,
+14,20,51,20574,
+16,21,50,20574,
+11,24,50,20574,
+27,32,38,20574,
+21,34,40,20574,
+8,37,42,20574,
+6,35,44,20574,
+3,22,52,20574,
+8,18,53,20574,
+13,18,52,20574,
+19,30,44,20574,
+26,29,41,20574,
+11,31,46,20574,
+13,23,50,20574,
+23,35,38,20574,
+10,17,53,20574,
+2,13,55,20574,
+11,26,49,20574,
+19,34,41,20574,
+0,8,56,20574,
+24,32,40,20574,
+0,40,40,20574,
+4,7,56,20574,
+5,26,50,20574,
+1,40,40,20574,
+26,26,43,20574,
+26,34,37,20596,
+1,8,56,20596,
+4,28,49,20596,
+20,20,49,20596,
+14,34,43,20596,
+14,14,53,20596,
+5,24,51,20596,
+15,36,41,20596,
+15,24,49,20596,
+0,39,41,20596,
+9,39,40,20596,
+32,33,33,20654,
+13,27,48,20654,
+29,29,39,20654,
+25,27,43,20654,
+3,13,55,20654,
+1,39,41,20654,
+19,21,49,20654,
+13,15,53,20654,
+32,32,34,20662,
+22,28,44,20662,
+4,22,52,20662,
+12,36,42,20662,
+12,12,54,20662,
+2,8,56,20662,
+0,30,48,20662,
+8,32,46,20662,
+10,20,52,20662,
+18,24,48,20662,
+2,40,40,20662,
+8,15,54,20662,
+1,30,48,20662,
+15,26,48,20662,
+0,17,54,20662,
+6,12,55,20662,
+28,30,39,20662,
+0,33,46,20662,
+9,38,41,20662,
+31,33,34,20689,
+9,10,55,20689,
+5,34,45,20689,
+23,34,39,20689,
+6,31,47,20689,
+11,13,54,20689,
+9,25,50,20689,
+1,17,54,20689,
+6,19,53,20689,
+1,33,46,20689,
+19,27,46,20689,
+2,39,41,20689,
+11,22,51,20689,
+25,30,41,20689,
+0,38,42,20689,
+2,30,48,20689,
+6,16,54,20689,
+6,6,56,20689,
+22,31,42,20689,
+2,17,54,20689,
+20,28,45,20689,
+18,22,49,20689,
+26,33,38,20689,
+17,34,42,20689,
+0,20,53,20689,
+1,38,42,20689,
+15,22,50,20689,
+3,40,40,20689,
+12,19,52,20689,
+8,29,48,20689,
+8,36,43,20689,
+10,30,47,20689,
+12,16,53,20689,
+2,33,46,20689,
+8,21,52,20689,
+11,28,48,20689,
+18,26,47,20689,
+3,8,56,20689,
+24,28,43,20689,
+5,28,49,20689,
+8,11,55,20689,
+1,20,53,20689,
+20,31,43,20689,
+5,7,56,20689,
+31,32,35,20724,
+7,35,44,20724,
+4,13,55,20724,
+9,23,51,20724,
+13,21,51,20724,
+21,33,41,20724,
+15,31,45,20724,
+3,39,41,20724,
+9,27,49,20724,
+13,39,39,20724,
+27,31,39,20724,
+2,38,42,20724,
+14,30,46,20724,
+10,14,54,20724,
+18,38,38,20724,
+30,34,34,20727,
+6,26,50,20727,
+2,20,53,20727,
+11,34,44,20727,
+6,24,51,20727,
+5,22,52,20727,
+20,37,38,20727,
+13,38,40,20727,
+16,29,46,20727,
+3,30,48,20727,
+18,37,39,20727,
+3,17,54,20727,
+17,18,51,20727,
+17,30,45,20727,
+10,33,45,20727,
+15,35,42,20727,
+3,33,46,20727,
+9,37,42,20727,
+9,18,53,20727,
+30,33,35,20761,
+19,33,42,20761,
+16,16,52,20761,
+4,8,56,20761,
+4,40,40,20761,
+16,32,44,20761,
+20,36,39,20761,
+3,38,42,20761,
+0,9,56,20761,
+25,36,36,20761,
+6,34,45,20761,
+12,35,43,20761,
+17,25,48,20761,
+13,32,45,20761,
+31,31,36,20791,
+16,19,51,20791,
+1,9,56,20791,
+23,33,40,20791,
+7,12,55,20791,
+24,31,41,20791,
+15,17,52,20791,
+3,20,53,20791,
+4,39,41,20791,
+21,29,44,20791,
+15,28,47,20791,
+0,37,43,20791,
+25,35,37,20791,
+7,31,47,20791,
+7,19,53,20791,
+1,37,43,20791,
+13,37,41,20791,
+5,13,55,20791,
+11,17,53,20791,
+23,29,43,20791,
+17,23,49,20791,
+13,29,47,20791,
+4,30,48,20791,
+12,24,50,20791,
+18,36,40,20791,
+30,32,36,20798,
+4,33,46,20798,
+18,31,44,20798,
+10,39,40,20798,
+23,24,46,20798,
+9,32,46,20798,
+0,14,55,20798,
+7,16,54,20798,
+16,38,39,20798,
+14,33,44,20798,
+12,26,49,20798,
+4,17,54,20798,
+26,32,39,20798,
+6,28,49,20798,
+12,31,46,20798,
+6,7,56,20798,
+2,9,56,20798,
+9,15,54,20798,
+14,25,49,20798,
+22,37,37,20798,
+29,34,35,20835,
+2,37,43,20835,
+27,27,42,20835,
+19,19,50,20835,
+1,14,55,20835,
+22,23,47,20835,
+14,18,52,20835,
+4,38,42,20835,
+26,28,42,20835,
+18,28,46,20835,
+6,22,52,20835,
+18,20,50,20835,
+22,36,38,20835,
+11,20,52,20835,
+5,40,40,20835,
+4,20,53,20835,
+8,35,44,20835,
+10,25,50,20835,
+7,26,50,20835,
+5,8,56,20835,
+20,35,40,20835,
+10,38,41,20835,
+14,23,50,20835,
+2,14,55,20835,
+25,34,38,20835,
+22,25,46,20835,
+16,37,40,20835,
+28,29,40,20835,
+10,10,55,20835,
+9,36,43,20835,
+9,29,48,20835,
+9,21,52,20835,
+7,24,51,20835,
+15,20,51,20835,
+0,25,51,20835,
+29,33,36,20876,
+24,25,45,20876,
+3,9,56,20876,
+21,24,47,20876,
+5,39,41,20876,
+17,33,43,20876,
+9,11,55,20876,
+1,25,51,20876,
+3,37,43,20876,
+17,27,47,20876,
+19,29,45,20876,
+0,27,50,20876,
+21,22,48,20876,
+5,30,48,20876,
+12,13,54,20876,
+27,30,40,20876,
+21,32,42,20876,
+12,22,51,20876,
+13,36,42,20876,
+14,27,48,20876,
+25,29,42,20876,
+5,17,54,20876,
+3,14,55,20876,
+5,33,46,20876,
+10,27,49,20876,
+10,23,51,20876,
+6,13,55,20876,
+30,31,37,20891,
+18,35,41,20891,
+7,34,45,20891,
+11,30,47,20891,
+23,26,45,20891,
+2,25,51,20891,
+17,21,50,20891,
+14,15,53,20891,
+1,27,50,20891,
+22,35,39,20891,
+15,34,43,20891,
+0,36,44,20891,
+12,28,48,20891,
+5,38,42,20891,
+20,23,48,20891,
+16,36,41,20891,
+22,30,43,20891,
+1,36,44,20891,
+10,18,53,20891,
+21,26,46,20891,
+16,24,49,20891,
+11,14,54,20891,
+2,27,50,20891,
+0,23,52,20891,
+10,37,42,20891,
+4,9,56,20891,
+8,12,55,20891,
+0,32,47,20891,
+13,19,52,20891,
+5,20,53,20891,
+8,19,53,20891,
+1,32,47,20891,
+20,25,47,20891,
+23,32,41,20891,
+19,32,43,20891,
+1,23,52,20891,
+4,37,43,20891,
+28,35,35,20929,
+8,31,47,20929,
+7,7,56,20929,
+29,32,37,20929,
+13,16,53,20929,
+7,28,49,20929,
+25,33,39,20929,
+3,25,51,20929,
+11,33,45,20929,
+2,36,44,20929,
+8,16,54,20929,
+0,10,56,20929,
+28,34,36,20933,
+6,40,40,20933,
+20,30,44,20933,
+16,26,48,20933,
+6,8,56,20933,
+12,34,44,20933,
+1,10,56,20933,
+2,23,52,20933,
+20,34,41,20933,
+4,14,55,20933,
+7,22,52,20933,
+26,31,40,20933,
+2,32,47,20933,
+25,26,44,20933,
+3,27,50,20933,
+22,27,45,20933,
+14,21,51,20933,
+14,39,39,20933,
+6,39,41,20933,
+16,22,50,20933,
+0,18,54,20933,
+22,34,40,20933,
+8,26,50,20933,
+14,38,40,20933,
+10,32,46,20933,
+24,30,42,20933,
+6,30,48,20933,
+2,10,56,20933,
+3,36,44,20933,
+15,30,46,20933,
+8,24,51,20933,
+6,17,54,20933,
+19,24,48,20933,
+1,18,54,20933,
+10,15,54,20933,
+6,33,46,20933,
+24,27,44,20933,
+24,36,37,20953,
+11,39,40,20953,
+9,35,44,20953,
+20,21,49,20953,
+12,17,53,20953,
+3,23,52,20953,
+0,29,49,20953,
+28,33,37,20987,
+5,9,56,20987,
+16,31,45,20987,
+4,25,51,20987,
+3,32,47,20987,
+1,29,49,20987,
+13,35,43,20987,
+5,37,43,20987,
+7,13,55,20987,
+30,30,38,20989,
+2,18,54,20989,
+6,38,42,20989,
+18,34,42,20989,
+16,35,42,20989,
+6,20,53,20989,
+4,27,50,20989,
+20,27,46,20989,
+24,35,38,20989,
+10,21,52,20989,
+3,10,56,20989,
+10,36,43,20989,
+13,24,50,20989,
+8,34,45,20989,
+14,32,45,20989,
+10,29,48,20989,
+11,25,50,20989,
+13,31,46,20989,
+17,29,46,20989,
+14,37,41,20989,
+19,22,49,20989,
+10,11,55,20989,
+11,38,41,20989,
+14,29,47,20989,
+19,26,47,20989,
+5,14,55,20989,
+29,31,38,21023,
+2,29,49,21023,
+13,26,49,21023,
+12,20,52,21023,
+4,36,44,21023,
+16,28,47,21023,
+19,38,38,21023,
+17,32,44,21023,
+28,28,41,21023,
+25,32,40,21023,
+7,8,56,21023,
+4,32,47,21023,
+3,18,54,21023,
+8,28,49,21023,
+18,18,51,21023,
+23,28,44,21023,
+0,0,57,21023,
+18,30,45,21023,
+16,17,52,21023,
+7,40,40,21023,
+4,23,52,21023,
+0,21,53,21023,
+0,1,57,21023,
+15,33,44,21023,
+0,15,55,21023,
+9,12,55,21023,
+27,35,36,21073,
+0,35,45,21073,
+21,28,45,21073,
+1,35,45,21073,
+5,25,51,21073,
+15,25,49,21073,
+1,15,55,21073,
+17,19,51,21073,
+21,31,43,21073,
+9,19,53,21073,
+27,29,41,21073,
+11,27,49,21073,
+1,1,57,21073,
+7,39,41,21073,
+1,21,53,21073,
+19,37,39,21073,
+11,23,51,21073,
+9,31,47,21073,
+3,29,49,21073,
+8,22,52,21073,
+28,32,38,21083,
+4,10,56,21083,
+24,34,39,21083,
+20,33,42,21083,
+12,30,47,21083,
+7,30,48,21083,
+6,9,56,21083,
+18,25,48,21083,
+0,2,57,21083,
+9,16,54,21083,
+15,18,52,21083,
+23,31,42,21083,
+11,18,53,21083,
+11,37,42,21083,
+2,15,55,21083,
+5,27,50,21083,
+6,37,43,21083,
+7,33,46,21083,
+2,21,53,21083,
+18,23,49,21083,
+13,13,54,21083,
+27,34,37,21099,
+1,2,57,21099,
+21,37,38,21099,
+2,35,45,21099,
+17,38,39,21099,
+7,17,54,21099,
+13,22,51,21099,
+22,33,41,21099,
+26,27,43,21099,
+15,23,50,21099,
+12,14,54,21099,
+14,36,42,21099,
+4,18,54,21099,
+0,11,56,21099,
+5,36,44,21099,
+26,30,41,21099,
+2,2,57,21099,
+7,38,42,21099,
+6,14,55,21099,
+13,28,48,21099,
+9,26,50,21099,
+19,36,40,21099,
+16,20,51,21099,
+17,37,40,21099,
+9,24,51,21099,
+0,3,57,21099,
+21,36,39,21099,
+19,31,44,21099,
+25,28,43,21099,
+8,13,55,21099,
+5,32,47,21099,
+15,27,48,21099,
+1,11,56,21099,
+7,20,53,21099,
+5,23,52,21099,
+12,33,45,21099,
+4,29,49,21099,
+1,3,57,21099,
+3,21,53,21099,
+3,35,45,21099,
+15,15,53,21099,
+3,15,55,21099,
+14,16,53,21099,
+16,34,43,21099,
+2,11,56,21099,
+5,10,56,21099,
+19,20,50,21099,
+14,19,52,21099,
+13,34,44,21099,
+11,32,46,21099,
+22,29,44,21099,
+10,35,44,21099,
+19,28,46,21099,
+9,34,45,21099,
+2,3,57,21099,
+27,33,38,21166,
+18,33,43,21166,
+18,27,47,21166,
+29,30,39,21166,
+6,25,51,21166,
+11,15,54,21166,
+8,8,56,21166,
+8,40,40,21166,
+24,33,40,21166,
+5,18,54,21166,
+0,31,48,21166,
+18,21,50,21166,
+6,27,50,21166,
+12,39,40,21166,
+0,4,57,21166,
+1,4,57,21166,
+28,31,39,21198,
+11,36,43,21198,
+11,21,52,21198,
+11,29,48,21198,
+1,31,48,21198,
+8,39,41,21198,
+24,29,43,21198,
+9,28,49,21198,
+4,21,53,21198,
+4,35,45,21198,
+21,35,40,21198,
+4,15,55,21198,
+20,29,45,21198,
+7,9,56,21198,
+3,11,56,21198,
+17,36,41,21198,
+17,24,49,21198,
+13,17,53,21198,
+23,37,37,21198,
+23,23,47,21198,
+33,33,33,21243,
+11,11,55,21243,
+3,3,57,21243,
+25,31,41,21243,
+15,39,39,21243,
+15,21,51,21243,
+5,29,49,21243,
+19,35,41,21243,
+7,37,43,21243,
+24,24,46,21243,
+8,30,48,21243,
+26,36,36,21243,
+6,36,44,21243,
+22,24,47,21243,
+6,23,52,21243,
+32,33,34,21252,
+9,22,52,21252,
+2,31,48,21252,
+15,38,40,21252,
+6,32,47,21252,
+12,38,41,21252,
+12,25,50,21252,
+2,4,57,21252,
+8,33,46,21252,
+17,26,48,21252,
+23,36,38,21252,
+8,17,54,21252,
+10,12,55,21252,
+26,35,37,21252,
+10,19,53,21252,
+14,35,43,21252,
+23,25,46,21252,
+10,31,47,21252,
+7,14,55,21252,
+8,38,42,21252,
+22,32,42,21252,
+0,34,46,21252,
+14,24,50,21252,
+10,16,54,21252,
+6,10,56,21252,
+16,30,46,21252,
+22,22,48,21252,
+14,26,49,21252,
+8,20,53,21252,
+4,11,56,21252,
+32,32,35,21286,
+20,32,43,21286,
+31,34,34,21286,
+13,20,52,21286,
+1,34,46,21286,
+17,22,50,21286,
+14,31,46,21286,
+3,4,57,21286,
+3,31,48,21286,
+12,27,49,21286,
+12,23,51,21286,
+21,23,48,21286,
+27,32,39,21286,
+0,5,57,21286,
+15,32,45,21286,
+5,15,55,21286,
+15,29,47,21286,
+5,35,45,21286,
+31,33,35,21299,
+21,25,47,21299,
+15,37,41,21299,
+9,13,55,21299,
+7,25,51,21299,
+25,25,45,21299,
+23,35,39,21299,
+5,21,53,21299,
+17,31,45,21299,
+1,5,57,21299,
+10,26,50,21299,
+26,34,38,21299,
+2,34,46,21299,
+6,18,54,21299,
+22,26,46,21299,
+10,24,51,21299,
+12,18,53,21299,
+12,37,42,21299,
+24,26,45,21299,
+21,30,44,21299,
+0,26,51,21299,
+0,19,54,21299,
+27,28,42,21299,
+13,30,47,21299,
+17,35,42,21299,
+1,26,51,21299,
+2,5,57,21299,
+21,34,41,21299,
+1,19,54,21299,
+6,29,49,21299,
+7,27,50,21299,
+23,30,43,21299,
+20,24,48,21299,
+0,12,56,21299,
+0,24,52,21299,
+7,36,44,21299,
+4,4,57,21299,
+19,34,42,21299,
+0,16,55,21299,
+10,34,45,21299,
+0,40,41,21299,
+16,33,44,21299,
+4,31,48,21299,
+24,32,41,21299,
+18,29,46,21299,
+9,40,40,21299,
+1,12,56,21299,
+14,22,51,21299,
+26,29,42,21299,
+2,26,51,21299,
+3,34,46,21299,
+13,14,54,21299,
+31,32,36,21352,
+2,19,54,21352,
+8,9,56,21352,
+30,34,35,21352,
+1,24,52,21352,
+29,29,40,21352,
+17,28,47,21352,
+17,17,52,21352,
+11,35,44,21352,
+1,40,41,21352,
+5,11,56,21352,
+7,32,47,21352,
+16,25,49,21352,
+7,23,52,21352,
+1,16,55,21352,
+8,37,43,21352,
+13,33,45,21352,
+9,39,41,21352,
+23,27,45,21352,
+3,5,57,21352,
+21,21,49,21352,
+18,32,44,21352,
+0,28,50,21352,
+28,30,40,21352,
+2,24,52,21352,
+12,32,46,21352,
+14,28,48,21352,
+2,12,56,21352,
+16,18,52,21352,
+8,14,55,21352,
+15,36,42,21352,
+0,39,42,21352,
+20,26,47,21352,
+16,23,50,21352,
+2,16,55,21352,
+23,34,40,21352,
+7,10,56,21352,
+9,30,48,21352,
+1,28,50,21352,
+20,22,49,21352,
+2,40,41,21352,
+12,15,54,21352,
+30,33,36,21384,
+10,28,49,21384,
+0,6,57,21384,
+9,17,54,21384,
+9,33,46,21384,
+26,33,39,21384,
+6,21,53,21384,
+18,19,51,21384,
+19,30,45,21384,
+3,26,51,21384,
+6,15,55,21384,
+1,39,42,21384,
+6,35,45,21384,
+3,19,54,21384,
+21,27,46,21384,
+1,6,57,21384,
+26,26,44,21384,
+20,38,38,21384,
+14,34,44,21384,
+10,22,52,21384,
+4,34,46,21384,
+2,28,50,21384,
+25,30,42,21384,
+2,6,57,21384,
+18,38,39,21384,
+3,12,56,21384,
+2,39,42,21384,
+3,24,52,21384,
+12,36,43,21384,
+12,21,52,21384,
+7,18,54,21384,
+9,38,42,21384,
+12,29,48,21384,
+16,27,48,21384,
+27,31,40,21393,
+25,27,44,21393,
+17,20,51,21393,
+3,40,41,21393,
+3,16,55,21393,
+9,20,53,21393,
+8,25,51,21393,
+25,36,37,21393,
+15,19,52,21393,
+13,39,40,21393,
+20,37,39,21393,
+19,25,48,21393,
+15,16,53,21393,
+11,12,55,21393,
+4,5,57,21393,
+5,31,48,21393,
+7,29,49,21393,
+29,35,35,21425,
+31,31,37,21425,
+11,19,53,21425,
+19,23,49,21425,
+11,31,47,21425,
+8,27,50,21425,
+18,37,40,21425,
+22,28,45,21425,
+30,32,37,21453,
+3,28,50,21453,
+4,19,54,21453,
+0,38,43,21453,
+0,22,53,21453,
+29,34,36,21453,
+6,11,56,21453,
+11,16,54,21453,
+4,26,51,21453,
+3,39,42,21453,
+1,38,43,21453,
+17,34,43,21453,
+3,6,57,21453,
+10,13,55,21453,
+21,33,42,21453,
+13,38,41,21453,
+25,35,38,21453,
+14,17,53,21453,
+22,31,43,21453,
+13,25,50,21453,
+1,22,53,21453,
+20,36,40,21453,
+8,36,44,21453,
+4,12,56,21453,
+24,28,44,21453,
+4,24,52,21453,
+8,32,47,21453,
+11,26,50,21453,
+4,16,55,21453,
+2,38,43,21453,
+5,34,46,21453,
+22,37,38,21453,
+4,40,41,21453,
+2,22,53,21453,
+8,23,52,21453,
+20,31,44,21453,
+11,24,51,21453,
+16,39,39,21453,
+9,9,56,21453,
+0,7,57,21453,
+16,21,51,21453,
+0,33,47,21453,
+1,33,47,21453,
+7,35,45,21453,
+7,21,53,21453,
+29,33,37,21505,
+1,7,57,21505,
+5,5,57,21505,
+7,15,55,21505,
+19,27,47,21505,
+9,37,43,21505,
+23,33,41,21505,
+13,27,49,21505,
+15,35,43,21505,
+19,33,43,21505,
+13,23,51,21505,
+10,40,40,21505,
+4,28,50,21505,
+16,38,40,21505,
+26,32,40,21505,
+20,20,50,21505,
+14,20,52,21505,
+8,10,56,21505,
+20,28,46,21505,
+18,24,49,21505,
+0,30,49,21505,
+22,36,39,21505,
+6,31,48,21505,
+24,31,42,21505,
+18,36,41,21505,
+4,39,42,21505,
+4,6,57,21505,
+15,24,50,21505,
+13,18,53,21505,
+3,38,43,21505,
+3,22,53,21505,
+10,39,41,21505,
+5,26,51,21505,
+5,19,54,21505,
+9,14,55,21505,
+2,33,47,21505,
+19,21,50,21505,
+1,30,49,21505,
+11,34,45,21505,
+15,26,49,21505,
+25,34,39,21505,
+15,31,46,21505,
+2,7,57,21505,
+13,37,42,21505,
+18,26,48,21505,
+10,30,48,21505,
+8,18,54,21505,
+0,13,56,21505,
+2,30,49,21505,
+10,33,46,21505,
+5,12,56,21505,
+10,17,54,21505,
+28,35,36,21547,
+30,31,38,21547,
+16,32,45,21547,
+17,30,46,21547,
+5,24,52,21547,
+14,30,47,21547,
+12,35,44,21547,
+0,37,44,21547,
+7,11,56,21547,
+11,28,49,21547,
+1,13,56,21547,
+16,37,41,21547,
+23,29,44,21547,
+1,37,44,21547,
+28,29,41,21547,
+20,35,41,21547,
+8,29,49,21547,
+5,40,41,21547,
+5,16,55,21547,
+16,29,47,21547,
+27,27,43,21547,
+9,25,51,21547,
+21,29,45,21547,
+3,33,47,21547,
+3,7,57,21547,
+10,38,42,21547,
+14,14,54,21547,
+18,22,50,21547,
+6,34,46,21547,
+4,38,43,21547,
+29,32,38,21592,
+5,28,50,21592,
+4,22,53,21592,
+11,22,52,21592,
+10,20,53,21592,
+22,35,40,21592,
+13,32,46,21592,
+2,13,56,21592,
+28,34,37,21592,
+2,37,44,21592,
+26,28,43,21592,
+9,27,50,21592,
+14,33,45,21592,
+15,22,51,21592,
+27,30,41,21592,
+3,30,49,21592,
+5,6,57,21592,
+18,31,45,21592,
+5,39,42,21592,
+13,15,54,21592,
+6,19,54,21592,
+15,28,48,21592,
+12,12,55,21592,
+0,8,57,21592,
+18,35,42,21592,
+9,36,44,21592,
+6,26,51,21592,
+25,33,40,21599,
+9,23,52,21599,
+3,37,44,21599,
+4,7,57,21599,
+13,29,48,21599,
+13,36,43,21599,
+8,21,53,21599,
+3,13,56,21599,
+4,33,47,21599,
+8,35,45,21599,
+21,32,43,21599,
+13,21,52,21599,
+9,32,47,21599,
+7,31,48,21599,
+8,15,55,21599,
+24,37,37,21599,
+12,19,53,21599,
+12,31,47,21599,
+23,24,47,21599,
+0,17,55,21599,
+1,8,57,21599,
+17,33,44,21599,
+25,29,43,21599,
+17,25,49,21599,
+1,17,55,21599,
+11,13,55,21599,
+16,36,42,21599,
+24,36,38,21605,
+0,20,54,21605,
+6,24,52,21605,
+6,12,56,21605,
+12,16,54,21605,
+4,30,49,21605,
+9,10,56,21605,
+24,25,46,21605,
+22,23,48,21605,
+28,33,38,21659,
+1,20,54,21659,
+6,40,41,21659,
+17,18,52,21659,
+18,28,47,21659,
+14,39,40,21659,
+23,32,42,21659,
+6,16,55,21659,
+2,8,57,21659,
+15,34,44,21659,
+5,38,43,21659,
+5,22,53,21659,
+17,23,50,21659,
+10,37,43,21659,
+2,17,55,21659,
+19,29,46,21659,
+22,25,47,21659,
+26,31,41,21659,
+22,30,44,21659,
+20,34,42,21659,
+12,26,50,21659,
+6,28,50,21659,
+2,20,54,21659,
+16,19,52,21659,
+9,18,54,21659,
+23,26,46,21659,
+27,36,36,21692,
+14,25,50,21692,
+4,13,56,21692,
+11,40,40,21692,
+30,30,39,21692,
+4,37,44,21692,
+21,24,48,21692,
+6,39,42,21692,
+6,6,57,21692,
+12,24,51,21692,
+10,14,55,21692,
+8,11,56,21692,
+22,34,41,21692,
+7,34,46,21692,
+14,38,41,21692,
+19,32,44,21692,
+16,16,53,21692,
+0,36,45,21692,
+3,8,57,21692,
+17,27,48,21692,
+1,36,45,21692,
+24,35,39,21692,
+29,31,39,21714,
+15,17,53,21714,
+3,17,55,21714,
+19,19,51,21714,
+27,35,37,21714,
+11,39,41,21714,
+9,29,49,21714,
+5,7,57,21714,
+5,33,47,21714,
+12,34,45,21714,
+3,20,54,21714,
+11,30,48,21714,
+18,20,51,21714,
+20,30,45,21714,
+24,30,43,21714,
+2,36,45,21714,
+21,26,47,21714,
+19,38,39,21714,
+10,25,51,21714,
+11,17,54,21714,
+11,33,46,21714,
+14,23,51,21714,
+7,19,54,21714,
+7,26,51,21714,
+25,26,45,21714,
+21,22,49,21714,
+14,27,49,21714,
+5,30,49,21714,
+0,32,48,21714,
+1,32,48,21714,
+10,27,50,21714,
+28,32,39,21768,
+8,31,48,21768,
+7,12,56,21768,
+7,24,52,21768,
+12,28,49,21768,
+11,38,42,21768,
+6,38,43,21768,
+22,27,46,21768,
+21,38,38,21768,
+18,34,43,21768,
+27,34,38,21768,
+4,8,57,21768,
+15,20,52,21768,
+14,37,42,21768,
+0,25,52,21768,
+20,25,48,21768,
+14,18,53,21768,
+6,22,53,21768,
+16,35,43,21768,
+13,35,44,21768,
+19,37,40,21768,
+7,16,55,21768,
+1,25,52,21768,
+0,27,51,21768,
+4,17,55,21768,
+20,23,49,21768,
+11,20,53,21768,
+7,40,41,21768,
+24,27,45,21768,
+3,36,45,21768,
+0,9,57,21768,
+5,37,44,21768,
+25,32,41,21768,
+5,13,56,21768,
+21,37,39,21768,
+17,21,51,21768,
+9,21,53,21768,
+17,39,39,21768,
+9,15,55,21768,
+1,9,57,21768,
+9,35,45,21768,
+1,27,51,21768,
+2,32,48,21768,
+24,34,40,21768,
+12,22,52,21768,
+0,14,56,21768,
+4,20,54,21768,
+16,24,50,21768,
+10,36,44,21768,
+28,28,42,21768,
+2,25,52,21768,
+1,14,56,21768,
+7,28,50,21768,
+10,32,47,21768,
+16,31,46,21768,
+17,38,40,21768,
+16,26,49,21768,
+10,23,52,21768,
+6,33,47,21768,
+7,39,42,21768,
+2,27,51,21768,
+15,30,47,21768,
+6,7,57,21768,
+33,33,34,21833,
+27,29,42,21833,
+2,9,57,21833,
+8,34,46,21833,
+10,10,56,21833,
+14,32,46,21833,
+32,34,34,21846,
+2,14,56,21846,
+14,15,54,21846,
+22,33,42,21846,
+21,36,40,21846,
+3,32,48,21846,
+6,30,49,21846,
+4,36,45,21846,
+12,13,55,21846,
+9,11,56,21846,
+23,28,45,21846,
+17,32,45,21846,
+19,36,41,21846,
+5,8,57,21846,
+0,23,53,21846,
+20,27,47,21846,
+19,24,49,21846,
+21,31,44,21846,
+3,25,52,21846,
+32,33,35,21873,
+20,33,43,21873,
+3,27,51,21873,
+23,31,43,21873,
+13,31,47,21873,
+13,19,53,21873,
+17,29,47,21873,
+3,9,57,21873,
+11,37,43,21873,
+5,17,55,21873,
+17,37,41,21873,
+1,23,53,21873,
+27,33,39,21873,
+15,33,45,21873,
+18,30,46,21873,
+26,30,42,21873,
+10,18,54,21873,
+21,28,46,21873,
+14,36,43,21873,
+14,29,48,21873,
+26,36,37,21873,
+5,20,54,21873,
+16,22,51,21873,
+29,30,40,21873,
+6,37,44,21873,
+19,26,48,21873,
+13,16,54,21873,
+26,27,44,21873,
+20,21,50,21873,
+8,19,54,21873,
+14,21,52,21873,
+0,29,50,21873,
+8,26,51,21873,
+0,35,46,21873,
+3,14,56,21873,
+6,13,56,21873,
+7,38,43,21873,
+1,35,46,21873,
+2,23,53,21873,
+7,22,53,21873,
+10,29,49,21873,
+31,34,35,21900,
+1,29,50,21900,
+23,37,38,21900,
+11,14,55,21900,
+8,12,56,21900,
+8,24,52,21900,
+4,32,48,21900,
+12,40,40,21900,
+32,32,36,21915,
+16,28,48,21915,
+25,28,44,21915,
+28,31,40,21915,
+19,22,50,21915,
+4,25,52,21915,
+2,29,50,21915,
+8,40,41,21915,
+13,26,50,21915,
+2,35,46,21915,
+26,35,38,21915,
+8,16,55,21915,
+4,9,57,21915,
+23,36,39,21915,
+12,39,41,21915,
+13,24,51,21915,
+15,39,40,21915,
+5,36,45,21915,
+4,27,51,21915,
+24,33,41,21915,
+9,31,48,21915,
+31,33,36,21942,
+21,35,41,21942,
+7,33,47,21942,
+7,7,57,21942,
+11,25,51,21942,
+19,31,45,21942,
+3,23,53,21942,
+16,34,44,21942,
+8,28,50,21942,
+12,30,48,21942,
+4,14,56,21942,
+0,18,55,21942,
+17,36,42,21942,
+12,17,54,21942,
+0,10,57,21942,
+6,8,57,21942,
+12,33,46,21942,
+8,39,42,21942,
+18,33,44,21942,
+7,30,49,21942,
+13,34,45,21942,
+11,27,50,21942,
+18,25,49,21942,
+3,35,46,21942,
+1,18,55,21942,
+10,15,55,21942,
+25,31,42,21942,
+15,38,41,21942,
+1,10,57,21942,
+15,25,50,21942,
+6,17,55,21942,
+3,29,50,21942,
+10,21,53,21942,
+10,35,45,21942,
+22,29,45,21942,
+19,35,42,21942,
+30,35,35,21977,
+6,20,54,21977,
+30,34,36,21992,
+12,38,42,21992,
+18,18,52,21992,
+12,20,53,21992,
+27,32,40,21992,
+2,18,55,21992,
+5,32,48,21992,
+26,34,39,21992,
+11,36,44,21992,
+9,34,46,21992,
+2,10,57,21992,
+18,23,50,21992,
+24,29,44,21992,
+16,17,53,21992,
+13,28,49,21992,
+7,37,44,21992,
+4,23,53,21992,
+11,32,47,21992,
+7,13,56,21992,
+5,25,52,21992,
+17,19,52,21992,
+23,35,40,21992,
+31,32,37,22011,
+19,28,47,22011,
+11,23,52,22011,
+15,23,51,22011,
+5,9,57,22011,
+5,27,51,22011,
+15,27,49,22011,
+0,21,54,22011,
+4,35,46,22011,
+22,32,43,22011,
+5,14,56,22011,
+18,27,48,22011,
+14,35,44,22011,
+8,38,43,22011,
+4,29,50,22011,
+20,29,46,22011,
+13,22,52,22011,
+10,11,56,22011,
+6,36,45,22011,
+8,22,53,22011,
+3,18,55,22011,
+9,19,54,22011,
+30,33,37,22047,
+15,37,42,22047,
+3,10,57,22047,
+1,21,54,22047,
+9,26,51,22047,
+15,18,53,22047,
+16,20,52,22047,
+20,32,44,22047,
+2,21,54,22047,
+0,15,56,22047,
+11,18,54,22047,
+24,24,47,22047,
+9,24,52,22047,
+21,34,42,22047,
+9,12,56,22047,
+19,20,51,22047,
+8,33,47,22047,
+29,35,36,22090,
+0,31,49,22090,
+0,41,41,22090,
+12,37,43,22090,
+9,40,41,22090,
+7,8,57,22090,
+1,15,56,22090,
+27,28,43,22090,
+9,16,55,22090,
+23,23,48,22090,
+17,35,43,22090,
+29,29,41,22090,
+7,17,55,22090,
+5,23,53,22090,
+1,41,41,22090,
+23,25,47,22090,
+11,29,49,22090,
+1,31,49,22090,
+25,37,37,22090,
+13,13,55,22090,
+0,40,42,22090,
+22,24,48,22090,
+24,32,42,22090,
+0,0,58,22090,
+6,32,48,22090,
+23,30,44,22090,
+25,36,38,22090,
+1,40,42,22090,
+4,18,55,22090,
+4,10,57,22090,
+2,15,56,22090,
+8,30,49,22090,
+12,14,55,22090,
+0,1,58,22090,
+28,30,41,22090,
+17,24,50,22090,
+20,38,39,22090,
+15,32,46,22090,
+16,30,47,22090,
+0,34,47,22090,
+26,33,40,22090,
+9,28,50,22090,
+6,25,52,22090,
+7,20,54,22090,
+10,31,48,22090,
+23,34,41,22090,
+9,39,42,22090,
+18,39,39,22090,
+19,34,43,22090,
+14,19,53,22090,
+21,30,45,22090,
+17,26,49,22090,
+5,35,46,22090,
+25,25,46,22090,
+2,41,41,22090,
+6,27,51,22090,
+14,31,47,22090,
+1,34,47,22090,
+31,31,38,22107,
+6,9,57,22107,
+26,29,43,22107,
+18,21,51,22107,
+1,1,58,22107,
+2,31,49,22107,
+29,34,37,22107,
+15,15,54,22107,
+17,31,46,22107,
+3,21,54,22107,
+5,29,50,22107,
+2,40,42,22107,
+6,14,56,22107,
+30,32,38,22131,
+24,26,46,22131,
+18,38,40,22131,
+14,16,54,22131,
+0,2,58,22131,
+1,2,58,22131,
+2,34,47,22131,
+8,13,56,22131,
+20,37,40,22131,
+22,22,49,22131,
+8,37,44,22131,
+22,26,47,22131,
+13,40,40,22131,
+15,29,48,22131,
+21,25,48,22131,
+0,39,43,22131,
+0,11,57,22131,
+16,33,45,22131,
+15,21,52,22131,
+3,15,56,22131,
+15,36,43,22131,
+7,36,45,22131,
+12,25,51,22131,
+11,15,55,22131,
+21,23,49,22131,
+11,21,53,22131,
+3,31,49,22131,
+1,11,57,22131,
+27,31,41,22131,
+1,39,43,22131,
+3,41,41,22131,
+25,35,39,22131,
+11,35,45,22131,
+13,39,41,22131,
+10,34,46,22131,
+14,26,50,22131,
+2,2,58,22131,
+22,38,38,22131,
+14,24,51,22131,
+18,32,45,22131,
+12,27,50,22131,
+0,3,58,22131,
+3,40,42,22131,
+4,21,54,22131,
+13,30,48,22131,
+29,33,38,22184,
+18,37,41,22184,
+9,38,43,22184,
+25,30,43,22184,
+22,37,39,22184,
+13,33,46,22184,
+23,27,46,22184,
+2,11,57,22184,
+17,22,51,22184,
+6,23,53,22184,
+13,17,54,22184,
+5,18,55,22184,
+2,39,43,22184,
+1,3,58,22184,
+5,10,57,22184,
+9,22,53,22184,
+18,29,47,22184,
+3,34,47,22184,
+12,36,44,22184,
+28,36,36,22191,
+6,29,50,22191,
+14,34,45,22191,
+12,23,52,22191,
+2,3,58,22191,
+10,19,54,22191,
+7,32,48,22191,
+6,35,46,22191,
+12,32,47,22191,
+20,36,41,22191,
+10,26,51,22191,
+8,8,57,22191,
+17,28,48,22191,
+20,24,49,22191,
+4,15,56,22191,
+19,30,46,22191,
+26,26,45,22191,
+16,39,40,22191,
+13,38,42,22191,
+4,41,41,22191,
+8,17,55,22191,
+7,25,52,22191,
+13,20,53,22191,
+11,11,56,22191,
+4,31,49,22191,
+28,35,37,22213,
+25,27,45,22213,
+21,33,43,22213,
+3,11,57,22213,
+21,27,47,22213,
+3,39,43,22213,
+7,27,51,22213,
+9,33,47,22213,
+7,9,57,22213,
+0,4,58,22213,
+8,20,54,22213,
+22,36,40,22213,
+10,24,52,22213,
+10,12,56,22213,
+0,26,52,22213,
+20,26,48,22213,
+4,40,42,22213,
+0,38,44,22213,
+22,31,44,22213,
+14,28,49,22213,
+26,32,41,22213,
+16,25,50,22213,
+17,34,44,22213,
+1,38,44,22213,
+1,4,58,22213,
+4,34,47,22213,
+1,26,52,22213,
+10,16,55,22213,
+25,34,40,22213,
+16,38,41,22213,
+7,14,56,22213,
+10,40,41,22213,
+9,30,49,22213,
+3,3,58,22213,
+21,21,50,22213,
+5,21,54,22213,
+30,31,39,22246,
+23,33,42,22246,
+2,26,52,22246,
+14,22,52,22246,
+28,34,38,22258,
+2,4,58,22258,
+10,28,50,22258,
+22,28,46,22258,
+20,22,50,22258,
+2,38,44,22258,
+12,18,54,22258,
+18,36,42,22258,
+6,10,57,22258,
+10,39,42,22258,
+8,36,45,22258,
+0,28,51,22258,
+0,24,53,22258,
+6,18,55,22258,
+24,28,45,22258,
+9,13,56,22258,
+5,15,56,22258,
+9,37,44,22258,
+15,35,44,22258,
+4,39,43,22258,
+4,11,57,22258,
+1,24,53,22258,
+1,28,51,22258,
+20,31,45,22258,
+19,33,44,22258,
+29,32,39,22282,
+11,31,48,22282,
+16,27,49,22282,
+24,31,43,22282,
+16,23,51,22282,
+0,19,55,22282,
+12,29,49,22282,
+13,37,43,22282,
+5,41,41,22282,
+7,23,53,22282,
+17,17,53,22282,
+5,31,49,22282,
+1,19,55,22282,
+19,25,49,22282,
+16,37,42,22282,
+3,38,44,22282,
+16,18,53,22282,
+5,40,42,22282,
+28,29,42,22282,
+2,24,53,22282,
+18,19,52,22282,
+3,4,58,22282,
+2,28,51,22282,
+0,5,58,22282,
+24,37,38,22282,
+3,26,52,22282,
+20,35,42,22282,
+22,35,41,22282,
+2,19,55,22282,
+7,29,50,22282,
+13,14,55,22282,
+7,35,46,22282,
+1,5,58,22282,
+19,23,50,22282,
+5,34,47,22282,
+8,32,48,22282,
+0,16,56,22282,
+17,20,52,22282,
+11,34,46,22282,
+0,12,57,22282,
+20,28,47,22282,
+8,25,52,22282,
+2,5,58,22282,
+6,21,54,22282,
+0,33,48,22282,
+24,36,39,22303,
+27,30,42,22303,
+1,16,56,22303,
+10,22,53,22303,
+10,38,43,22303,
+27,27,44,22303,
+27,36,37,22351,
+8,27,51,22351,
+28,33,39,22351,
+1,12,57,22351,
+12,21,53,22351,
+8,9,57,22351,
+3,24,53,22351,
+12,35,45,22351,
+19,27,48,22351,
+1,33,48,22351,
+12,15,55,22351,
+0,37,45,22351,
+3,28,51,22351,
+1,37,45,22351,
+5,39,43,22351,
+15,19,53,22351,
+5,11,57,22351,
+9,17,55,22351,
+25,33,41,22351,
+13,25,51,22351,
+15,31,47,22351,
+3,19,55,22351,
+23,29,45,22351,
+4,38,44,22351,
+4,4,58,22351,
+8,14,56,22351,
+4,26,52,22351,
+14,40,40,22351,
+16,32,46,22351,
+2,16,56,22351,
+26,28,44,22351,
+6,15,56,22351,
+2,33,48,22351,
+9,20,54,22351,
+15,16,54,22351,
+2,12,57,22351,
+7,18,55,22351,
+27,35,38,22380,
+13,27,50,22380,
+11,19,54,22380,
+17,30,47,22380,
+7,10,57,22380,
+18,35,43,22380,
+10,33,47,22380,
+11,26,51,22380,
+14,39,41,22380,
+6,41,41,22380,
+21,29,46,22380,
+2,37,45,22380,
+3,5,58,22380,
+6,31,49,22380,
+0,22,54,22380,
+0,30,50,22380,
+18,24,50,22380,
+30,30,40,22394,
+6,40,42,22394,
+0,6,58,22394,
+14,30,48,22394,
+20,20,51,22394,
+4,24,53,22394,
+14,33,46,22394,
+11,12,56,22394,
+21,32,44,22394,
+1,6,58,22394,
+26,31,42,22394,
+1,30,50,22394,
+14,17,54,22394,
+24,35,40,22394,
+6,34,47,22394,
+3,16,56,22394,
+11,24,52,22394,
+33,34,34,22430,
+18,26,49,22430,
+16,21,52,22430,
+18,31,46,22430,
+16,36,43,22430,
+13,36,44,22430,
+4,28,51,22430,
+15,26,50,22430,
+16,29,48,22430,
+10,30,49,22430,
+1,22,54,22430,
+3,12,57,22430,
+8,23,53,22430,
+3,33,48,22430,
+25,29,44,22430,
+9,36,45,22430,
+4,19,55,22430,
+13,23,52,22430,
+13,32,47,22430,
+11,40,41,22430,
+11,16,55,22430,
+23,32,43,22430,
+15,24,51,22430,
+29,31,40,22430,
+17,33,45,22430,
+33,33,35,22455,
+19,39,39,22455,
+19,21,51,22455,
+3,37,45,22455,
+2,6,58,22455,
+22,34,42,22455,
+2,30,50,22455,
+2,22,54,22455,
+14,38,42,22455,
+14,20,53,22455,
+8,29,50,22455,
+11,28,50,22455,
+32,34,35,22481,
+4,5,58,22481,
+5,26,52,22481,
+19,38,40,22481,
+8,35,46,22481,
+20,34,43,22481,
+10,37,44,22481,
+5,38,44,22481,
+10,13,56,22481,
+11,39,42,22481,
+15,34,45,22481,
+21,38,39,22481,
+6,11,57,22481,
+27,34,39,22481,
+6,39,43,22481,
+7,21,54,22481,
+28,32,40,22481,
+4,16,56,22481,
+3,22,54,22481,
+3,6,58,22481,
+22,30,45,22481,
+4,12,57,22481,
+18,22,51,22481,
+9,32,48,22481,
+32,33,36,22514,
+23,24,48,22514,
+4,33,48,22514,
+13,18,54,22514,
+3,30,50,22514,
+12,31,48,22514,
+15,28,49,22514,
+4,37,45,22514,
+24,25,47,22514,
+19,32,45,22514,
+21,37,40,22514,
+7,15,56,22514,
+5,24,53,22514,
+17,39,40,22514,
+9,25,52,22514,
+5,28,51,22514,
+7,41,41,22514,
+5,19,55,22514,
+31,35,35,22535,
+9,27,51,22535,
+13,29,49,22535,
+9,9,57,22535,
+19,29,47,22535,
+19,37,41,22535,
+7,31,49,22535,
+0,36,46,22535,
+24,30,44,22535,
+18,28,48,22535,
+8,10,57,22535,
+24,34,41,22535,
+9,14,56,22535,
+15,22,52,22535,
+31,34,36,22549,
+7,40,42,22549,
+8,18,55,22549,
+22,25,48,22549,
+1,36,46,22549,
+25,32,42,22549,
+0,7,58,22549,
+1,7,58,22549,
+7,34,47,22549,
+23,26,47,22549,
+17,38,41,22549,
+5,5,58,22549,
+14,37,43,22549,
+26,37,37,22549,
+11,38,43,22549,
+22,23,49,22549,
+11,22,53,22549,
+10,17,55,22549,
+17,25,50,22549,
+10,20,54,22549,
+4,6,58,22549,
+12,34,46,22549,
+26,36,38,22549,
+20,30,46,22549,
+6,38,44,22549,
+4,22,54,22549,
+18,34,44,22549,
+4,30,50,22549,
+2,36,46,22549,
+6,26,52,22549,
+32,32,37,22576,
+28,28,43,22576,
+16,35,44,22576,
+23,38,38,22576,
+14,14,55,22576,
+25,26,46,22576,
+5,16,56,22576,
+2,7,58,22576,
+5,12,57,22576,
+5,33,48,22576,
+21,36,41,22576,
+27,33,40,22576,
+0,13,57,22576,
+21,24,49,22576,
+17,27,49,22576,
+13,15,55,22576,
+23,37,39,22576,
+31,33,37,22606,
+13,21,53,22606,
+27,29,43,22606,
+7,39,43,22606,
+17,23,51,22606,
+1,13,57,22606,
+13,35,45,22606,
+5,37,45,22606,
+7,11,57,22606,
+11,33,47,22606,
+9,23,53,22606,
+12,19,54,22606,
+21,26,48,22606,
+10,36,45,22606,
+6,24,53,22606,
+6,28,51,22606,
+24,27,46,22606,
+30,35,36,22613,
+3,36,46,22613,
+12,26,51,22613,
+19,36,42,22613,
+8,21,54,22613,
+14,25,51,22613,
+29,30,41,22613,
+22,33,43,22613,
+2,13,57,22613,
+17,37,42,22613,
+9,35,46,22613,
+3,7,58,22613,
+6,19,55,22613,
+22,27,47,22613,
+17,18,53,22613,
+11,30,49,22613,
+26,35,39,22613,
+9,29,50,22613,
+12,24,52,22613,
+12,12,56,22613,
+12,16,55,22613,
+5,30,50,22613,
+26,30,43,22613,
+23,36,40,22613,
+30,34,37,22632,
+8,15,56,22632,
+12,40,41,22632,
+20,33,44,22632,
+15,40,40,22632,
+5,22,54,22632,
+0,32,49,22632,
+0,17,56,22632,
+14,27,50,22632,
+21,22,50,22632,
+0,20,55,22632,
+5,6,58,22632,
+28,31,41,22632,
+11,13,56,22632,
+1,32,49,22632,
+20,25,49,22632,
+16,31,47,22632,
+1,20,55,22632,
+8,41,41,22632,
+23,31,44,22632,
+1,17,56,22632,
+19,19,52,22632,
+11,37,44,22632,
+8,31,49,22632,
+16,19,53,22632,
+3,13,57,22632,
+15,39,41,22632,
+21,31,45,22632,
+12,28,50,22632,
+6,16,56,22632,
+14,36,44,22632,
+8,40,42,22632,
+0,8,58,22632,
+16,16,54,22632,
+18,20,52,22632,
+4,36,46,22632,
+10,32,48,22632,
+31,32,38,22669,
+8,34,47,22669,
+12,39,42,22669,
+24,33,42,22669,
+10,25,52,22669,
+7,38,44,22669,
+6,33,48,22669,
+2,32,49,22669,
+2,20,55,22669,
+4,7,58,22669,
+7,26,52,22669,
+23,28,46,22669,
+14,32,47,22669,
+17,32,46,22669,
+20,23,50,22669,
+2,17,56,22669,
+15,30,48,22669,
+1,8,58,22669,
+14,23,52,22669,
+6,12,57,22669,
+15,17,54,22669,
+15,33,46,22669,
+26,27,45,22669,
+9,10,57,22669,
+6,37,45,22669,
+21,35,42,22669,
+10,27,51,22669,
+9,18,55,22669,
+16,26,50,22669,
+10,14,56,22669,
+26,34,40,22669,
+2,8,58,22669,
+0,27,52,22669,
+29,36,36,22711,
+18,30,47,22711,
+15,38,42,22711,
+16,24,51,22711,
+20,27,48,22711,
+30,33,38,22711,
+17,21,52,22711,
+15,20,53,22711,
+4,13,57,22711,
+7,24,53,22711,
+3,20,55,22711,
+27,32,41,22711,
+3,32,49,22711,
+3,17,56,22711,
+0,35,47,22711,
+7,28,51,22711,
+17,29,48,22711,
+17,36,43,22711,
+0,25,53,22711,
+21,28,47,22711,
+8,39,43,22711,
+8,11,57,22711,
+1,27,52,22711,
+25,28,45,22711,
+13,31,48,22711,
+7,19,55,22711,
+1,25,53,22711,
+25,31,43,22711,
+1,35,47,22711,
+23,35,41,22711,
+29,35,37,22734,
+11,17,55,22734,
+19,35,43,22734,
+6,30,50,22734,
+6,22,54,22734,
+14,18,54,22734,
+6,6,58,22734,
+11,20,54,22734,
+2,27,52,22734,
+5,36,46,22734,
+12,22,53,22734,
+3,8,58,22734,
+19,24,50,22734,
+12,38,43,22734,
+16,34,45,22734,
+25,37,38,22734,
+2,25,53,22734,
+5,7,58,22734,
+14,29,49,22734,
+19,26,49,22734,
+19,31,46,22734,
+10,23,53,22734,
+2,35,47,22734,
+18,33,45,22734,
+9,21,54,22734,
+4,20,55,22734,
+29,34,38,22777,
+13,34,46,22777,
+4,32,49,22777,
+7,16,56,22777,
+10,29,50,22777,
+4,17,56,22777,
+10,35,46,22777,
+22,29,46,22777,
+16,28,49,22777,
+20,21,51,22777,
+25,36,39,22777,
+20,39,39,22777,
+7,33,48,22777,
+12,33,47,22777,
+11,36,45,22777,
+7,12,57,22777,
+0,29,51,22777,
+9,15,56,22777,
+24,29,45,22777,
+3,27,52,22777,
+5,13,57,22777,
+1,29,51,22777,
+31,31,39,22794,
+3,25,53,22794,
+9,41,41,22794,
+3,35,47,22794,
+15,37,43,22794,
+7,37,45,22794,
+9,31,49,22794,
+20,38,40,22794,
+8,26,52,22794,
+4,8,58,22794,
+22,32,44,22794,
+8,38,44,22794,
+16,22,52,22794,
+30,32,39,22822,
+0,41,42,22822,
+0,9,58,22822,
+18,39,40,22822,
+0,23,54,22822,
+12,30,49,22822,
+0,14,57,22822,
+9,40,42,22822,
+14,35,45,22822,
+13,26,51,22822,
+21,34,43,22822,
+19,22,51,22822,
+13,19,54,22822,
+14,21,53,22822,
+1,14,57,22822,
+26,33,41,22822,
+1,23,54,22822,
+1,9,58,22822,
+29,29,42,22822,
+1,41,42,22822,
+9,34,47,22822,
+14,15,55,22822,
+2,29,51,22822,
+28,30,42,22822,
+6,36,46,22822,
+7,22,54,22822,
+12,37,44,22822,
+2,23,54,22822,
+23,34,42,22822,
+11,32,48,22822,
+8,28,51,22822,
+22,38,39,22822,
+6,7,58,22822,
+2,14,57,22822,
+10,10,57,22822,
+10,18,55,22822,
+4,27,52,22822,
+2,41,42,22822,
+7,30,50,22822,
+18,38,41,22822,
+13,24,52,22822,
+28,36,37,22842,
+19,28,48,22842,
+8,24,53,22842,
+27,28,44,22842,
+24,32,43,22842,
+20,32,45,22842,
+12,13,56,22842,
+0,40,43,22842,
+18,25,50,22842,
+2,9,58,22842,
+5,20,55,22842,
+25,35,40,22842,
+13,40,41,22842,
+11,25,52,22842,
+5,32,49,22842,
+17,35,44,22842,
+8,19,55,22842,
+4,35,47,22842,
+13,16,55,22842,
+1,40,43,22842,
+5,17,56,22842,
+20,37,41,22842,
+4,25,53,22842,
+20,29,47,22842,
+3,29,51,22842,
+9,11,57,22842,
+15,25,51,22842,
+9,39,43,22842,
+29,33,39,22862,
+11,27,51,22862,
+11,14,56,22862,
+28,35,38,22886,
+19,34,44,22886,
+13,28,50,22886,
+26,29,44,22886,
+22,37,40,22886,
+5,8,58,22886,
+2,40,43,22886,
+13,39,42,22886,
+3,9,58,22886,
+27,31,42,22886,
+3,14,57,22886,
+6,13,57,22886,
+15,27,50,22886,
+3,23,54,22886,
+3,41,42,22886,
+23,30,45,22886,
+18,27,49,22886,
+18,23,51,22886,
+16,40,40,22886,
+24,24,48,22886,
+8,16,56,22886,
+18,37,42,22886,
+18,18,53,22886,
+8,12,57,22886,
+15,36,44,22886,
+0,39,44,22886,
+8,33,48,22886,
+10,21,54,22886,
+21,30,46,22886,
+8,37,45,22886,
+16,39,41,22886,
+3,40,43,22886,
+15,32,47,22886,
+5,27,52,22886,
+12,17,55,22886,
+1,39,44,22886,
+4,29,51,22886,
+23,25,48,22886,
+15,23,52,22886,
+17,19,53,22886,
+23,23,49,22886,
+5,25,53,22886,
+17,31,47,22886,
+11,23,53,22886,
+25,25,47,22886,
+5,35,47,22886,
+0,18,56,22886,
+0,34,48,22886,
+16,30,48,22886,
+20,36,42,22886,
+12,20,54,22886,
+9,38,44,22886,
+1,34,48,22886,
+22,24,49,22886,
+6,17,56,22886,
+6,20,55,22886,
+14,31,48,22886,
+22,36,41,22886,
+4,9,58,22886,
+10,15,56,22886,
+1,18,56,22886,
+4,14,57,22886,
+28,34,39,22955,
+24,26,47,22955,
+16,17,54,22955,
+4,41,42,22955,
+16,33,46,22955,
+6,32,49,22955,
+7,36,46,22955,
+2,39,44,22955,
+9,26,52,22955,
+30,31,40,22955,
+25,30,44,22955,
+0,31,50,22955,
+4,23,54,22955,
+1,31,50,22955,
+11,29,50,22955,
+25,34,41,22955,
+13,38,43,22955,
+10,41,41,22955,
+11,35,46,22955,
+10,31,49,22955,
+13,22,53,22955,
+7,7,58,22955,
+8,30,50,22955,
+16,38,42,22955,
+2,34,48,22955,
+2,18,56,22955,
+26,32,42,22955,
+22,26,48,22955,
+24,38,38,22955,
+0,10,58,22955,
+18,32,46,22955,
+10,40,42,22955,
+8,22,54,22955,
+6,8,58,22955,
+17,26,50,22955,
+1,10,58,22955,
+4,40,43,22955,
+29,32,40,22996,
+12,36,45,22996,
+19,20,52,22996,
+10,34,47,22996,
+16,20,53,22996,
+2,31,50,22996,
+15,18,54,22996,
+17,24,51,22996,
+0,21,55,22996,
+3,39,44,22996,
+21,33,44,22996,
+24,37,39,22996,
+9,28,51,22996,
+9,24,53,22996,
+15,29,49,22996,
+1,21,55,22996,
+23,27,47,22996,
+7,13,57,22996,
+5,29,51,22996,
+23,33,43,22996,
+13,33,47,22996,
+9,19,55,22996,
+27,37,37,23007,
+21,25,49,23007,
+34,34,34,23040,
+22,22,50,23040,
+2,10,58,23040,
+14,34,46,23040,
+26,26,46,23040,
+6,27,52,23040,
+3,34,48,23040,
+18,29,48,23040,
+18,21,52,23040,
+18,36,43,23040,
+3,18,56,23040,
+27,36,38,23040,
+0,38,45,23040,
+10,39,43,23040,
+5,9,58,23040,
+5,41,42,23040,
+3,31,50,23040,
+19,30,47,23040,
+6,25,53,23040,
+5,23,54,23040,
+6,35,47,23040,
+5,14,57,23040,
+17,34,45,23040,
+21,23,50,23040,
+2,21,55,23040,
+10,11,57,23040,
+11,18,55,23040,
+13,30,49,23040,
+1,38,45,23040,
+33,34,35,23072,
+25,27,46,23072,
+22,31,45,23072,
+24,36,40,23072,
+12,32,48,23072,
+9,16,56,23072,
+2,38,45,23072,
+14,19,54,23072,
+12,25,52,23072,
+3,10,58,23072,
+22,35,42,23072,
+24,31,44,23072,
+4,39,44,23072,
+14,26,51,23072,
+28,33,40,23072,
+7,20,55,23072,
+0,15,57,23072,
+16,37,43,23072,
+9,12,57,23072,
+13,37,44,23072,
+28,29,43,23072,
+33,33,36,23113,
+17,28,49,23113,
+13,13,56,23113,
+21,27,48,23113,
+32,35,35,23113,
+12,27,51,23113,
+20,35,43,23113,
+7,17,56,23113,
+5,40,43,23113,
+9,33,48,23113,
+7,32,49,23113,
+27,35,39,23113,
+15,15,55,23113,
+1,15,57,23113,
+15,35,45,23113,
+3,21,55,23113,
+9,37,45,23113,
+15,21,53,23113,
+19,33,45,23113,
+4,34,48,23113,
+32,34,36,23122,
+4,18,56,23122,
+20,24,50,23122,
+12,14,56,23122,
+8,36,46,23122,
+24,28,46,23122,
+14,24,52,23122,
+22,28,47,23122,
+14,16,55,23122,
+17,22,52,23122,
+14,40,41,23122,
+20,31,46,23122,
+4,31,50,23122,
+7,8,58,23122,
+20,26,49,23122,
+27,30,43,23122,
+25,33,42,23122,
+6,29,51,23122,
+2,15,57,23122,
+3,38,45,23122,
+11,21,54,23122,
+10,38,44,23122,
+14,28,50,23122,
+10,26,52,23122,
+4,10,58,23122,
+6,41,42,23122,
+9,22,54,23122,
+30,30,41,23139,
+6,23,54,23139,
+6,9,58,23139,
+14,39,42,23139,
+6,14,57,23139,
+9,30,50,23139,
+0,0,59,23139,
+24,35,41,23139,
+11,15,56,23139,
+19,39,40,23139,
+12,23,53,23139,
+4,21,55,23139,
+16,25,51,23139,
+32,33,37,23184,
+5,39,44,23184,
+7,27,52,23184,
+0,1,59,23184,
+31,35,36,23184,
+8,13,57,23184,
+1,1,59,23184,
+21,39,39,23184,
+7,35,47,23184,
+11,41,41,23184,
+27,27,45,23184,
+21,21,51,23184,
+11,31,49,23184,
+7,25,53,23184,
+29,31,41,23184,
+13,17,55,23184,
+3,15,57,23184,
+18,35,44,23184,
+12,35,46,23184,
+12,29,50,23184,
+0,37,46,23184,
+6,40,43,23184,
+16,27,50,23184,
+0,11,58,23184,
+4,38,45,23184,
+0,26,53,23184,
+5,18,56,23184,
+10,24,53,23184,
+21,38,40,23184,
+0,2,59,23184,
+27,34,40,23184,
+13,20,54,23184,
+20,22,51,23184,
+10,28,51,23184,
+5,34,48,23184,
+11,40,42,23184,
+26,28,45,23184,
+31,34,37,23220,
+1,26,53,23220,
+1,2,59,23220,
+5,31,50,23220,
+19,38,41,23220,
+10,19,55,23220,
+23,29,46,23220,
+1,11,58,23220,
+19,25,50,23220,
+26,31,43,23220,
+11,34,47,23220,
+1,37,46,23220,
+16,36,44,23220,
+20,28,48,23220,
+0,28,52,23220,
+28,32,41,23220,
+16,32,47,23220,
+2,37,46,23220,
+2,2,59,23220,
+8,20,55,23220,
+8,32,49,23220,
+14,22,53,23220,
+5,10,58,23220,
+26,37,38,23220,
+8,17,56,23220,
+14,38,43,23220,
+2,26,53,23220,
+16,23,52,23220,
+17,40,40,23220,
+23,32,44,23220,
+22,34,43,23220,
+2,11,58,23220,
+1,28,52,23220,
+21,32,45,23220,
+15,31,48,23220,
+4,15,57,23220,
+0,3,59,23220,
+0,33,49,23220,
+13,36,45,23220,
+21,29,47,23220,
+5,21,55,23220,
+11,11,57,23220,
+19,23,51,23220,
+7,29,51,23220,
+1,33,49,23220,
+25,29,45,23220,
+11,39,43,23220,
+17,39,41,23220,
+1,3,59,23220,
+19,27,49,23220,
+21,37,41,23220,
+30,36,36,23260,
+2,28,52,23260,
+20,34,44,23260,
+8,8,58,23260,
+10,16,56,23260,
+32,32,38,23260,
+0,24,54,23260,
+26,36,39,23260,
+17,30,48,23260,
+10,33,48,23260,
+10,12,57,23260,
+9,36,46,23260,
+6,39,44,23260,
+12,18,55,23260,
+1,24,54,23260,
+3,11,58,23260,
+23,38,39,23260,
+3,26,53,23260,
+5,38,45,23260,
+17,17,54,23260,
+7,14,57,23260,
+2,33,49,23260,
+18,19,53,23260,
+3,37,46,23260,
+7,41,42,23260,
+31,33,38,23282,
+2,3,59,23282,
+17,33,46,23282,
+19,37,42,23282,
+10,37,45,23282,
+14,33,47,23282,
+7,9,58,23282,
+30,35,37,23282,
+18,31,47,23282,
+7,23,54,23282,
+16,18,54,23282,
+2,24,54,23282,
+6,18,56,23282,
+24,34,42,23282,
+6,34,48,23282,
+8,27,52,23282,
+14,30,49,23282,
+0,19,56,23282,
+0,4,59,23282,
+3,28,52,23282,
+13,32,48,23282,
+17,38,42,23282,
+6,31,50,23282,
+15,34,46,23282,
+17,20,53,23282,
+23,37,40,23282,
+16,29,49,23282,
+25,32,43,23282,
+8,35,47,23282,
+1,4,59,23282,
+8,25,53,23282,
+1,19,56,23282,
+7,40,43,23282,
+13,25,52,23282,
+3,3,59,23282,
+9,13,57,23282,
+27,33,41,23290,
+5,15,57,23290,
+3,33,49,23290,
+13,27,51,23290,
+10,22,54,23290,
+30,34,38,23321,
+18,26,50,23321,
+6,10,58,23321,
+10,30,50,23321,
+22,30,46,23321,
+24,30,45,23321,
+0,30,51,23321,
+14,37,44,23321,
+2,19,56,23321,
+26,35,40,23321,
+3,24,54,23321,
+11,26,52,23321,
+11,38,44,23321,
+4,11,58,23321,
+19,32,46,23321,
+13,14,56,23321,
+4,37,46,23321,
+21,36,42,23321,
+4,26,53,23321,
+2,4,59,23321,
+18,24,51,23321,
+12,21,54,23321,
+6,21,55,23321,
+15,26,51,23321,
+15,19,54,23321,
+1,30,51,23321,
+4,28,52,23321,
+28,28,44,23321,
+20,20,52,23321,
+24,25,48,23321,
+0,16,57,23321,
+2,30,51,23321,
+18,34,45,23321,
+6,38,45,23321,
+12,15,56,23321,
+29,30,42,23331,
+15,24,52,23331,
+0,36,47,23331,
+3,4,59,23331,
+11,28,51,23331,
+19,21,52,23331,
+31,32,39,23394,
+11,24,53,23394,
+12,31,49,23394,
+9,20,55,23394,
+1,36,47,23394,
+19,36,43,23394,
+15,40,41,23394,
+16,21,53,23394,
+4,33,49,23394,
+23,36,41,23394,
+9,17,56,23394,
+8,29,51,23394,
+1,16,57,23394,
+0,5,59,23394,
+16,35,45,23394,
+9,32,49,23394,
+3,19,56,23394,
+7,39,44,23394,
+19,29,48,23394,
+29,36,37,23394,
+27,29,44,23394,
+23,24,49,23394,
+15,16,55,23394,
+12,41,41,23394,
+13,23,53,23394,
+11,19,55,23394,
+17,37,43,23394,
+1,5,59,23394,
+0,12,58,23394,
+4,24,54,23394,
+12,40,42,23394,
+15,28,50,23394,
+20,30,47,23394,
+22,33,44,23394,
+18,28,49,23394,
+2,16,57,23394,
+7,34,48,23394,
+23,26,48,23394,
+28,31,42,23394,
+7,18,56,23394,
+8,14,57,23394,
+12,34,47,23394,
+2,36,47,23394,
+1,12,58,23394,
+8,41,42,23394,
+8,23,54,23394,
+8,9,58,23394,
+0,22,55,23394,
+29,35,38,23430,
+14,17,55,23430,
+5,26,53,23430,
+13,29,50,23430,
+2,5,59,23430,
+13,35,46,23430,
+22,25,49,23430,
+6,15,57,23430,
+15,39,42,23430,
+5,37,46,23430,
+7,31,50,23430,
+5,11,58,23430,
+3,30,51,23430,
+30,33,39,23430,
+25,26,47,23430,
+1,22,55,23430,
+10,36,46,23430,
+14,20,54,23430,
+26,30,44,23430,
+2,12,58,23430,
+18,22,52,23430,
+5,28,52,23430,
+25,38,38,23430,
+26,34,41,23430,
+4,19,56,23430,
+11,16,56,23430,
+4,4,59,23430,
+8,40,43,23430,
+22,23,50,23430,
+2,22,55,23430,
+7,10,58,23430,
+11,12,57,23430,
+24,33,43,23430,
+3,36,47,23430,
+12,39,43,23430,
+11,33,48,23430,
+20,33,45,23430,
+24,27,47,23430,
+3,16,57,23430,
+9,27,52,23430,
+7,21,55,23430,
+25,37,39,23436,
+23,31,45,23436,
+3,5,59,23436,
+21,35,43,23436,
+17,25,51,23436,
+5,33,49,23436,
+9,25,53,23436,
+9,35,47,23436,
+11,37,45,23436,
+5,24,54,23436,
+21,24,50,23436,
+4,30,51,23436,
+27,32,42,23451,
+22,27,48,23451,
+3,12,58,23451,
+0,6,59,23451,
+14,36,45,23451,
+13,18,55,23451,
+21,31,46,23451,
+21,26,49,23451,
+17,27,50,23451,
+10,13,57,23451,
+23,35,42,23451,
+3,22,55,23451,
+15,22,53,23451,
+1,6,59,23451,
+15,38,43,23451,
+7,38,45,23451,
+29,34,39,23482,
+17,36,44,23482,
+6,37,46,23482,
+16,31,48,23482,
+26,27,46,23482,
+11,22,54,23482,
+20,39,40,23482,
+25,36,40,23482,
+4,16,57,23482,
+6,11,58,23482,
+8,39,44,23482,
+11,30,50,23482,
+2,6,59,23482,
+6,26,53,23482,
+4,36,47,23482,
+25,31,44,23482,
+23,28,47,23482,
+17,32,47,23482,
+4,5,59,23482,
+17,23,52,23482,
+28,37,37,23522,
+31,31,40,23522,
+19,35,44,23522,
+5,19,56,23522,
+9,29,51,23522,
+15,33,47,23522,
+7,15,57,23522,
+8,34,48,23522,
+18,40,40,23522,
+0,32,50,23522,
+8,18,56,23522,
+6,28,52,23522,
+12,38,44,23522,
+4,12,58,23522,
+28,36,38,23534,
+12,26,52,23534,
+14,32,48,23534,
+30,32,40,23534,
+10,17,56,23534,
+1,32,50,23534,
+8,31,50,23534,
+4,22,55,23534,
+10,20,55,23534,
+14,25,52,23534,
+20,38,41,23534,
+25,28,46,23534,
+20,25,50,23534,
+10,32,49,23534,
+14,27,51,23534,
+5,30,51,23534,
+21,22,51,23534,
+9,23,54,23534,
+9,9,58,23534,
+18,39,41,23534,
+22,39,39,23534,
+15,30,49,23534,
+9,41,42,23534,
+3,6,59,23534,
+13,21,54,23534,
+9,14,57,23534,
+6,33,49,23534,
+22,38,40,23534,
+18,30,48,23534,
+6,24,54,23534,
+8,10,58,23534,
+0,42,42,23534,
+2,32,50,23534,
+16,34,46,23534,
+14,14,56,23534,
+12,28,51,23534,
+17,18,54,23534,
+18,33,46,23534,
+0,35,48,23534,
+21,28,48,23534,
+1,42,42,23534,
+26,33,42,23544,
+12,24,53,23544,
+13,15,56,23544,
+20,23,51,23544,
+29,33,40,23592,
+0,41,43,23592,
+20,27,49,23592,
+5,36,47,23592,
+28,35,39,23592,
+5,16,57,23592,
+0,7,59,23592,
+12,19,55,23592,
+9,40,43,23592,
+15,37,44,23592,
+1,35,48,23592,
+8,21,55,23592,
+1,41,43,23592,
+29,29,43,23592,
+5,5,59,23592,
+19,19,53,23592,
+19,31,47,23592,
+17,29,49,23592,
+25,35,41,23592,
+13,31,49,23592,
+13,41,41,23592,
+1,7,59,23592,
+2,42,42,23592,
+18,38,42,23592,
+20,37,42,23592,
+2,35,48,23592,
+22,32,45,23592,
+24,29,46,23592,
+16,26,51,23592,
+28,30,43,23592,
+3,32,50,23592,
+5,12,58,23592,
+11,36,46,23592,
+6,19,56,23592,
+4,6,59,23592,
+16,19,54,23592,
+21,34,44,23592,
+18,20,53,23592,
+10,27,52,23592,
+0,13,58,23592,
+13,40,42,23592,
+8,38,45,23592,
+7,37,46,23592,
+22,37,41,23592,
+7,11,58,23592,
+14,23,53,23592,
+10,25,53,23592,
+2,41,43,23592,
+2,7,59,23592,
+22,29,47,23592,
+1,13,58,23592,
+13,34,47,23592,
+23,34,43,23592,
+7,26,53,23592,
+5,22,55,23592,
+10,35,47,23592,
+0,40,44,23592,
+12,16,56,23592,
+24,32,44,23592,
+0,20,56,23592,
+16,24,52,23592,
+19,26,50,23592,
+14,29,50,23592,
+3,42,42,23592,
+12,12,57,23592,
+1,20,56,23592,
+12,33,48,23592,
+1,40,44,23592,
+7,28,52,23592,
+16,16,55,23592,
+2,13,58,23592,
+14,35,46,23592,
+6,30,51,23592,
+16,40,41,23592,
+34,34,35,23671,
+8,15,57,23671,
+19,24,51,23671,
+9,39,44,23671,
+27,28,45,23671,
+0,17,57,23671,
+3,35,48,23671,
+12,37,45,23671,
+0,27,53,23671,
+11,13,57,23671,
+13,39,43,23671,
+33,35,35,23691,
+17,21,53,23691,
+3,41,43,23691,
+1,17,57,23691,
+3,7,59,23691,
+15,17,55,23691,
+7,33,49,23691,
+17,35,45,23691,
+1,27,53,23691,
+27,31,43,23691,
+20,32,46,23691,
+2,20,56,23691,
+4,32,50,23691,
+28,34,40,23691,
+2,40,44,23691,
+16,28,50,23691,
+6,36,47,23691,
+24,38,39,23691,
+0,25,54,23691,
+6,16,57,23691,
+9,34,48,23691,
+9,18,56,23691,
+15,20,54,23691,
+33,34,36,23709,
+7,24,54,23709,
+16,39,42,23709,
+26,29,45,23709,
+9,31,50,23709,
+19,34,45,23709,
+2,17,57,23709,
+30,31,41,23709,
+3,13,58,23709,
+27,37,38,23709,
+18,37,43,23709,
+5,6,59,23709,
+10,29,51,23709,
+2,27,53,23709,
+1,25,54,23709,
+12,30,50,23709,
+22,36,42,23709,
+4,42,42,23709,
+12,22,54,23709,
+6,12,58,23709,
+20,21,52,23709,
+14,18,55,23709,
+3,20,56,23709,
+20,29,48,23709,
+10,41,42,23709,
+25,34,42,23709,
+0,8,59,23709,
+23,30,46,23709,
+10,23,54,23709,
+6,22,55,23709,
+20,36,43,23709,
+4,35,48,23709,
+10,14,57,23709,
+9,10,58,23709,
+2,25,54,23709,
+3,40,44,23709,
+24,37,40,23709,
+0,29,52,23709,
+32,35,36,23747,
+4,41,43,23747,
+1,8,59,23747,
+11,32,49,23747,
+11,17,56,23747,
+27,36,39,23747,
+1,29,52,23747,
+0,39,45,23747,
+11,20,55,23747,
+29,32,41,23747,
+15,36,45,23747,
+19,28,49,23747,
+4,7,59,23747,
+7,19,56,23747,
+1,39,45,23747,
+9,21,55,23747,
+33,33,37,23767,
+3,27,53,23767,
+3,17,57,23767,
+13,38,44,23767,
+5,32,50,23767,
+4,13,58,23767,
+2,8,59,23767,
+8,11,58,23767,
+16,22,53,23767,
+16,38,43,23767,
+2,29,52,23767,
+19,22,52,23767,
+26,32,43,23767,
+10,40,43,23767,
+8,37,46,23767,
+32,34,37,23777,
+13,26,52,23777,
+8,26,53,23777,
+2,39,45,23777,
+25,30,45,23777,
+21,30,47,23777,
+18,25,51,23777,
+7,30,51,23777,
+9,38,45,23777,
+3,25,54,23777,
+4,40,44,23777,
+8,28,52,23777,
+4,20,56,23777,
+18,27,50,23777,
+14,21,54,23777,
+5,42,42,23777,
+24,36,41,23777,
+31,36,36,23822,
+15,32,48,23822,
+24,24,49,23822,
+6,6,59,23822,
+3,8,59,23822,
+16,33,47,23822,
+23,33,44,23822,
+4,27,53,23822,
+27,35,40,23822,
+3,29,52,23822,
+17,31,48,23822,
+7,36,47,23822,
+13,24,53,23822,
+0,23,55,23822,
+4,17,57,23822,
+28,33,41,23822,
+5,35,48,23822,
+7,16,57,23822,
+15,25,52,23822,
+13,28,51,23822,
+25,25,48,23822,
+8,33,49,23822,
+11,27,52,23822,
+9,15,57,23822,
+5,7,59,23822,
+3,39,45,23822,
+23,25,49,23822,
+11,35,47,23822,
+13,19,55,23822,
+31,35,37,23843,
+11,25,53,23843,
+1,23,55,23843,
+5,41,43,23843,
+21,33,45,23843,
+15,27,51,23843,
+12,36,46,23843,
+18,36,44,23843,
+8,24,54,23843,
+24,26,48,23843,
+18,23,52,23843,
+18,32,47,23843,
+7,12,58,23843,
+14,15,56,23843,
+4,25,54,23843,
+16,30,49,23843,
+32,33,38,23864,
+0,34,49,23864,
+10,39,44,23864,
+22,35,43,23864,
+23,23,50,23864,
+2,23,55,23864,
+14,31,49,23864,
+1,34,49,23864,
+5,13,58,23864,
+14,41,41,23864,
+7,22,55,23864,
+22,24,50,23864,
+6,32,50,23864,
+14,40,42,23864,
+0,38,46,23864,
+10,18,56,23864,
+10,34,48,23864,
+0,14,58,23864,
+5,40,44,23864,
+20,35,44,23864,
+4,29,52,23864,
+4,8,59,23864,
+1,14,58,23864,
+28,29,44,23864,
+17,34,46,23864,
+14,34,47,23864,
+10,31,50,23864,
+1,38,46,23864,
+22,26,49,23864,
+22,31,46,23864,
+19,40,40,23864,
+31,34,38,23882,
+8,19,56,23882,
+5,20,56,23882,
+16,37,44,23882,
+13,16,56,23882,
+26,26,47,23882,
+2,34,49,23882,
+0,31,51,23882,
+12,13,57,23882,
+0,9,59,23882,
+23,27,48,23882,
+13,33,48,23882,
+21,39,40,23882,
+24,31,45,23882,
+4,39,45,23882,
+3,23,55,23882,
+1,9,59,23882,
+15,23,53,23882,
+13,37,45,23882,
+1,31,51,23882,
+5,17,57,23882,
+5,27,53,23882,
+11,29,51,23882,
+25,27,47,23882,
+25,33,43,23882,
+19,39,41,23882,
+2,38,46,23882,
+30,30,42,23882,
+26,38,38,23882,
+10,10,58,23882,
+2,14,58,23882,
+18,18,54,23882,
+6,42,42,23882,
+24,35,42,23882,
+30,36,37,23944,
+8,30,51,23944,
+27,30,44,23944,
+19,30,48,23944,
+6,35,48,23944,
+9,11,58,23944,
+9,26,53,23944,
+11,14,57,23944,
+29,31,42,23944,
+2,31,51,23944,
+26,37,39,23944,
+17,26,51,23944,
+21,38,41,23944,
+9,37,46,23944,
+6,7,59,23944,
+21,25,50,23944,
+6,41,43,23944,
+15,35,46,23944,
+14,39,43,23944,
+5,25,54,23944,
+3,34,49,23944,
+15,29,50,23944,
+11,41,42,23944,
+19,33,46,23944,
+11,23,54,23944,
+2,9,59,23944,
+17,19,54,23944,
+18,29,49,23944,
+27,34,41,23944,
+10,21,55,23944,
+8,16,57,23944,
+24,28,47,23944,
+3,14,58,23944,
+13,30,50,23944,
+32,32,39,23977,
+12,32,49,23977,
+3,38,46,23977,
+17,24,52,23977,
+10,38,45,23977,
+8,36,47,23977,
+19,38,42,23977,
+22,22,51,23977,
+30,35,38,23977,
+12,20,55,23977,
+12,17,56,23977,
+6,13,58,23977,
+9,28,52,23977,
+13,22,54,23977,
+5,8,59,23977,
+11,40,43,23977,
+19,20,53,23977,
+5,29,52,23977,
+4,23,55,23977,
+20,31,47,23977,
+16,17,55,23977,
+17,40,41,23977,
+31,33,39,23999,
+21,23,51,23999,
+9,33,49,23999,
+5,39,45,23999,
+3,31,51,23999,
+21,27,49,23999,
+23,39,39,23999,
+3,9,59,23999,
+28,32,42,23999,
+16,20,54,23999,
+6,20,56,23999,
+6,40,44,23999,
+22,28,48,23999,
+8,12,58,23999,
+26,36,40,23999,
+23,38,40,23999,
+4,34,49,23999,
+7,32,50,23999,
+26,31,44,23999,
+0,18,57,23999,
+8,22,55,23999,
+9,24,54,23999,
+17,28,50,23999,
+27,27,46,23999,
+18,35,45,23999,
+10,15,57,23999,
+6,27,53,23999,
+18,21,53,23999,
+1,18,57,23999,
+6,17,57,23999,
+15,18,55,23999,
+17,39,42,23999,
+21,37,42,23999,
+26,28,46,23999,
+22,34,44,23999,
+4,38,46,23999,
+14,38,44,23999,
+20,26,50,23999,
+14,26,52,23999,
+4,14,58,23999,
+2,18,57,23999,
+0,21,56,23999,
+16,36,45,23999,
+12,27,52,23999,
+7,42,42,23999,
+20,24,51,23999,
+6,25,54,23999,
+30,34,39,24038,
+12,25,53,24038,
+23,32,45,24038,
+0,37,47,24038,
+1,21,56,24038,
+12,35,47,24038,
+11,39,44,24038,
+9,19,56,24038,
+4,31,51,24038,
+7,35,48,24038,
+4,9,59,24038,
+23,37,41,24038,
+7,41,43,24038,
+23,29,47,24038,
+19,37,43,24038,
+5,23,55,24038,
+7,7,59,24038,
+29,37,37,24053,
+1,37,47,24053,
+14,24,53,24053,
+29,36,38,24074,
+11,34,48,24074,
+2,21,56,24074,
+20,34,45,24074,
+11,18,56,24074,
+24,34,43,24074,
+6,8,59,24074,
+6,29,52,24074,
+0,10,59,24074,
+13,36,46,24074,
+21,32,46,24074,
+14,28,51,24074,
+6,39,45,24074,
+5,34,49,24074,
+25,29,46,24074,
+1,10,59,24074,
+14,19,55,24074,
+15,21,54,24074,
+9,30,51,24074,
+3,18,57,24074,
+11,31,50,24074,
+17,38,43,24074,
+17,22,53,24074,
+7,13,58,24074,
+27,33,42,24074,
+26,35,41,24074,
+2,37,47,24074,
+16,32,48,24074,
+7,40,44,24074,
+5,38,46,24074,
+10,11,58,24074,
+10,37,46,24074,
+25,32,44,24074,
+5,14,58,24074,
+20,28,49,24074,
+2,10,59,24074,
+31,32,40,24096,
+16,25,52,24096,
+10,26,53,24096,
+7,20,56,24096,
+21,36,43,24096,
+12,29,51,24096,
+21,29,48,24096,
+16,27,51,24096,
+9,16,57,24096,
+15,15,56,24096,
+9,36,47,24096,
+21,21,52,24096,
+3,21,56,24096,
+13,13,57,24096,
+15,31,49,24096,
+29,35,39,24125,
+17,33,47,24125,
+11,21,55,24125,
+3,37,47,24125,
+19,25,51,24125,
+15,41,41,24125,
+7,17,57,24125,
+5,31,51,24125,
+7,27,53,24125,
+5,9,59,24125,
+10,28,52,24125,
+20,22,52,24125,
+14,16,56,24125,
+8,32,50,24125,
+12,14,57,24125,
+9,12,58,24125,
+23,36,42,24125,
+0,33,50,24125,
+14,33,48,24125,
+30,33,40,24139,
+12,23,54,24139,
+0,15,58,24139,
+4,18,57,24139,
+18,31,48,24139,
+12,41,42,24139,
+15,40,42,24139,
+6,23,55,24139,
+11,38,45,24139,
+1,33,50,24139,
+7,25,54,24139,
+29,30,43,24139,
+9,22,55,24139,
+10,33,49,24139,
+19,27,50,24139,
+1,15,58,24139,
+14,37,45,24139,
+3,10,59,24139,
+25,38,39,24139,
+17,30,49,24139,
+15,34,47,24139,
+0,26,54,24139,
+10,24,54,24139,
+24,30,46,24139,
+8,42,42,24139,
+12,40,43,24139,
+8,35,48,24139,
+28,28,45,24139,
+22,30,47,24139,
+4,21,56,24139,
+2,33,50,24139,
+19,36,44,24139,
+0,28,53,24139,
+2,15,58,24139,
+6,34,49,24139,
+1,26,54,24139,
+13,17,56,24139,
+25,37,40,24163,
+13,20,55,24163,
+16,23,53,24163,
+19,23,52,24163,
+1,28,53,24163,
+13,32,49,24163,
+7,8,59,24163,
+7,29,52,24163,
+4,37,47,24163,
+19,32,47,24163,
+17,37,44,24163,
+28,31,43,24163,
+8,41,43,24163,
+11,15,57,24163,
+27,29,45,24163,
+7,39,45,24163,
+15,39,43,24163,
+6,38,46,24163,
+6,14,58,24163,
+2,26,54,24163,
+26,34,42,24167,
+14,30,50,24167,
+18,34,46,24167,
+14,22,54,24167,
+28,37,38,24217,
+16,29,50,24217,
+10,19,56,24217,
+16,35,46,24217,
+29,34,40,24217,
+2,28,53,24217,
+8,13,58,24217,
+4,10,59,24217,
+22,33,45,24217,
+6,9,59,24217,
+6,31,51,24217,
+5,18,57,24217,
+3,33,50,24217,
+3,15,58,24217,
+8,40,44,24217,
+0,36,48,24217,
+0,0,60,24217,
+20,40,40,24217,
+8,20,56,24217,
+12,39,44,24217,
+18,26,51,24217,
+3,26,54,24217,
+0,24,55,24217,
+18,19,54,24217,
+10,30,51,24217,
+24,33,44,24217,
+1,36,48,24217,
+26,30,45,24217,
+0,1,60,24217,
+28,36,39,24256,
+24,25,49,24256,
+25,36,41,24256,
+1,1,60,24256,
+13,27,52,24256,
+20,39,41,24256,
+1,24,55,24256,
+21,35,44,24256,
+27,32,43,24256,
+8,27,53,24256,
+5,21,56,24256,
+0,11,59,24256,
+8,17,57,24256,
+3,28,53,24256,
+23,35,43,24256,
+5,37,47,24256,
+31,31,41,24273,
+1,11,59,24273,
+7,23,55,24273,
+13,25,53,24273,
+13,35,47,24273,
+19,29,49,24273,
+17,17,55,24273,
+12,18,56,24273,
+20,30,48,24273,
+18,24,52,24273,
+2,36,48,24273,
+12,34,48,24273,
+0,30,52,24273,
+0,2,60,24273,
+15,26,52,24273,
+4,33,50,24273,
+10,16,57,24273,
+1,30,52,24273,
+1,2,60,24273,
+18,40,41,24273,
+16,18,55,24273,
+10,36,47,24273,
+15,38,44,24273,
+8,25,54,24273,
+30,32,41,24283,
+12,31,50,24283,
+22,39,40,24283,
+23,24,50,24283,
+25,26,48,24283,
+9,32,50,24283,
+2,24,55,24283,
+17,20,54,24283,
+20,33,46,24283,
+4,15,58,24283,
+7,34,49,24283,
+11,26,53,24283,
+23,31,46,24283,
+23,26,49,24283,
+2,11,59,24283,
+34,35,35,24318,
+11,37,46,24318,
+5,10,59,24318,
+11,11,58,24318,
+14,36,46,24318,
+10,12,58,24318,
+2,30,52,24318,
+20,38,42,24318,
+2,2,60,24318,
+18,28,50,24318,
+34,34,36,24330,
+4,26,54,24330,
+10,22,55,24330,
+0,3,60,24330,
+24,27,48,24330,
+20,20,53,24330,
+11,28,52,24330,
+28,35,40,24330,
+7,14,58,24330,
+18,39,42,24330,
+3,36,48,24330,
+6,18,57,24330,
+22,25,50,24330,
+8,29,52,24330,
+9,42,42,24330,
+22,38,41,24330,
+4,28,53,24330,
+7,38,46,24330,
+8,8,59,24330,
+8,39,45,24330,
+15,24,53,24330,
+15,28,51,24330,
+3,24,55,24330,
+17,36,45,24330,
+12,21,55,24330,
+0,19,57,24330,
+1,3,60,24330,
+9,35,48,24330,
+33,35,36,24354,
+19,35,45,24354,
+13,29,51,24354,
+9,41,43,24354,
+15,19,55,24354,
+3,11,59,24354,
+7,31,51,24354,
+29,33,41,24354,
+25,31,45,24354,
+1,19,57,24354,
+19,21,53,24354,
+21,31,47,24354,
+11,33,49,24354,
+7,9,59,24354,
+6,21,56,24354,
+2,3,60,24354,
+11,24,54,24354,
+12,38,45,24354,
+3,30,52,24354,
+0,42,43,24354,
+16,21,54,24354,
+5,33,50,24354,
+13,14,57,24354,
+13,23,54,24354,
+22,27,49,24354,
+25,35,42,24354,
+6,37,47,24354,
+2,19,57,24354,
+9,13,58,24354,
+26,27,47,24354,
+33,34,37,24388,
+26,33,43,24388,
+5,15,58,24388,
+22,23,51,24388,
+1,42,43,24388,
+13,41,42,24388,
+32,36,36,24403,
+4,36,48,24403,
+0,4,60,24403,
+1,4,60,24403,
+18,38,43,24403,
+5,26,54,24403,
+9,20,56,24403,
+6,10,59,24403,
+23,28,48,24403,
+0,41,44,24403,
+17,32,48,24403,
+9,40,44,24403,
+4,24,55,24403,
+15,16,56,24403,
+18,22,53,24403,
+21,26,50,24403,
+22,37,42,24403,
+27,38,38,24403,
+2,42,43,24403,
+11,19,56,24403,
+20,37,43,24403,
+17,25,52,24403,
+25,28,47,24403,
+8,23,55,24403,
+3,3,60,24403,
+16,31,49,24403,
+32,35,37,24433,
+15,33,48,24433,
+1,41,44,24433,
+4,11,59,24433,
+29,29,44,24433,
+24,39,39,24433,
+12,15,57,24433,
+13,40,43,24433,
+21,24,51,24433,
+16,41,41,24433,
+5,28,53,24433,
+3,19,57,24433,
+27,37,39,24433,
+15,37,45,24433,
+9,17,57,24433,
+17,27,51,24433,
+9,27,53,24433,
+0,22,56,24433,
+0,16,58,24433,
+28,30,44,24433,
+4,30,52,24433,
+2,4,60,24433,
+24,38,40,24433,
+16,40,42,24433,
+28,34,41,24433,
+1,16,58,24433,
+8,34,49,24433,
+14,17,56,24433,
+23,34,44,24433,
+14,32,49,24433,
+16,34,47,24433,
+14,20,55,24433,
+1,22,56,24433,
+2,41,44,24433,
+7,18,57,24433,
+33,33,38,24471,
+9,25,54,24471,
+21,34,45,24471,
+18,33,47,24471,
+11,30,51,24471,
+3,42,43,24471,
+22,32,46,24471,
+2,22,56,24471,
+8,14,58,24471,
+32,34,38,24484,
+2,16,58,24484,
+10,32,50,24484,
+8,38,46,24484,
+0,12,59,24484,
+18,30,49,24484,
+0,32,51,24484,
+24,32,45,24484,
+6,33,50,24484,
+0,40,45,24484,
+15,22,54,24484,
+30,31,42,24484,
+0,5,60,24484,
+6,15,58,24484,
+3,4,60,24484,
+5,36,48,24484,
+27,36,40,24484,
+15,30,50,24484,
+24,29,47,24484,
+11,16,57,24484,
+11,36,47,24484,
+1,12,59,24484,
+0,35,49,24484,
+27,31,44,24484,
+19,31,48,24484,
+31,36,37,24502,
+13,39,44,24502,
+8,31,51,24502,
+7,21,56,24502,
+1,40,45,24502,
+16,39,43,24502,
+1,32,51,24502,
+3,41,44,24502,
+24,37,41,24502,
+5,24,55,24502,
+8,9,59,24502,
+4,19,57,24502,
+21,28,49,24502,
+1,5,60,24502,
+20,25,51,24502,
+9,29,52,24502,
+7,37,47,24502,
+5,11,59,24502,
+17,23,53,24502,
+9,39,45,24502,
+1,35,49,24502,
+6,26,54,24502,
+10,42,42,24502,
+10,35,48,24502,
+2,32,51,24502,
+12,37,46,24502,
+20,27,50,24502,
+22,36,43,24502,
+3,16,58,24502,
+13,34,48,24502,
+18,37,44,24502,
+3,22,56,24502,
+5,30,52,24502,
+14,27,52,24502,
+22,29,48,24502,
+4,42,43,24502,
+11,12,58,24502,
+27,28,46,24502,
+2,5,60,24502,
+12,26,53,24502,
+29,32,42,24502,
+21,22,52,24502,
+2,12,59,24502,
+2,40,45,24502,
+6,28,53,24502,
+13,18,56,24502,
+14,25,53,24502,
+11,22,55,24502,
+17,29,50,24502,
+31,35,38,24530,
+13,31,50,24530,
+17,35,46,24530,
+7,10,59,24530,
+10,41,43,24530,
+14,35,47,24530,
+25,34,43,24530,
+2,35,49,24530,
+20,36,44,24530,
+4,4,60,24530,
+12,28,52,24530,
+4,41,44,24530,
+19,34,46,24530,
+26,29,46,24530,
+20,32,47,24530,
+20,23,52,24530,
+10,13,58,24530,
+3,32,51,24530,
+32,33,39,24575,
+3,12,59,24575,
+12,33,49,24575,
+3,40,45,24575,
+3,5,60,24575,
+13,21,55,24575,
+9,23,55,24575,
+27,35,41,24575,
+3,35,49,24575,
+5,19,57,24575,
+4,16,58,24575,
+0,6,60,24575,
+12,24,54,24575,
+16,38,44,24575,
+4,22,56,24575,
+10,40,44,24575,
+6,36,48,24575,
+16,26,52,24575,
+26,32,44,24575,
+10,20,56,24575,
+24,36,42,24575,
+0,39,46,24575,
+15,36,46,24575,
+28,33,42,24575,
+6,24,55,24575,
+1,6,60,24575,
+8,18,57,24575,
+9,34,49,24575,
+5,42,43,24575,
+10,17,57,24575,
+13,38,45,24575,
+6,11,59,24575,
+10,27,53,24575,
+30,37,37,24608,
+14,29,51,24608,
+19,26,51,24608,
+19,19,54,24608,
+31,34,39,24608,
+1,39,46,24608,
+7,33,50,24608,
+7,15,58,24608,
+17,18,55,24608,
+23,30,47,24608,
+30,36,38,24627,
+6,30,52,24627,
+2,6,60,24627,
+18,20,54,24627,
+14,23,54,24627,
+8,21,56,24627,
+9,14,58,24627,
+12,19,56,24627,
+25,30,46,24627,
+21,40,40,24627,
+7,26,54,24627,
+2,39,46,24627,
+4,32,51,24627,
+16,24,53,24627,
+26,38,39,24627,
+10,25,54,24627,
+16,28,51,24627,
+14,41,42,24627,
+4,40,45,24627,
+19,24,52,24627,
+4,12,59,24627,
+4,5,60,24627,
+9,38,46,24627,
+14,14,57,24627,
+8,37,47,24627,
+16,19,55,24627,
+7,28,53,24627,
+19,40,41,24627,
+20,29,49,24627,
+5,41,44,24627,
+4,35,49,24627,
+21,39,41,24627,
+9,31,51,24627,
+23,33,45,24627,
+13,15,57,24627,
+9,9,59,24627,
+21,30,48,24627,
+5,16,58,24627,
+26,37,40,24638,
+19,28,50,24638,
+10,29,52,24638,
+12,30,51,24638,
+5,22,56,24638,
+3,6,60,24638,
+18,36,45,24638,
+0,27,54,24638,
+11,32,50,24638,
+22,35,44,24638,
+14,40,43,24638,
+8,10,59,24638,
+6,19,57,24638,
+1,27,54,24638,
+30,35,39,24686,
+3,39,46,24686,
+21,33,46,24686,
+17,21,54,24686,
+10,39,45,24686,
+19,39,42,24686,
+16,16,56,24686,
+32,32,40,24697,
+12,36,47,24697,
+21,38,42,24697,
+16,33,48,24697,
+0,7,60,24697,
+30,30,43,24697,
+7,36,48,24697,
+2,27,54,24697,
+11,42,42,24697,
+12,16,57,24697,
+0,20,57,24697,
+27,34,42,24697,
+6,42,43,24697,
+20,35,45,24697,
+25,33,44,24697,
+24,35,43,24697,
+5,12,59,24697,
+20,21,53,24697,
+1,7,60,24697,
+28,29,45,24697,
+11,35,48,24697,
+7,24,55,24697,
+0,29,53,24697,
+0,13,59,24697,
+5,5,60,24697,
+16,37,45,24697,
+5,40,45,24697,
+1,20,57,24697,
+0,25,55,24697,
+31,33,40,24716,
+23,39,40,24716,
+5,32,51,24716,
+15,17,56,24716,
+15,32,49,24716,
+15,20,55,24716,
+25,25,49,24716,
+1,13,59,24716,
+7,11,59,24716,
+17,31,49,24716,
+5,35,49,24716,
+1,25,55,24716,
+29,31,43,24716,
+17,41,41,24716,
+1,29,53,24716,
+11,41,43,24716,
+24,24,50,24716,
+4,6,60,24716,
+12,12,58,24716,
+18,32,48,24716,
+8,33,50,24716,
+0,17,58,24716,
+0,38,47,24716,
+17,40,42,24716,
+2,20,57,24716,
+18,25,52,24716,
+4,39,46,24716,
+24,31,46,24716,
+7,30,52,24716,
+14,39,44,24716,
+24,26,49,24716,
+6,41,44,24716,
+12,22,55,24716,
+8,15,58,24716,
+2,7,60,24716,
+26,36,41,24716,
+3,27,54,24716,
+2,29,53,24716,
+23,25,50,24716,
+2,25,55,24716,
+1,38,47,24716,
+1,17,58,24716,
+17,34,47,24716,
+11,13,58,24716,
+27,30,45,24716,
+13,37,46,24716,
+19,22,53,24716,
+22,31,47,24716,
+9,18,57,24716,
+18,27,51,24716,
+13,26,53,24716,
+29,37,38,24742,
+2,13,59,24742,
+23,38,41,24742,
+10,23,55,24742,
+19,38,43,24742,
+6,22,56,24742,
+8,26,54,24742,
+26,26,48,24742,
+16,30,50,24742,
+16,22,54,24742,
+6,16,58,24742,
+0,34,50,24742,
+30,34,40,24754,
+14,18,56,24754,
+14,34,48,24754,
+2,17,58,24754,
+11,20,56,24754,
+13,28,52,24754,
+8,28,53,24754,
+10,34,49,24754,
+1,34,50,24754,
+2,38,47,24754,
+28,32,43,24754,
+14,31,50,24754,
+11,40,44,24754,
+3,7,60,24754,
+9,21,56,24754,
+15,27,52,24754,
+3,20,57,24754,
+29,36,39,24787,
+25,27,48,24787,
+17,39,43,24787,
+11,17,57,24787,
+7,19,57,24787,
+23,23,51,24787,
+15,35,47,24787,
+23,27,49,24787,
+3,13,59,24787,
+13,33,49,24787,
+3,29,53,24787,
+21,37,43,24787,
+3,25,55,24787,
+11,27,53,24787,
+9,37,47,24787,
+15,25,53,24787,
+19,33,47,24787,
+10,14,58,24787,
+2,34,50,24787,
+22,26,50,24787,
+10,38,46,24787,
+13,24,54,24787,
+22,24,51,24787,
+6,12,59,24787,
+6,40,45,24787,
+5,6,60,24787,
+4,27,54,24787,
+6,32,51,24787,
+23,37,42,24787,
+6,35,49,24787,
+26,31,45,24787,
+3,38,47,24787,
+18,23,53,24787,
+9,10,59,24787,
+14,21,55,24787,
+3,17,58,24787,
+5,39,46,24787,
+10,31,51,24787,
+11,25,54,24787,
+19,30,49,24787,
+7,42,43,24787,
+0,8,60,24787,
+8,36,48,24787,
+24,28,48,24787,
+20,31,48,24787,
+18,35,46,24787,
+8,24,55,24787,
+22,34,45,24787,
+0,31,52,24787,
+0,23,56,24787,
+3,34,50,24787,
+1,8,60,24787,
+26,35,42,24805,
+4,20,57,24805,
+4,7,60,24805,
+14,38,45,24805,
+18,29,50,24805,
+1,23,56,24805,
+13,19,56,24805,
+19,37,44,24805,
+4,29,53,24805,
+4,13,59,24805,
+8,11,59,24805,
+1,31,52,24805,
+31,32,41,24860,
+11,29,52,24860,
+4,25,55,24860,
+7,41,44,24860,
+29,35,40,24860,
+21,25,51,24860,
+11,39,45,24860,
+27,27,47,24860,
+27,33,43,24860,
+25,39,39,24860,
+15,29,51,24860,
+8,30,52,24860,
+16,36,46,24860,
+24,34,44,24860,
+12,32,50,24860,
+2,8,60,24860,
+17,38,44,24860,
+22,28,49,24860,
+23,32,46,24860,
+25,38,40,24860,
+17,26,52,24860,
+7,22,56,24860,
+4,17,58,24860,
+4,38,47,24860,
+7,16,58,24860,
+26,28,47,24860,
+2,23,56,24860,
+2,31,52,24860,
+15,41,42,24860,
+30,33,41,24886,
+14,15,57,24886,
+9,15,58,24886,
+21,27,50,24886,
+9,33,50,24886,
+5,27,54,24886,
+13,30,51,24886,
+15,23,54,24886,
+28,38,38,24906,
+20,34,46,24906,
+4,34,50,24906,
+12,42,42,24906,
+22,22,52,24906,
+6,6,60,24906,
+10,18,57,24906,
+12,35,48,24906,
+21,36,44,24906,
+6,39,46,24906,
+3,8,60,24906,
+9,26,54,24906,
+0,37,48,24906,
+18,18,55,24906,
+7,40,45,24906,
+8,19,57,24906,
+12,41,43,24906,
+28,37,39,24923,
+7,12,59,24923,
+3,23,56,24923,
+15,40,43,24923,
+21,23,52,24923,
+9,28,53,24923,
+1,37,48,24923,
+7,32,51,24923,
+25,32,45,24923,
+13,36,47,24923,
+21,32,47,24923,
+5,20,57,24923,
+17,28,51,24923,
+17,24,53,24923,
+23,29,48,24923,
+13,16,57,24923,
+23,36,43,24923,
+5,7,60,24923,
+3,31,52,24923,
+25,29,47,24923,
+11,23,55,24923,
+35,35,35,24968,
+5,29,53,24968,
+25,37,41,24968,
+7,35,49,24968,
+17,19,55,24968,
+5,13,59,24968,
+5,25,55,24968,
+12,13,58,24968,
+8,42,43,24968,
+19,20,54,24968,
+0,14,59,24968,
+10,21,56,24968,
+20,26,51,24968,
+34,35,36,24993,
+2,37,48,24993,
+29,30,44,24993,
+5,17,58,24993,
+10,37,47,24993,
+13,22,55,24993,
+29,34,41,24993,
+5,38,47,24993,
+11,34,49,24993,
+1,14,59,24993,
+20,24,52,24993,
+12,40,44,24993,
+12,20,56,24993,
+4,8,60,24993,
+28,36,40,24993,
+14,26,53,24993,
+6,27,54,24993,
+11,38,46,24993,
+4,23,56,24993,
+16,17,56,24993,
+18,21,54,24993,
+26,34,43,24993,
+4,31,52,24993,
+9,36,48,24993,
+0,9,60,24993,
+14,37,46,24993,
+11,14,58,24993,
+2,14,59,24993,
+16,20,55,24993,
+33,36,36,25018,
+8,41,44,25018,
+28,31,44,25018,
+20,40,41,25018,
+16,32,49,25018,
+5,34,50,25018,
+10,10,59,25018,
+34,34,37,25018,
+1,9,60,25018,
+12,27,53,25018,
+12,17,57,25018,
+9,24,55,25018,
+19,36,45,25018,
+17,33,48,25018,
+3,37,48,25018,
+15,39,44,25018,
+17,37,45,25018,
+11,31,51,25018,
+9,11,59,25018,
+33,35,37,25044,
+21,29,49,25044,
+22,40,40,25044,
+28,28,46,25044,
+20,28,50,25044,
+14,28,52,25044,
+8,16,58,25044,
+8,22,56,25044,
+24,30,47,25044,
+15,18,56,25044,
+15,34,48,25044,
+25,36,42,25044,
+12,25,54,25044,
+6,20,57,25044,
+20,39,42,25044,
+2,9,60,25044,
+6,7,60,25044,
+9,30,52,25044,
+31,31,42,25044,
+22,39,41,25044,
+18,41,41,25044,
+6,29,53,25044,
+6,25,55,25044,
+18,31,49,25044,
+3,14,59,25044,
+7,39,46,25044,
+27,29,46,25044,
+15,31,50,25044,
+6,13,59,25044,
+14,33,49,25044,
+18,40,42,25044,
+30,32,42,25052,
+0,18,58,25052,
+22,30,48,25052,
+14,24,54,25052,
+18,34,47,25052,
+17,22,54,25052,
+5,8,60,25052,
+6,38,47,25052,
+8,32,51,25052,
+10,15,58,25052,
+16,27,52,25052,
+33,34,38,25098,
+4,37,48,25098,
+12,29,52,25098,
+8,12,59,25098,
+1,18,58,25098,
+8,40,45,25098,
+19,32,48,25098,
+32,36,37,25098,
+17,30,50,25098,
+27,32,44,25098,
+6,17,58,25098,
+10,33,50,25098,
+22,33,46,25098,
+5,31,52,25098,
+16,35,47,25098,
+28,35,41,25098,
+12,39,45,25098,
+8,35,49,25098,
+16,25,53,25098,
+0,21,57,25098,
+24,33,45,25098,
+0,33,51,25098,
+3,9,60,25098,
+23,35,44,25098,
+19,25,52,25098,
+5,23,56,25098,
+15,21,55,25098,
+21,35,45,25098,
+21,21,53,25098,
+1,21,57,25098,
+9,19,57,25098,
+1,33,51,25098,
+19,27,51,25098,
+2,18,58,25098,
+26,30,46,25098,
+10,26,54,25098,
+22,38,42,25098,
+6,34,50,25098,
+4,14,59,25098,
+14,19,56,25098,
+20,22,53,25098,
+10,28,53,25098,
+13,32,50,25098,
+32,35,38,25134,
+20,38,43,25134,
+9,42,43,25134,
+2,33,51,25134,
+29,33,42,25134,
+11,18,57,25134,
+2,21,57,25134,
+27,38,39,25134,
+7,27,54,25134,
+15,38,45,25134,
+18,39,43,25134,
+13,42,42,25134,
+4,9,60,25134,
+14,30,51,25134,
+3,18,58,25134,
+0,36,49,25134,
+24,39,40,25134,
+0,43,43,25134,
+7,7,60,25134,
+1,36,49,25134,
+7,20,57,25134,
+9,41,44,25134,
+13,35,48,25134,
+16,29,51,25134,
+12,23,55,25134,
+5,37,48,25134,
+27,37,40,25142,
+11,21,56,25142,
+20,33,47,25142,
+7,13,59,25142,
+1,43,43,25142,
+31,37,37,25185,
+3,33,51,25185,
+23,31,47,25185,
+15,15,57,25185,
+3,21,57,25185,
+13,41,43,25185,
+11,37,47,25185,
+7,29,53,25185,
+33,33,39,25185,
+7,25,55,25185,
+19,23,53,25185,
+25,35,43,25185,
+0,42,44,25185,
+6,8,60,25185,
+10,36,48,25185,
+0,28,54,25185,
+0,10,60,25185,
+16,41,42,25185,
+17,36,46,25185,
+9,16,58,25185,
+1,42,44,25185,
+10,24,55,25185,
+1,10,60,25185,
+14,36,47,25185,
+8,39,46,25185,
+20,30,49,25185,
+24,38,41,25185,
+24,25,50,25185,
+6,31,52,25185,
+14,16,57,25185,
+32,34,39,25209,
+31,36,38,25209,
+16,23,54,25209,
+0,26,55,25209,
+26,33,44,25209,
+2,36,49,25209,
+6,23,56,25209,
+9,22,56,25209,
+12,34,49,25209,
+1,28,54,25209,
+19,29,50,25209,
+2,43,43,25209,
+22,37,43,25209,
+1,26,55,25209,
+25,26,49,25209,
+10,11,59,25209,
+7,38,47,25209,
+13,13,58,25209,
+5,14,59,25209,
+25,31,46,25209,
+19,35,46,25209,
+7,17,58,25209,
+18,38,44,25209,
+2,42,44,25209,
+12,38,46,25209,
+12,14,58,25209,
+4,18,58,25209,
+2,10,60,25209,
+28,34,42,25209,
+2,28,54,25209,
+10,30,52,25209,
+18,26,52,25209,
+16,40,43,25209,
+2,26,55,25209,
+14,22,55,25209,
+20,37,44,25209,
+23,26,50,25209,
+13,20,56,25209,
+7,34,50,25209,
+13,40,44,25209,
+9,32,51,25209,
+5,9,60,25209,
+24,27,49,25209,
+23,24,51,25209,
+12,31,51,25209,
+0,41,45,25209,
+4,33,51,25209,
+21,31,48,25209,
+4,21,57,25209,
+0,15,59,25209,
+27,36,41,25219,
+9,12,59,25219,
+9,40,45,25219,
+3,36,49,25219,
+29,29,45,25219,
+1,15,59,25219,
+9,35,49,25219,
+3,43,43,25219,
+13,17,57,25219,
+13,27,53,25219,
+1,41,45,25219,
+31,35,39,25256,
+26,27,48,25256,
+6,37,48,25256,
+0,30,53,25256,
+3,10,60,25256,
+18,28,51,25256,
+8,27,54,25256,
+3,28,54,25256,
+28,30,45,25256,
+18,24,53,25256,
+24,37,42,25256,
+3,42,44,25256,
+3,26,55,25256,
+10,19,57,25256,
+15,26,53,25256,
+18,19,55,25256,
+15,37,46,25256,
+11,15,58,25256,
+22,25,51,25256,
+11,33,50,25256,
+2,15,59,25256,
+23,34,45,25256,
+1,30,53,25256,
+13,25,54,25256,
+30,31,43,25256,
+2,41,45,25256,
+0,24,56,25256,
+2,30,53,25256,
+25,28,48,25256,
+4,36,49,25256,
+10,42,43,25256,
+32,33,40,25297,
+1,24,56,25297,
+6,14,59,25297,
+15,28,52,25297,
+11,26,54,25297,
+30,37,38,25297,
+8,20,57,25297,
+21,34,46,25297,
+22,27,50,25297,
+7,8,60,25297,
+16,39,44,25297,
+5,18,58,25297,
+8,25,55,25297,
+29,32,43,25297,
+17,32,49,25297,
+8,13,59,25297,
+13,29,52,25297,
+17,17,56,25297,
+7,23,56,25297,
+23,28,49,25297,
+4,43,43,25297,
+8,29,53,25297,
+11,28,53,25297,
+17,20,55,25297,
+7,31,52,25297,
+3,41,45,25297,
+15,33,49,25297,
+5,33,51,25297,
+3,15,59,25297,
+27,31,45,25297,
+5,21,57,25297,
+13,39,45,25297,
+4,28,54,25297,
+0,40,46,25297,
+20,20,54,25297,
+4,42,44,25297,
+24,32,46,25297,
+22,36,44,25297,
+16,34,48,25297,
+16,18,56,25297,
+2,24,56,25297,
+4,10,60,25297,
+10,41,44,25297,
+25,34,44,25297,
+6,9,60,25297,
+1,40,46,25297,
+8,38,47,25297,
+8,17,58,25297,
+16,31,50,25297,
+15,24,54,25297,
+22,23,52,25297,
+4,26,55,25297,
+12,18,57,25297,
+30,36,39,25347,
+18,33,48,25347,
+22,32,47,25347,
+31,34,40,25347,
+18,37,45,25347,
+9,39,46,25347,
+19,21,54,25347,
+26,39,39,25347,
+3,30,53,25347,
+27,35,42,25347,
+21,26,51,25347,
+14,32,50,25347,
+2,40,46,25347,
+26,38,40,25347,
+10,22,56,25347,
+10,16,58,25347,
+8,34,50,25347,
+20,36,45,25347,
+12,21,56,25347,
+24,29,48,25347,
+3,24,56,25347,
+24,36,43,25347,
+0,0,61,25347,
+11,36,48,25347,
+21,24,52,25347,
+0,11,60,25347,
+5,36,49,25347,
+4,41,45,25347,
+1,11,60,25347,
+16,21,55,25347,
+17,27,52,25347,
+28,33,43,25360,
+4,15,59,25360,
+21,40,41,25360,
+15,19,56,25360,
+11,24,55,25360,
+12,37,47,25360,
+27,28,47,25360,
+7,37,48,25360,
+0,1,61,25360,
+19,41,41,25360,
+17,35,47,25360,
+13,23,55,25360,
+1,1,61,25360,
+17,25,53,25360,
+11,11,59,25360,
+19,31,49,25360,
+5,43,43,25360,
+14,42,42,25360,
+18,30,50,25360,
+6,18,58,25360,
+18,22,54,25360,
+10,32,51,25360,
+11,30,52,25360,
+5,42,44,25360,
+0,2,61,25360,
+19,40,42,25360,
+5,28,54,25360,
+5,10,60,25360,
+10,12,59,25360,
+16,38,45,25360,
+30,35,40,25420,
+0,35,50,25420,
+2,11,60,25420,
+0,19,58,25420,
+10,40,45,25420,
+26,32,45,25420,
+4,30,53,25420,
+21,28,50,25420,
+3,40,46,25420,
+14,35,48,25420,
+1,2,61,25420,
+13,34,49,25420,
+10,35,49,25420,
+1,19,58,25420,
+15,30,51,25420,
+9,27,54,25420,
+19,34,47,25420,
+5,26,55,25420,
+26,37,41,25420,
+26,29,47,25420,
+14,41,43,25420,
+1,35,50,25420,
+6,33,51,25420,
+6,21,57,25420,
+21,39,42,25420,
+22,29,49,25420,
+7,14,59,25420,
+0,32,52,25420,
+4,24,56,25420,
+20,32,48,25420,
+8,8,60,25420,
+2,35,50,25420,
+2,19,58,25420,
+13,38,46,25420,
+23,40,40,25420,
+13,14,58,25420,
+8,31,52,25420,
+2,2,61,25420,
+1,32,52,25420,
+29,38,38,25449,
+32,32,41,25449,
+20,25,52,25449,
+8,23,56,25449,
+15,16,57,25449,
+3,11,60,25449,
+7,9,60,25449,
+9,20,57,25449,
+20,27,51,25449,
+15,36,47,25449,
+0,3,61,25449,
+0,39,47,25449,
+1,39,47,25449,
+5,41,45,25449,
+29,37,39,25466,
+19,39,43,25466,
+11,19,57,25466,
+9,13,59,25466,
+13,31,51,25466,
+17,29,51,25466,
+31,33,41,25466,
+9,25,55,25466,
+9,29,53,25466,
+5,15,59,25466,
+23,39,41,25466,
+1,3,61,25466,
+14,20,56,25466,
+2,32,52,25466,
+4,40,46,25466,
+14,40,44,25466,
+23,30,48,25466,
+12,15,58,25466,
+0,22,57,25466,
+12,33,50,25466,
+6,36,49,25466,
+9,38,47,25466,
+27,34,43,25466,
+14,17,57,25466,
+3,19,58,25466,
+2,3,61,25466,
+5,30,53,25466,
+17,23,54,25466,
+2,39,47,25466,
+9,17,58,25466,
+23,33,46,25466,
+17,41,42,25466,
+21,38,43,25466,
+3,35,50,25466,
+22,35,45,25466,
+14,27,53,25466,
+11,42,43,25466,
+6,43,43,25466,
+21,22,53,25466,
+15,22,55,25466,
+1,22,57,25466,
+25,30,47,25466,
+6,42,44,25466,
+26,36,42,25476,
+6,10,60,25476,
+6,28,54,25476,
+12,26,54,25476,
+30,30,44,25476,
+18,36,46,25476,
+23,38,42,25476,
+12,28,53,25476,
+3,32,52,25476,
+4,11,60,25476,
+0,16,59,25476,
+5,24,56,25476,
+0,4,61,25476,
+29,36,40,25529,
+10,39,46,25529,
+9,34,50,25529,
+8,37,48,25529,
+14,25,54,25529,
+24,35,44,25529,
+2,22,57,25529,
+7,18,58,25529,
+30,34,41,25529,
+6,26,55,25529,
+17,40,43,25529,
+20,23,53,25529,
+1,4,61,25529,
+29,31,44,25529,
+1,16,59,25529,
+11,41,44,25529,
+25,33,45,25529,
+3,3,61,25529,
+7,33,51,25529,
+3,39,47,25529,
+21,33,47,25529,
+7,21,57,25529,
+8,14,59,25529,
+5,40,46,25529,
+2,16,59,25529,
+20,35,46,25529,
+28,29,46,25529,
+11,16,58,25529,
+4,35,50,25529,
+4,19,58,25529,
+20,29,50,25529,
+16,37,46,25529,
+16,26,53,25529,
+19,26,52,25529,
+14,29,52,25529,
+11,22,56,25529,
+2,4,61,25529,
+19,38,44,25529,
+14,39,45,25529,
+6,15,59,25529,
+6,41,45,25529,
+3,22,57,25529,
+21,30,49,25529,
+13,18,57,25529,
+0,12,60,25529,
+16,28,52,25529,
+12,36,48,25529,
+28,32,44,25554,
+4,32,52,25554,
+10,27,54,25554,
+8,9,60,25554,
+1,12,60,25554,
+6,30,53,25554,
+12,24,55,25554,
+27,30,46,25554,
+11,40,45,25554,
+16,33,49,25554,
+35,35,36,25648,
+11,32,51,25648,
+17,39,44,25648,
+3,4,61,25648,
+25,39,40,25648,
+11,12,59,25648,
+4,39,47,25648,
+13,21,56,25648,
+0,5,61,25648,
+19,28,51,25648,
+19,24,53,25648,
+21,37,44,25648,
+24,31,47,25648,
+7,36,49,25648,
+9,23,56,25648,
+3,16,59,25648,
+9,31,52,25648,
+5,11,60,25648,
+11,35,49,25648,
+13,37,47,25648,
+1,5,61,25648,
+29,35,41,25648,
+23,37,43,25648,
+7,43,43,25648,
+19,19,55,25648,
+12,30,52,25648,
+2,12,60,25648,
+34,36,36,25659,
+6,24,56,25659,
+16,24,54,25659,
+0,38,48,25659,
+18,32,49,25659,
+1,38,48,25659,
+18,20,55,25659,
+7,42,44,25659,
+31,32,42,25659,
+4,22,57,25659,
+7,10,60,25659,
+7,28,54,25659,
+22,31,48,25659,
+15,32,50,25659,
+28,38,39,25659,
+17,34,48,25659,
+10,20,57,25659,
+17,18,56,25659,
+2,5,61,25659,
+10,25,55,25659,
+17,31,50,25659,
+5,35,50,25659,
+7,26,55,25659,
+10,29,53,25659,
+25,25,50,25659,
+34,35,37,25685,
+10,13,59,25685,
+5,19,58,25685,
+14,23,55,25685,
+26,35,43,25685,
+25,38,41,25685,
+24,26,50,25685,
+8,18,58,25685,
+2,38,48,25685,
+6,40,46,25685,
+3,12,60,25685,
+14,34,49,25685,
+26,26,49,25685,
+24,24,51,25685,
+10,38,47,25685,
+16,19,56,25685,
+28,37,40,25685,
+4,4,61,25685,
+5,32,52,25685,
+4,16,59,25685,
+10,17,58,25685,
+30,33,42,25685,
+26,31,46,25685,
+15,42,42,25685,
+8,33,51,25685,
+19,33,48,25685,
+0,27,55,25685,
+8,21,57,25685,
+15,35,48,25685,
+9,37,48,25685,
+33,36,37,25718,
+27,33,44,25718,
+12,19,57,25718,
+1,27,55,25718,
+5,39,47,25718,
+7,15,59,25718,
+15,41,43,25718,
+19,37,45,25718,
+25,27,49,25718,
+7,41,45,25718,
+17,21,55,25718,
+3,5,61,25718,
+23,25,51,25718,
+10,34,50,25718,
+22,34,46,25718,
+14,14,58,25718,
+14,38,46,25718,
+34,34,38,25720,
+18,27,52,25720,
+20,21,54,25720,
+6,11,60,25720,
+0,29,54,25720,
+16,30,51,25720,
+3,38,48,25720,
+0,6,61,25720,
+24,34,45,25720,
+0,34,51,25720,
+12,42,43,25720,
+33,35,38,25746,
+5,22,57,25746,
+2,27,55,25746,
+1,29,54,25746,
+17,38,45,25746,
+13,15,58,25746,
+1,34,51,25746,
+1,6,61,25746,
+13,33,50,25746,
+23,27,50,25746,
+18,25,53,25746,
+18,35,47,25746,
+25,37,42,25746,
+9,14,59,25746,
+14,31,51,25746,
+11,39,46,25746,
+7,30,53,25746,
+4,12,60,25746,
+15,20,56,25746,
+8,36,49,25746,
+0,25,56,25746,
+24,28,49,25746,
+7,24,56,25746,
+16,16,57,25746,
+6,19,58,25746,
+12,41,44,25746,
+2,6,61,25746,
+19,22,54,25746,
+15,40,44,25746,
+13,26,54,25746,
+2,29,54,25746,
+28,36,41,25746,
+16,36,47,25746,
+23,36,44,25746,
+19,30,50,25746,
+29,34,42,25746,
+6,35,50,25746,
+22,26,51,25746,
+2,34,51,25746,
+32,37,37,25782,
+4,5,61,25782,
+20,41,41,25782,
+27,27,48,25782,
+5,16,59,25782,
+23,23,52,25782,
+9,9,60,25782,
+20,31,49,25782,
+21,36,45,25782,
+1,25,56,25782,
+13,28,53,25782,
+8,43,43,25782,
+23,32,47,25782,
+15,27,53,25782,
+15,17,57,25782,
+3,27,55,25782,
+8,42,44,25782,
+6,32,52,25782,
+4,38,48,25782,
+12,22,56,25782,
+12,16,58,25782,
+26,28,48,25782,
+22,24,52,25782,
+8,10,60,25782,
+32,36,38,25789,
+0,20,58,25789,
+20,40,42,25789,
+8,28,54,25789,
+1,20,58,25789,
+10,23,56,25789,
+20,34,47,25789,
+10,31,52,25789,
+7,40,46,25789,
+2,25,56,25789,
+8,26,55,25789,
+16,22,55,25789,
+22,40,41,25789,
+25,32,46,25789,
+29,30,45,25789,
+11,27,54,25789,
+3,34,51,25789,
+3,29,54,25789,
+15,25,54,25789,
+3,6,61,25789,
+6,39,47,25789,
+33,34,39,25812,
+18,29,51,25812,
+2,20,58,25812,
+26,34,44,25812,
+22,28,50,25812,
+18,41,42,25812,
+6,22,57,25812,
+22,39,42,25812,
+12,40,45,25812,
+21,32,48,25812,
+18,23,54,25812,
+14,18,57,25812,
+9,18,58,25812,
+12,32,51,25812,
+13,36,48,25812,
+5,12,60,25812,
+0,13,60,25812,
+12,12,59,25812,
+1,13,60,25812,
+25,36,43,25812,
+32,35,39,25856,
+0,7,61,25856,
+4,27,55,25856,
+0,17,59,25856,
+13,24,55,25856,
+25,29,48,25856,
+0,37,49,25856,
+0,31,53,25856,
+8,41,45,25856,
+3,25,56,25856,
+28,31,45,25856,
+15,29,52,25856,
+21,25,52,25856,
+8,15,59,25856,
+11,20,57,25856,
+20,39,43,25856,
+12,35,49,25856,
+7,11,60,25856,
+1,37,49,25856,
+1,31,53,25856,
+11,29,53,25856,
+1,17,59,25856,
+9,21,57,25856,
+31,31,43,25856,
+27,39,39,25856,
+9,33,51,25856,
+11,25,55,25856,
+21,27,51,25856,
+5,5,61,25856,
+23,29,49,25856,
+15,39,45,25856,
+11,13,59,25856,
+1,7,61,25856,
+5,38,48,25856,
+19,36,46,25856,
+8,30,53,25856,
+27,38,40,25856,
+18,40,43,25856,
+10,37,48,25856,
+6,16,59,25856,
+4,29,54,25856,
+13,30,52,25856,
+2,13,60,25856,
+4,34,51,25856,
+28,35,42,25856,
+4,6,61,25856,
+30,32,43,25856,
+3,20,58,25856,
+14,21,56,25856,
+2,7,61,25856,
+7,19,58,25856,
+2,17,59,25856,
+11,38,47,25856,
+2,37,49,25856,
+31,37,38,25878,
+14,37,47,25878,
+7,35,50,25878,
+17,37,46,25878,
+11,17,58,25878,
+17,26,53,25878,
+2,31,53,25878,
+24,40,40,25878,
+8,24,56,25878,
+22,38,43,25878,
+22,22,53,25878,
+10,14,59,25878,
+4,25,56,25878,
+28,28,47,25878,
+7,32,52,25878,
+17,28,52,25878,
+11,34,50,25878,
+31,36,39,25929,
+27,32,45,25929,
+0,23,57,25929,
+33,33,40,25929,
+24,39,41,25929,
+3,13,60,25929,
+9,36,49,25929,
+5,27,55,25929,
+9,43,43,25929,
+21,23,53,25929,
+13,19,57,25929,
+3,37,49,25929,
+17,33,49,25929,
+1,23,57,25929,
+29,33,43,25929,
+3,31,53,25929,
+27,37,41,25929,
+27,29,47,25929,
+23,35,45,25929,
+3,17,59,25929,
+15,23,55,25929,
+3,7,61,25929,
+7,39,47,25929,
+20,38,44,25929,
+4,20,58,25929,
+24,30,48,25929,
+20,26,52,25929,
+6,12,60,25929,
+8,40,46,25929,
+32,34,40,25933,
+16,32,50,25933,
+9,28,54,25933,
+9,42,44,25933,
+12,39,46,25933,
+17,24,54,25933,
+18,39,44,25933,
+9,10,60,25933,
+24,33,46,25933,
+5,6,61,25933,
+5,29,54,25933,
+15,34,49,25933,
+21,29,50,25933,
+21,35,46,25933,
+2,23,57,25933,
+7,22,57,25933,
+5,34,51,25933,
+13,42,43,25933,
+9,26,55,25933,
+22,33,47,25933,
+18,34,48,25933,
+6,38,48,25933,
+24,38,42,25933,
+16,42,42,25933,
+18,18,56,25933,
+16,35,48,25933,
+4,13,60,25933,
+0,43,44,25933,
+18,31,50,25933,
+20,24,53,25933,
+20,28,51,25933,
+22,30,49,25933,
+8,11,60,25933,
+14,15,58,25933,
+26,30,47,25933,
+14,33,50,25933,
+15,38,46,25933,
+0,8,61,25933,
+11,31,52,25933,
+1,8,61,25933,
+25,35,44,25933,
+19,32,49,25933,
+4,31,53,25933,
+13,41,44,25933,
+4,37,49,25933,
+1,43,44,25933,
+4,7,61,25933,
+31,35,40,25987,
+16,41,43,25987,
+5,25,56,25987,
+19,20,55,25987,
+11,23,56,25987,
+7,16,59,25987,
+17,19,56,25987,
+4,17,59,25987,
+9,15,59,25987,
+3,23,57,25987,
+15,31,51,25987,
+9,41,45,25987,
+14,26,54,25987,
+10,18,58,25987,
+30,38,38,25990,
+5,20,58,25990,
+22,37,44,25990,
+0,42,45,25990,
+2,43,44,25990,
+27,36,42,25990,
+12,27,54,25990,
+13,22,56,25990,
+2,8,61,25990,
+13,16,58,25990,
+14,28,53,25990,
+28,34,43,25990,
+8,19,58,25990,
+8,35,50,25990,
+6,27,55,25990,
+30,37,39,26028,
+9,30,53,26028,
+10,21,57,26028,
+26,33,45,26028,
+1,42,45,26028,
+17,30,51,26028,
+10,33,51,26028,
+18,21,55,26028,
+16,40,44,26028,
+8,32,52,26028,
+16,20,56,26028,
+9,24,56,26028,
+12,20,57,26028,
+6,6,61,26028,
+0,33,52,26028,
+6,34,51,26028,
+18,38,45,26028,
+2,42,45,26028,
+7,12,60,26028,
+6,29,54,26028,
+20,33,48,26028,
+17,36,47,26028,
+19,27,52,26028,
+32,33,41,26073,
+13,32,51,26073,
+16,17,57,26073,
+8,39,47,26073,
+23,31,48,26073,
+1,33,52,26073,
+3,8,61,26073,
+12,29,53,26073,
+20,37,45,26073,
+13,40,45,26073,
+11,37,48,26073,
+16,27,53,26073,
+5,13,60,26073,
+3,43,44,26073,
+4,23,57,26073,
+12,25,55,26073,
+24,37,43,26073,
+12,13,59,26073,
+5,37,49,26073,
+25,31,47,26073,
+5,7,61,26073,
+5,31,53,26073,
+19,25,53,26073,
+13,35,49,26073,
+5,17,59,26073,
+19,35,47,26073,
+0,36,50,26073,
+30,36,40,26080,
+14,36,48,26080,
+0,14,60,26080,
+16,25,54,26080,
+7,38,48,26080,
+14,24,55,26080,
+12,38,47,26080,
+1,14,60,26080,
+10,36,49,26080,
+2,33,52,26080,
+0,41,46,26080,
+1,36,50,26080,
+26,39,40,26080,
+9,40,46,26080,
+8,22,57,26080,
+6,25,56,26080,
+30,31,44,26080,
+12,17,58,26080,
+15,18,57,26080,
+31,34,41,26106,
+11,14,59,26106,
+10,43,43,26106,
+1,41,46,26106,
+3,42,45,26106,
+29,29,46,26106,
+21,21,54,26106,
+17,22,55,26106,
+20,30,50,26106,
+20,22,54,26106,
+6,20,58,26106,
+2,14,60,26106,
+10,42,44,26106,
+12,34,50,26106,
+10,28,54,26106,
+28,30,46,26106,
+10,10,60,26106,
+14,30,52,26106,
+2,36,50,26106,
+29,32,44,26106,
+25,26,50,26106,
+4,43,44,26106,
+23,34,46,26106,
+10,26,55,26106,
+26,38,41,26106,
+8,16,59,26106,
+4,8,61,26106,
+2,41,46,26106,
+16,29,52,26106,
+16,39,45,26106,
+15,21,56,26106,
+24,25,51,26106,
+9,11,60,26106,
+3,33,52,26106,
+0,9,61,26106,
+1,9,61,26106,
+15,37,47,26106,
+7,27,55,26106,
+19,29,51,26106,
+27,35,43,26117,
+21,41,41,26117,
+5,23,57,26117,
+21,31,49,26117,
+6,13,60,26117,
+3,14,60,26117,
+4,42,45,26117,
+3,36,50,26117,
+22,36,45,26117,
+0,18,59,26117,
+24,27,50,26117,
+21,40,42,26117,
+0,21,58,26117,
+7,29,54,26117,
+29,38,39,26179,
+9,19,58,26179,
+6,31,53,26179,
+21,34,47,26179,
+27,31,46,26179,
+1,18,59,26179,
+1,21,58,26179,
+2,9,61,26179,
+10,41,45,26179,
+19,41,42,26179,
+30,35,41,26179,
+23,26,51,26179,
+6,37,49,26179,
+10,15,59,26179,
+6,17,59,26179,
+14,19,57,26179,
+25,34,45,26179,
+3,41,46,26179,
+26,27,49,26179,
+6,7,61,26179,
+19,23,54,26179,
+9,35,50,26179,
+7,34,51,26179,
+13,39,46,26179,
+24,36,44,26179,
+8,12,60,26179,
+23,24,52,26179,
+12,23,56,26179,
+2,18,59,26179,
+26,37,42,26179,
+9,32,52,26179,
+14,42,43,26179,
+18,37,46,26179,
+28,33,44,26179,
+24,32,47,26179,
+18,26,53,26179,
+2,21,58,26179,
+11,18,58,26179,
+0,28,55,26179,
+12,31,52,26179,
+4,33,52,26179,
+10,30,53,26179,
+0,40,47,26179,
+23,40,41,26179,
+5,43,44,26179,
+1,40,47,26179,
+16,23,55,26179,
+1,28,55,26179,
+25,28,49,26179,
+19,40,43,26179,
+5,8,61,26179,
+29,37,40,26213,
+7,25,56,26213,
+9,39,47,26213,
+21,39,43,26213,
+11,33,51,26213,
+3,9,61,26213,
+11,21,57,26213,
+22,32,48,26213,
+0,26,56,26213,
+10,24,56,26213,
+8,38,48,26213,
+4,36,50,26213,
+32,32,42,26222,
+20,36,46,26222,
+4,14,60,26222,
+18,28,52,26222,
+22,25,52,26222,
+17,32,50,26222,
+2,28,55,26222,
+16,34,49,26222,
+4,41,46,26222,
+14,41,44,26222,
+1,26,56,26222,
+7,20,58,26222,
+2,40,47,26222,
+23,28,50,26222,
+3,21,58,26222,
+22,27,51,26222,
+6,23,57,26222,
+3,18,59,26222,
+15,15,58,26222,
+18,33,49,26222,
+13,27,54,26222,
+15,33,50,26222,
+9,22,57,26222,
+5,42,45,26222,
+31,33,42,26250,
+23,39,42,26250,
+18,24,54,26250,
+10,40,46,26250,
+16,38,46,26250,
+14,22,56,26250,
+26,32,46,26250,
+14,16,58,26250,
+0,30,54,26250,
+2,26,56,26250,
+35,36,36,26305,
+15,26,54,26305,
+12,37,48,26305,
+27,28,48,26305,
+1,30,54,26305,
+17,42,42,26305,
+9,16,59,26305,
+4,9,61,26305,
+5,33,52,26305,
+15,28,53,26305,
+29,36,41,26305,
+16,31,51,26305,
+17,35,48,26305,
+24,29,49,26305,
+8,27,55,26305,
+3,40,47,26305,
+7,13,60,26305,
+11,36,49,26305,
+13,20,57,26305,
+3,28,55,26305,
+19,39,44,26305,
+7,31,53,26305,
+13,29,53,26305,
+11,43,43,26305,
+35,35,37,26330,
+13,25,55,26330,
+7,37,49,26330,
+13,13,59,26330,
+17,41,43,26330,
+7,7,61,26330,
+7,17,59,26330,
+30,34,42,26330,
+2,30,54,26330,
+21,38,44,26330,
+26,36,43,26330,
+3,26,56,26330,
+4,21,58,26330,
+11,28,54,26330,
+27,34,44,26330,
+5,14,60,26330,
+18,19,56,26330,
+11,42,44,26330,
+19,34,48,26330,
+6,8,61,26330,
+12,14,59,26330,
+4,18,59,26330,
+14,40,45,26330,
+8,29,54,26330,
+21,26,52,26330,
+6,43,44,26330,
+8,34,51,26330,
+10,11,60,26330,
+26,29,48,26330,
+14,32,51,26330,
+0,10,61,26330,
+34,36,37,26343,
+5,36,50,26343,
+13,38,47,26343,
+22,23,53,26343,
+19,31,50,26343,
+1,10,61,26343,
+14,35,49,26343,
+23,38,43,26343,
+5,41,46,26343,
+11,26,55,26343,
+13,17,58,26343,
+0,39,48,26343,
+34,35,38,26382,
+6,42,45,26382,
+20,32,49,26382,
+17,40,44,26382,
+9,12,60,26382,
+4,28,55,26382,
+15,36,48,26382,
+30,30,45,26382,
+20,20,55,26382,
+8,25,56,26382,
+4,40,47,26382,
+22,29,50,26382,
+25,40,40,26382,
+13,34,50,26382,
+0,24,57,26382,
+10,35,50,26382,
+0,15,60,26382,
+2,10,61,26382,
+18,30,51,26382,
+10,19,58,26382,
+22,35,46,26382,
+3,30,54,26382,
+17,20,56,26382,
+0,35,51,26382,
+1,39,48,26382,
+21,24,53,26382,
+1,24,57,26382,
+21,28,51,26382,
+28,39,39,26382,
+15,24,55,26382,
+24,35,45,26382,
+1,15,60,26382,
+33,37,37,26407,
+7,23,57,26407,
+17,27,53,26407,
+11,41,45,26407,
+17,17,57,26407,
+11,15,59,26407,
+25,39,41,26407,
+1,35,51,26407,
+19,21,55,26407,
+29,31,45,26407,
+23,33,47,26407,
+5,9,61,26407,
+10,32,52,26407,
+28,38,40,26407,
+8,20,58,26407,
+4,26,56,26407,
+2,15,60,26407,
+16,18,57,26407,
+25,30,48,26407,
+2,39,48,26407,
+6,33,52,26407,
+9,38,48,26407,
+18,36,47,26407,
+2,24,57,26407,
+33,36,38,26431,
+15,30,52,26431,
+17,25,54,26431,
+29,35,42,26431,
+10,39,47,26431,
+2,35,51,26431,
+5,21,58,26431,
+3,10,61,26431,
+25,33,46,26431,
+5,18,59,26431,
+23,30,49,26431,
+19,38,45,26431,
+11,30,53,26431,
+4,30,54,26431,
+6,14,60,26431,
+12,18,58,26431,
+6,36,50,26431,
+16,21,56,26431,
+0,32,53,26431,
+25,38,42,26431,
+14,39,46,26431,
+28,32,45,26431,
+20,27,52,26431,
+10,22,57,26431,
+11,24,56,26431,
+18,22,55,26431,
+6,41,46,26431,
+8,13,60,26431,
+34,34,39,26448,
+20,25,53,26448,
+5,40,47,26448,
+7,8,61,26448,
+28,29,47,26448,
+21,33,48,26448,
+3,24,57,26448,
+3,15,60,26448,
+5,28,55,26448,
+8,17,59,26448,
+13,31,52,26448,
+16,37,47,26448,
+17,29,52,26448,
+1,32,53,26448,
+7,43,44,26448,
+3,39,48,26448,
+28,37,41,26448,
+12,33,51,26448,
+8,37,49,26448,
+12,21,57,26448,
+20,35,47,26448,
+31,32,43,26448,
+8,31,53,26448,
+23,37,44,26448,
+13,23,56,26448,
+17,39,45,26448,
+15,19,57,26448,
+33,35,39,26484,
+3,35,51,26484,
+9,27,55,26484,
+21,37,45,26484,
+11,40,46,26484,
+4,10,61,26484,
+5,26,56,26484,
+26,35,44,26484,
+32,37,38,26504,
+10,16,59,26504,
+2,32,53,26504,
+6,9,61,26504,
+9,34,51,26504,
+15,42,43,26504,
+30,33,43,26504,
+7,42,45,26504,
+27,30,47,26504,
+9,29,54,26504,
+4,39,48,26504,
+4,15,60,26504,
+4,24,57,26504,
+32,36,39,26533,
+14,27,54,26533,
+6,18,59,26533,
+21,30,50,26533,
+21,22,54,26533,
+12,36,49,26533,
+6,21,58,26533,
+24,31,48,26533,
+5,30,54,26533,
+12,43,43,26533,
+8,23,57,26533,
+0,11,61,26533,
+4,35,51,26533,
+13,37,48,26533,
+20,29,51,26533,
+3,32,53,26533,
+7,33,52,26533,
+0,19,59,26533,
+11,11,60,26533,
+9,25,56,26533,
+15,41,44,26533,
+27,33,45,26533,
+25,37,43,26533,
+1,19,59,26533,
+1,11,61,26533,
+17,23,55,26533,
+12,28,54,26533,
+0,0,62,26533,
+10,12,60,26533,
+28,36,42,26533,
+12,42,44,26533,
+20,41,42,26533,
+33,34,40,26561,
+20,23,54,26561,
+15,22,56,26561,
+9,20,58,26561,
+7,14,60,26561,
+0,1,62,26561,
+15,16,58,26561,
+6,40,47,26561,
+16,33,50,26561,
+7,36,50,26561,
+14,20,57,26561,
+12,26,55,26561,
+6,28,55,26561,
+0,38,49,26561,
+19,26,53,26561,
+22,31,49,26561,
+11,35,50,26561,
+1,1,62,26561,
+19,37,46,26561,
+17,34,49,26561,
+22,41,41,26561,
+11,19,58,26561,
+29,34,43,26561,
+14,29,53,26561,
+2,11,61,26561,
+2,19,59,26561,
+7,41,46,26561,
+1,38,49,26561,
+14,25,55,26561,
+26,31,47,26561,
+13,14,59,26561,
+5,10,61,26561,
+10,38,48,26561,
+6,26,56,26561,
+0,22,58,26561,
+22,40,42,26561,
+16,26,54,26561,
+24,34,46,26561,
+0,2,62,26561,
+18,32,50,26561,
+14,17,58,26561,
+4,32,53,26561,
+2,38,49,26561,
+8,8,61,26561,
+16,28,53,26561,
+8,43,44,26561,
+19,28,52,26561,
+11,32,52,26561,
+32,35,40,26611,
+1,2,62,26611,
+22,34,47,26611,
+1,22,58,26611,
+20,40,43,26611,
+31,38,38,26611,
+17,38,46,26611,
+14,38,47,26611,
+27,39,40,26611,
+15,32,51,26611,
+12,41,45,26611,
+12,15,59,26611,
+9,13,60,26611,
+23,36,45,26611,
+5,24,57,26611,
+15,40,45,26611,
+5,15,60,26611,
+5,39,48,26611,
+3,11,61,26611,
+17,31,51,26611,
+7,9,61,26611,
+9,37,49,26611,
+15,35,49,26611,
+9,17,59,26611,
+19,33,49,26611,
+11,39,47,26611,
+31,37,39,26629,
+5,35,51,26629,
+3,19,59,26629,
+9,31,53,26629,
+25,25,51,26629,
+18,42,42,26629,
+26,26,50,26629,
+6,30,54,26629,
+2,22,58,26629,
+2,2,62,26629,
+14,34,50,26629,
+21,36,46,26629,
+24,26,51,26629,
+18,35,48,26629,
+12,30,53,26629,
+0,3,62,26629,
+8,42,45,26629,
+19,24,54,26629,
+1,3,62,26629,
+7,21,58,26629,
+7,18,59,26629,
+22,39,43,26629,
+3,38,49,26629,
+25,27,50,26629,
+10,27,55,26629,
+27,38,41,26629,
+11,22,57,26629,
+18,41,43,26629,
+24,24,52,26629,
+0,16,60,26629,
+12,24,56,26629,
+16,36,48,26629,
+29,30,46,26629,
+3,22,58,26629,
+8,33,52,26629,
+26,34,45,26629,
+23,32,48,26629,
+31,36,40,26679,
+1,16,60,26679,
+20,39,44,26679,
+13,18,58,26679,
+25,36,44,26679,
+10,29,54,26679,
+24,40,41,26679,
+16,24,55,26679,
+6,10,61,26679,
+10,34,51,26679,
+2,3,62,26679,
+31,31,44,26679,
+5,32,53,26679,
+4,11,61,26679,
+23,25,52,26679,
+25,32,47,26679,
+19,19,56,26679,
+28,35,43,26679,
+4,19,59,26679,
+7,40,47,26679,
+11,16,59,26679,
+7,28,55,26679,
+13,21,57,26679,
+9,23,57,26679,
+27,27,49,26679,
+33,33,41,26700,
+23,27,51,26700,
+13,33,51,26700,
+20,34,48,26700,
+8,14,60,26700,
+18,20,56,26700,
+0,34,52,26700,
+2,16,60,26700,
+16,30,52,26700,
+18,40,44,26700,
+30,32,44,26700,
+12,40,46,26700,
+0,4,62,26700,
+8,36,50,26700,
+24,28,50,26700,
+6,15,60,26700,
+24,39,42,26700,
+14,31,52,26700,
+20,31,50,26700,
+14,23,56,26700,
+10,25,56,26700,
+1,34,52,26700,
+8,41,46,26700,
+28,31,46,26700,
+4,38,49,26700,
+6,39,48,26700,
+32,34,41,26726,
+7,26,56,26726,
+26,28,49,26726,
+1,4,62,26726,
+6,24,57,26726,
+15,39,46,26726,
+18,27,53,26726,
+27,37,42,26726,
+17,18,57,26726,
+3,3,62,26726,
+6,35,51,26726,
+19,30,51,26726,
+2,4,62,26726,
+4,22,58,26726,
+22,26,52,26726,
+22,38,44,26726,
+10,20,58,26726,
+2,34,52,26726,
+0,12,61,26726,
+11,12,60,26726,
+18,25,54,26726,
+3,16,60,26726,
+30,38,39,26750,
+7,30,54,26750,
+0,27,56,26750,
+1,12,61,26750,
+0,29,55,26750,
+1,27,56,26750,
+17,21,56,26750,
+20,21,55,26750,
+9,43,44,26750,
+16,19,57,26750,
+13,36,49,26750,
+21,32,49,26750,
+19,36,47,26750,
+8,9,61,26750,
+29,33,44,26750,
+25,29,49,26750,
+1,29,55,26750,
+5,19,59,26750,
+23,23,53,26750,
+5,11,61,26750,
+31,35,41,26770,
+17,37,47,26770,
+13,43,43,26770,
+3,34,52,26770,
+24,38,43,26770,
+0,37,50,26770,
+13,28,54,26770,
+22,28,51,26770,
+0,5,62,26770,
+10,13,60,26770,
+16,42,43,26770,
+8,18,59,26770,
+13,42,44,26770,
+8,21,58,26770,
+12,35,50,26770,
+2,27,56,26770,
+11,38,48,26770,
+22,24,53,26770,
+30,37,40,26785,
+27,32,46,26785,
+20,38,45,26785,
+3,4,62,26785,
+2,12,61,26785,
+6,32,53,26785,
+12,19,58,26785,
+18,29,52,26785,
+14,37,48,26785,
+10,37,49,26785,
+1,5,62,26785,
+19,22,55,26785,
+5,38,49,26785,
+10,17,59,26785,
+10,31,53,26785,
+13,26,55,26785,
+18,39,45,26785,
+9,42,45,26785,
+15,27,54,26785,
+7,10,61,26785,
+1,37,50,26785,
+23,29,50,26785,
+23,35,46,26785,
+2,29,55,26785,
+0,44,44,26785,
+4,16,60,26785,
+28,28,48,26785,
+12,32,52,26785,
+8,28,55,26785,
+2,37,50,26785,
+14,14,59,26785,
+2,5,62,26785,
+5,22,58,26785,
+1,44,44,26785,
+16,41,44,26785,
+8,40,47,26785,
+0,43,45,26785,
+7,39,48,26785,
+24,33,47,26785,
+12,39,47,26785,
+7,15,60,26785,
+27,36,43,26799,
+0,25,57,26799,
+21,27,52,26799,
+7,24,57,26799,
+27,29,48,26799,
+3,27,56,26799,
+15,20,57,26799,
+9,33,52,26799,
+3,12,61,26799,
+25,35,45,26799,
+21,35,47,26799,
+7,35,51,26799,
+21,25,53,26799,
+1,25,57,26799,
+3,29,55,26799,
+15,29,53,26799,
+13,15,59,26799,
+15,25,55,26799,
+13,41,45,26799,
+11,27,55,26799,
+1,43,45,26799,
+26,40,40,26804,
+8,26,56,26804,
+4,4,62,26804,
+16,22,56,26804,
+16,16,58,26804,
+4,34,52,26804,
+28,34,44,26804,
+2,44,44,26804,
+30,36,41,26841,
+22,33,48,26841,
+9,14,60,26841,
+32,33,42,26841,
+0,31,54,26841,
+24,30,49,26841,
+9,36,50,26841,
+12,22,57,26841,
+18,23,55,26841,
+17,33,50,26841,
+15,38,47,26841,
+2,25,57,26841,
+3,37,50,26841,
+6,19,59,26841,
+1,31,54,26841,
+6,11,61,26841,
+9,41,46,26841,
+13,30,53,26841,
+11,29,54,26841,
+11,34,51,26841,
+2,43,45,26841,
+15,17,58,26841,
+22,37,45,26841,
+3,5,62,26841,
+10,23,57,26841,
+26,39,41,26841,
+0,6,62,26841,
+26,30,48,26841,
+0,42,46,26841,
+8,30,54,26841,
+31,34,42,26862,
+24,37,44,26862,
+4,27,56,26862,
+16,40,45,26862,
+1,42,46,26862,
+0,20,59,26862,
+18,34,49,26862,
+13,24,56,26862,
+2,31,54,26862,
+6,38,49,26862,
+15,34,50,26862,
+1,6,62,26862,
+26,33,46,26862,
+17,26,54,26862,
+12,16,59,26862,
+4,12,61,26862,
+16,32,51,26862,
+3,44,44,26862,
+5,16,60,26862,
+1,20,59,26862,
+16,35,49,26862,
+17,28,53,26862,
+11,25,56,26862,
+7,32,53,26862,
+4,29,55,26862,
+9,9,61,26862,
+3,25,57,26862,
+3,43,45,26862,
+29,39,39,26888,
+21,29,51,26888,
+14,18,58,26888,
+22,22,54,26888,
+22,30,50,26888,
+26,38,42,26888,
+6,22,58,26888,
+2,6,62,26888,
+18,38,46,26888,
+2,42,46,26888,
+11,20,58,26888,
+19,32,50,26888,
+8,10,61,26888,
+20,37,46,26888,
+10,43,44,26888,
+13,40,46,26888,
+4,5,62,26888,
+20,26,53,26888,
+29,38,40,26918,
+2,20,59,26918,
+5,34,52,26918,
+4,37,50,26918,
+21,41,42,26918,
+18,31,51,26918,
+14,21,57,26918,
+9,21,58,26918,
+9,18,59,26918,
+14,33,51,26918,
+3,31,54,26918,
+30,31,45,26918,
+21,23,54,26918,
+4,44,44,26918,
+12,12,60,26918,
+36,36,36,26993,
+20,28,52,26993,
+3,6,62,26993,
+8,15,60,26993,
+10,42,45,26993,
+30,35,42,26993,
+19,42,42,26993,
+0,17,60,26993,
+17,36,48,26993,
+8,24,57,26993,
+3,42,46,26993,
+8,39,48,26993,
+11,13,60,26993,
+5,12,61,26993,
+0,41,47,26993,
+35,36,37,27019,
+9,28,55,27019,
+17,24,55,27019,
+19,35,48,27019,
+3,20,59,27019,
+1,17,60,27019,
+29,32,45,27019,
+15,31,52,27019,
+4,25,57,27019,
+4,43,45,27019,
+20,33,49,27019,
+25,31,48,27019,
+0,13,61,27019,
+8,35,51,27019,
+5,27,56,27019,
+21,40,43,27019,
+15,23,56,27019,
+27,35,44,27019,
+9,40,47,27019,
+5,29,55,27019,
+7,19,59,27019,
+23,41,41,27019,
+29,37,41,27019,
+23,31,49,27019,
+1,13,61,27019,
+19,41,43,27019,
+11,31,53,27019,
+11,17,59,27019,
+7,11,61,27019,
+11,37,49,27019,
+1,41,47,27019,
+29,29,47,27019,
+20,24,54,27019,
+6,16,60,27019,
+12,38,48,27019,
+10,33,52,27019,
+16,39,46,27019,
+2,17,60,27019,
+9,26,56,27019,
+0,7,62,27019,
+4,31,54,27019,
+0,23,58,27019,
+17,30,52,27019,
+14,36,49,27019,
+23,40,42,27019,
+28,30,47,27019,
+13,35,50,27019,
+7,38,49,27019,
+2,13,61,27019,
+35,35,38,27046,
+2,41,47,27046,
+1,23,58,27046,
+1,7,62,27046,
+14,43,43,27046,
+23,34,47,27046,
+34,37,37,27046,
+26,37,43,27046,
+5,5,62,27046,
+13,19,58,27046,
+5,37,50,27046,
+14,42,44,27046,
+10,14,60,27046,
+10,36,50,27046,
+22,36,46,27046,
+14,28,54,27046,
+6,34,52,27046,
+4,42,46,27046,
+4,6,62,27046,
+34,36,38,27063,
+25,34,46,27063,
+2,23,58,27063,
+14,26,55,27063,
+8,32,53,27063,
+13,32,52,27063,
+24,36,45,27063,
+9,30,54,27063,
+10,41,46,27063,
+0,36,51,27063,
+2,7,62,27063,
+19,20,56,27063,
+7,22,58,27063,
+32,32,43,27063,
+4,20,59,27063,
+19,40,44,27063,
+18,18,57,27063,
+5,44,44,27063,
+0,33,53,27063,
+3,17,60,27063,
+21,39,44,27063,
+12,27,55,27063,
+1,36,51,27063,
+15,37,48,27063,
+28,33,45,27063,
+27,31,47,27063,
+19,27,53,27063,
+17,19,57,27063,
+5,43,45,27063,
+23,39,43,27063,
+11,23,57,27063,
+3,41,47,27063,
+5,25,57,27063,
+13,39,47,27063,
+1,33,53,27063,
+31,33,43,27063,
+3,13,61,27063,
+29,36,42,27076,
+2,36,51,27076,
+6,12,61,27076,
+16,27,54,27076,
+6,27,56,27076,
+20,30,51,27076,
+18,21,56,27076,
+12,29,54,27076,
+21,34,48,27076,
+12,34,51,27076,
+34,35,39,27126,
+9,10,61,27126,
+14,15,59,27126,
+19,25,54,27126,
+2,33,53,27126,
+13,22,57,27126,
+33,37,38,27126,
+3,23,58,27126,
+25,26,51,27126,
+6,29,55,27126,
+21,31,50,27126,
+17,42,43,27126,
+18,37,47,27126,
+3,7,62,27126,
+14,41,45,27126,
+5,31,54,27126,
+24,32,48,27126,
+0,40,48,27126,
+1,40,48,27126,
+24,25,52,27126,
+10,18,59,27126,
+28,39,40,27126,
+20,36,47,27126,
+16,20,57,27126,
+10,21,58,27126,
+6,37,50,27126,
+5,6,62,27126,
+30,34,43,27126,
+5,42,46,27126,
+4,17,60,27126,
+7,16,60,27126,
+26,27,50,27126,
+14,30,53,27126,
+12,25,56,27126,
+4,41,47,27126,
+33,36,39,27160,
+8,11,61,27160,
+9,39,48,27160,
+11,43,44,27160,
+9,15,60,27160,
+19,29,52,27160,
+3,36,51,27160,
+16,25,55,27160,
+25,40,41,27160,
+5,20,59,27160,
+4,13,61,27160,
+16,29,53,27160,
+13,16,59,27160,
+9,24,57,27160,
+17,41,44,27160,
+24,27,51,27160,
+8,19,59,27160,
+21,21,55,27160,
+3,33,53,27160,
+9,35,51,27160,
+19,39,45,27160,
+6,44,44,27160,
+14,24,56,27160,
+2,40,48,27160,
+0,8,62,27160,
+26,36,44,27160,
+12,20,58,27160,
+16,38,47,27160,
+8,38,49,27160,
+10,40,47,27160,
+4,7,62,27160,
+10,28,55,27160,
+26,32,47,27160,
+16,17,58,27160,
+4,23,58,27160,
+23,38,44,27160,
+23,26,52,27160,
+17,22,56,27160,
+28,38,41,27160,
+20,22,55,27160,
+25,28,50,27160,
+22,32,49,27160,
+1,8,62,27160,
+7,34,52,27160,
+11,42,45,27160,
+21,38,45,27160,
+6,43,45,27160,
+27,34,45,27160,
+6,25,57,27160,
+25,39,42,27160,
+16,34,50,27160,
+10,26,56,27160,
+2,8,62,27160,
+8,22,58,27160,
+14,40,46,27160,
+34,34,40,27207,
+32,38,38,27207,
+18,33,50,27207,
+15,18,58,27207,
+3,40,48,27207,
+4,36,51,27207,
+6,31,54,27207,
+12,13,60,27207,
+11,33,52,27207,
+17,32,51,27207,
+23,28,51,27207,
+32,37,39,27226,
+33,35,40,27226,
+23,24,53,27226,
+7,12,61,27226,
+27,28,49,27226,
+7,27,56,27226,
+12,37,49,27226,
+4,33,53,27226,
+17,40,45,27226,
+12,17,59,27226,
+5,17,60,27226,
+9,32,53,27226,
+12,31,53,27226,
+5,13,61,27226,
+29,35,43,27226,
+7,29,55,27226,
+15,33,51,27226,
+15,21,57,27226,
+5,41,47,27226,
+17,35,49,27226,
+19,23,55,27226,
+6,6,62,27226,
+10,30,54,27226,
+6,42,46,27226,
+30,30,46,27226,
+18,26,54,27226,
+13,38,48,27226,
+24,35,46,27226,
+6,20,59,27226,
+0,14,61,27226,
+28,37,42,27226,
+11,14,60,27226,
+22,27,52,27226,
+18,28,53,27226,
+24,29,50,27226,
+3,8,62,27226,
+11,36,50,27226,
+22,25,53,27226,
+25,38,43,27226,
+26,29,49,27226,
+29,31,46,27226,
+19,34,49,27226,
+22,35,47,27226,
+11,41,46,27226,
+5,7,62,27226,
+7,37,50,27226,
+1,14,61,27226,
+5,23,58,27226,
+0,28,56,27226,
+32,36,40,27275,
+8,16,60,27275,
+4,40,48,27275,
+16,23,56,27275,
+7,44,44,27275,
+16,31,52,27275,
+2,14,61,27275,
+10,10,61,27275,
+14,19,58,27275,
+31,32,44,27275,
+14,35,50,27275,
+1,28,56,27275,
+19,38,46,27275,
+0,21,59,27275,
+15,36,49,27275,
+23,33,48,27275,
+0,39,49,27275,
+12,23,57,27275,
+5,36,51,27275,
+7,43,45,27275,
+5,33,53,27275,
+13,27,55,27275,
+19,31,51,27275,
+1,21,59,27275,
+9,19,59,27275,
+25,33,47,27275,
+15,43,43,27275,
+7,25,57,27275,
+23,37,45,27275,
+9,11,61,27275,
+1,39,49,27275,
+18,36,48,27275,
+4,8,62,27275,
+28,32,46,27275,
+14,32,52,27275,
+20,32,50,27275,
+8,34,52,27275,
+0,18,60,27275,
+2,28,56,27275,
+15,28,54,27275,
+1,18,60,27275,
+10,39,48,27275,
+0,9,62,27275,
+18,24,55,27275,
+0,30,55,27275,
+0,26,57,27275,
+6,17,60,27275,
+10,15,60,27275,
+30,33,44,27291,
+15,42,44,27291,
+10,24,57,27291,
+1,30,55,27291,
+21,37,46,27291,
+22,29,51,27291,
+11,18,59,27291,
+1,26,57,27291,
+3,14,61,27291,
+31,38,39,27334,
+13,34,51,27334,
+17,39,46,27334,
+13,29,54,27334,
+10,35,51,27334,
+33,34,41,27334,
+21,26,53,27334,
+2,21,59,27334,
+7,31,54,27334,
+9,38,49,27334,
+6,13,61,27334,
+1,9,62,27334,
+26,35,45,27334,
+14,39,47,27334,
+6,41,47,27334,
+25,30,49,27334,
+2,39,49,27334,
+11,21,58,27334,
+15,26,55,27334,
+2,18,60,27334,
+18,30,52,27334,
+20,42,42,27334,
+22,41,42,27334,
+21,28,52,27334,
+8,12,61,27334,
+5,40,48,27334,
+6,23,58,27334,
+8,27,56,27334,
+28,29,48,27334,
+3,28,56,27334,
+9,22,58,27334,
+0,35,52,27334,
+2,26,57,27334,
+27,40,40,27334,
+14,22,57,27334,
+6,7,62,27334,
+2,30,55,27334,
+12,43,44,27334,
+28,36,43,27334,
+20,35,48,27334,
+16,37,48,27334,
+7,42,46,27334,
+23,30,50,27334,
+2,9,62,27334,
+22,23,54,27334,
+32,35,41,27387,
+31,37,40,27387,
+11,28,55,27387,
+8,29,55,27387,
+11,40,47,27387,
+13,25,56,27387,
+1,35,52,27387,
+7,20,59,27387,
+25,37,44,27387,
+20,41,43,27387,
+3,39,49,27387,
+21,33,49,27387,
+3,21,59,27387,
+15,15,59,27387,
+15,41,45,27387,
+27,39,41,27387,
+22,40,43,27387,
+5,8,62,27387,
+3,18,60,27387,
+14,16,59,27387,
+4,14,61,27387,
+2,35,52,27387,
+8,37,50,27387,
+11,26,56,27387,
+27,30,48,27387,
+29,34,44,27387,
+10,32,53,27387,
+21,24,54,27387,
+6,36,51,27387,
+12,42,45,27387,
+13,20,58,27387,
+6,33,53,27387,
+15,30,53,27387,
+3,26,57,27387,
+3,30,55,27387,
+17,27,54,27387,
+18,19,57,27387,
+3,9,62,27387,
+27,33,46,27387,
+4,28,56,27387,
+8,44,44,27387,
+20,20,56,27387,
+20,40,44,27387,
+27,38,42,27406,
+12,33,52,27406,
+15,24,56,27406,
+9,16,60,27406,
+11,30,54,27406,
+18,42,43,27406,
+17,20,57,27406,
+4,39,49,27406,
+31,36,41,27448,
+20,27,53,27448,
+19,21,56,27448,
+8,25,57,27448,
+8,43,45,27448,
+24,31,49,27448,
+3,35,52,27448,
+7,17,60,27448,
+4,21,59,27448,
+24,41,41,27448,
+13,13,60,27448,
+13,31,53,27448,
+17,25,55,27448,
+19,37,47,27448,
+13,37,49,27448,
+17,29,53,27448,
+13,17,59,27448,
+7,41,47,27448,
+7,13,61,27448,
+12,14,60,27448,
+6,40,48,27448,
+4,18,60,27448,
+0,24,58,27448,
+24,40,42,27448,
+0,32,54,27448,
+12,36,50,27448,
+23,36,46,27448,
+4,9,62,27448,
+1,24,58,27448,
+9,34,52,27448,
+26,31,48,27448,
+4,26,57,27448,
+24,34,47,27448,
+12,41,46,27448,
+1,32,54,27448,
+18,41,44,27448,
+20,25,54,27448,
+8,31,54,27448,
+15,40,46,27448,
+4,30,55,27448,
+22,39,44,27448,
+7,7,62,27448,
+30,39,39,27491,
+10,11,61,27491,
+7,23,58,27491,
+17,17,58,27491,
+5,14,61,27491,
+10,19,59,27491,
+33,33,42,27491,
+17,38,47,27491,
+21,30,51,27491,
+30,38,40,27506,
+22,34,48,27506,
+0,38,50,27506,
+0,10,62,27506,
+8,42,46,27506,
+14,38,48,27506,
+32,34,42,27506,
+6,8,62,27506,
+2,24,58,27506,
+16,18,58,27506,
+18,22,56,27506,
+2,32,54,27506,
+17,34,50,27506,
+1,10,62,27506,
+8,20,59,27506,
+5,28,56,27506,
+28,35,44,27506,
+22,31,50,27506,
+10,38,49,27506,
+1,38,50,27506,
+4,35,52,27506,
+20,29,52,27506,
+7,36,51,27506,
+11,24,57,27506,
+25,36,45,27506,
+20,39,45,27506,
+16,21,57,27506,
+16,33,51,27506,
+9,27,56,27506,
+9,12,61,27506,
+21,36,47,27506,
+11,39,48,27506,
+0,15,61,27506,
+11,15,60,27506,
+24,39,43,27506,
+11,35,51,27506,
+27,37,43,27506,
+31,31,45,27506,
+13,23,57,27506,
+1,15,61,27506,
+5,21,59,27506,
+5,39,49,27506,
+9,29,55,27506,
+7,33,53,27506,
+26,34,46,27506,
+2,10,62,27506,
+2,38,50,27506,
+10,22,58,27506,
+3,24,58,27506,
+12,21,58,27506,
+18,40,45,27506,
+3,32,54,27506,
+12,18,59,27506,
+5,18,60,27506,
+30,32,45,27518,
+18,32,51,27518,
+5,9,62,27518,
+15,19,58,27518,
+21,22,55,27518,
+5,30,55,27518,
+5,26,57,27518,
+19,33,50,27518,
+15,35,50,27518,
+30,37,41,27560,
+9,37,50,27560,
+31,35,42,27560,
+2,15,61,27560,
+29,30,47,27560,
+18,35,49,27560,
+14,27,55,27560,
+16,36,49,27560,
+25,32,48,27560,
+9,44,44,27560,
+19,26,54,27560,
+12,28,55,27560,
+3,38,50,27560,
+3,10,62,27560,
+7,40,48,27560,
+12,40,47,27560,
+26,26,51,27560,
+22,38,45,27560,
+14,29,54,27560,
+8,17,60,27560,
+15,32,52,27560,
+14,34,51,27560,
+6,14,61,27560,
+16,43,43,27560,
+23,32,49,27560,
+13,43,44,27560,
+19,28,53,27560,
+8,13,61,27560,
+5,35,52,27560,
+17,23,56,27560,
+20,23,55,27560,
+11,32,53,27560,
+28,31,47,27560,
+8,41,47,27560,
+17,31,52,27560,
+25,25,52,27560,
+29,33,45,27570,
+9,25,57,27570,
+3,15,61,27570,
+15,39,47,27570,
+25,27,51,27570,
+9,43,45,27570,
+6,28,56,27570,
+24,38,44,27570,
+12,26,56,27570,
+4,24,58,27570,
+4,32,54,27570,
+24,26,52,27570,
+16,28,54,27570,
+16,42,44,27570,
+10,16,60,27570,
+26,40,41,27587,
+8,23,58,27587,
+14,25,56,27587,
+20,34,49,27587,
+7,8,62,27587,
+16,26,55,27587,
+27,27,50,27587,
+6,39,49,27587,
+15,22,57,27587,
+13,42,45,27587,
+9,31,54,27587,
+6,21,59,27587,
+20,38,46,27587,
+30,36,42,27644,
+6,18,60,27644,
+26,28,50,27644,
+14,20,58,27644,
+4,38,50,27644,
+4,10,62,27644,
+12,30,54,27644,
+10,34,52,27644,
+8,36,51,27644,
+24,28,51,27644,
+19,36,48,27644,
+6,9,62,27644,
+26,39,42,27644,
+6,26,57,27644,
+6,30,55,27644,
+27,36,44,27644,
+0,19,60,27644,
+0,44,45,27644,
+18,39,46,27644,
+9,42,46,27644,
+36,36,37,27699,
+24,24,53,27699,
+20,31,51,27699,
+1,19,60,27699,
+9,20,59,27699,
+1,44,45,27699,
+32,33,43,27699,
+4,15,61,27699,
+19,24,55,27699,
+16,41,45,27699,
+23,27,52,27699,
+13,33,52,27699,
+29,39,40,27699,
+27,32,47,27699,
+15,16,59,27699,
+8,33,53,27699,
+17,37,48,27699,
+11,11,61,27699,
+23,25,53,27699,
+35,37,37,27724,
+11,19,59,27724,
+23,35,47,27724,
+35,36,38,27735,
+2,19,60,27735,
+0,34,53,27735,
+21,32,50,27735,
+16,30,53,27735,
+13,14,60,27735,
+10,12,61,27735,
+0,11,62,27735,
+13,36,50,27735,
+0,43,46,27735,
+5,24,58,27735,
+0,22,59,27735,
+5,32,54,27735,
+19,30,52,27735,
+10,27,56,27735,
+28,34,45,27735,
+2,44,45,27735,
+6,35,52,27735,
+7,14,61,27735,
+31,34,43,27735,
+13,41,46,27735,
+14,37,49,27735,
+14,31,53,27735,
+25,35,46,27735,
+14,17,59,27735,
+1,11,62,27735,
+11,38,49,27735,
+1,43,46,27735,
+1,34,53,27735,
+29,38,41,27735,
+10,29,55,27735,
+1,22,59,27735,
+25,29,50,27735,
+16,24,56,27735,
+8,40,48,27735,
+5,10,62,27735,
+24,33,48,27735,
+12,39,48,27735,
+21,42,42,27735,
+11,22,58,27735,
+26,38,43,27735,
+10,37,50,27735,
+34,37,38,27751,
+2,22,59,27751,
+12,15,60,27751,
+22,26,53,27751,
+12,24,57,27751,
+7,28,56,27751,
+18,27,54,27751,
+5,38,50,27751,
+22,37,46,27751,
+2,34,53,27751,
+2,43,46,27751,
+0,0,63,27751,
+28,28,49,27751,
+2,11,62,27751,
+12,35,51,27751,
+3,44,45,27751,
+3,19,60,27751,
+9,17,60,27751,
+21,35,48,27751,
+0,1,63,27751,
+0,37,51,27751,
+24,37,45,27751,
+5,15,61,27751,
+7,21,59,27751,
+1,37,51,27751,
+7,39,49,27751,
+23,29,51,27751,
+19,19,57,27751,
+1,1,63,27751,
+9,13,61,27751,
+21,41,43,27751,
+9,41,47,27751,
+35,35,39,27779,
+27,29,49,27779,
+16,40,46,27779,
+8,8,62,27779,
+10,44,44,27779,
+22,28,52,27779,
+15,38,48,27779,
+0,2,63,27779,
+0,42,47,27779,
+7,18,60,27779,
+18,20,57,27779,
+34,36,39,27808,
+1,42,47,27808,
+30,35,43,27808,
+3,11,62,27808,
+1,2,63,27808,
+3,34,53,27808,
+13,18,59,27808,
+23,23,54,27808,
+10,25,57,27808,
+7,26,57,27808,
+14,23,57,27808,
+29,37,42,27808,
+2,37,51,27808,
+7,30,55,27808,
+26,33,47,27808,
+9,23,58,27808,
+10,43,45,27808,
+19,42,43,27808,
+18,25,55,27808,
+3,22,59,27808,
+3,43,46,27808,
+23,41,42,27808,
+7,9,62,27808,
+13,21,58,27808,
+18,29,53,27808,
+22,33,49,27808,
+24,30,50,27808,
+22,24,54,27808,
+6,24,58,27808,
+6,32,54,27808,
+10,31,54,27808,
+18,38,47,27808,
+11,16,60,27808,
+2,42,47,27808,
+12,32,53,27808,
+17,18,58,27808,
+21,40,44,27808,
+0,16,61,27808,
+20,21,56,27808,
+33,38,38,27838,
+0,29,56,27838,
+2,2,63,27838,
+26,30,49,27838,
+4,19,60,27838,
+30,31,46,27838,
+4,44,45,27838,
+13,40,47,27838,
+1,29,56,27838,
+0,3,63,27838,
+13,28,55,27838,
+0,27,57,27838,
+20,37,47,27838,
+1,16,61,27838,
+19,41,44,27838,
+7,35,52,27838,
+23,40,43,27838,
+9,36,51,27838,
+3,37,51,27838,
+15,27,55,27838,
+17,21,57,27838,
+21,27,53,27838,
+33,37,39,27854,
+1,27,57,27854,
+27,35,45,27854,
+9,33,53,27854,
+1,3,63,27854,
+17,33,51,27854,
+18,34,50,27854,
+6,38,50,27854,
+10,42,46,27854,
+6,10,62,27854,
+16,35,50,27854,
+4,22,59,27854,
+4,11,62,27854,
+13,26,56,27854,
+19,22,56,27854,
+4,34,53,27854,
+11,34,52,27854,
+4,43,46,27854,
+26,37,44,27854,
+8,14,61,27854,
+16,19,58,27854,
+2,16,61,27854,
+34,35,40,27875,
+14,43,44,27875,
+2,29,56,27875,
+29,32,46,27875,
+10,20,59,27875,
+21,25,54,27875,
+15,34,51,27875,
+15,29,54,27875,
+6,15,61,27875,
+3,42,47,27875,
+2,27,57,27875,
+2,3,63,27875,
+32,32,44,27875,
+28,40,40,27875,
+8,28,56,27875,
+16,32,52,27875,
+0,4,63,27875,
+14,42,45,27875,
+9,40,48,27875,
+0,41,48,27875,
+22,30,51,27875,
+13,30,54,27875,
+33,36,40,27914,
+8,39,49,27914,
+0,31,55,27914,
+21,29,52,27914,
+11,27,56,27914,
+19,32,51,27914,
+28,39,41,27914,
+29,36,43,27914,
+5,19,60,27914,
+16,39,47,27914,
+11,12,61,27914,
+12,19,59,27914,
+17,36,49,27914,
+1,4,63,27914,
+3,16,61,27914,
+4,37,51,27914,
+29,29,48,27914,
+31,33,44,27914,
+19,40,45,27914,
+8,21,59,27914,
+15,25,56,27914,
+5,44,45,27914,
+1,41,48,27914,
+23,39,44,27914,
+3,29,56,27914,
+3,27,57,27914,
+25,31,49,27914,
+11,29,55,27914,
+1,31,55,27914,
+21,39,45,27914,
+17,43,43,27914,
+25,41,41,27914,
+3,3,63,27914,
+19,35,49,27914,
+24,36,46,27914,
+28,30,48,27914,
+8,18,60,27914,
+0,12,62,27914,
+2,41,48,27914,
+17,28,54,27914,
+23,34,48,27914,
+17,42,44,27914,
+18,23,56,27914,
+1,12,62,27914,
+16,22,57,27914,
+8,30,55,27914,
+28,33,46,27914,
+10,17,60,27914,
+12,38,49,27914,
+2,4,63,27914,
+8,9,62,27914,
+7,32,54,27914,
+4,42,47,27914,
+7,24,58,27914,
+32,38,39,27961,
+8,26,57,27961,
+14,33,52,27961,
+22,36,47,27961,
+20,33,50,27961,
+15,20,58,27961,
+25,40,42,27961,
+0,25,58,27961,
+18,31,52,27961,
+5,34,53,27961,
+5,43,46,27961,
+1,25,58,27961,
+10,41,47,27961,
+11,37,50,27961,
+17,26,55,27961,
+23,31,50,27961,
+2,31,55,27961,
+10,13,61,27961,
+5,11,62,27961,
+25,34,47,27961,
+5,22,59,27961,
+2,12,62,27961,
+12,22,58,27961,
+20,26,54,27961,
+30,34,44,27961,
+28,38,42,27961,
+14,36,50,27961,
+14,14,60,27961,
+32,37,40,27986,
+10,23,58,27986,
+16,16,59,27986,
+8,35,52,27986,
+7,38,50,27986,
+22,22,55,27986,
+4,16,61,27986,
+2,25,58,27986,
+14,41,46,27986,
+20,28,53,27986,
+7,10,62,27986,
+34,34,41,27986,
+4,29,56,27986,
+11,44,44,27986,
+0,5,63,27986,
+3,4,63,27986,
+27,31,48,27986,
+3,41,48,27986,
+4,27,57,27986,
+13,39,48,27986,
+13,15,60,27986,
+13,24,57,27986,
+13,35,51,27986,
+5,37,51,27986,
+33,35,41,28004,
+15,17,59,28004,
+25,39,43,28004,
+21,23,55,28004,
+17,41,45,28004,
+15,31,53,28004,
+1,5,63,28004,
+7,15,61,28004,
+15,37,49,28004,
+11,43,45,28004,
+3,31,55,28004,
+11,25,57,28004,
+6,44,45,28004,
+3,12,62,28004,
+18,37,48,28004,
+10,36,51,28004,
+26,36,45,28004,
+6,19,60,28004,
+9,14,61,28004,
+5,42,47,28004,
+19,39,46,28004,
+23,38,45,28004,
+3,25,58,28004,
+2,5,63,28004,
+10,33,53,28004,
+17,30,53,28004,
+21,34,49,28004,
+11,31,54,28004,
+0,20,60,28004,
+0,36,52,28004,
+12,16,60,28004,
+20,36,48,28004,
+11,42,46,28004,
+24,32,49,28004,
+1,36,52,28004,
+32,36,41,28059,
+14,21,58,28059,
+20,24,55,28059,
+4,41,48,28059,
+0,40,49,28059,
+6,43,46,28059,
+6,34,53,28059,
+14,18,59,28059,
+4,4,63,28059,
+9,28,56,28059,
+21,38,46,28059,
+17,24,56,28059,
+6,11,62,28059,
+27,34,46,28059,
+6,22,59,28059,
+1,20,60,28059,
+28,37,43,28059,
+13,32,53,28059,
+5,16,61,28059,
+5,29,56,28059,
+1,40,49,28059,
+11,20,59,28059,
+29,35,44,28059,
+4,31,55,28059,
+3,5,63,28059,
+31,39,39,28090,
+15,23,57,28090,
+9,21,59,28090,
+9,39,49,28090,
+21,31,51,28090,
+5,27,57,28090,
+26,32,48,28090,
+4,12,62,28090,
+2,20,60,28090,
+12,34,52,28090,
+16,38,48,28090,
+20,30,52,28090,
+8,32,54,28090,
+10,40,48,28090,
+2,36,52,28090,
+8,24,58,28090,
+0,6,63,28090,
+14,28,55,28090,
+9,18,60,28090,
+14,40,47,28090,
+0,33,54,28090,
+17,40,46,28090,
+2,40,49,28090,
+4,25,58,28090,
+25,26,52,28090,
+31,38,40,28101,
+25,38,44,28101,
+9,9,62,28101,
+6,37,51,28101,
+19,27,54,28101,
+9,26,57,28101,
+1,6,63,28101,
+9,30,55,28101,
+1,33,54,28101,
+26,27,51,28101,
+14,26,56,28101,
+22,32,50,28101,
+8,10,62,28101,
+8,38,50,28101,
+6,42,47,28101,
+30,30,47,28101,
+2,33,54,28101,
+3,20,60,28101,
+12,12,61,28101,
+24,27,52,28101,
+12,27,56,28101,
+2,6,63,28101,
+33,34,42,28143,
+3,36,52,28143,
+3,40,49,28143,
+7,19,60,28143,
+0,23,59,28143,
+24,25,53,28143,
+7,44,45,28143,
+5,41,48,28143,
+4,5,63,28143,
+19,20,57,28143,
+31,32,45,28143,
+9,35,52,28143,
+24,35,47,28143,
+12,29,55,28143,
+27,40,41,28143,
+11,17,60,28143,
+15,43,44,28143,
+16,27,55,28143,
+0,17,61,28143,
+25,28,51,28143,
+8,15,61,28143,
+1,23,59,28143,
+5,31,55,28143,
+11,41,47,28143,
+13,19,59,28143,
+29,31,47,28143,
+19,29,53,28143,
+11,13,61,28143,
+31,37,41,28163,
+19,25,55,28163,
+1,17,61,28163,
+22,42,42,28163,
+18,18,58,28163,
+14,30,54,28163,
+0,13,62,28163,
+16,34,51,28163,
+6,16,61,28163,
+5,12,62,28163,
+16,29,54,28163,
+20,42,43,28163,
+22,35,48,28163,
+12,37,50,28163,
+32,35,42,28182,
+6,29,56,28182,
+27,28,50,28182,
+23,26,53,28182,
+5,25,58,28182,
+22,41,43,28182,
+7,43,46,28182,
+2,17,61,28182,
+7,11,62,28182,
+17,19,58,28182,
+7,22,59,28182,
+15,42,45,28182,
+3,33,54,28182,
+18,33,51,28182,
+11,23,58,28182,
+18,21,57,28182,
+30,33,45,28182,
+17,35,50,28182,
+1,13,62,28182,
+13,38,49,28182,
+27,39,42,28182,
+19,38,47,28182,
+2,23,59,28182,
+7,34,53,28182,
+6,27,57,28182,
+3,6,63,28182,
+23,37,46,28182,
+28,36,44,28182,
+4,20,60,28182,
+4,36,52,28182,
+12,44,44,28182,
+19,34,50,28182,
+26,35,46,28182,
+4,40,49,28182,
+13,22,58,28182,
+2,13,62,28182,
+10,14,61,28182,
+16,25,56,28182,
+20,41,44,28182,
+26,29,50,28182,
+23,28,52,28182,
+17,32,52,28182,
+28,32,47,28182,
+12,43,45,28182,
+25,33,48,28182,
+0,7,63,28182,
+11,36,51,28182,
+15,33,52,28182,
+12,25,57,28182,
+24,29,51,28182,
+21,21,56,28182,
+1,7,63,28182,
+23,33,49,28182,
+7,37,51,28182,
+3,17,61,28182,
+5,5,63,28182,
+17,39,47,28182,
+3,23,59,28182,
+21,37,47,28182,
+25,37,45,28182,
+11,33,53,28182,
+20,22,56,28182,
+22,40,44,28182,
+10,28,56,28182,
+16,20,58,28182,
+14,24,57,28182,
+0,39,50,28182,
+4,33,54,28182,
+12,31,54,28182,
+4,6,63,28182,
+9,32,54,28182,
+9,24,58,28182,
+18,36,49,28182,
+14,15,60,28182,
+30,39,40,28253,
+23,24,54,28253,
+31,36,42,28253,
+14,39,48,28253,
+24,41,42,28253,
+15,36,50,28253,
+6,41,48,28253,
+14,35,51,28253,
+22,27,53,28253,
+10,21,59,28253,
+29,34,45,28253,
+15,41,46,28253,
+7,42,47,28253,
+3,13,62,28253,
+1,39,50,28253,
+27,38,43,28253,
+6,31,55,28253,
+2,7,63,28253,
+17,22,57,28253,
+18,43,43,28253,
+10,39,49,28253,
+18,42,44,28253,
+10,18,60,28253,
+6,12,62,28253,
+12,42,46,28253,
+18,28,54,28253,
+6,25,58,28253,
+2,39,50,28253,
+9,10,62,28253,
+20,32,51,28253,
+9,38,50,28253,
+10,26,57,28253,
+8,44,45,28253,
+5,20,60,28253,
+10,30,55,28253,
+8,19,60,28253,
+30,38,41,28288,
+18,26,55,28288,
+5,36,52,28288,
+11,40,48,28288,
+25,30,50,28288,
+22,25,54,28288,
+13,16,60,28288,
+20,40,45,28288,
+24,40,43,28288,
+12,20,59,28288,
+19,31,52,28288,
+4,23,59,28288,
+16,31,53,28288,
+5,40,49,28288,
+4,17,61,28288,
+16,17,59,28288,
+19,23,56,28288,
+7,29,56,28288,
+20,35,49,28288,
+7,16,61,28288,
+28,29,49,28288,
+16,37,49,28288,
+7,27,57,28288,
+33,33,43,28308,
+3,7,63,28308,
+27,33,47,28308,
+9,15,61,28308,
+8,22,59,28308,
+14,32,53,28308,
+8,34,53,28308,
+4,13,62,28308,
+32,34,43,28315,
+8,11,62,28315,
+13,34,52,28315,
+22,29,52,28315,
+10,35,52,28315,
+8,43,46,28315,
+23,30,51,28315,
+5,33,54,28315,
+5,6,63,28315,
+21,33,50,28315,
+27,30,49,28315,
+18,41,45,28315,
+15,21,58,28315,
+3,39,50,28315,
+15,18,59,28315,
+22,39,45,28315,
+18,30,53,28315,
+21,26,54,28315,
+24,39,44,28315,
+12,17,60,28315,
+0,28,57,28315,
+30,37,42,28345,
+0,8,63,28345,
+15,28,55,28345,
+4,7,63,28345,
+1,28,57,28345,
+16,23,57,28345,
+7,41,48,28345,
+23,36,47,28345,
+12,13,61,28345,
+28,35,45,28345,
+1,8,63,28345,
+12,41,47,28345,
+36,37,37,28397,
+15,40,47,28397,
+13,27,56,28397,
+8,37,51,28397,
+21,28,53,28397,
+0,35,53,28397,
+19,37,48,28397,
+27,37,44,28397,
+31,35,43,28397,
+13,29,55,28397,
+5,23,59,28397,
+5,17,61,28397,
+7,31,55,28397,
+1,35,53,28397,
+6,36,52,28397,
+6,20,60,28397,
+36,36,38,28403,
+18,24,56,28403,
+0,30,56,28403,
+24,34,48,28403,
+4,39,50,28403,
+7,12,62,28403,
+8,42,47,28403,
+15,26,56,28403,
+6,40,49,28403,
+20,39,46,28403,
+2,8,63,28403,
+1,30,56,28403,
+25,36,46,28403,
+2,28,57,28403,
+17,38,48,28403,
+12,23,58,28403,
+24,31,50,28403,
+11,14,61,28403,
+13,37,50,28403,
+5,13,62,28403,
+2,35,53,28403,
+31,31,46,28403,
+14,19,59,28403,
+26,41,41,28403,
+26,31,49,28403,
+7,25,58,28403,
+22,23,55,28403,
+35,37,38,28436,
+30,32,46,28436,
+10,32,54,28436,
+26,40,42,28436,
+0,26,58,28436,
+18,40,46,28436,
+10,24,58,28436,
+0,14,62,28436,
+2,30,56,28436,
+8,16,61,28436,
+0,21,60,28436,
+6,6,63,28436,
+13,44,44,28436,
+1,14,62,28436,
+12,36,51,28436,
+16,43,44,28436,
+8,29,56,28436,
+15,30,54,28436,
+1,26,58,28436,
+14,38,49,28436,
+21,36,48,28436,
+26,34,47,28436,
+29,40,40,28436,
+6,33,54,28436,
+11,28,56,28436,
+22,34,49,28436,
+35,36,39,28476,
+9,19,60,28476,
+3,28,57,28476,
+1,21,60,28476,
+8,27,57,28476,
+12,33,53,28476,
+9,44,45,28476,
+3,8,63,28476,
+21,24,55,28476,
+13,25,57,28476,
+11,21,59,28476,
+17,27,55,28476,
+29,39,41,28476,
+11,39,49,28476,
+3,35,53,28476,
+5,7,63,28476,
+13,43,45,28476,
+10,10,62,28476,
+22,38,46,28476,
+34,38,38,28482,
+14,22,58,28482,
+2,26,58,28482,
+2,14,62,28482,
+10,38,50,28482,
+24,38,45,28482,
+16,42,45,28482,
+21,30,52,28482,
+29,30,48,28482,
+30,36,43,28482,
+0,38,51,28482,
+20,27,54,28482,
+3,30,56,28482,
+11,18,60,28482,
+0,18,61,28482,
+2,21,60,28482,
+10,15,61,28482,
+17,34,51,28482,
+1,38,51,28482,
+6,17,61,28482,
+9,22,59,28482,
+9,43,46,28482,
+11,26,57,28482,
+13,31,54,28482,
+5,39,50,28482,
+34,37,39,28500,
+1,18,61,28500,
+17,29,54,28500,
+29,33,46,28500,
+11,30,55,28500,
+26,39,43,28500,
+9,11,62,28500,
+6,23,59,28500,
+9,34,53,28500,
+22,31,51,28500,
+12,40,48,28500,
+18,19,58,28500,
+3,14,62,28500,
+4,8,63,28500,
+28,31,48,28500,
+16,33,52,28500,
+18,35,50,28500,
+2,18,61,28500,
+6,13,62,28500,
+0,32,55,28500,
+20,20,57,28500,
+32,33,44,28500,
+13,42,46,28500,
+3,26,58,28500,
+29,38,42,28500,
+2,38,51,28500,
+8,41,48,28500,
+4,28,57,28500,
+7,36,52,28500,
+7,20,60,28500,
+15,39,48,28500,
+7,40,49,28500,
+15,24,57,28500,
+35,35,40,28555,
+8,31,55,28555,
+1,32,55,28555,
+13,20,59,28555,
+20,29,53,28555,
+0,45,45,28555,
+4,35,53,28555,
+20,25,55,28555,
+11,35,52,28555,
+15,15,60,28555,
+25,32,49,28555,
+27,36,45,28555,
+0,9,63,28555,
+17,25,56,28555,
+3,21,60,28555,
+9,37,51,28555,
+1,9,63,28555,
+19,21,57,28555,
+15,35,51,28555,
+1,45,45,28555,
+19,33,51,28555,
+8,12,62,28555,
+18,32,52,28555,
+0,44,46,28555,
+16,36,50,28555,
+14,16,60,28555,
+4,30,56,28555,
+34,36,40,28561,
+8,25,58,28561,
+1,44,46,28561,
+31,34,44,28561,
+23,32,50,28561,
+17,20,58,28561,
+2,32,55,28561,
+20,38,47,28561,
+16,41,46,28561,
+9,42,47,28561,
+18,39,47,28561,
+2,9,63,28561,
+33,38,39,28598,
+3,18,61,28598,
+2,45,45,28598,
+6,7,63,28598,
+3,38,51,28598,
+21,42,43,28598,
+7,33,54,28598,
+2,44,46,28598,
+26,38,44,28598,
+20,34,50,28598,
+14,34,52,28598,
+4,26,58,28598,
+4,14,62,28598,
+28,34,46,28598,
+26,26,52,28598,
+23,42,42,28598,
+0,24,59,28598,
+27,32,48,28598,
+6,39,50,28598,
+18,22,57,28598,
+4,21,60,28598,
+21,41,44,28598,
+1,24,59,28598,
+19,36,49,28598,
+5,8,63,28598,
+0,43,47,28598,
+5,28,57,28598,
+25,27,52,28598,
+3,32,55,28598,
+15,32,53,28598,
+13,17,60,28598,
+9,29,56,28598,
+23,35,48,28598,
+9,16,61,28598,
+33,37,40,28627,
+17,31,53,28627,
+29,37,43,28627,
+9,27,57,28627,
+25,25,53,28627,
+13,41,47,28627,
+23,41,43,28627,
+3,9,63,28627,
+25,35,47,28627,
+1,43,47,28627,
+3,45,45,28627,
+19,43,43,28627,
+7,17,61,28627,
+7,23,59,28627,
+5,35,53,28627,
+13,13,61,28627,
+17,37,49,28627,
+27,27,51,28627,
+17,17,59,28627,
+21,22,56,28627,
+19,28,54,28627,
+16,21,58,28627,
+16,18,59,28627,
+12,14,61,28627,
+26,28,51,28627,
+2,24,59,28627,
+10,19,60,28627,
+3,44,46,28627,
+24,26,53,28627,
+4,38,51,28627,
+11,24,58,28627,
+5,30,56,28627,
+14,27,56,28627,
+19,42,44,28627,
+30,35,44,28627,
+4,18,61,28627,
+11,32,54,28627,
+24,37,46,28627,
+10,44,45,28627,
+2,43,47,28627,
+13,23,58,28627,
+34,35,41,28660,
+7,13,62,28660,
+14,29,55,28660,
+19,26,55,28660,
+22,37,47,28660,
+24,28,52,28660,
+8,36,52,28660,
+8,20,60,28660,
+12,28,56,28660,
+10,11,62,28660,
+11,38,50,28660,
+20,31,52,28660,
+5,14,62,28660,
+14,37,50,28660,
+10,43,46,28660,
+5,26,58,28660,
+16,40,47,28660,
+28,40,41,28660,
+10,22,59,28660,
+16,28,55,28660,
+20,23,56,28660,
+8,40,49,28660,
+10,34,53,28660,
+23,40,44,28660,
+4,32,55,28660,
+12,21,59,28660,
+32,39,39,28706,
+4,9,63,28706,
+3,24,59,28706,
+33,36,41,28706,
+4,45,45,28706,
+24,33,49,28706,
+5,21,60,28706,
+21,32,51,28706,
+9,41,48,28706,
+12,39,49,28706,
+21,40,45,28706,
+13,36,51,28706,
+11,15,61,28706,
+23,27,53,28706,
+17,23,57,28706,
+13,33,53,28706,
+19,41,45,28706,
+7,7,63,28706,
+15,19,59,28706,
+25,29,51,28706,
+3,43,47,28706,
+21,35,49,28706,
+9,31,55,28706,
+28,28,50,28706,
+4,44,46,28706,
+16,26,56,28706,
+14,44,44,28706,
+32,38,40,28718,
+24,24,54,28718,
+12,18,60,28718,
+0,42,48,28718,
+8,33,54,28718,
+9,12,62,28718,
+1,42,48,28718,
+0,15,62,28718,
+0,10,63,28718,
+12,26,57,28718,
+6,8,63,28718,
+28,39,42,28718,
+12,30,55,28718,
+26,33,48,28718,
+6,28,57,28718,
+25,41,42,28718,
+14,25,57,28718,
+10,37,51,28718,
+9,25,58,28718,
+14,43,45,28718,
+1,10,63,28718,
+7,39,50,28718,
+1,15,62,28718,
+30,31,47,28718,
+27,29,50,28718,
+5,18,61,28718,
+19,30,53,28718,
+6,35,53,28718,
+27,35,46,28718,
+23,25,54,28718,
+15,38,49,28718,
+26,37,45,28718,
+5,38,51,28718,
+2,42,48,28718,
+0,34,54,28718,
+16,30,54,28718,
+18,38,48,28718,
+6,30,56,28718,
+15,22,58,28718,
+13,40,48,28718,
+20,37,48,28718,
+12,35,52,28718,
+10,42,47,28718,
+29,36,44,28738,
+1,34,54,28738,
+19,24,56,28738,
+0,37,52,28738,
+2,15,62,28738,
+2,10,63,28738,
+22,33,50,28738,
+4,24,59,28738,
+14,31,54,28738,
+32,32,45,28738,
+1,37,52,28738,
+29,32,47,28738,
+8,23,59,28738,
+17,43,44,28738,
+32,37,41,28787,
+5,32,55,28787,
+8,17,61,28787,
+23,29,52,28787,
+25,40,43,28787,
+4,43,47,28787,
+5,9,63,28787,
+23,39,45,28787,
+31,33,45,28787,
+5,45,45,28787,
+6,26,58,28787,
+14,42,46,28787,
+2,34,54,28787,
+26,30,50,28787,
+34,34,42,28789,
+6,14,62,28789,
+22,26,54,28789,
+10,16,61,28789,
+14,20,59,28789,
+6,21,60,28789,
+10,29,56,28789,
+3,42,48,28789,
+8,13,62,28789,
+22,28,53,28789,
+2,37,52,28789,
+24,30,51,28789,
+19,40,46,28789,
+5,44,46,28789,
+28,38,43,28789,
+18,27,55,28789,
+10,27,57,28789,
+3,10,63,28789,
+21,39,46,28789,
+3,15,62,28789,
+17,42,45,28789,
+33,35,42,28819,
+3,34,54,28819,
+9,20,60,28819,
+16,24,57,28819,
+9,36,52,28819,
+16,39,48,28819,
+18,34,51,28819,
+18,29,54,28819,
+6,38,51,28819,
+15,16,60,28819,
+24,36,47,28819,
+30,34,45,28819,
+6,18,61,28819,
+7,28,57,28819,
+0,41,49,28819,
+31,39,40,28852,
+5,24,59,28852,
+7,8,63,28852,
+16,35,51,28852,
+11,19,60,28852,
+25,39,44,28852,
+0,19,61,28852,
+11,44,45,28852,
+28,33,47,28852,
+17,33,52,28852,
+3,37,52,28852,
+9,40,49,28852,
+7,35,53,28852,
+1,41,49,28852,
+1,19,61,28852,
+5,43,47,28852,
+23,23,55,28852,
+29,29,49,28852,
+12,24,58,28852,
+4,42,48,28852,
+12,32,54,28852,
+0,22,60,28852,
+22,36,48,28852,
+32,36,42,28861,
+14,17,60,28861,
+25,34,48,28861,
+4,15,62,28861,
+1,22,60,28861,
+15,34,52,28861,
+22,24,55,28861,
+18,25,56,28861,
+8,39,50,28861,
+10,41,48,28861,
+6,32,55,28861,
+4,10,63,28861,
+28,30,49,28861,
+17,36,50,28861,
+7,30,56,28861,
+17,41,46,28861,
+13,14,61,28861,
+10,31,55,28861,
+6,9,63,28861,
+31,38,41,28883,
+19,35,50,28883,
+11,11,62,28883,
+9,33,54,28883,
+25,31,50,28883,
+23,34,49,28883,
+2,19,61,28883,
+2,41,49,28883,
+11,34,53,28883,
+14,41,47,28883,
+21,27,54,28883,
+19,19,58,28883,
+6,45,45,28883,
+11,22,59,28883,
+11,43,46,28883,
+12,38,50,28883,
+18,20,58,28883,
+4,34,54,28883,
+6,44,46,28883,
+10,12,62,28883,
+22,30,52,28883,
+2,22,60,28883,
+26,36,46,28883,
+7,26,58,28883,
+4,37,52,28883,
+23,38,46,28883,
+28,37,44,28883,
+14,23,58,28883,
+7,14,62,28883,
+13,28,56,28883,
+19,32,52,28883,
+16,32,53,28883,
+10,25,58,28883,
+12,15,61,28883,
+20,21,57,28883,
+0,29,57,28883,
+0,11,63,28883,
+20,33,51,28883,
+7,21,60,28883,
+15,27,56,28883,
+23,31,51,28883,
+9,17,61,28883,
+27,41,41,28895,
+1,11,63,28895,
+27,31,49,28895,
+21,25,55,28895,
+9,23,59,28895,
+3,19,61,28895,
+11,37,51,28895,
+15,29,55,28895,
+13,39,49,28895,
+19,39,47,28895,
+1,29,57,28895,
+3,41,49,28895,
+21,29,53,28895,
+29,35,45,28895,
+13,21,59,28895,
+14,36,51,28895,
+13,18,60,28895,
+5,42,48,28895,
+6,24,59,28895,
+27,40,42,28922,
+3,22,60,28922,
+0,27,58,28922,
+13,26,57,28922,
+11,42,47,28922,
+5,10,63,28922,
+33,34,43,28955,
+18,31,53,28955,
+1,27,58,28955,
+17,18,59,28955,
+19,22,57,28955,
+31,37,42,28955,
+18,37,49,28955,
+2,29,57,28955,
+5,15,62,28955,
+25,38,45,28955,
+21,38,47,28955,
+6,43,47,28955,
+14,33,53,28955,
+15,37,50,28955,
+17,21,58,28955,
+27,34,47,28955,
+2,11,63,28955,
+7,38,51,28955,
+9,13,62,28955,
+13,30,55,28955,
+7,18,61,28955,
+0,0,64,28955,
+2,27,58,28955,
+5,34,54,28955,
+22,42,43,28955,
+8,28,57,28955,
+20,36,49,28955,
+0,31,56,28955,
+8,8,63,28955,
+15,44,44,28955,
+21,34,50,28955,
+0,1,64,28955,
+5,37,52,28955,
+8,35,53,28955,
+7,32,55,28955,
+11,29,56,28955,
+11,16,61,28955,
+1,31,56,28955,
+16,19,59,28955,
+4,41,49,28955,
+13,35,52,28955,
+32,35,43,29006,
+17,40,47,29006,
+1,1,64,29006,
+20,43,43,29006,
+4,19,61,29006,
+17,28,55,29006,
+7,9,63,29006,
+11,27,57,29006,
+15,43,45,29006,
+3,11,63,29006,
+15,25,57,29006,
+27,39,43,29006,
+7,45,45,29006,
+3,29,57,29006,
+14,40,48,29006,
+0,16,62,29006,
+10,20,60,29006,
+8,30,56,29006,
+24,32,50,29006,
+0,40,50,29006,
+0,2,64,29006,
+4,22,60,29006,
+20,42,44,29006,
+30,40,40,29010,
+10,36,52,29010,
+20,28,54,29010,
+10,40,49,29010,
+2,31,56,29010,
+16,38,49,29010,
+22,41,44,29010,
+1,2,64,29010,
+20,26,55,29010,
+31,32,46,29010,
+17,26,56,29010,
+26,32,49,29010,
+1,40,50,29010,
+1,16,62,29010,
+7,44,46,29010,
+15,31,54,29010,
+18,23,57,29010,
+9,39,50,29010,
+30,39,41,29052,
+3,27,58,29052,
+2,40,50,29052,
+24,42,42,29052,
+6,42,48,29052,
+16,22,58,29052,
+2,16,62,29052,
+22,22,56,29052,
+30,30,48,29052,
+8,26,58,29052,
+2,2,64,29052,
+8,14,62,29052,
+6,10,63,29052,
+28,36,45,29052,
+24,35,48,29052,
+17,30,54,29052,
+15,42,46,29052,
+12,19,60,29052,
+12,44,45,29052,
+10,33,54,29052,
+6,15,62,29052,
+8,21,60,29052,
+30,33,46,29052,
+0,36,53,29052,
+0,3,64,29052,
+1,36,53,29052,
+29,31,48,29052,
+4,29,57,29052,
+24,41,43,29052,
+3,31,56,29052,
+20,41,45,29052,
+11,41,48,29052,
+15,20,59,29052,
+4,11,63,29052,
+1,3,64,29052,
+7,24,59,29052,
+21,23,56,29052,
+21,31,52,29052,
+31,36,43,29081,
+0,25,59,29081,
+5,41,49,29081,
+7,43,47,29081,
+37,37,37,29124,
+11,31,55,29124,
+5,19,61,29124,
+1,25,59,29124,
+23,37,47,29124,
+30,38,42,29124,
+6,34,54,29124,
+12,22,59,29124,
+13,32,54,29124,
+5,22,60,29124,
+8,18,61,29124,
+3,16,62,29124,
+27,38,44,29124,
+20,30,53,29124,
+36,37,38,29142,
+26,27,52,29142,
+22,32,51,29142,
+3,40,50,29142,
+19,38,48,29142,
+11,12,62,29142,
+2,3,64,29142,
+12,34,53,29142,
+12,43,46,29142,
+4,27,58,29142,
+6,37,52,29142,
+2,36,53,29142,
+22,40,45,29142,
+8,38,51,29142,
+13,24,58,29142,
+18,43,44,29142,
+26,35,47,29142,
+10,23,59,29142,
+2,25,59,29142,
+22,35,49,29142,
+11,25,58,29142,
+25,26,53,29142,
+10,17,61,29142,
+25,37,46,29142,
+16,16,60,29142,
+20,24,56,29142,
+0,4,64,29142,
+28,32,48,29142,
+24,40,44,29142,
+13,38,50,29142,
+0,12,63,29142,
+18,42,45,29142,
+10,13,62,29142,
+25,28,52,29142,
+14,14,61,29142,
+4,31,56,29142,
+1,4,64,29142,
+29,34,46,29142,
+36,36,39,29173,
+35,38,38,29173,
+8,32,55,29173,
+21,37,48,29173,
+15,17,60,29173,
+17,24,57,29173,
+0,33,55,29173,
+27,28,51,29173,
+17,39,48,29173,
+24,27,53,29173,
+33,33,44,29173,
+1,12,63,29173,
+3,3,64,29173,
+9,28,57,29173,
+3,36,53,29173,
+12,37,51,29173,
+8,45,45,29173,
+8,9,63,29173,
+1,33,55,29173,
+35,37,39,29195,
+15,41,47,29195,
+3,25,59,29195,
+19,27,55,29195,
+5,11,63,29195,
+5,29,57,29195,
+25,33,49,29195,
+9,35,53,29195,
+13,15,61,29195,
+17,35,51,29195,
+8,44,46,29195,
+4,40,50,29195,
+20,40,46,29195,
+32,34,44,29195,
+2,4,64,29195,
+16,34,52,29195,
+4,16,62,29195,
+14,28,56,29195,
+12,42,47,29195,
+2,12,63,29195,
+7,42,48,29195,
+9,30,56,29195,
+18,33,52,29195,
+24,25,54,29195,
+26,29,51,29195,
+6,41,49,29195,
+30,37,43,29195,
+23,33,50,29195,
+2,33,55,29195,
+7,10,63,29195,
+19,34,51,29195,
+14,21,59,29195,
+15,23,58,29195,
+5,27,58,29195,
+7,15,62,29195,
+6,19,61,29195,
+14,39,49,29195,
+19,29,54,29195,
+14,18,60,29195,
+18,36,50,29195,
+6,22,60,29195,
+16,27,56,29195,
+11,36,52,29195,
+4,36,53,29195,
+14,30,55,29195,
+35,36,40,29246,
+14,26,57,29246,
+26,41,42,29246,
+12,16,61,29246,
+10,39,50,29246,
+0,5,64,29246,
+18,41,46,29246,
+3,4,64,29246,
+9,26,58,29246,
+9,14,62,29246,
+11,20,60,29246,
+22,39,46,29246,
+12,29,56,29246,
+8,24,59,29246,
+23,26,54,29246,
+0,20,61,29246,
+34,38,39,29246,
+24,29,52,29246,
+7,34,54,29246,
+27,33,48,29246,
+0,39,51,29246,
+31,35,44,29246,
+23,28,53,29246,
+1,5,64,29246,
+12,27,57,29246,
+5,31,56,29246,
+11,40,49,29246,
+24,39,45,29246,
+7,37,52,29246,
+9,21,60,29246,
+1,20,61,29246,
+15,36,51,29246,
+17,32,53,29246,
+3,12,63,29246,
+29,40,41,29246,
+8,43,47,29246,
+4,25,59,29246,
+19,25,56,29246,
+16,29,55,29246,
+15,33,53,29246,
+3,33,55,29246,
+27,37,45,29246,
+1,39,51,29246,
+28,35,46,29246,
+5,40,50,29246,
+2,5,64,29246,
+14,35,52,29246,
+34,37,40,29292,
+28,29,50,29292,
+20,35,50,29292,
+19,20,58,29292,
+26,40,43,29292,
+2,20,61,29292,
+5,16,62,29292,
+16,37,50,29292,
+25,30,51,29292,
+9,18,61,29292,
+6,29,57,29292,
+6,11,63,29292,
+29,39,42,29292,
+9,38,51,29292,
+11,33,54,29292,
+2,39,51,29292,
+16,44,44,29292,
+20,32,52,29292,
+4,4,64,29292,
+12,41,48,29292,
+4,12,63,29292,
+0,23,60,29292,
+23,36,48,29292,
+15,40,48,29292,
+27,30,50,29292,
+18,18,59,29292,
+18,21,58,29292,
+22,27,54,29292,
+6,27,58,29292,
+12,31,55,29292,
+5,36,53,29292,
+3,5,64,29292,
+23,24,55,29292,
+13,19,60,29292,
+20,39,47,29292,
+25,36,47,29292,
+1,23,60,29292,
+3,20,61,29292,
+13,44,45,29292,
+16,25,57,29292,
+16,43,45,29292,
+9,32,55,29292,
+4,33,55,29292,
+5,25,59,29292,
+19,31,53,29292,
+19,37,49,29292,
+33,39,39,29343,
+35,35,41,29343,
+21,33,51,29343,
+11,23,59,29343,
+7,19,61,29343,
+9,45,45,29343,
+7,41,49,29343,
+3,39,51,29343,
+17,19,59,29343,
+21,21,57,29343,
+11,17,61,29343,
+9,9,63,29343,
+31,31,47,29343,
+30,36,44,29343,
+12,12,62,29343,
+0,6,64,29343,
+8,42,48,29343,
+30,32,47,29343,
+10,28,57,29343,
+16,31,54,29343,
+12,25,58,29343,
+33,38,40,29368,
+24,34,49,29368,
+8,15,62,29368,
+0,17,62,29368,
+9,44,46,29368,
+6,31,56,29368,
+2,23,60,29368,
+23,30,52,29368,
+1,6,64,29368,
+18,28,55,29368,
+26,39,44,29368,
+34,36,41,29368,
+7,22,60,29368,
+20,22,57,29368,
+18,40,47,29368,
+8,10,63,29368,
+22,29,53,29368,
+11,13,62,29368,
+17,38,49,29368,
+13,34,53,29368,
+1,17,62,29368,
+13,22,59,29368,
+29,38,43,29368,
+13,43,46,29368,
+10,35,53,29368,
+22,25,55,29368,
+18,26,56,29368,
+6,40,50,29368,
+6,16,62,29368,
+16,42,46,29368,
+14,32,54,29368,
+14,24,58,29368,
+8,34,54,29368,
+24,38,46,29368,
+26,34,48,29368,
+10,30,56,29368,
+2,6,64,29368,
+16,20,59,29368,
+26,31,50,29368,
+22,38,47,29368,
+4,20,61,29368,
+17,22,58,29368,
+2,17,62,29368,
+4,5,64,29368,
+8,37,52,29368,
+9,24,59,29368,
+21,36,49,29368,
+0,13,63,29368,
+24,31,51,29368,
+3,23,60,29368,
+4,39,51,29368,
+5,12,63,29368,
+32,33,45,29384,
+7,11,63,29384,
+5,33,55,29384,
+9,43,47,29384,
+7,29,57,29384,
+21,43,43,29384,
+13,37,51,29384,
+1,13,63,29384,
+33,37,41,29416,
+29,33,47,29416,
+19,23,57,29416,
+10,14,62,29416,
+18,30,54,29416,
+14,38,50,29416,
+10,26,58,29416,
+22,34,50,29416,
+27,36,46,29416,
+21,42,44,29416,
+3,6,64,29416,
+10,21,60,29416,
+6,36,53,29416,
+0,35,54,29416,
+21,28,54,29416,
+0,45,46,29416,
+2,13,63,29416,
+7,27,58,29416,
+1,45,46,29416,
+3,17,62,29416,
+29,30,49,29416,
+23,42,43,29416,
+21,26,55,29416,
+6,25,59,29416,
+1,35,54,29416,
+13,42,47,29416,
+31,34,45,29416,
+14,15,61,29416,
+11,39,50,29416,
+12,20,60,29416,
+12,36,52,29416,
+15,28,56,29416,
+16,17,60,29416,
+10,38,51,29416,
+0,44,47,29416,
+26,38,45,29416,
+0,7,64,29416,
+2,35,54,29416,
+12,40,49,29416,
+10,18,61,29416,
+32,39,40,29474,
+34,35,42,29474,
+4,23,60,29474,
+2,45,46,29474,
+19,43,44,29474,
+7,31,56,29474,
+8,19,61,29474,
+5,20,61,29474,
+1,7,64,29474,
+13,16,61,29474,
+23,41,44,29474,
+13,29,56,29474,
+16,41,47,29474,
+5,5,64,29474,
+28,41,41,29474,
+8,41,49,29474,
+28,31,49,29474,
+29,37,44,29474,
+1,44,47,29474,
+5,39,51,29474,
+13,27,57,29474,
+3,13,63,29474,
+15,39,49,29474,
+15,21,59,29474,
+21,41,45,29474,
+4,6,64,29474,
+8,22,60,29474,
+0,28,58,29474,
+0,38,52,29474,
+20,38,48,29474,
+28,40,42,29474,
+32,38,41,29502,
+4,17,62,29502,
+33,36,42,29502,
+1,38,52,29502,
+2,44,47,29502,
+0,30,57,29502,
+17,34,52,29502,
+9,42,48,29502,
+1,28,58,29502,
+7,40,50,29502,
+6,12,63,29502,
+15,18,60,29502,
+2,7,64,29502,
+7,16,62,29502,
+18,24,57,29502,
+22,31,52,29502,
+10,32,55,29502,
+22,23,56,29502,
+25,32,50,29502,
+18,39,48,29502,
+16,23,58,29502,
+28,34,47,29502,
+12,33,54,29502,
+1,30,57,29502,
+21,30,53,29502,
+15,30,55,29502,
+15,26,57,29502,
+3,35,54,29502,
+9,10,63,29502,
+30,35,45,29502,
+19,42,45,29502,
+9,15,62,29502,
+6,33,55,29502,
+10,45,45,29502,
+18,35,51,29502,
+3,45,46,29502,
+2,28,58,29502,
+2,38,52,29502,
+10,44,46,29502,
+0,43,48,29502,
+25,42,42,29502,
+16,36,51,29502,
+9,34,54,29502,
+21,24,56,29502,
+2,30,57,29502,
+8,29,57,29502,
+17,27,56,29502,
+5,23,60,29502,
+13,41,48,29502,
+12,17,61,29502,
+28,39,43,29516,
+12,23,59,29516,
+16,33,53,29516,
+25,35,48,29516,
+4,13,63,29516,
+27,32,49,29516,
+3,7,64,29516,
+23,40,45,29516,
+9,37,52,29516,
+3,44,47,29516,
+1,43,48,29516,
+19,33,52,29516,
+15,35,52,29516,
+8,11,63,29516,
+20,27,55,29516,
+23,32,51,29516,
+24,37,47,29516,
+11,28,57,29516,
+7,36,53,29516,
+13,31,55,29516,
+17,29,55,29516,
+11,35,53,29516,
+7,25,59,29516,
+25,41,43,29516,
+23,35,49,29516,
+20,29,54,29516,
+8,27,58,29516,
+3,28,58,29516,
+4,45,46,29516,
+6,20,61,29516,
+14,44,45,29516,
+4,35,54,29516,
+32,37,42,29573,
+3,38,52,29573,
+20,34,51,29573,
+10,24,59,29573,
+18,32,53,29573,
+2,43,48,29573,
+0,26,59,29573,
+14,19,60,29573,
+11,30,56,29573,
+21,40,46,29573,
+12,13,62,29573,
+19,36,50,29573,
+22,37,48,29573,
+5,6,64,29573,
+5,17,62,29573,
+3,30,57,29573,
+6,39,51,29573,
+13,25,58,29573,
+17,37,50,29573,
+19,41,46,29573,
+1,26,59,29573,
+10,43,47,29573,
+16,40,48,29573,
+0,8,64,29573,
+0,32,56,29573,
+34,34,43,29615,
+8,31,56,29615,
+17,44,44,29615,
+26,37,46,29615,
+14,43,46,29615,
+11,14,62,29615,
+4,7,64,29615,
+31,40,40,29615,
+14,22,59,29615,
+1,32,56,29615,
+2,26,59,29615,
+4,44,47,29615,
+26,26,53,29615,
+11,26,58,29615,
+1,8,64,29615,
+20,25,56,29615,
+14,34,53,29615,
+25,40,44,29615,
+11,21,60,29615,
+0,21,61,29615,
+3,43,48,29615,
+29,36,45,29615,
+27,27,52,29615,
+7,12,63,29615,
+31,39,41,29640,
+5,13,63,29640,
+25,27,53,29640,
+27,35,47,29640,
+7,33,55,29640,
+9,19,61,29640,
+9,41,49,29640,
+33,35,43,29640,
+17,25,57,29640,
+1,21,61,29640,
+17,43,45,29640,
+2,8,64,29640,
+2,32,56,29640,
+4,28,58,29640,
+8,40,50,29640,
+4,38,52,29640,
+28,38,44,29640,
+26,28,52,29640,
+20,20,58,29640,
+32,32,46,29640,
+8,16,62,29640,
+0,14,63,29640,
+15,24,58,29640,
+30,31,48,29640,
+4,30,57,29640,
+6,23,60,29640,
+9,22,60,29640,
+0,42,49,29640,
+24,33,50,29640,
+15,32,54,29640,
+12,39,50,29640,
+5,45,46,29640,
+14,37,51,29640,
+17,31,54,29640,
+23,39,46,29640,
+21,35,50,29640,
+18,19,59,29640,
+31,33,46,29640,
+26,33,49,29640,
+1,42,49,29640,
+3,26,59,29640,
+19,21,58,29640,
+11,38,51,29640,
+1,14,63,29640,
+25,25,54,29640,
+5,35,54,29640,
+2,21,61,29640,
+11,18,61,29640,
+6,6,64,29640,
+0,18,62,29640,
+10,42,48,29640,
+24,26,54,29640,
+6,17,62,29640,
+18,38,49,29640,
+29,32,48,29640,
+13,20,60,29640,
+1,18,62,29640,
+8,36,53,29640,
+2,14,63,29640,
+21,32,52,29640,
+3,32,56,29640,
+28,28,51,29640,
+32,36,43,29694,
+10,15,62,29694,
+2,42,49,29694,
+14,42,47,29694,
+17,42,46,29694,
+15,38,50,29694,
+13,36,52,29694,
+31,38,42,29694,
+4,43,48,29694,
+10,10,63,29694,
+3,8,64,29694,
+24,28,53,29694,
+19,28,55,29694,
+11,32,55,29694,
+5,44,47,29694,
+20,31,53,29694,
+17,20,59,29694,
+7,20,61,29694,
+5,7,64,29694,
+8,25,59,29694,
+20,37,49,29694,
+25,29,52,29694,
+13,40,49,29694,
+19,40,47,29694,
+25,39,45,29694,
+3,21,61,29694,
+9,29,57,29694,
+9,11,63,29694,
+15,15,61,29694,
+11,45,45,29694,
+27,29,51,29694,
+7,39,51,29694,
+21,39,47,29694,
+2,18,62,29694,
+18,22,58,29694,
+10,34,54,29694,
+30,34,46,29694,
+10,37,52,29694,
+19,26,56,29694,
+5,38,52,29694,
+5,28,58,29694,
+11,44,46,29694,
+4,26,59,29694,
+14,29,56,29694,
+14,16,61,29694,
+23,27,54,29694,
+9,27,58,29694,
+5,30,57,29694,
+13,33,54,29694,
+3,42,49,29694,
+14,27,57,29694,
+27,41,42,29716,
+21,22,57,29716,
+3,14,63,29716,
+22,33,51,29716,
+6,13,63,29716,
+0,24,60,29716,
+4,8,64,29716,
+4,32,56,29716,
+24,36,48,29716,
+16,28,56,29716,
+3,18,62,29716,
+19,30,54,29716,
+6,45,46,29716,
+0,9,64,29716,
+6,35,54,29716,
+26,30,51,29716,
+24,24,55,29716,
+1,24,60,29716,
+8,12,63,29716,
+28,33,48,29716,
+12,28,57,29716,
+8,33,55,29716,
+4,21,61,29716,
+20,23,57,29716,
+7,23,60,29716,
+5,43,48,29716,
+16,39,49,29716,
+9,31,56,29716,
+11,24,59,29716,
+16,21,59,29716,
+27,40,43,29749,
+28,37,45,29749,
+0,37,53,29749,
+1,9,64,29749,
+12,35,53,29749,
+17,17,60,29749,
+13,17,61,29749,
+23,29,53,29749,
+31,37,43,29793,
+11,43,47,29793,
+23,25,55,29793,
+17,41,47,29793,
+1,37,53,29793,
+13,23,59,29793,
+2,24,60,29793,
+24,30,52,29793,
+12,30,56,29793,
+16,18,60,29793,
+30,40,41,29813,
+6,7,64,29813,
+2,9,64,29813,
+33,34,44,29813,
+4,14,63,29813,
+4,42,49,29813,
+9,40,50,29813,
+22,36,49,29813,
+16,26,57,29813,
+9,16,62,29813,
+0,34,55,29813,
+6,44,47,29813,
+16,30,55,29813,
+26,36,47,29813,
+0,41,50,29813,
+14,41,48,29813,
+25,34,49,29813,
+22,43,43,29813,
+23,38,47,29813,
+10,19,61,29813,
+1,41,50,29813,
+14,31,55,29813,
+1,34,55,29813,
+29,35,46,29813,
+37,37,38,29851,
+13,13,62,29851,
+2,37,53,29851,
+5,26,59,29851,
+17,23,58,29851,
+29,29,50,29851,
+10,41,49,29851,
+7,17,62,29851,
+12,14,62,29851,
+6,28,58,29851,
+28,30,50,29851,
+18,34,52,29851,
+22,42,44,29851,
+12,26,58,29851,
+10,22,60,29851,
+4,18,62,29851,
+36,38,38,29872,
+22,28,54,29872,
+6,38,52,29872,
+25,38,46,29872,
+5,8,64,29872,
+12,21,60,29872,
+30,39,42,29872,
+6,30,57,29872,
+14,25,58,29872,
+22,26,55,29872,
+20,43,44,29872,
+16,35,52,29872,
+3,24,60,29872,
+23,34,50,29872,
+2,41,50,29872,
+32,35,44,29872,
+2,34,55,29872,
+5,32,56,29872,
+8,20,61,29872,
+8,39,51,29872,
+27,39,44,29872,
+3,9,64,29872,
+15,44,45,29872,
+19,24,57,29872,
+17,36,51,29872,
+15,19,60,29872,
+19,39,48,29872,
+36,37,39,29903,
+9,36,53,29903,
+7,13,63,29903,
+3,37,53,29903,
+19,35,51,29903,
+17,33,53,29903,
+9,25,59,29903,
+25,31,51,29903,
+5,21,61,29903,
+12,38,51,29903,
+11,42,48,29903,
+27,34,48,29903,
+24,42,43,29903,
+18,27,56,29903,
+20,42,45,29903,
+6,43,48,29903,
+21,38,48,29903,
+12,18,61,29903,
+10,11,63,29903,
+5,14,63,29903,
+15,22,59,29903,
+11,15,62,29903,
+5,42,49,29903,
+7,35,54,29903,
+10,29,57,29903,
+15,43,46,29903,
+35,38,39,29944,
+18,29,55,29944,
+7,45,46,29944,
+13,39,50,29944,
+27,31,50,29944,
+15,34,53,29944,
+3,41,50,29944,
+22,41,45,29944,
+3,34,55,29944,
+36,36,40,29957,
+4,24,60,29957,
+4,9,64,29957,
+5,18,62,29957,
+30,38,43,29957,
+17,40,48,29957,
+12,32,55,29957,
+22,30,53,29957,
+18,37,50,29957,
+20,33,52,29957,
+11,34,54,29957,
+24,41,44,29957,
+8,23,60,29957,
+31,36,44,29957,
+10,27,58,29957,
+6,26,59,29957,
+23,23,56,29957,
+4,37,53,29957,
+11,37,52,29957,
+9,12,63,29957,
+19,32,53,29957,
+12,45,45,29957,
+35,37,40,29983,
+31,32,47,29983,
+7,44,47,29983,
+7,7,64,29983,
+23,31,52,29983,
+0,15,63,29983,
+15,37,51,29983,
+1,15,63,29983,
+21,27,55,29983,
+9,33,55,29983,
+16,24,58,29983,
+28,36,46,29983,
+12,44,46,29983,
+0,10,64,29983,
+6,32,56,29983,
+14,36,52,29983,
+18,44,44,29983,
+20,36,50,29983,
+16,32,54,29983,
+22,24,56,29983,
+6,8,64,29983,
+14,20,60,29983,
+14,40,49,29983,
+4,41,50,29983,
+8,17,62,29983,
+1,10,64,29983,
+7,28,58,29983,
+10,31,56,29983,
+4,34,55,29983,
+20,41,46,29983,
+7,38,52,29983,
+27,38,45,29983,
+21,29,54,29983,
+7,30,57,29983,
+21,34,51,29983,
+18,43,45,29983,
+30,33,47,29983,
+2,15,63,29983,
+18,25,57,29983,
+15,42,47,29983,
+34,39,39,30011,
+6,21,61,30011,
+22,40,46,30011,
+10,40,50,30011,
+26,32,50,30011,
+2,10,64,30011,
+16,38,50,30011,
+10,16,62,30011,
+34,38,40,30025,
+14,33,54,30025,
+12,24,59,30025,
+24,40,45,30025,
+24,32,51,30025,
+6,14,63,30025,
+30,30,49,30025,
+18,31,54,30025,
+5,24,60,30025,
+6,42,49,30025,
+0,40,51,30025,
+12,43,47,30025,
+15,29,56,30025,
+9,20,61,30025,
+15,16,61,30025,
+23,37,48,30025,
+24,35,49,30025,
+7,43,48,30025,
+35,36,41,30060,
+21,25,56,30060,
+1,40,51,30060,
+5,9,64,30060,
+13,28,57,30060,
+8,13,63,30060,
+3,15,63,30060,
+25,37,47,30060,
+11,41,49,30060,
+11,19,61,30060,
+29,41,41,30060,
+15,27,57,30060,
+19,19,59,30060,
+9,39,51,30060,
+5,37,53,30060,
+33,33,45,30060,
+29,31,49,30060,
+13,35,53,30060,
+26,42,42,30060,
+18,42,46,30060,
+6,18,62,30060,
+32,34,45,30060,
+0,29,58,30060,
+20,21,58,30060,
+0,22,61,30060,
+0,19,62,30060,
+2,40,51,30060,
+29,40,42,30060,
+18,20,59,30060,
+26,35,48,30060,
+13,30,56,30060,
+11,22,60,30060,
+3,10,64,30060,
+10,36,53,30060,
+8,45,46,30060,
+8,35,54,30060,
+30,37,44,30060,
+7,26,59,30060,
+14,23,59,30060,
+29,34,47,30060,
+19,38,49,30060,
+1,22,61,30060,
+1,29,58,30060,
+14,17,61,30060,
+5,34,55,30060,
+1,19,62,30060,
+34,37,41,30093,
+5,41,50,30093,
+26,41,43,30093,
+10,25,59,30093,
+20,40,47,30093,
+7,32,56,30093,
+7,8,64,30093,
+13,26,58,30093,
+19,22,58,30093,
+2,19,62,30093,
+20,28,55,30093,
+2,29,58,30093,
+17,28,56,30093,
+2,22,61,30093,
+28,32,49,30093,
+22,35,50,30093,
+8,44,47,30093,
+13,14,62,30093,
+3,40,51,30093,
+0,31,57,30093,
+15,41,48,30093,
+13,21,60,30093,
+4,15,63,30093,
+9,23,60,30093,
+33,39,40,30129,
+0,27,59,30129,
+1,27,59,30129,
+21,37,49,30129,
+11,11,63,30129,
+29,39,43,30129,
+15,31,55,30129,
+7,21,61,30129,
+21,31,53,30129,
+17,39,49,30129,
+11,29,57,30129,
+17,21,59,30129,
+31,35,45,30129,
+1,31,57,30129,
+4,10,64,30129,
+8,28,58,30129,
+20,26,56,30129,
+22,32,52,30129,
+0,36,54,30129,
+26,40,44,30129,
+12,42,48,30129,
+8,38,52,30129,
+6,24,60,30129,
+1,36,54,30129,
+8,30,57,30129,
+17,18,60,30129,
+12,15,62,30129,
+10,12,63,30129,
+6,9,64,30129,
+24,39,46,30129,
+26,27,53,30129,
+3,29,58,30129,
+13,38,51,30129,
+25,33,50,30129,
+35,35,42,30167,
+7,14,63,30167,
+18,41,47,30167,
+3,22,61,30167,
+22,39,47,30167,
+33,38,41,30167,
+11,27,58,30167,
+2,27,59,30167,
+2,31,57,30167,
+17,30,55,30167,
+6,37,53,30167,
+3,19,62,30167,
+10,33,55,30167,
+7,42,49,30167,
+27,37,46,30167,
+9,17,62,30167,
+17,26,57,30167,
+15,25,58,30167,
+13,18,61,30167,
+34,36,42,30187,
+2,36,54,30187,
+20,30,54,30187,
+12,34,54,30187,
+27,28,52,30187,
+4,40,51,30187,
+0,11,64,30187,
+25,26,54,30187,
+18,23,58,30187,
+6,34,55,30187,
+16,19,60,30187,
+8,43,48,30187,
+7,18,62,30187,
+6,41,50,30187,
+14,39,50,30187,
+12,37,52,30187,
+22,22,57,30187,
+16,44,45,30187,
+13,32,55,30187,
+28,35,47,30187,
+25,28,53,30187,
+1,11,64,30187,
+17,35,52,30187,
+11,31,56,30187,
+3,27,59,30187,
+13,45,45,30187,
+27,33,49,30187,
+3,31,57,30187,
+9,13,63,30187,
+23,33,51,30187,
+21,23,57,30187,
+5,15,63,30187,
+10,20,61,30187,
+30,36,45,30197,
+16,34,53,30197,
+24,27,54,30197,
+11,16,62,30197,
+29,38,44,30197,
+19,34,52,30197,
+13,44,46,30197,
+26,29,52,30197,
+11,40,50,30197,
+16,43,46,30197,
+5,10,64,30197,
+18,36,51,30197,
+4,19,62,30197,
+16,22,59,30197,
+2,11,64,30197,
+8,26,59,30197,
+4,29,58,30197,
+3,36,54,30197,
+4,22,61,30197,
+9,45,46,30197,
+9,35,54,30197,
+33,37,42,30236,
+10,39,51,30236,
+26,39,45,30236,
+18,33,53,30236,
+32,40,40,30248,
+8,8,64,30248,
+8,32,56,30248,
+0,33,56,30248,
+20,39,48,30248,
+15,20,60,30248,
+0,39,52,30248,
+7,24,60,30248,
+0,25,60,30248,
+20,24,57,30248,
+15,36,52,30248,
+0,16,63,30248,
+0,0,65,30248,
+25,36,48,30248,
+12,19,61,30248,
+19,27,56,30248,
+23,36,49,30248,
+24,25,55,30248,
+16,37,51,30248,
+7,9,64,30248,
+8,21,61,30248,
+28,29,51,30248,
+1,39,52,30248,
+12,41,49,30248,
+4,31,57,30248,
+32,39,41,30274,
+9,44,47,30274,
+15,40,49,30274,
+3,11,64,30274,
+5,40,51,30274,
+21,43,44,30274,
+1,33,56,30274,
+20,35,51,30274,
+4,27,59,30274,
+24,29,53,30274,
+1,16,63,30274,
+1,25,60,30274,
+13,24,59,30274,
+0,1,65,30274,
+31,31,48,30274,
+11,36,53,30274,
+23,43,43,30274,
+1,1,65,30274,
+13,43,47,30274,
+11,25,59,30274,
+7,37,53,30274,
+19,29,55,30274,
+18,40,48,30274,
+12,22,60,30274,
+30,32,48,30274,
+4,36,54,30274,
+28,41,42,30274,
+9,38,52,30274,
+16,42,47,30274,
+2,25,60,30274,
+17,32,54,30274,
+24,38,47,30274,
+23,42,44,30274,
+10,23,60,30274,
+0,2,65,30274,
+9,28,58,30274,
+8,14,63,30274,
+8,42,49,30274,
+25,30,52,30274,
+2,16,63,30274,
+32,33,46,30274,
+2,33,56,30274,
+2,39,52,30274,
+14,28,57,30274,
+17,24,58,30274,
+23,28,54,30274,
+14,35,53,30274,
+1,2,65,30274,
+5,29,58,30274,
+27,30,51,30274,
+21,42,45,30274,
+6,15,63,30274,
+7,41,50,30274,
+23,26,55,30274,
+15,33,54,30274,
+5,19,62,30274,
+34,35,43,30313,
+7,34,55,30313,
+5,22,61,30313,
+9,30,57,30313,
+19,37,50,30313,
+8,18,62,30313,
+14,30,56,30313,
+24,34,50,30313,
+32,38,42,30330,
+6,10,64,30330,
+0,46,46,30330,
+22,38,48,30330,
+10,17,62,30330,
+28,40,43,30330,
+2,2,65,30330,
+16,29,56,30330,
+31,34,46,30330,
+1,46,46,30330,
+26,34,49,30330,
+19,44,44,30330,
+4,11,64,30330,
+16,16,61,30330,
+17,38,50,30330,
+20,32,53,30330,
+3,39,52,30330,
+33,36,43,30363,
+0,45,47,30363,
+12,29,57,30363,
+21,33,52,30363,
+3,25,60,30363,
+27,36,47,30363,
+29,33,48,30363,
+16,27,57,30363,
+3,16,63,30363,
+0,3,65,30363,
+9,43,48,30363,
+3,33,56,30363,
+11,12,63,30363,
+5,27,59,30363,
+19,43,45,30363,
+5,31,57,30363,
+1,45,47,30363,
+15,17,61,30363,
+19,25,57,30363,
+11,33,55,30363,
+29,37,45,30363,
+1,3,65,30363,
+23,41,45,30363,
+15,23,59,30363,
+2,46,46,30363,
+14,26,58,30363,
+14,14,62,30363,
+26,38,46,30363,
+13,42,48,30363,
+12,27,58,30363,
+6,40,51,30363,
+21,36,50,30363,
+5,36,54,30363,
+14,21,60,30363,
+2,3,65,30363,
+2,45,47,30363,
+21,41,46,30363,
+19,31,54,30363,
+10,13,63,30363,
+9,26,59,30363,
+25,42,43,30363,
+13,15,62,30363,
+22,27,55,30363,
+23,30,53,30363,
+26,31,51,30363,
+0,44,48,30363,
+0,12,64,30363,
+8,24,60,30363,
+14,38,51,30363,
+6,29,58,30363,
+6,22,61,30363,
+19,42,46,30363,
+0,4,65,30363,
+28,39,44,30385,
+10,45,46,30385,
+1,12,64,30385,
+4,33,56,30385,
+29,30,50,30385,
+30,35,46,30385,
+12,31,56,30385,
+23,24,56,30385,
+4,25,60,30385,
+9,32,56,30385,
+22,29,54,30385,
+6,19,62,30385,
+4,39,52,30385,
+16,41,48,30385,
+13,34,54,30385,
+8,9,64,30385,
+3,46,46,30385,
+24,31,52,30385,
+1,44,48,30385,
+10,35,54,30385,
+22,34,51,30385,
+4,16,63,30385,
+14,18,61,30385,
+1,4,65,30385,
+5,11,64,30385,
+16,31,55,30385,
+11,20,61,30385,
+25,41,44,30385,
+13,37,52,30385,
+19,20,59,30385,
+31,40,41,30417,
+8,37,53,30417,
+32,37,43,30417,
+3,45,47,30417,
+3,3,65,30417,
+11,39,51,30417,
+9,21,61,30417,
+7,15,63,30417,
+2,44,48,30417,
+18,28,56,30417,
+0,20,62,30417,
+28,34,48,30417,
+2,12,64,30417,
+12,16,62,30417,
+12,40,50,30417,
+8,41,50,30417,
+16,25,58,30417,
+14,32,55,30417,
+2,4,65,30417,
+22,25,56,30417,
+7,10,64,30417,
+28,31,50,30417,
+23,40,46,30417,
+10,44,47,30417,
+8,34,55,30417,
+20,38,49,30417,
+1,20,62,30417,
+14,45,45,30417,
+21,21,58,30417,
+9,14,63,30417,
+15,39,50,30417,
+18,21,59,30417,
+18,39,49,30417,
+31,39,42,30450,
+9,42,49,30450,
+6,27,59,30450,
+6,31,57,30450,
+34,34,44,30468,
+2,20,62,30468,
+20,22,58,30468,
+10,38,52,30468,
+4,46,46,30468,
+18,18,60,30468,
+6,36,54,30468,
+14,44,46,30468,
+10,28,58,30468,
+3,12,64,30468,
+18,30,55,30468,
+3,44,48,30468,
+24,37,48,30468,
+12,36,53,30468,
+10,30,57,30468,
+18,26,57,30468,
+9,18,62,30468,
+21,40,47,30468,
+21,28,55,30468,
+0,43,49,30468,
+17,19,60,30468,
+0,35,55,30468,
+12,25,59,30468,
+33,35,44,30508,
+7,40,51,30508,
+5,39,52,30508,
+4,45,47,30508,
+25,40,45,30508,
+11,23,60,30508,
+5,25,60,30508,
+25,32,51,30508,
+5,33,56,30508,
+17,44,45,30508,
+0,23,61,30508,
+3,4,65,30508,
+0,5,65,30508,
+5,16,63,30508,
+1,5,65,30508,
+1,35,55,30508,
+1,23,61,30508,
+13,41,49,30508,
+13,19,61,30508,
+1,43,49,30508,
+25,35,49,30508,
+19,41,47,30508,
+28,38,45,30508,
+27,32,50,30508,
+10,43,48,30508,
+6,11,64,30508,
+14,24,59,30508,
+13,22,60,30508,
+29,36,46,30508,
+21,26,56,30508,
+3,20,62,30508,
+18,35,52,30508,
+0,38,53,30508,
+2,43,49,30508,
+23,35,50,30508,
+1,38,53,30508,
+14,43,47,30508,
+2,35,55,30508,
+19,23,58,30508,
+26,37,47,30508,
+7,29,58,30508,
+22,37,49,30508,
+7,19,62,30508,
+17,34,53,30508,
+2,23,61,30508,
+11,17,62,30508,
+17,22,59,30508,
+17,43,46,30508,
+31,38,43,30533,
+2,5,65,30533,
+22,31,53,30533,
+7,22,61,30533,
+16,20,60,30533,
+4,12,64,30533,
+32,36,44,30554,
+4,44,48,30554,
+16,36,52,30554,
+21,30,54,30554,
+9,24,60,30554,
+37,38,38,30600,
+27,42,42,30600,
+23,32,52,30600,
+12,12,63,30600,
+5,46,46,30600,
+16,40,49,30600,
+10,26,59,30600,
+2,38,53,30600,
+4,4,65,30600,
+32,32,47,30600,
+12,33,55,30600,
+15,28,57,30600,
+27,35,48,30600,
+9,9,64,30600,
+8,15,63,30600,
+19,36,51,30600,
+0,17,63,30600,
+27,41,43,30600,
+7,31,57,30600,
+31,33,47,30600,
+17,37,51,30600,
+5,45,47,30600,
+3,43,49,30600,
+7,27,59,30600,
+19,33,53,30600,
+37,37,39,30616,
+3,5,65,30616,
+11,13,63,30616,
+23,39,47,30616,
+3,35,55,30616,
+15,35,53,30616,
+9,37,53,30616,
+3,23,61,30616,
+13,29,57,30616,
+1,17,63,30616,
+8,10,64,30616,
+10,32,56,30616,
+4,20,62,30616,
+20,34,52,30616,
+0,6,65,30616,
+6,25,60,30616,
+36,38,39,30648,
+16,33,54,30648,
+6,39,52,30648,
+15,30,56,30648,
+6,33,56,30648,
+6,16,63,30648,
+7,36,54,30648,
+17,42,47,30648,
+30,31,49,30648,
+30,41,41,30648,
+3,38,53,30648,
+10,21,61,30648,
+13,27,58,30648,
+22,23,57,30648,
+9,34,55,30648,
+1,6,65,30648,
+11,45,46,30648,
+9,41,50,30648,
+2,17,63,30648,
+25,39,46,30648,
+11,35,54,30648,
+18,24,58,30648,
+30,40,42,30648,
+18,32,54,30648,
+14,42,48,30648,
+0,42,50,30648,
+0,30,58,30648,
+30,34,47,30648,
+27,40,44,30648,
+2,6,65,30648,
+10,14,63,30648,
+1,42,50,30648,
+19,40,48,30648,
+8,40,51,30648,
+0,28,59,30648,
+0,13,64,30648,
+14,15,62,30648,
+5,12,64,30648,
+15,26,58,30648,
+36,37,40,30676,
+26,33,50,30676,
+5,44,48,30676,
+10,42,49,30676,
+12,20,61,30676,
+1,30,58,30676,
+20,27,56,30676,
+29,32,49,30676,
+4,23,61,30676,
+4,35,55,30676,
+17,29,56,30676,
+12,39,51,30676,
+11,44,47,30676,
+16,17,61,30676,
+24,33,51,30676,
+1,13,64,30676,
+21,39,48,30676,
+21,24,57,30676,
+7,11,64,30676,
+15,21,60,30676,
+4,5,65,30676,
+16,23,59,30676,
+20,29,55,30676,
+4,43,49,30676,
+13,31,56,30676,
+1,28,59,30676,
+31,37,44,30676,
+27,27,53,30676,
+21,35,51,30676,
+35,39,39,30708,
+17,27,57,30708,
+3,17,63,30708,
+26,26,54,30708,
+18,38,50,30708,
+2,42,50,30708,
+2,30,58,30708,
+6,46,46,30708,
+10,18,62,30708,
+14,34,54,30708,
+4,38,53,30708,
+22,43,44,30708,
+13,16,62,30708,
+8,19,62,30708,
+11,38,52,30708,
+5,20,62,30708,
+20,37,50,30708,
+11,28,58,30708,
+8,22,61,30708,
+35,38,40,30723,
+2,28,59,30723,
+14,37,52,30723,
+8,29,58,30723,
+28,37,46,30723,
+2,13,64,30723,
+26,28,53,30723,
+13,40,50,30723,
+6,45,47,30723,
+30,39,43,30723,
+15,38,51,30723,
+3,6,65,30723,
+11,30,57,30723,
+33,34,45,30723,
+25,27,54,30723,
+15,18,61,30723,
+28,28,52,30723,
+20,44,44,30723,
+22,42,45,30723,
+36,36,41,30751,
+0,32,57,30751,
+3,30,58,30751,
+12,23,60,30751,
+3,42,50,30751,
+24,36,49,30751,
+13,36,53,30751,
+17,41,48,30751,
+27,29,52,30751,
+3,13,64,30751,
+11,43,48,30751,
+28,33,49,30751,
+3,28,59,30751,
+7,33,56,30751,
+8,27,59,30751,
+7,25,60,30751,
+24,43,43,30751,
+7,39,52,30751,
+7,16,63,30751,
+32,35,45,30751,
+0,7,65,30751,
+1,32,57,30751,
+8,31,57,30751,
+21,32,53,30751,
+4,17,63,30751,
+20,25,57,30751,
+20,43,45,30751,
+15,32,55,30751,
+15,45,45,30751,
+5,23,61,30751,
+9,15,63,30751,
+27,39,45,30751,
+5,5,65,30751,
+17,31,55,30751,
+5,35,55,30751,
+35,37,41,30772,
+5,43,49,30772,
+25,25,55,30772,
+29,35,47,30772,
+13,25,59,30772,
+1,7,65,30772,
+25,29,53,30772,
+6,12,64,30772,
+8,36,54,30772,
+6,44,48,30772,
+26,36,48,30772,
+10,24,60,30772,
+24,28,54,30772,
+0,26,60,30772,
+24,42,44,30772,
+24,26,55,30772,
+20,31,54,30772,
+9,10,64,30772,
+22,33,52,30772,
+16,39,50,30772,
+15,44,46,30772,
+2,32,57,30772,
+4,6,65,30772,
+34,39,40,30786,
+12,17,62,30786,
+23,38,48,30786,
+1,26,60,30786,
+17,25,58,30786,
+11,26,59,30786,
+25,38,47,30786,
+14,19,61,30786,
+5,38,53,30786,
+2,7,65,30786,
+14,41,49,30786,
+10,37,53,30786,
+14,22,60,30786,
+4,30,58,30786,
+2,26,60,30786,
+30,38,44,30786,
+22,36,50,30786,
+4,42,50,30786,
+20,42,46,30786,
+26,30,52,30786,
+6,20,62,30786,
+25,34,50,30786,
+10,41,50,30786,
+10,34,55,30786,
+22,41,46,30786,
+20,20,59,30786,
+11,32,56,30786,
+4,28,59,30786,
+8,11,64,30786,
+19,28,56,30786,
+34,38,41,30831,
+4,13,64,30831,
+7,46,46,30831,
+3,32,57,30831,
+12,13,63,30831,
+0,41,51,30831,
+31,36,45,30831,
+24,41,45,30831,
+15,24,59,30831,
+9,40,51,30831,
+19,21,59,30831,
+13,33,55,30831,
+1,41,51,30831,
+23,27,55,30831,
+19,39,49,30831,
+11,21,61,30831,
+7,45,47,30831,
+3,7,65,30831,
+15,43,47,30831,
+5,17,63,30831,
+29,29,51,30831,
+35,36,42,30874,
+28,30,51,30874,
+18,44,45,30874,
+0,37,54,30874,
+3,26,60,30874,
+18,19,60,30874,
+24,30,53,30874,
+12,45,46,30874,
+0,21,62,30874,
+12,35,54,30874,
+9,19,62,30874,
+23,34,51,30874,
+2,41,51,30874,
+21,38,49,30874,
+9,22,61,30874,
+19,26,57,30874,
+6,35,55,30874,
+11,42,49,30874,
+1,37,54,30874,
+19,30,55,30874,
+6,23,61,30874,
+23,29,54,30874,
+5,6,65,30874,
+6,43,49,30874,
+11,14,63,30874,
+14,29,57,30874,
+27,34,49,30874,
+29,41,42,30874,
+9,29,58,30874,
+1,21,62,30874,
+24,24,56,30874,
+8,39,52,30874,
+26,42,43,30874,
+5,30,58,30874,
+34,37,42,30894,
+8,16,63,30894,
+16,28,57,30894,
+14,27,58,30894,
+6,38,53,30894,
+12,44,47,30894,
+5,42,50,30894,
+17,20,60,30894,
+8,33,56,30894,
+21,22,58,30894,
+31,32,48,30894,
+8,25,60,30894,
+7,12,64,30894,
+2,37,54,30894,
+2,21,62,30894,
+18,43,46,30894,
+4,32,57,30894,
+18,22,59,30894,
+33,40,40,30894,
+17,36,52,30894,
+11,18,62,30894,
+7,44,48,30894,
+28,36,47,30894,
+0,8,65,30894,
+18,34,53,30894,
+27,38,46,30894,
+17,40,49,30894,
+25,31,52,30894,
+29,40,43,30894,
+19,35,52,30894,
+20,41,47,30894,
+16,35,53,30894,
+5,13,64,30894,
+13,20,61,30894,
+1,8,65,30894,
+5,28,59,30894,
+4,7,65,30894,
+23,25,56,30894,
+9,31,57,30894,
+33,39,41,30920,
+27,31,51,30920,
+9,27,59,30920,
+13,39,51,30920,
+3,41,51,30920,
+16,30,56,30920,
+0,34,56,30920,
+12,28,58,30920,
+24,40,46,30920,
+4,26,60,30920,
+0,14,64,30920,
+12,38,52,30920,
+0,18,63,30920,
+15,42,48,30920,
+2,8,65,30920,
+22,40,47,30920,
+1,34,56,30920,
+9,36,54,30920,
+12,30,57,30920,
+30,33,48,30920,
+1,14,64,30920,
+20,23,58,30920,
+7,20,62,30920,
+22,28,55,30920,
+14,31,56,30920,
+26,41,44,30920,
+18,37,51,30920,
+1,18,63,30920,
+33,33,46,30920,
+3,21,62,30920,
+15,15,62,30920,
+17,33,54,30920,
+3,37,54,30920,
+6,17,63,30920,
+30,37,45,30920,
+10,15,63,30920,
+14,40,50,30920,
+22,26,56,30920,
+10,10,64,30920,
+16,26,58,30920,
+32,34,46,30926,
+2,14,64,30926,
+8,46,46,30926,
+2,34,56,30926,
+14,16,62,30926,
+6,6,65,30926,
+0,24,61,30926,
+18,42,47,30926,
+16,21,60,30926,
+12,43,48,30926,
+20,36,51,30926,
+33,38,42,30980,
+11,24,60,30980,
+15,34,54,30980,
+2,18,63,30980,
+29,39,44,30980,
+15,37,52,30980,
+20,33,53,30980,
+25,37,48,30980,
+4,41,51,30980,
+9,11,64,30980,
+1,24,61,30980,
+5,32,57,30980,
+3,8,65,30980,
+13,23,60,30980,
+8,45,47,30980,
+17,23,59,30980,
+7,43,49,30980,
+23,31,53,30980,
+35,35,43,31000,
+7,23,61,31000,
+7,35,55,31000,
+17,17,61,31000,
+11,37,53,31000,
+23,37,49,31000,
+5,7,65,31000,
+6,30,58,31000,
+30,30,50,31000,
+6,42,50,31000,
+22,30,54,31000,
+26,40,45,31000,
+34,36,43,31010,
+24,35,50,31010,
+19,32,54,31010,
+19,24,58,31010,
+16,18,61,31010,
+2,24,61,31010,
+29,34,48,31010,
+3,14,64,31010,
+16,38,51,31010,
+6,28,59,31010,
+4,21,62,31010,
+18,29,56,31010,
+14,36,53,31010,
+5,26,60,31010,
+6,13,64,31010,
+4,37,54,31010,
+12,26,59,31010,
+26,32,51,31010,
+21,34,52,31010,
+3,34,56,31010,
+10,40,51,31010,
+7,38,53,31010,
+14,25,59,31010,
+29,31,50,31010,
+11,34,55,31010,
+13,17,62,31010,
+31,35,46,31010,
+11,41,50,31010,
+3,18,63,31010,
+18,27,57,31010,
+26,35,49,31010,
+0,40,52,31010,
+8,44,48,31010,
+12,32,56,31010,
+8,12,64,31010,
+24,32,52,31010,
+20,40,48,31010,
+1,40,52,31010,
+10,29,58,31010,
+19,38,50,31010,
+10,19,62,31010,
+4,8,65,31010,
+32,40,41,31054,
+10,22,61,31054,
+16,32,55,31054,
+9,39,52,31054,
+21,27,56,31054,
+16,45,45,31054,
+9,25,60,31054,
+0,9,65,31054,
+9,33,56,31054,
+9,16,63,31054,
+12,21,61,31054,
+24,39,47,31054,
+3,24,61,31054,
+13,13,63,31054,
+23,23,57,31054,
+15,19,61,31054,
+15,41,49,31054,
+7,17,63,31054,
+5,41,51,31054,
+1,9,65,31054,
+21,29,55,31054,
+27,37,47,31054,
+33,37,43,31082,
+28,32,50,31082,
+16,44,46,31082,
+4,14,64,31082,
+2,40,52,31082,
+8,20,62,31082,
+4,34,56,31082,
+6,32,57,31082,
+12,14,63,31082,
+15,22,60,31082,
+18,41,48,31082,
+22,24,57,31082,
+4,18,63,31082,
+22,39,48,31082,
+12,42,49,31082,
+32,39,42,31102,
+5,37,54,31102,
+18,31,55,31102,
+17,39,50,31102,
+10,27,59,31102,
+14,33,55,31102,
+6,7,65,31102,
+21,37,50,31102,
+13,45,46,31102,
+5,21,62,31102,
+2,9,65,31102,
+13,35,54,31102,
+10,31,57,31102,
+22,35,51,31102,
+29,38,45,31102,
+28,42,42,31102,
+10,36,54,31102,
+12,18,62,31102,
+30,36,46,31102,
+6,26,60,31102,
+7,30,58,31102,
+26,39,46,31102,
+7,42,50,31102,
+3,40,52,31102,
+18,25,58,31102,
+21,44,44,31102,
+9,46,46,31102,
+4,24,61,31102,
+16,24,59,31102,
+28,35,48,31102,
+23,43,44,31102,
+5,8,65,31102,
+13,44,47,31102,
+28,41,43,31112,
+16,43,47,31112,
+8,35,55,31112,
+8,43,49,31112,
+8,23,61,31112,
+7,28,59,31112,
+7,13,64,31112,
+21,43,45,31112,
+9,45,47,31112,
+21,25,57,31112,
+11,15,63,31112,
+3,9,65,31112,
+15,29,57,31112,
+25,33,51,31112,
+22,32,53,31112,
+10,11,64,31112,
+5,34,56,31112,
+5,14,64,31112,
+8,38,53,31112,
+13,28,58,31112,
+14,20,61,31112,
+13,38,52,31112,
+32,38,43,31188,
+34,35,44,31188,
+13,30,57,31188,
+23,42,45,31188,
+15,27,58,31188,
+21,31,54,31188,
+27,33,50,31188,
+6,41,51,31188,
+14,39,51,31188,
+5,18,63,31188,
+4,40,52,31188,
+12,24,60,31188,
+28,40,44,31188,
+20,28,56,31188,
+33,36,44,31211,
+6,37,54,31211,
+21,42,46,31211,
+6,21,62,31211,
+9,44,48,31211,
+9,12,64,31211,
+0,15,64,31211,
+26,27,54,31211,
+0,36,55,31211,
+19,44,45,31211,
+12,37,53,31211,
+1,15,64,31211,
+27,28,53,31211,
+20,39,49,31211,
+0,29,59,31211,
+4,9,65,31211,
+8,17,63,31211,
+25,36,49,31211,
+13,43,48,31211,
+15,31,56,31211,
+19,19,60,31211,
+17,28,57,31211,
+32,33,47,31211,
+20,21,59,31211,
+11,40,51,31211,
+7,32,57,31211,
+1,36,55,31211,
+23,33,52,31211,
+5,24,61,31211,
+7,7,65,31211,
+31,41,41,31235,
+31,31,49,31235,
+25,43,43,31235,
+1,29,59,31235,
+17,35,53,31235,
+16,42,48,31235,
+18,20,60,31235,
+18,36,52,31235,
+24,38,48,31235,
+12,41,50,31235,
+30,32,49,31235,
+2,15,64,31235,
+10,25,60,31235,
+9,20,62,31235,
+31,40,42,31248,
+2,36,55,31248,
+6,8,65,31248,
+25,42,44,31248,
+20,30,55,31248,
+18,40,49,31248,
+10,16,63,31248,
+0,31,58,31248,
+7,26,60,31248,
+0,10,65,31248,
+0,46,47,31248,
+12,34,55,31248,
+17,30,56,31248,
+14,23,60,31248,
+20,26,57,31248,
+23,36,50,31248,
+10,39,52,31248,
+25,28,54,31248,
+15,40,50,31248,
+10,33,56,31248,
+15,16,62,31248,
+23,41,46,31248,
+2,29,59,31248,
+31,34,47,31248,
+29,37,46,31248,
+19,43,46,31248,
+1,31,58,31248,
+11,29,58,31248,
+11,19,62,31248,
+26,29,53,31248,
+19,22,59,31248,
+19,34,53,31248,
+25,26,55,31248,
+1,10,65,31248,
+1,46,47,31248,
+11,22,61,31248,
+13,26,59,31248,
+16,34,54,31248,
+6,14,64,31248,
+6,34,56,31248,
+0,22,62,31248,
+8,30,58,31248,
+8,42,50,31248,
+1,22,62,31248,
+16,37,52,31248,
+2,46,47,31248,
+14,17,62,31248,
+28,29,52,31248,
+27,36,48,31248,
+18,33,54,31248,
+2,31,58,31248,
+5,40,52,31248,
+13,32,56,31248,
+0,45,48,31248,
+22,38,49,31248,
+8,13,64,31248,
+8,28,59,31248,
+32,37,44,31282,
+17,26,58,31282,
+26,38,47,31282,
+20,35,52,31282,
+6,18,63,31282,
+0,27,60,31282,
+2,10,65,31282,
+17,21,60,31282,
+1,27,60,31282,
+15,36,53,31282,
+1,45,48,31282,
+24,27,55,31282,
+0,19,63,31282,
+28,39,45,31282,
+3,36,55,31282,
+3,15,64,31282,
+0,39,53,31282,
+1,19,63,31282,
+5,9,65,31282,
+31,39,43,31304,
+11,31,57,31304,
+9,35,55,31304,
+9,43,49,31304,
+3,29,59,31304,
+25,41,45,31304,
+29,33,49,31304,
+19,37,51,31304,
+21,41,47,31304,
+15,25,59,31304,
+7,41,51,31304,
+13,21,61,31304,
+1,39,53,31304,
+11,27,59,31304,
+9,23,61,31304,
+22,22,58,31304,
+26,34,50,31304,
+2,22,62,31304,
+10,46,46,31304,
+38,38,38,31328,
+24,34,51,31328,
+11,36,54,31328,
+6,24,61,31328,
+27,30,52,31328,
+2,27,60,31328,
+24,29,54,31328,
+2,45,48,31328,
+25,30,53,31328,
+2,19,63,31328,
+13,42,49,31328,
+19,42,47,31328,
+7,37,54,31328,
+30,35,47,31328,
+3,10,65,31328,
+9,38,53,31328,
+37,38,39,31360,
+18,23,59,31360,
+17,18,61,31360,
+10,45,47,31360,
+3,46,47,31360,
+7,21,62,31360,
+17,38,51,31360,
+13,14,63,31360,
+2,39,53,31360,
+21,23,58,31360,
+3,31,58,31360,
+4,36,55,31360,
+0,44,49,31360,
+3,22,62,31360,
+13,18,62,31360,
+24,25,56,31360,
+14,35,54,31360,
+14,45,46,31360,
+4,15,64,31360,
+34,34,45,31360,
+8,32,57,31360,
+3,27,60,31360,
+4,29,59,31360,
+1,44,49,31360,
+12,15,63,31360,
+0,33,57,31360,
+23,28,55,31360,
+11,11,64,31360,
+36,39,39,31412,
+37,37,40,31412,
+16,41,49,31412,
+16,19,61,31412,
+19,29,56,31412,
+7,8,65,31412,
+23,40,47,31412,
+21,36,51,31412,
+17,32,55,31412,
+3,45,48,31412,
+21,33,53,31412,
+33,35,45,31412,
+17,45,45,31412,
+15,33,55,31412,
+3,19,63,31412,
+1,33,57,31412,
+3,39,53,31412,
+9,17,63,31412,
+19,27,57,31412,
+20,32,54,31412,
+10,44,48,31412,
+8,26,60,31412,
+6,40,52,31412,
+16,22,60,31412,
+36,38,40,31419,
+10,12,64,31419,
+20,24,58,31419,
+17,44,46,31419,
+4,46,47,31419,
+4,10,65,31419,
+7,14,64,31419,
+28,34,49,31419,
+14,44,47,31419,
+7,34,56,31419,
+4,31,58,31419,
+31,38,44,31419,
+25,40,46,31419,
+2,44,49,31419,
+23,26,56,31419,
+26,31,52,31419,
+2,33,57,31419,
+7,18,63,31419,
+29,30,51,31419,
+6,9,65,31419,
+27,42,43,31419,
+4,22,62,31419,
+20,38,50,31419,
+14,38,52,31419,
+22,34,52,31419,
+14,28,58,31419,
+10,20,62,31419,
+28,38,46,31419,
+4,45,48,31419,
+12,40,51,31419,
+32,36,45,31437,
+21,40,48,31437,
+14,30,57,31437,
+9,42,50,31437,
+4,27,60,31437,
+23,30,54,31437,
+30,41,42,31437,
+9,30,58,31437,
+18,39,50,31437,
+13,24,60,31437,
+0,25,61,31437,
+15,20,61,31437,
+29,36,47,31437,
+0,11,65,31437,
+19,41,48,31437,
+11,39,52,31437,
+4,19,63,31437,
+11,16,63,31437,
+5,36,55,31437,
+11,33,56,31437,
+24,37,49,31437,
+7,24,61,31437,
+28,31,51,31437,
+17,24,59,31437,
+3,44,49,31437,
+24,31,53,31437,
+27,41,44,31437,
+8,41,51,31437,
+4,39,53,31437,
+9,13,64,31437,
+35,39,40,31498,
+36,37,41,31498,
+5,15,64,31498,
+16,29,57,31498,
+9,28,59,31498,
+11,25,60,31498,
+3,33,57,31498,
+13,37,53,31498,
+1,11,65,31498,
+19,31,55,31498,
+1,25,61,31498,
+15,39,51,31498,
+17,43,47,31498,
+5,29,59,31498,
+8,21,62,31498,
+0,43,50,31498,
+12,29,58,31498,
+8,37,54,31498,
+12,19,62,31498,
+30,40,43,31498,
+16,27,58,31498,
+22,27,56,31498,
+14,43,48,31498,
+26,37,48,31498,
+12,22,61,31498,
+10,43,49,31498,
+25,35,50,31498,
+13,41,50,31498,
+2,11,65,31498,
+5,10,65,31498,
+5,31,58,31498,
+35,38,41,31525,
+2,25,61,31525,
+13,34,55,31525,
+10,35,55,31525,
+10,23,61,31525,
+22,29,55,31525,
+19,25,58,31525,
+5,46,47,31525,
+1,43,50,31525,
+32,32,48,31525,
+0,16,64,31525,
+4,44,49,31525,
+1,16,64,31525,
+2,43,50,31525,
+25,32,52,31525,
+22,37,50,31525,
+16,31,56,31525,
+7,40,52,31525,
+8,8,65,31525,
+5,22,62,31525,
+10,38,53,31525,
+14,26,59,31525,
+11,46,46,31525,
+4,33,57,31525,
+31,33,48,31525,
+12,27,59,31525,
+27,32,51,31525,
+12,31,57,31525,
+23,39,48,31525,
+5,45,48,31525,
+5,27,60,31525,
+27,40,45,31525,
+23,24,57,31525,
+9,32,57,31525,
+15,23,60,31525,
+5,19,63,31525,
+3,11,65,31525,
+7,9,65,31525,
+31,37,45,31534,
+3,25,61,31534,
+27,35,49,31534,
+23,35,51,31534,
+11,45,47,31534,
+5,39,53,31534,
+25,39,47,31534,
+16,16,62,31534,
+8,14,64,31534,
+0,0,66,31534,
+34,40,40,31581,
+36,36,42,31581,
+14,32,56,31581,
+12,36,54,31581,
+22,44,44,31581,
+8,34,56,31581,
+16,40,50,31581,
+2,16,64,31581,
+0,1,66,31581,
+17,42,48,31581,
+8,18,63,31581,
+6,15,64,31581,
+6,36,55,31581,
+30,39,44,31581,
+9,26,60,31581,
+18,28,57,31581,
+18,35,53,31581,
+22,43,45,31581,
+6,29,59,31581,
+1,1,66,31581,
+3,43,50,31581,
+34,39,41,31620,
+14,21,61,31620,
+10,17,63,31620,
+22,25,57,31620,
+15,17,62,31620,
+35,37,42,31620,
+30,34,48,31620,
+0,38,54,31620,
+18,30,56,31620,
+0,2,66,31620,
+6,10,65,31620,
+14,42,49,31620,
+33,34,46,31620,
+6,31,58,31620,
+22,31,54,31620,
+20,44,45,31620,
+24,43,44,31620,
+3,16,64,31620,
+19,36,52,31620,
+8,24,61,31620,
+14,14,63,31620,
+11,12,64,31620,
+30,31,50,31620,
+11,44,48,31620,
+0,35,56,31620,
+1,38,54,31620,
+6,46,47,31620,
+1,2,66,31620,
+17,34,54,31620,
+19,20,60,31620,
+21,28,56,31620,
+16,36,53,31620,
+5,44,49,31620,
+16,25,59,31620,
+4,25,61,31620,
+19,40,49,31620,
+4,11,65,31620,
+17,37,52,31620,
+1,35,56,31620,
+23,32,53,31620,
+28,37,47,31620,
+13,15,63,31620,
+21,39,49,31620,
+21,21,59,31620,
+9,41,51,31620,
+5,33,57,31620,
+2,38,54,31620,
+34,38,42,31664,
+10,42,50,31664,
+18,26,58,31664,
+14,18,62,31664,
+6,22,62,31664,
+22,42,46,31664,
+2,2,66,31664,
+10,30,58,31664,
+18,21,60,31664,
+29,32,50,31664,
+10,13,64,31664,
+0,42,51,31664,
+11,20,62,31664,
+32,35,46,31664,
+6,27,60,31664,
+20,22,59,31664,
+20,43,46,31664,
+24,42,45,31664,
+10,28,59,31664,
+0,3,66,31664,
+6,45,48,31664,
+20,34,53,31664,
+2,35,56,31664,
+4,43,50,31664,
+21,26,57,31664,
+15,45,46,31664,
+19,33,54,31664,
+1,3,66,31664,
+21,30,55,31664,
+9,21,62,31664,
+1,42,51,31664,
+26,33,51,31664,
+27,39,46,31664,
+15,35,54,31664,
+6,19,63,31664,
+9,37,54,31664,
+6,39,53,31664,
+4,16,64,31664,
+8,40,52,31664,
+12,16,63,31664,
+18,18,61,31664,
+3,38,54,31664,
+24,33,52,31664,
+0,12,65,31664,
+29,42,42,31678,
+12,39,52,31678,
+30,38,45,31678,
+2,3,66,31678,
+0,20,63,31678,
+12,25,60,31678,
+2,42,51,31678,
+18,38,51,31678,
+12,33,56,31678,
+8,9,65,31678,
+1,12,65,31678,
+1,20,63,31678,
+7,36,55,31678,
+16,33,55,31678,
+33,40,41,31733,
+7,15,64,31733,
+35,36,43,31733,
+20,37,51,31733,
+13,40,51,31733,
+29,35,48,31733,
+21,35,52,31733,
+15,44,47,31733,
+3,35,56,31733,
+11,23,61,31733,
+17,19,61,31733,
+11,43,49,31733,
+5,25,61,31733,
+5,11,65,31733,
+19,23,59,31733,
+7,29,59,31733,
+29,41,43,31733,
+17,41,49,31733,
+11,35,55,31733,
+0,4,66,31733,
+14,24,60,31733,
+24,36,50,31733,
+10,32,57,31733,
+0,23,62,31733,
+15,28,58,31733,
+15,38,52,31733,
+25,38,48,31733,
+18,32,55,31733,
+2,20,63,31733,
+20,42,47,31733,
+9,34,56,31733,
+9,14,64,31733,
+1,4,66,31733,
+31,36,46,31733,
+6,44,49,31733,
+2,12,65,31733,
+24,41,46,31733,
+28,33,50,31733,
+26,36,49,31733,
+17,22,60,31733,
+3,42,51,31733,
+5,43,50,31733,
+7,46,47,31733,
+1,23,62,31733,
+11,38,53,31733,
+7,31,58,31733,
+18,45,45,31733,
+3,3,66,31733,
+9,18,63,31733,
+22,41,47,31733,
+13,22,61,31733,
+7,10,65,31733,
+23,38,49,31733,
+27,27,54,31733,
+6,33,57,31733,
+33,39,42,31768,
+13,29,58,31768,
+15,30,57,31768,
+26,43,43,31768,
+13,19,62,31768,
+14,37,53,31768,
+34,37,43,31768,
+2,4,66,31768,
+4,38,54,31768,
+18,44,46,31768,
+10,26,60,31768,
+26,42,44,31768,
+26,28,54,31768,
+12,46,46,31768,
+28,28,53,31768,
+26,26,55,31768,
+4,35,56,31768,
+14,41,50,31768,
+2,23,62,31768,
+29,40,44,31768,
+22,23,58,31768,
+5,16,64,31768,
+20,29,56,31768,
+16,20,61,31768,
+7,22,62,31768,
+14,34,55,31768,
+12,45,47,31768,
+3,12,65,31768,
+7,27,60,31768,
+3,20,63,31768,
+20,27,57,31768,
+7,45,48,31768,
+9,24,61,31768,
+16,39,51,31768,
+15,43,48,31768,
+7,39,53,31768,
+27,29,53,31768,
+13,27,59,31768,
+17,29,57,31768,
+7,19,63,31768,
+11,17,63,31768,
+25,27,55,31768,
+13,31,57,31768,
+22,36,51,31768,
+21,32,54,31768,
+13,36,54,31768,
+3,4,66,31768,
+0,30,59,31768,
+0,5,66,31768,
+21,24,58,31768,
+18,24,59,31768,
+4,42,51,31768,
+33,38,43,31838,
+18,43,47,31838,
+26,41,45,31838,
+19,39,50,31838,
+17,27,58,31838,
+25,34,51,31838,
+22,33,53,31838,
+27,38,47,31838,
+1,30,59,31838,
+25,29,54,31838,
+6,11,65,31838,
+10,41,51,31838,
+15,26,59,31838,
+1,5,66,31838,
+3,23,62,31838,
+6,25,61,31838,
+12,12,64,31838,
+12,44,48,31838,
+0,28,60,31838,
+28,36,48,31838,
+2,5,66,31838,
+24,40,47,31838,
+10,21,62,31838,
+8,15,64,31838,
+16,23,60,31838,
+8,36,55,31838,
+11,42,50,31838,
+9,40,52,31838,
+26,30,53,31838,
+15,32,56,31838,
+21,38,50,31838,
+20,41,48,31838,
+1,28,60,31838,
+11,30,58,31838,
+4,20,63,31838,
+5,38,54,31838,
+6,43,50,31838,
+10,37,54,31838,
+0,41,52,31838,
+0,17,64,31838,
+30,37,46,31838,
+2,30,59,31838,
+24,28,55,31838,
+27,34,50,31838,
+4,12,65,31838,
+35,35,44,31886,
+7,44,49,31886,
+25,25,56,31886,
+20,31,55,31886,
+31,32,49,31886,
+1,17,64,31886,
+5,35,56,31886,
+11,13,64,31886,
+17,31,56,31886,
+29,29,52,31886,
+1,41,52,31886,
+32,41,41,31886,
+8,29,59,31886,
+11,28,59,31886,
+29,39,45,31886,
+15,21,61,31886,
+9,9,65,31886,
+33,33,47,31886,
+7,33,57,31886,
+22,40,48,31886,
+12,20,62,31886,
+34,36,44,31896,
+2,28,60,31896,
+4,4,66,31896,
+32,40,42,31896,
+6,16,64,31896,
+28,30,52,31896,
+24,26,56,31896,
+0,32,58,31896,
+8,10,65,31896,
+16,17,62,31896,
+8,46,47,31896,
+2,17,64,31896,
+1,32,58,31896,
+20,25,58,31896,
+17,40,50,31896,
+4,23,62,31896,
+32,34,47,31896,
+8,31,58,31896,
+2,41,52,31896,
+23,34,52,31896,
+3,30,59,31896,
+14,15,63,31896,
+3,5,66,31896,
+30,33,49,31896,
+5,42,51,31896,
+15,42,49,31896,
+24,30,54,31896,
+0,6,66,31896,
+8,22,62,31896,
+26,40,46,31896,
+18,42,48,31896,
+10,34,56,31896,
+2,32,58,31896,
+10,14,64,31896,
+8,45,48,31896,
+15,18,62,31896,
+10,18,63,31896,
+8,27,60,31896,
+3,28,60,31896,
+1,6,66,31896,
+8,39,53,31896,
+5,20,63,31896,
+13,33,56,31896,
+12,23,61,31896,
+0,13,65,31896,
+13,25,60,31896,
+0,37,55,31896,
+3,41,52,31896,
+27,31,52,31896,
+12,43,49,31896,
+23,27,56,31896,
+8,19,63,31896,
+32,39,43,31957,
+13,39,52,31957,
+19,28,57,31957,
+12,35,55,31957,
+3,17,64,31957,
+5,12,65,31957,
+17,36,53,31957,
+13,16,63,31957,
+11,32,57,31957,
+33,37,44,31957,
+19,35,53,31957,
+1,37,55,31957,
+17,25,59,31957,
+7,25,61,31957,
+25,31,53,31957,
+31,35,47,31957,
+1,13,65,31957,
+25,37,49,31957,
+23,29,55,31957,
+7,11,65,31957,
+6,38,54,31957,
+2,6,66,31957,
+18,34,54,31957,
+16,35,54,31957,
+14,40,51,31957,
+6,35,56,31957,
+4,5,66,31957,
+0,26,61,31957,
+12,38,53,31957,
+4,30,59,31957,
+18,37,52,31957,
+16,45,46,31957,
+19,30,56,31957,
+28,42,43,31957,
+3,32,58,31957,
+10,24,61,31957,
+11,26,60,31957,
+23,37,50,31957,
+1,26,61,31957,
+29,34,49,31957,
+7,43,50,31957,
+2,13,65,31957,
+2,37,55,31957,
+5,23,62,31957,
+20,20,60,31957,
+4,28,60,31957,
+20,36,52,31957,
+4,17,64,31957,
+26,35,50,31957,
+30,30,51,31957,
+6,42,51,31957,
+24,24,57,31957,
+19,26,58,31957,
+8,44,49,31957,
+29,38,46,31972,
+13,46,46,31972,
+4,41,52,31972,
+16,44,47,31972,
+15,24,60,31972,
+23,44,44,31972,
+7,16,64,31972,
+3,6,66,31972,
+14,19,62,31972,
+14,29,58,31972,
+2,26,61,31972,
+28,41,44,31972,
+14,22,61,31972,
+24,39,48,31972,
+20,40,49,31972,
+8,33,57,31972,
+12,17,63,31972,
+21,44,45,31972,
+9,36,55,31972,
+27,37,48,31972,
+24,35,51,31972,
+9,15,64,31972,
+19,21,60,31972,
+3,37,55,31972,
+13,45,47,31972,
+17,33,55,31972,
+3,13,65,31972,
+15,37,53,31972,
+23,25,57,31972,
+11,41,51,31972,
+23,43,45,31972,
+29,31,51,31972,
+9,29,59,31972,
+26,32,52,31972,
+10,40,52,31972,
+16,28,58,31972,
+32,38,44,32030,
+16,38,52,32030,
+22,28,56,32030,
+4,32,58,32030,
+0,34,57,32030,
+20,33,54,32030,
+16,30,57,32030,
+6,20,63,32030,
+6,12,65,32030,
+30,36,47,32030,
+0,7,66,32030,
+3,26,61,32030,
+19,38,51,32030,
+18,41,49,32030,
+21,43,46,32030,
+11,37,54,32030,
+5,30,59,32030,
+11,21,62,32030,
+15,34,55,32030,
+1,34,57,32030,
+14,27,59,32030,
+21,34,53,32030,
+9,46,47,32030,
+1,7,66,32030,
+14,31,57,32030,
+31,41,42,32055,
+9,10,65,32055,
+22,39,49,32055,
+5,5,66,32055,
+34,35,45,32055,
+26,39,47,32055,
+9,31,58,32055,
+23,31,54,32055,
+21,22,59,32055,
+15,41,50,32055,
+18,19,61,32055,
+12,42,50,32055,
+4,6,66,32055,
+18,22,60,32055,
+14,36,54,32055,
+12,30,58,32055,
+23,42,46,32055,
+9,22,62,32055,
+13,44,48,32055,
+16,43,48,32055,
+12,28,59,32055,
+22,30,55,32055,
+24,32,53,32055,
+22,26,57,32055,
+38,38,39,32126,
+7,38,54,32126,
+12,13,64,32126,
+2,7,66,32126,
+6,23,62,32126,
+28,40,45,32126,
+5,28,60,32126,
+2,34,57,32126,
+28,32,51,32126,
+0,40,53,32126,
+17,20,61,32126,
+8,11,65,32126,
+4,13,65,32126,
+4,37,55,32126,
+19,32,55,32126,
+20,23,59,32126,
+33,36,45,32126,
+7,35,56,32126,
+9,45,48,32126,
+25,43,44,32126,
+1,40,53,32126,
+28,35,49,32126,
+5,41,52,32126,
+8,25,61,32126,
+0,21,63,32126,
+9,27,60,32126,
+31,40,43,32126,
+5,17,64,32126,
+19,45,45,32126,
+21,37,51,32126,
+37,39,39,32143,
+9,19,63,32143,
+1,21,63,32143,
+17,39,51,32143,
+9,39,53,32143,
+11,14,64,32143,
+11,34,56,32143,
+5,32,58,32143,
+16,26,59,32143,
+22,35,52,32143,
+2,40,53,32143,
+37,38,40,32163,
+19,44,46,32163,
+8,43,50,32163,
+13,20,62,32163,
+4,26,61,32163,
+11,18,63,32163,
+18,29,57,32163,
+25,42,45,32163,
+2,21,63,32163,
+7,42,51,32163,
+21,42,47,32163,
+3,7,66,32163,
+3,34,57,32163,
+8,16,64,32163,
+16,32,56,32163,
+5,6,66,32163,
+36,39,40,32210,
+32,33,48,32210,
+12,32,57,32210,
+6,30,59,32210,
+18,27,58,32210,
+0,47,47,32210,
+11,24,61,32210,
+7,12,65,32210,
+32,37,45,32210,
+21,29,56,32210,
+16,21,61,32210,
+19,24,59,32210,
+7,20,63,32210,
+17,23,60,32210,
+3,40,53,32210,
+31,39,44,32210,
+25,33,52,32210,
+9,44,49,32210,
+9,33,57,32210,
+21,27,57,32210,
+15,15,63,32210,
+27,33,51,32210,
+19,43,47,32210,
+5,37,55,32210,
+29,37,47,32210,
+23,41,47,32210,
+13,23,61,32210,
+37,37,41,32229,
+1,47,47,32229,
+13,35,55,32229,
+13,43,49,32229,
+3,21,63,32229,
+5,13,65,32229,
+0,46,48,32229,
+0,18,64,32229,
+12,26,60,32229,
+0,8,66,32229,
+0,24,62,32229,
+6,28,60,32229,
+20,39,50,32229,
+25,36,50,32229,
+4,34,57,32229,
+31,34,48,32229,
+24,38,49,32229,
+14,16,63,32229,
+16,42,49,32229,
+14,25,60,32229,
+28,39,46,32229,
+4,7,66,32229,
+18,31,56,32229,
+1,18,64,32229,
+0,14,65,32229,
+36,38,41,32239,
+10,15,64,32239,
+1,46,48,32239,
+6,17,64,32239,
+10,36,55,32239,
+14,33,56,32239,
+6,41,52,32239,
+14,39,52,32239,
+1,24,62,32239,
+1,8,66,32239,
+7,23,62,32239,
+23,23,58,32239,
+25,41,46,32239,
+31,31,50,32239,
+10,29,59,32239,
+2,47,47,32239,
+17,17,62,32239,
+1,14,65,32239,
+13,38,53,32239,
+5,26,61,32239,
+2,24,62,32239,
+16,18,62,32239,
+2,18,64,32239,
+18,40,50,32239,
+2,8,66,32239,
+8,38,54,32239,
+26,38,48,32239,
+6,32,58,32239,
+2,46,48,32239,
+30,32,50,32239,
+22,32,54,32239,
+22,24,58,32239,
+10,46,47,32239,
+2,14,65,32239,
+35,40,40,32266,
+10,31,58,32266,
+4,40,53,32266,
+8,35,56,32266,
+10,10,65,32266,
+11,40,52,32266,
+21,41,48,32266,
+27,36,49,32266,
+23,36,51,32266,
+12,41,51,32266,
+4,21,63,32266,
+0,45,49,32266,
+15,40,51,32266,
+23,33,53,32266,
+1,45,49,32266,
+13,17,63,32266,
+9,25,61,32266,
+3,47,47,32266,
+27,43,43,32266,
+35,39,41,32292,
+9,11,65,32292,
+21,31,55,32292,
+22,38,50,32292,
+6,6,66,32292,
+10,22,62,32292,
+14,46,46,32292,
+30,42,42,32292,
+34,34,46,32292,
+8,42,51,32292,
+27,28,54,32292,
+30,35,48,32292,
+36,37,42,32320,
+19,42,48,32320,
+3,8,66,32320,
+10,27,60,32320,
+12,37,54,32320,
+12,21,62,32320,
+27,42,44,32320,
+3,24,62,32320,
+3,46,48,32320,
+18,36,53,32320,
+3,18,64,32320,
+10,45,48,32320,
+6,37,55,32320,
+17,45,46,32320,
+2,45,49,32320,
+15,22,61,32320,
+5,7,66,32320,
+21,25,58,32320,
+18,25,59,32320,
+5,34,57,32320,
+15,29,58,32320,
+15,19,62,32320,
+30,41,43,32320,
+9,43,50,32320,
+7,30,59,32320,
+33,35,46,32320,
+14,45,47,32320,
+10,19,63,32320,
+31,38,45,32320,
+17,35,54,32320,
+6,13,65,32320,
+26,27,55,32320,
+3,14,65,32320,
+29,33,50,32320,
+10,39,53,32320,
+16,24,60,32320,
+0,36,56,32320,
+7,28,60,32320,
+35,38,42,32366,
+13,30,58,32366,
+26,34,51,32366,
+23,40,48,32366,
+13,42,50,32366,
+20,28,57,32366,
+8,12,65,32366,
+26,29,54,32366,
+6,26,61,32366,
+9,16,64,32366,
+8,20,63,32366,
+19,34,54,32366,
+1,36,56,32366,
+19,37,52,32366,
+13,13,64,32366,
+17,44,47,32366,
+28,29,53,32366,
+4,47,47,32366,
+7,41,52,32366,
+5,40,53,32366,
+13,28,59,32366,
+20,35,53,32366,
+25,28,55,32366,
+16,37,53,32366,
+25,40,47,32366,
+7,17,64,32366,
+15,31,57,32366,
+27,41,45,32366,
+3,45,49,32366,
+15,27,59,32366,
+5,21,63,32366,
+4,46,48,32366,
+12,14,64,32366,
+0,44,50,32366,
+32,36,46,32366,
+4,24,62,32366,
+2,36,56,32366,
+30,40,44,32366,
+24,34,52,32366,
+4,18,64,32366,
+20,30,56,32366,
+12,34,56,32366,
+14,44,48,32366,
+4,8,66,32366,
+12,18,63,32366,
+0,39,54,32366,
+17,28,58,32366,
+10,44,49,32366,
+16,34,55,32366,
+8,23,62,32366,
+7,32,58,32366,
+16,41,50,32366,
+34,40,41,32392,
+0,9,66,32392,
+28,38,47,32392,
+4,14,65,32392,
+1,44,50,32392,
+25,26,56,32392,
+17,38,52,32392,
+15,36,54,32392,
+27,30,53,32392,
+17,30,57,32392,
+1,39,54,32392,
+10,33,57,32392,
+1,9,66,32392,
+18,33,55,32392,
+20,26,58,32392,
+2,44,50,32392,
+28,34,50,32392,
+14,20,62,32392,
+3,36,56,32392,
+6,34,57,32392,
+0,29,60,32392,
+9,38,54,32392,
+2,39,54,32392,
+6,7,66,32392,
+34,39,42,32437,
+25,30,54,32437,
+2,9,66,32437,
+24,27,56,32437,
+29,36,48,32437,
+12,24,61,32437,
+21,36,52,32437,
+36,36,43,32437,
+20,21,60,32437,
+11,15,64,32437,
+11,36,55,32437,
+17,43,48,32437,
+4,45,49,32437,
+0,31,59,32437,
+9,35,56,32437,
+21,40,49,32437,
+13,32,57,32437,
+1,29,60,32437,
+24,29,55,32437,
+1,31,59,32437,
+7,37,55,32437,
+7,13,65,32437,
+35,37,43,32466,
+19,41,49,32466,
+11,29,59,32466,
+5,47,47,32466,
+19,19,61,32466,
+8,30,59,32466,
+24,37,50,32466,
+5,46,48,32466,
+6,40,53,32466,
+29,30,52,32466,
+19,22,60,32466,
+5,24,62,32466,
+3,44,50,32466,
+20,38,51,32466,
+5,8,66,32466,
+13,26,60,32466,
+5,18,64,32466,
+18,20,61,32466,
+2,29,60,32466,
+22,44,45,32466,
+27,40,46,32466,
+2,31,59,32466,
+18,39,51,32466,
+31,37,46,32466,
+6,21,63,32466,
+26,31,53,32466,
+3,9,66,32466,
+14,43,49,32466,
+5,14,65,32466,
+9,42,51,32466,
+3,39,54,32466,
+11,31,58,32466,
+11,46,47,32466,
+21,33,54,32466,
+14,35,55,32466,
+26,37,49,32466,
+17,26,59,32466,
+14,23,61,32466,
+10,25,61,32466,
+30,39,45,32466,
+10,11,65,32466,
+7,26,61,32466,
+8,28,60,32466,
+4,36,56,32466,
+24,44,44,32466,
+12,40,52,32466,
+8,17,64,32466,
+20,32,55,32466,
+28,31,52,32466,
+22,34,53,32466,
+23,28,56,32466,
+22,22,59,32466,
+11,22,62,32466,
+10,43,50,32466,
+22,43,46,32466,
+34,38,43,32512,
+14,38,53,32512,
+8,41,52,32512,
+17,32,56,32512,
+32,32,49,32512,
+0,43,51,32512,
+3,29,60,32512,
+15,16,63,32512,
+24,43,45,32512,
+24,25,57,32512,
+20,45,45,32512,
+15,39,52,32512,
+15,33,56,32512,
+11,45,48,32512,
+25,39,48,32512,
+11,27,60,32512,
+0,27,61,32512,
+15,25,60,32512,
+9,20,63,32512,
+0,15,65,32512,
+9,12,65,32512,
+11,39,53,32512,
+21,23,59,32512,
+1,15,65,32512,
+1,27,61,32512,
+11,19,63,32512,
+31,33,49,32512,
+33,41,41,32532,
+25,35,51,32532,
+19,29,57,32532,
+13,41,51,32532,
+17,21,61,32532,
+3,31,59,32532,
+5,45,49,32532,
+23,39,49,32532,
+1,43,51,32532,
+20,44,46,32532,
+8,32,58,32532,
+10,16,64,32532,
+4,44,50,32532,
+0,22,63,32532,
+24,31,54,32532,
+0,33,58,32532,
+4,9,66,32532,
+18,23,60,32532,
+4,39,54,32532,
+33,40,42,32551,
+29,42,43,32551,
+22,37,51,32551,
+27,35,50,32551,
+33,34,47,32551,
+23,30,55,32551,
+23,26,57,32551,
+6,47,47,32551,
+2,15,65,32551,
+2,43,51,32551,
+1,33,58,32551,
+14,17,63,32551,
+1,22,63,32551,
+19,27,58,32551,
+7,7,66,32551,
+7,34,57,32551,
+17,42,49,32551,
+9,23,62,32551,
+2,27,61,32551,
+13,21,62,32551,
+13,37,54,32551,
+6,18,64,32551,
+24,42,46,32551,
+6,8,66,32551,
+6,24,62,32551,
+6,46,48,32551,
+0,10,66,32551,
+0,19,64,32551,
+1,10,66,32551,
+28,37,48,32551,
+6,14,65,32551,
+5,36,56,32551,
+17,18,62,32551,
+2,22,63,32551,
+15,46,46,32551,
+20,24,59,32551,
+2,33,58,32551,
+35,36,44,32582,
+30,34,49,32582,
+4,29,60,32582,
+16,40,51,32582,
+22,42,47,32582,
+27,32,52,32582,
+32,35,47,32582,
+8,13,65,32582,
+11,44,49,32582,
+19,31,56,32582,
+23,35,52,32582,
+25,32,53,32582,
+4,31,59,32582,
+8,37,55,32582,
+29,41,44,32582,
+7,40,53,32582,
+20,43,47,32582,
+1,19,64,32582,
+15,45,47,32582,
+27,39,47,32582,
+33,39,43,32610,
+3,15,65,32610,
+11,33,57,32610,
+3,27,61,32610,
+3,43,51,32610,
+7,21,63,32610,
+14,42,50,32610,
+10,38,54,32610,
+2,10,66,32610,
+30,38,46,32610,
+14,30,58,32610,
+34,37,44,32625,
+2,19,64,32625,
+10,35,56,32625,
+13,34,56,32625,
+16,29,58,32625,
+13,14,64,32625,
+26,43,44,32625,
+16,22,61,32625,
+5,44,50,32625,
+22,29,56,32625,
+8,26,61,32625,
+14,28,59,32625,
+19,40,50,32625,
+16,19,62,32625,
+5,9,66,32625,
+3,33,58,32625,
+13,18,63,32625,
+3,22,63,32625,
+9,30,59,32625,
+22,27,57,32625,
+5,39,54,32625,
+21,39,50,32625,
+6,45,49,32625,
+30,31,51,32625,
+9,28,60,32625,
+3,10,66,32625,
+10,42,51,32625,
+17,24,60,32625,
+26,42,45,32625,
+15,44,48,32625,
+18,35,54,32625,
+12,36,55,32625,
+18,45,46,32625,
+12,15,64,32625,
+16,27,59,32625,
+19,36,53,32625,
+24,41,47,32625,
+31,36,47,32652,
+9,41,52,32652,
+13,24,61,32652,
+4,15,65,32652,
+29,32,51,32652,
+12,29,59,32652,
+16,31,57,32652,
+3,19,64,32652,
+5,29,60,32652,
+4,43,51,32652,
+9,17,64,32652,
+29,40,45,32652,
+4,27,61,32652,
+11,25,61,32652,
+11,11,65,32652,
+17,37,53,32652,
+29,35,49,32652,
+19,25,59,32652,
+7,47,47,32652,
+5,31,59,32652,
+6,36,56,32652,
+0,42,52,32652,
+20,42,48,32652,
+16,36,54,32652,
+1,42,52,32652,
+7,18,64,32652,
+7,8,66,32652,
+14,32,57,32652,
+32,41,42,32721,
+4,22,63,32721,
+10,12,65,32721,
+0,38,55,32721,
+23,24,58,32721,
+4,33,58,32721,
+10,20,63,32721,
+33,38,44,32721,
+22,41,48,32721,
+18,44,47,32721,
+0,25,62,32721,
+12,31,58,32721,
+26,33,52,32721,
+7,24,62,32721,
+8,34,57,32721,
+15,20,62,32721,
+7,46,48,32721,
+9,32,58,32721,
+12,46,47,32721,
+23,32,54,32721,
+1,38,55,32721,
+22,31,55,32721,
+1,25,62,32721,
+17,34,55,32721,
+11,43,50,32721,
+17,41,50,32721,
+25,38,49,32721,
+7,14,65,32721,
+12,22,62,32721,
+4,10,66,32721,
+20,34,54,32721,
+2,42,52,32721,
+26,36,50,32721,
+18,38,52,32721,
+6,44,50,32721,
+14,26,60,32721,
+18,28,58,32721,
+4,19,64,32721,
+11,16,64,32721,
+6,39,54,32721,
+23,38,50,32721,
+32,40,43,32740,
+2,25,62,32740,
+10,23,62,32740,
+22,25,58,32740,
+26,41,46,32740,
+20,37,52,32740,
+12,27,60,32740,
+6,9,66,32740,
+8,40,53,32740,
+18,30,57,32740,
+2,38,55,32740,
+24,36,51,32740,
+12,45,48,32740,
+13,40,52,32740,
+21,28,57,32740,
+8,21,63,32740,
+24,33,53,32740,
+0,35,57,32740,
+28,33,51,32740,
+12,19,63,32740,
+12,39,53,32740,
+5,27,61,32740,
+15,43,49,32740,
+19,33,55,32740,
+9,13,65,32740,
+35,35,45,32769,
+7,45,49,32769,
+5,43,51,32769,
+9,37,55,32769,
+1,35,57,32769,
+15,23,61,32769,
+5,15,65,32769,
+21,35,53,32769,
+15,35,55,32769,
+6,29,60,32769,
+21,30,56,32769,
+18,43,48,32769,
+34,36,45,32798,
+0,11,66,32798,
+27,38,48,32798,
+3,42,52,32798,
+5,33,58,32798,
+30,37,47,32798,
+29,39,46,32798,
+9,26,61,32798,
+6,31,59,32798,
+14,41,51,32798,
+5,22,63,32798,
+15,38,53,32798,
+2,35,57,32798,
+3,25,62,32798,
+1,11,66,32798,
+3,38,55,32798,
+24,40,48,32798,
+21,26,58,32798,
+2,11,66,32798,
+14,21,62,32798,
+11,38,54,32798,
+16,33,56,32798,
+5,10,66,32798,
+28,36,49,32798,
+7,36,56,32798,
+32,39,44,32836,
+16,16,63,32836,
+10,30,59,32836,
+16,25,60,32836,
+0,16,65,32836,
+18,26,59,32836,
+16,39,52,32836,
+12,44,49,32836,
+14,37,54,32836,
+8,47,47,32836,
+19,20,61,32836,
+21,21,60,32836,
+11,35,56,32836,
+33,33,48,32836,
+12,33,57,32836,
+20,41,49,32836,
+1,16,65,32836,
+5,19,64,32836,
+28,43,43,32836,
+15,17,63,32836,
+33,37,45,32863,
+19,39,51,32863,
+27,27,55,32863,
+3,35,57,32863,
+32,34,48,32863,
+8,24,62,32863,
+10,28,60,32863,
+8,8,66,32863,
+20,22,60,32863,
+22,36,52,32863,
+28,42,44,32863,
+18,32,56,32863,
+8,46,48,32863,
+4,42,52,32863,
+8,18,64,32863,
+28,28,54,32863,
+2,16,65,32863,
+25,34,52,32863,
+4,25,62,32863,
+26,28,55,32863,
+7,44,50,32863,
+10,41,52,32863,
+31,32,50,32863,
+26,40,47,32863,
+4,38,55,32863,
+8,14,65,32863,
+22,40,49,32863,
+10,17,64,32863,
+7,39,54,32863,
+21,38,51,32863,
+18,21,61,32863,
+27,34,51,32863,
+3,11,66,32863,
+27,29,54,32863,
+6,27,61,32863,
+7,9,66,32863,
+38,39,39,32922,
+6,15,65,32922,
+9,34,57,32922,
+11,42,51,32922,
+6,43,51,32922,
+38,38,40,32938,
+14,14,64,32938,
+26,26,56,32938,
+16,46,46,32938,
+14,34,56,32938,
+10,32,58,32938,
+0,0,67,32938,
+30,33,50,32938,
+22,33,54,32938,
+18,42,49,32938,
+6,33,58,32938,
+31,42,42,32938,
+15,30,58,32938,
+6,22,63,32938,
+14,18,63,32938,
+15,42,50,32938,
+37,39,40,32964,
+0,1,67,32964,
+11,12,65,32964,
+4,35,57,32964,
+20,29,57,32964,
+13,15,64,32964,
+21,32,55,32964,
+31,35,48,32964,
+12,25,61,32964,
+8,45,49,32964,
+3,16,65,32964,
+23,44,45,32964,
+11,20,63,32964,
+19,23,60,32964,
+9,40,53,32964,
+15,28,59,32964,
+7,29,60,32964,
+25,27,56,32964,
+0,41,53,32964,
+16,45,47,32964,
+13,36,55,32964,
+28,41,45,32964,
+17,40,51,32964,
+29,29,53,32964,
+31,41,43,32964,
+9,21,63,32964,
+25,29,55,32964,
+1,1,67,32964,
+13,29,59,32964,
+1,41,53,32964,
+7,31,59,32964,
+21,45,45,32964,
+18,18,62,32964,
+6,10,66,32964,
+26,30,54,32964,
+12,43,50,32964,
+14,24,61,32964,
+0,2,67,32964,
+21,44,46,32964,
+20,27,58,32964,
+4,11,66,32964,
+32,38,45,32964,
+6,19,64,32964,
+5,42,52,32964,
+28,30,53,32964,
+13,31,58,32964,
+5,25,62,32964,
+25,37,50,32964,
+5,38,55,32964,
+11,23,62,32964,
+23,43,46,32964,
+17,29,58,32964,
+1,2,67,32964,
+23,34,53,32964,
+2,41,53,32964,
+13,46,47,32964,
+17,19,62,32964,
+17,22,61,32964,
+10,37,55,32964,
+37,38,41,33001,
+22,23,59,33001,
+10,13,65,33001,
+29,38,47,33001,
+0,20,64,33001,
+12,16,64,33001,
+8,36,56,33001,
+24,28,56,33001,
+36,40,40,33013,
+16,44,48,33013,
+10,26,61,33013,
+25,44,44,33013,
+20,31,56,33013,
+4,16,65,33013,
+31,40,44,33013,
+34,35,46,33013,
+29,34,50,33013,
+2,2,67,33013,
+13,22,62,33013,
+1,20,64,33013,
+13,45,48,33013,
+15,32,57,33013,
+24,39,49,33013,
+0,3,67,33013,
+36,39,41,33041,
+21,24,59,33041,
+13,27,60,33041,
+0,23,63,33041,
+7,27,61,33041,
+1,3,67,33041,
+23,37,51,33041,
+27,37,49,33041,
+9,47,47,33041,
+13,19,63,33041,
+17,27,59,33041,
+25,43,45,33041,
+3,41,53,33041,
+25,25,57,33041,
+27,31,53,33041,
+7,15,65,33041,
+1,23,63,33041,
+5,35,57,33041,
+21,43,47,33041,
+13,39,53,33041,
+7,43,51,33041,
+17,31,57,33041,
+30,36,48,33041,
+28,40,46,33041,
+8,44,50,33041,
+14,40,52,33041,
+2,20,64,33041,
+18,24,60,33041,
+16,20,62,33041,
+0,12,66,33041,
+20,40,50,33041,
+0,30,60,33041,
+33,36,46,33041,
+17,36,54,33041,
+1,30,60,33041,
+9,46,48,33041,
+9,24,62,33041,
+15,26,60,33041,
+1,12,66,33041,
+24,26,57,33041,
+26,39,48,33041,
+24,30,55,33041,
+8,39,54,33041,
+9,18,64,33041,
+8,9,66,33041,
+2,23,63,33041,
+25,31,54,33041,
+18,37,53,33041,
+11,30,59,33041,
+19,45,46,33041,
+9,14,65,33041,
+7,22,63,33041,
+5,11,66,33041,
+7,33,58,33041,
+37,37,42,33058,
+19,35,54,33058,
+2,3,67,33058,
+23,42,47,33058,
+26,35,51,33058,
+36,38,42,33081,
+6,42,52,33081,
+12,38,54,33081,
+2,12,66,33081,
+30,30,52,33081,
+2,30,60,33081,
+6,38,55,33081,
+18,34,55,33081,
+25,42,46,33081,
+10,34,57,33081,
+0,37,56,33081,
+20,36,53,33081,
+3,20,64,33081,
+0,32,59,33081,
+18,41,50,33081,
+24,35,52,33081,
+11,28,60,33081,
+7,10,66,33081,
+0,4,67,33081,
+22,39,50,33081,
+0,28,61,33081,
+6,25,62,33081,
+8,29,60,33081,
+12,35,56,33081,
+16,23,61,33081,
+20,25,59,33081,
+1,28,61,33081,
+19,44,47,33081,
+1,4,67,33081,
+16,35,55,33081,
+16,43,49,33081,
+23,29,56,33081,
+13,44,49,33081,
+8,31,59,33081,
+1,37,56,33081,
+5,16,65,33081,
+35,40,41,33112,
+29,31,52,33112,
+11,41,52,33112,
+11,17,64,33112,
+1,32,59,33112,
+7,19,64,33112,
+4,41,53,33112,
+3,23,63,33112,
+15,41,51,33112,
+23,27,57,33112,
+13,33,57,33112,
+31,39,45,33112,
+3,3,67,33112,
+9,45,49,33112,
+2,32,59,33112,
+11,32,58,33112,
+19,38,52,33112,
+28,35,50,33112,
+2,28,61,33112,
+2,4,67,33112,
+12,42,51,33112,
+16,38,53,33112,
+2,37,56,33112,
+3,30,60,33112,
+32,37,46,33112,
+10,40,53,33112,
+19,28,58,33112,
+21,42,48,33112,
+3,12,66,33112,
+26,32,53,33112,
+15,37,54,33112,
+35,39,42,33148,
+19,30,57,33148,
+10,21,63,33148,
+15,21,62,33148,
+6,35,57,33148,
+28,32,52,33148,
+4,20,64,33148,
+21,34,54,33148,
+6,11,66,33148,
+9,36,56,33148,
+0,47,48,33148,
+12,12,65,33148,
+12,20,63,33148,
+30,42,43,33148,
+17,39,52,33148,
+0,5,67,33148,
+8,15,65,33148,
+28,39,47,33148,
+3,28,61,33148,
+21,37,52,33148,
+1,47,48,33148,
+17,33,56,33148,
+36,37,43,33185,
+32,33,49,33185,
+19,43,48,33185,
+3,32,59,33185,
+3,4,67,33185,
+17,25,60,33185,
+16,17,63,33185,
+0,17,65,33185,
+8,27,61,33185,
+8,43,51,33185,
+20,33,55,33185,
+27,43,44,33185,
+3,37,56,33185,
+23,41,48,33185,
+4,23,63,33185,
+29,37,48,33185,
+5,41,53,33185,
+1,17,65,33185,
+23,31,55,33185,
+11,37,55,33185,
+1,5,67,33185,
+11,13,65,33185,
+13,25,61,33185,
+25,41,47,33185,
+4,12,66,33185,
+24,24,58,33185,
+0,40,54,33185,
+4,30,60,33185,
+24,32,54,33185,
+12,23,62,33185,
+30,41,44,33185,
+2,47,48,33185,
+22,28,57,33185,
+0,46,49,33185,
+14,15,64,33185,
+1,40,54,33185,
+9,44,50,33185,
+6,16,65,33185,
+8,33,58,33185,
+15,34,56,33185,
+8,22,63,33185,
+14,36,55,33185,
+7,42,52,33185,
+2,17,65,33185,
+35,38,43,33220,
+31,34,49,33220,
+9,9,66,33220,
+10,47,47,33220,
+14,29,59,33220,
+22,35,53,33220,
+7,38,55,33220,
+11,26,61,33220,
+2,5,67,33220,
+15,18,63,33220,
+23,25,58,33220,
+9,39,54,33220,
+1,46,49,33220,
+19,26,59,33220,
+13,43,50,33220,
+27,42,45,33220,
+34,41,41,33220,
+7,25,62,33220,
+10,18,64,33220,
+0,34,58,33220,
+2,40,54,33220,
+8,10,66,33220,
+34,40,42,33237,
+10,24,62,33237,
+16,30,58,33237,
+22,30,56,33237,
+10,46,48,33237,
+0,26,62,33237,
+16,42,50,33237,
+24,38,50,33237,
+10,14,65,33237,
+1,34,58,33237,
+2,46,49,33237,
+4,4,67,33237,
+5,20,64,33237,
+34,34,47,33237,
+19,32,56,33237,
+31,38,46,33237,
+4,32,59,33237,
+14,46,47,33237,
+13,16,64,33237,
+14,31,58,33237,
+17,46,46,33237,
+20,20,61,33237,
+4,28,61,33237,
+16,28,59,33237,
+4,37,56,33237,
+26,38,49,33237,
+8,19,64,33237,
+1,26,62,33237,
+25,36,51,33237,
+20,39,51,33237,
+15,24,61,33237,
+3,47,48,33237,
+9,29,60,33237,
+27,33,52,33237,
+19,21,61,33237,
+17,45,47,33237,
+7,35,57,33237,
+3,17,65,33237,
+21,41,49,33237,
+33,35,47,33237,
+25,33,53,33237,
+9,31,59,33237,
+3,5,67,33237,
+5,23,63,33237,
+31,31,51,33237,
+22,26,58,33237,
+2,34,58,33237,
+14,22,62,33237,
+2,26,62,33237,
+18,40,51,33237,
+3,40,54,33237,
+0,6,67,33237,
+0,45,50,33237,
+30,32,51,33237,
+12,30,59,33237,
+27,36,50,33237,
+21,22,60,33237,
+14,45,48,33237,
+30,40,45,33252,
+14,27,60,33252,
+0,13,66,33252,
+5,12,66,33252,
+5,30,60,33252,
+30,35,49,33252,
+34,39,43,33302,
+3,46,49,33302,
+1,6,67,33302,
+19,42,49,33302,
+7,11,66,33302,
+14,39,53,33302,
+27,41,46,33302,
+11,34,57,33302,
+6,41,53,33302,
+1,45,50,33302,
+14,19,63,33302,
+10,45,49,33302,
+1,13,66,33302,
+36,36,44,33319,
+12,28,60,33319,
+17,44,48,33319,
+20,23,60,33319,
+32,36,47,33319,
+12,41,52,33319,
+12,17,64,33319,
+4,47,48,33319,
+18,22,61,33319,
+18,19,62,33319,
+2,6,67,33319,
+25,40,48,33319,
+2,45,50,33319,
+23,36,52,33319,
+2,13,66,33319,
+16,32,57,33319,
+18,29,58,33319,
+15,40,52,33319,
+13,38,54,33319,
+3,34,58,33319,
+22,38,51,33319,
+3,26,62,33319,
+5,32,59,33319,
+35,37,44,33348,
+23,40,49,33348,
+13,35,56,33348,
+4,5,67,33348,
+4,17,65,33348,
+5,28,61,33348,
+11,40,53,33348,
+5,37,56,33348,
+7,16,65,33348,
+9,15,65,33348,
+9,43,51,33348,
+21,29,57,33348,
+11,21,63,33348,
+9,27,61,33348,
+29,33,51,33348,
+10,36,56,33348,
+6,20,64,33348,
+12,32,58,33348,
+8,42,52,33348,
+16,26,60,33348,
+28,38,48,33348,
+4,40,54,33348,
+17,20,62,33348,
+22,32,55,33348,
+14,44,49,33348,
+8,38,55,33348,
+4,46,49,33348,
+8,25,62,33348,
+21,27,58,33348,
+18,27,59,33348,
+33,41,42,33379,
+13,42,51,33379,
+9,33,58,33379,
+18,31,57,33379,
+14,33,57,33379,
+3,13,66,33379,
+23,33,54,33379,
+6,23,63,33379,
+9,22,63,33379,
+22,45,45,33379,
+3,45,50,33379,
+3,6,67,33379,
+4,34,58,33379,
+6,30,60,33379,
+26,34,52,33379,
+10,44,50,33379,
+6,12,66,33379,
+22,44,46,33379,
+4,26,62,33379,
+34,38,44,33398,
+18,36,54,33398,
+30,39,46,33398,
+0,44,51,33398,
+10,39,54,33398,
+24,44,45,33398,
+0,21,64,33398,
+9,10,66,33398,
+19,24,60,33398,
+9,19,64,33398,
+21,31,56,33398,
+13,20,63,33398,
+16,41,51,33398,
+1,21,64,33398,
+5,47,48,33398,
+29,36,49,33398,
+33,40,43,33421,
+12,13,65,33421,
+27,28,55,33421,
+0,7,67,33421,
+27,40,47,33421,
+12,37,55,33421,
+8,35,57,33421,
+1,44,51,33421,
+17,35,55,33421,
+31,37,47,33421,
+29,43,43,33421,
+19,37,53,33421,
+17,43,49,33421,
+7,41,53,33421,
+1,7,67,33421,
+11,47,47,33421,
+17,23,61,33421,
+5,5,67,33421,
+5,17,65,33421,
+23,23,59,33421,
+16,21,62,33421,
+20,35,54,33421,
+2,21,64,33421,
+2,44,51,33421,
+21,40,50,33421,
+11,46,48,33421,
+11,24,62,33421,
+29,42,44,33421,
+6,37,56,33421,
+24,43,46,33421,
+10,29,60,33421,
+8,11,66,33421,
+4,45,50,33421,
+24,34,53,33421,
+4,6,67,33421,
+22,24,59,33421,
+11,18,64,33421,
+26,27,56,33421,
+12,26,61,33421,
+6,32,59,33421,
+28,34,51,33421,
+4,13,66,33421,
+5,40,54,33421,
+28,29,54,33421,
+6,28,61,33421,
+20,45,46,33421,
+16,37,54,33421,
+11,14,65,33421,
+17,38,53,33421,
+10,31,59,33421,
+5,46,49,33421,
+19,41,50,33421,
+2,7,67,33421,
+22,43,47,33421,
+13,23,62,33421,
+26,29,55,33421,
+14,25,61,33421,
+19,34,55,33421,
+5,34,58,33421,
+0,24,63,33421,
+20,44,47,33421,
+5,26,62,33421,
+27,30,54,33421,
+26,37,50,33421,
+8,16,65,33421,
+7,20,64,33421,
+25,28,56,33421,
+0,36,57,33421,
+14,43,50,33421,
+33,39,44,33506,
+24,37,51,33506,
+1,24,63,33506,
+21,36,53,33506,
+0,39,55,33506,
+15,36,55,33506,
+15,15,64,33506,
+35,36,45,33506,
+3,44,51,33506,
+1,36,57,33506,
+3,21,64,33506,
+11,45,49,33506,
+7,23,63,33506,
+1,39,55,33506,
+21,25,59,33506,
+3,7,67,33506,
+25,39,49,33506,
+17,17,63,33506,
+15,29,59,33506,
+29,41,45,33506,
+32,32,50,33506,
+20,28,58,33506,
+14,16,64,33506,
+26,44,44,33506,
+16,34,56,33506,
+20,38,52,33506,
+33,34,48,33506,
+7,12,66,33506,
+18,33,56,33506,
+7,30,60,33506,
+16,18,63,33506,
+18,25,60,33506,
+9,42,52,33506,
+2,24,63,33506,
+12,34,57,33506,
+6,47,48,33506,
+18,39,52,33506,
+24,42,47,33506,
+0,18,65,33506,
+2,36,57,33506,
+20,30,57,33506,
+23,39,50,33506,
+1,18,65,33506,
+9,25,62,33506,
+2,39,55,33506,
+5,45,50,33506,
+26,43,45,33506,
+25,26,57,33506,
+9,38,55,33506,
+6,17,65,33506,
+10,15,65,33506,
+34,37,45,33539,
+15,31,58,33539,
+10,43,51,33539,
+5,13,66,33539,
+5,6,67,33539,
+13,30,59,33539,
+10,27,61,33539,
+25,30,55,33539,
+15,46,47,33539,
+29,30,53,33539,
+31,33,50,33539,
+32,42,42,33553,
+0,14,66,33553,
+22,42,48,33553,
+6,40,54,33553,
+30,38,47,33553,
+4,44,51,33553,
+2,18,65,33553,
+32,35,48,33553,
+10,22,63,33553,
+0,43,52,33553,
+13,28,60,33553,
+20,43,48,33553,
+15,22,62,33553,
+17,42,50,33553,
+26,31,54,33553,
+12,40,53,33553,
+24,29,56,33553,
+0,8,67,33553,
+6,46,49,33553,
+16,24,61,33553,
+11,36,56,33553,
+4,21,64,33553,
+10,33,58,33553,
+17,30,58,33553,
+1,14,66,33553,
+7,28,61,33553,
+13,41,52,33553,
+7,32,59,33553,
+25,35,52,33553,
+3,36,57,33553,
+13,17,64,33553,
+24,27,57,33553,
+32,41,43,33581,
+12,21,63,33581,
+3,24,63,33581,
+8,41,53,33581,
+15,45,48,33581,
+28,37,49,33581,
+1,8,67,33581,
+15,27,60,33581,
+27,39,48,33581,
+4,7,67,33581,
+1,43,52,33581,
+7,37,56,33581,
+17,28,59,33581,
+28,31,53,33581,
+15,19,63,33581,
+3,39,55,33581,
+9,35,57,33581,
+15,39,53,33581,
+27,35,51,33581,
+21,33,55,33581,
+22,34,54,33581,
+30,34,50,33581,
+10,10,66,33581,
+14,38,54,33581,
+18,46,46,33581,
+6,26,62,33581,
+26,42,46,33581,
+6,34,58,33581,
+2,14,66,33581,
+11,44,50,33581,
+14,35,56,33581,
+22,37,52,33581,
+10,19,64,33581,
+2,8,67,33581,
+29,40,46,33581,
+13,32,58,33581,
+2,43,52,33581,
+20,26,59,33581,
+3,18,65,33581,
+11,39,54,33581,
+9,11,66,33581,
+33,38,45,33621,
+18,45,47,33621,
+20,32,56,33621,
+16,40,52,33621,
+32,40,44,33635,
+8,20,64,33635,
+4,24,63,33635,
+4,36,57,33635,
+3,14,66,33635,
+31,36,48,33635,
+14,42,51,33635,
+6,13,66,33635,
+6,45,50,33635,
+24,41,48,33635,
+0,31,60,33635,
+6,6,67,33635,
+4,39,55,33635,
+15,44,49,33635,
+27,32,53,33635,
+23,28,57,33635,
+5,21,64,33635,
+3,8,67,33635,
+7,47,48,33635,
+19,40,51,33635,
+17,32,57,33635,
+20,21,61,33635,
+3,43,52,33635,
+24,31,55,33635,
+5,44,51,33635,
+9,16,65,33635,
+8,23,63,33635,
+0,29,61,33635,
+12,47,47,33635,
+11,29,60,33635,
+1,31,60,33635,
+13,13,65,33635,
+15,33,57,33635,
+23,35,53,33635,
+13,37,55,33635,
+11,31,59,33635,
+39,39,39,33682,
+7,17,65,33682,
+5,7,67,33682,
+21,39,51,33682,
+1,29,61,33682,
+8,30,60,33682,
+12,46,48,33682,
+18,44,48,33682,
+12,18,64,33682,
+8,12,66,33682,
+12,24,62,33682,
+2,31,60,33682,
+20,42,49,33682,
+4,18,65,33682,
+30,31,52,33682,
+25,32,54,33682,
+24,25,58,33682,
+23,30,56,33682,
+12,14,65,33682,
+38,39,40,33715,
+17,26,60,33715,
+14,20,63,33715,
+7,40,54,33715,
+7,46,49,33715,
+29,35,50,33715,
+22,41,49,33715,
+26,41,47,33715,
+19,22,61,33715,
+35,35,46,33715,
+19,19,62,33715,
+2,29,61,33715,
+13,26,61,33715,
+19,29,58,33715,
+10,42,52,33715,
+22,22,60,33715,
+34,36,46,33715,
+18,20,62,33715,
+4,14,66,33715,
+28,43,44,33715,
+8,28,61,33715,
+10,38,55,33715,
+4,8,67,33715,
+7,34,58,33715,
+38,38,41,33759,
+8,37,56,33759,
+8,32,59,33759,
+37,40,40,33759,
+25,38,50,33759,
+14,23,62,33759,
+7,26,62,33759,
+4,43,52,33759,
+10,25,62,33759,
+23,26,58,33759,
+29,32,52,33759,
+3,31,60,33759,
+0,33,59,33759,
+32,39,45,33759,
+21,23,60,33759,
+5,36,57,33759,
+12,45,49,33759,
+5,24,63,33759,
+0,9,67,33759,
+19,31,57,33759,
+1,33,59,33759,
+3,29,61,33759,
+9,41,53,33759,
+29,39,47,33759,
+5,39,55,33759,
+17,41,51,33759,
+11,15,65,33759,
+1,9,67,33759,
+11,27,61,33759,
+15,25,61,33759,
+37,39,41,33786,
+19,27,59,33786,
+11,43,51,33786,
+0,42,53,33786,
+26,36,51,33786,
+6,21,64,33786,
+30,37,48,33786,
+28,42,45,33786,
+19,36,54,33786,
+6,44,51,33786,
+0,27,62,33786,
+1,27,62,33786,
+27,38,49,33786,
+26,33,53,33786,
+10,35,57,33786,
+2,9,67,33786,
+11,33,58,33786,
+23,38,51,33786,
+11,22,63,33786,
+17,37,54,33786,
+2,33,59,33786,
+5,18,65,33786,
+13,34,57,33786,
+1,42,53,33786,
+15,43,50,33786,
+6,7,67,33786,
+33,37,46,33786,
+7,13,66,33786,
+18,43,49,33786,
+18,35,55,33786,
+18,23,61,33786,
+7,45,50,33786,
+22,29,57,33786,
+31,42,43,33786,
+17,21,62,33786,
+20,24,60,33786,
+12,36,56,33786,
+24,36,52,33786,
+15,16,64,33786,
+5,14,66,33786,
+16,36,55,33786,
+36,40,41,33836,
+18,38,53,33836,
+37,38,42,33836,
+2,42,53,33836,
+8,47,48,33836,
+22,27,58,33836,
+10,11,66,33836,
+28,33,52,33836,
+14,30,59,33836,
+24,40,49,33836,
+4,31,60,33836,
+9,20,64,33836,
+2,27,62,33836,
+23,32,55,33836,
+8,17,65,33836,
+5,43,52,33836,
+16,29,59,33836,
+31,41,44,33836,
+13,40,53,33836,
+20,37,53,33836,
+11,19,64,33836,
+4,29,61,33836,
+5,8,67,33836,
+33,33,49,33836,
+3,33,59,33836,
+3,9,67,33836,
+23,45,45,33836,
+13,21,63,33836,
+9,23,63,33836,
+12,44,50,33836,
+14,28,60,33836,
+26,40,48,33836,
+8,40,54,33836,
+0,22,64,33836,
+28,36,50,33836,
+0,38,56,33836,
+8,46,49,33836,
+20,34,55,33836,
+16,46,47,33836,
+6,36,57,33836,
+1,38,56,33836,
+23,44,46,33836,
+1,22,64,33836,
+24,33,54,33836,
+0,15,66,33836,
+9,12,66,33836,
+28,41,46,33836,
+12,39,54,33836,
+14,17,64,33836,
+6,24,63,33836,
+20,41,50,33836,
+22,31,56,33836,
+36,39,42,33878,
+32,34,49,33878,
+17,34,56,33878,
+10,16,65,33878,
+14,41,52,33878,
+16,31,58,33878,
+9,30,60,33878,
+17,18,63,33878,
+21,45,46,33878,
+3,42,53,33878,
+6,39,55,33878,
+3,27,62,33878,
+1,15,66,33878,
+21,35,54,33878,
+16,22,62,33878,
+32,38,46,33878,
+8,34,58,33878,
+14,32,58,33878,
+2,38,56,33878,
+22,40,50,33878,
+8,26,62,33878,
+2,22,64,33878,
+16,27,60,33878,
+16,45,48,33878,
+12,29,60,33878,
+6,18,65,33878,
+15,38,54,33878,
+2,15,66,33878,
+17,24,61,33878,
+31,40,45,33886,
+23,24,59,33886,
+19,33,56,33886,
+7,44,51,33886,
+15,35,56,33886,
+25,44,45,33886,
+9,28,61,33886,
+4,33,59,33886,
+9,32,59,33886,
+7,21,64,33886,
+19,25,60,33886,
+5,31,60,33886,
+16,19,63,33886,
+9,37,56,33886,
+4,9,67,33886,
+12,31,59,33886,
+21,44,47,33886,
+16,39,53,33886,
+19,39,52,33886,
+0,19,65,33886,
+31,32,51,33886,
+7,7,67,33886,
+37,37,43,33948,
+5,29,61,33948,
+31,35,49,33948,
+13,47,47,33948,
+23,43,47,33948,
+35,41,41,33948,
+1,19,65,33948,
+18,42,50,33948,
+18,30,58,33948,
+6,14,66,33948,
+21,28,58,33948,
+18,28,59,33948,
+6,8,67,33948,
+21,38,52,33948,
+6,43,52,33948,
+0,10,67,33948,
+22,36,53,33948,
+11,42,52,33948,
+3,38,56,33948,
+4,42,53,33948,
+36,38,43,33970,
+8,13,66,33970,
+35,40,42,33970,
+27,34,52,33970,
+8,45,50,33970,
+4,27,62,33970,
+29,38,48,33970,
+0,35,58,33970,
+13,24,62,33970,
+3,22,64,33970,
+13,46,48,33970,
+13,18,64,33970,
+13,14,65,33970,
+10,41,53,33970,
+11,38,55,33970,
+1,10,67,33970,
+21,30,57,33970,
+25,43,46,33970,
+34,35,47,33970,
+22,25,59,33970,
+15,42,51,33970,
+30,33,51,33970,
+3,15,66,33970,
+25,34,53,33970,
+1,35,58,33970,
+14,37,55,33970,
+2,19,65,33970,
+11,25,62,33970,
+2,35,58,33970,
+28,28,55,33970,
+16,44,49,33970,
+28,40,47,33970,
+14,26,61,33970,
+2,10,67,33970,
+19,46,46,33970,
+17,40,52,33970,
+15,20,63,33970,
+7,36,57,33970,
+12,15,65,33970,
+16,33,57,33970,
+27,27,56,33970,
+0,25,63,33970,
+33,36,47,33983,
+7,24,63,33983,
+12,27,61,33983,
+21,43,48,33983,
+9,47,48,33983,
+12,43,51,33983,
+3,19,65,33983,
+27,29,55,33983,
+5,9,67,33983,
+1,25,63,33983,
+7,39,55,33983,
+13,45,49,33983,
+9,17,65,33983,
+35,39,43,34029,
+25,37,51,34029,
+19,45,47,34029,
+11,35,57,34029,
+5,33,59,34029,
+4,38,56,34029,
+10,20,64,34029,
+4,22,64,34029,
+26,28,56,34029,
+18,32,57,34029,
+12,22,63,34029,
+12,33,58,34029,
+24,39,50,34029,
+6,31,60,34029,
+30,36,49,34029,
+0,41,54,34029,
+9,40,54,34029,
+4,15,66,34029,
+23,42,48,34029,
+31,39,46,34029,
+10,23,63,34029,
+30,43,43,34029,
+9,46,49,34029,
+1,41,54,34029,
+5,27,62,34029,
+11,11,66,34029,
+29,34,51,34029,
+25,42,47,34029,
+21,26,59,34029,
+3,10,67,34029,
+29,29,54,34029,
+7,18,65,34029,
+15,23,62,34029,
+3,35,58,34029,
+27,37,50,34029,
+6,29,61,34029,
+26,39,49,34029,
+22,33,55,34029,
+2,25,63,34029,
+5,42,53,34029,
+30,42,44,34037,
+28,30,54,34037,
+10,30,60,34037,
+10,12,66,34037,
+18,26,60,34037,
+26,26,57,34037,
+14,34,57,34037,
+27,44,44,34037,
+34,41,42,34092,
+9,34,58,34092,
+21,32,56,34092,
+12,19,64,34092,
+19,44,48,34092,
+23,34,54,34092,
+36,37,44,34092,
+8,44,51,34092,
+26,30,55,34092,
+9,26,62,34092,
+2,41,54,34092,
+13,36,56,34092,
+8,21,64,34092,
+7,14,66,34092,
+20,40,51,34092,
+7,8,67,34092,
+25,29,56,34092,
+32,37,47,34092,
+7,43,52,34092,
+16,25,61,34092,
+23,37,52,34092,
+4,19,65,34092,
+11,16,65,34092,
+3,25,63,34092,
+21,21,61,34092,
+25,27,57,34092,
+27,43,45,34092,
+20,22,61,34092,
+4,35,58,34092,
+35,38,44,34125,
+5,38,56,34125,
+16,43,50,34125,
+4,10,67,34125,
+5,22,64,34125,
+10,28,61,34125,
+14,40,53,34125,
+10,37,56,34125,
+19,20,62,34125,
+34,40,43,34125,
+10,32,59,34125,
+26,35,52,34125,
+13,44,50,34125,
+20,29,58,34125,
+27,31,54,34125,
+14,21,63,34125,
+9,45,50,34125,
+3,41,54,34125,
+15,30,59,34125,
+18,41,51,34125,
+5,15,66,34125,
+6,33,59,34125,
+9,13,66,34125,
+13,39,54,34125,
+30,41,45,34125,
+21,42,49,34125,
+22,39,51,34125,
+6,9,67,34125,
+16,16,64,34125,
+0,48,48,34125,
+30,30,53,34125,
+15,28,60,34125,
+8,36,57,34125,
+18,21,62,34125,
+28,39,48,34125,
+6,27,62,34125,
+8,24,63,34125,
+18,37,54,34125,
+1,48,48,34125,
+6,42,53,34125,
+27,42,46,34125,
+24,28,57,34125,
+7,31,60,34125,
+20,31,57,34125,
+0,11,67,34125,
+24,35,53,34125,
+4,25,63,34125,
+8,39,55,34125,
+15,17,64,34125,
+28,35,51,34125,
+17,36,55,34125,
+25,41,48,34125,
+0,47,49,34125,
+13,29,60,34125,
+15,41,52,34125,
+20,27,59,34125,
+1,11,67,34125,
+19,35,55,34125,
+11,41,53,34125,
+17,29,59,34125,
+19,43,49,34125,
+25,31,55,34125,
+7,29,61,34125,
+1,47,49,34125,
+5,19,65,34125,
+23,41,49,34125,
+19,23,61,34125,
+29,37,49,34125,
+29,31,53,34125,
+13,31,59,34125,
+12,42,52,34125,
+24,30,56,34125,
+0,16,66,34125,
+20,36,54,34125,
+2,48,48,34125,
+8,18,65,34125,
+12,38,55,34125,
+32,33,50,34125,
+22,23,60,34125,
+12,25,62,34125,
+10,47,48,34125,
+1,16,66,34125,
+4,41,54,34125,
+34,39,44,34183,
+15,32,58,34183,
+2,11,67,34183,
+10,17,65,34183,
+19,38,53,34183,
+17,31,58,34183,
+25,25,58,34183,
+31,38,47,34183,
+17,46,47,34183,
+2,47,49,34183,
+5,35,58,34183,
+5,10,67,34183,
+14,47,47,34183,
+26,32,54,34183,
+18,34,56,34183,
+14,18,64,34183,
+8,14,66,34183,
+34,34,48,34183,
+2,16,66,34183,
+30,40,46,34183,
+14,24,62,34183,
+6,22,64,34183,
+6,38,56,34183,
+14,46,48,34183,
+24,26,58,34183,
+16,38,54,34183,
+10,40,54,34183,
+0,46,50,34183,
+31,34,50,34183,
+36,36,45,34228,
+18,18,63,34228,
+1,46,50,34228,
+11,20,64,34228,
+21,24,60,34228,
+8,8,67,34228,
+14,14,65,34228,
+33,42,42,34228,
+16,35,56,34228,
+10,46,49,34228,
+28,32,53,34228,
+17,22,62,34228,
+3,48,48,34228,
+8,43,52,34228,
+6,15,66,34228,
+9,21,64,34228,
+9,44,51,34228,
+0,37,57,34228,
+17,45,48,34228,
+12,35,57,34228,
+33,35,48,34228,
+17,27,60,34228,
+15,37,55,34228,
+11,23,63,34228,
+33,41,43,34254,
+35,37,45,34254,
+21,37,53,34254,
+5,25,63,34254,
+17,39,53,34254,
+13,15,65,34254,
+7,33,59,34254,
+23,29,57,34254,
+1,37,57,34254,
+3,47,49,34254,
+27,41,47,34254,
+17,19,63,34254,
+7,9,67,34254,
+13,27,61,34254,
+3,11,67,34254,
+13,43,51,34254,
+10,34,58,34254,
+2,46,50,34254,
+26,38,50,34254,
+10,26,62,34254,
+16,42,51,34254,
+0,30,61,34254,
+3,16,66,34254,
+11,30,60,34254,
+11,12,66,34254,
+18,24,61,34254,
+24,38,51,34254,
+21,41,50,34254,
+21,34,55,34254,
+1,30,61,34254,
+23,27,58,34254,
+5,41,54,34254,
+13,22,63,34254,
+15,26,61,34254,
+6,19,65,34254,
+14,45,49,34254,
+7,42,53,34254,
+2,37,57,34254,
+13,33,58,34254,
+7,27,62,34254,
+32,36,48,34260,
+4,48,48,34260,
+0,32,60,34260,
+0,0,68,34260,
+10,13,66,34260,
+24,32,55,34260,
+34,38,45,34308,
+19,30,58,34308,
+0,23,64,34308,
+8,31,60,34308,
+6,35,58,34308,
+2,30,61,34308,
+25,36,52,34308,
+30,35,50,34308,
+19,42,50,34308,
+16,20,63,34308,
+6,10,67,34308,
+0,40,55,34308,
+33,40,44,34308,
+20,39,52,34308,
+3,46,50,34308,
+0,20,65,34308,
+20,33,56,34308,
+10,45,50,34308,
+12,16,65,34308,
+22,45,46,34308,
+22,35,54,34308,
+1,32,60,34308,
+20,25,60,34308,
+0,1,68,34308,
+13,19,64,34308,
+9,36,57,34308,
+23,31,56,34308,
+1,1,68,34308,
+11,37,56,34308,
+1,40,55,34308,
+9,24,63,34308,
+11,32,59,34308,
+29,43,44,34308,
+31,31,52,34308,
+19,28,59,34308,
+4,11,67,34308,
+1,20,65,34308,
+11,28,61,34308,
+24,45,45,34308,
+1,23,64,34308,
+0,45,51,34308,
+25,40,49,34308,
+27,36,51,34308,
+8,29,61,34308,
+17,44,49,34308,
+4,47,49,34308,
+9,39,55,34308,
+27,33,53,34308,
+1,45,51,34308,
+17,33,57,34308,
+3,37,57,34308,
+30,32,52,34308,
+0,2,68,34308,
+2,32,60,34308,
+18,40,52,34308,
+0,28,62,34308,
+14,36,56,34308,
+4,16,66,34308,
+24,44,46,34308,
+23,40,50,34308,
+2,40,55,34308,
+7,22,64,34308,
+7,38,56,34308,
+22,44,47,34308,
+16,23,62,34308,
+28,38,49,34308,
+2,23,64,34308,
+2,20,65,34308,
+1,2,68,34308,
+1,28,62,34308,
+3,30,61,34308,
+6,25,63,34308,
+15,34,57,34308,
+9,18,65,34308,
+29,42,45,34328,
+30,39,47,34328,
+25,33,54,34328,
+7,15,66,34328,
+2,45,51,34328,
+14,44,50,34328,
+22,28,58,34328,
+20,46,46,34328,
+2,28,62,34328,
+4,46,50,34328,
+2,2,68,34328,
+22,38,52,34328,
+5,48,48,34328,
+24,24,59,34328,
+6,41,54,34328,
+14,39,54,34328,
+27,40,48,34328,
+0,3,68,34328,
+3,32,60,34328,
+9,14,66,34328,
+0,12,67,34328,
+22,30,57,34328,
+1,3,68,34328,
+23,36,53,34328,
+29,33,52,34328,
+24,43,47,34328,
+31,37,48,34367,
+8,9,67,34367,
+12,41,53,34367,
+3,20,65,34367,
+11,47,48,34367,
+3,40,55,34367,
+9,43,52,34367,
+15,40,53,34367,
+1,12,67,34367,
+3,23,64,34367,
+4,37,57,34367,
+8,33,59,34367,
+20,45,47,34367,
+19,32,57,34367,
+11,17,65,34367,
+23,25,59,34367,
+5,47,49,34367,
+17,25,61,34367,
+33,39,45,34410,
+5,11,67,34410,
+15,21,63,34410,
+7,19,65,34410,
+3,45,51,34410,
+0,34,59,34410,
+13,42,52,34410,
+32,42,43,34426,
+3,28,62,34426,
+19,26,60,34426,
+8,42,53,34426,
+8,27,62,34426,
+2,3,68,34426,
+5,16,66,34426,
+10,21,64,34426,
+11,40,54,34426,
+14,29,60,34426,
+4,30,61,34426,
+35,36,46,34426,
+26,44,45,34426,
+29,36,50,34426,
+16,30,59,34426,
+10,44,51,34426,
+2,12,67,34426,
+22,43,48,34426,
+1,34,59,34426,
+17,43,50,34426,
+13,25,62,34426,
+14,31,59,34426,
+7,35,58,34426,
+11,46,49,34426,
+7,10,67,34426,
+29,41,46,34426,
+13,38,55,34426,
+12,20,64,34426,
+4,32,60,34426,
+0,4,68,34426,
+0,44,52,34426,
+20,44,48,34426,
+16,28,60,34426,
+26,34,53,34426,
+16,17,64,34426,
+2,34,59,34426,
+16,41,52,34426,
+4,40,55,34426,
+1,4,68,34426,
+5,46,50,34426,
+32,41,44,34460,
+4,23,64,34460,
+34,37,46,34460,
+11,34,58,34460,
+4,20,65,34460,
+1,44,52,34460,
+22,26,59,34460,
+26,43,46,34460,
+11,26,62,34460,
+9,31,60,34460,
+3,3,68,34460,
+4,45,51,34460,
+12,23,63,34460,
+3,12,67,34460,
+39,39,40,34527,
+21,40,51,34527,
+19,41,51,34527,
+5,37,57,34527,
+7,25,63,34527,
+15,47,47,34527,
+9,29,61,34527,
+23,33,55,34527,
+13,35,57,34527,
+16,32,58,34527,
+8,38,56,34527,
+2,44,52,34527,
+20,20,62,34527,
+8,22,64,34527,
+12,30,60,34527,
+6,48,48,34527,
+2,4,68,34527,
+12,12,66,34527,
+28,34,52,34527,
+4,28,62,34527,
+24,42,48,34527,
+38,40,40,34531,
+22,32,56,34531,
+8,15,66,34531,
+15,46,48,34531,
+10,36,57,34531,
+10,24,63,34531,
+18,36,55,34531,
+15,18,64,34531,
+15,24,62,34531,
+0,17,66,34531,
+0,26,63,34531,
+21,29,58,34531,
+19,37,54,34531,
+14,43,51,34531,
+21,22,61,34531,
+14,15,65,34531,
+14,27,61,34531,
+6,11,67,34531,
+6,47,49,34531,
+10,39,55,34531,
+7,41,54,34531,
+19,21,62,34531,
+11,13,66,34531,
+33,34,49,34531,
+3,34,59,34531,
+1,26,63,34531,
+5,30,61,34531,
+26,37,51,34531,
+1,17,66,34531,
+11,45,50,34531,
+38,39,41,34569,
+18,29,59,34569,
+25,39,50,34569,
+30,38,48,34569,
+24,34,54,34569,
+6,16,66,34569,
+2,26,63,34569,
+3,4,68,34569,
+10,18,65,34569,
+2,17,66,34569,
+32,32,51,34569,
+0,5,68,34569,
+24,37,52,34569,
+14,33,58,34569,
+17,38,54,34569,
+12,28,61,34569,
+3,44,52,34569,
+33,38,46,34569,
+27,28,56,34569,
+22,42,49,34569,
+14,22,63,34569,
+12,32,59,34569,
+26,42,47,34569,
+18,46,47,34569,
+12,37,56,34569,
+4,12,67,34569,
+5,32,60,34569,
+18,31,58,34569,
+32,40,45,34569,
+16,37,55,34569,
+5,40,55,34569,
+37,40,41,34606,
+32,35,49,34606,
+17,35,56,34606,
+29,40,47,34606,
+20,35,55,34606,
+20,43,49,34606,
+5,23,64,34606,
+20,23,61,34606,
+28,29,55,34606,
+5,20,65,34606,
+13,16,65,34606,
+1,5,68,34606,
+8,19,65,34606,
+21,27,59,34606,
+21,31,57,34606,
+15,45,49,34606,
+27,39,49,34606,
+9,9,67,34606,
+9,33,59,34606,
+23,39,51,34606,
+5,45,51,34606,
+31,33,51,34606,
+10,14,66,34606,
+18,22,62,34606,
+38,38,42,34612,
+6,46,50,34612,
+10,43,52,34612,
+8,10,67,34612,
+4,34,59,34612,
+21,36,54,34612,
+2,5,68,34612,
+28,37,50,34612,
+18,27,60,34612,
+5,28,62,34612,
+16,26,61,34612,
+8,35,58,34612,
+26,29,56,34612,
+19,34,56,34612,
+20,38,53,34612,
+18,45,48,34612,
+14,19,64,34612,
+18,19,63,34612,
+3,26,63,34612,
+17,42,51,34612,
+9,27,62,34612,
+9,42,53,34612,
+18,39,53,34612,
+26,27,57,34612,
+3,17,66,34612,
+37,39,42,34636,
+6,37,57,34636,
+27,30,55,34636,
+28,44,44,34636,
+4,4,68,34636,
+4,44,52,34636,
+7,48,48,34636,
+29,30,54,34636,
+15,36,56,34636,
+6,30,61,34636,
+0,39,56,34636,
+30,34,51,34636,
+12,47,48,34636,
+27,35,52,34636,
+0,13,67,34636,
+0,43,53,34636,
+23,23,60,34636,
+25,28,57,34636,
+17,20,63,34636,
+1,39,56,34636,
diff --git a/src/cf_interface.h b/src/cf_interface.h
new file mode 100644
index 0000000..95809b0
--- /dev/null
+++ b/src/cf_interface.h
@@ -0,0 +1,23 @@
+#ifndef CF_INTERFACE_H
+#define CF_INTERFACE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_CF_INTERFACE
+
+#ifndef __CFORTRAN_LOADED
+#ifdef __clang__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wreserved-id-macro"
+# endif
+# include "cfortran.h"
+# ifdef __clang__
+# pragma GCC diagnostic pop
+# endif
+#endif
+
+#endif
+
+#endif
diff --git a/src/cfortran.h b/src/cfortran.h
new file mode 100644
index 0000000..222faba
--- /dev/null
+++ b/src/cfortran.h
@@ -0,0 +1,2559 @@
+/* cfortran.h 4.4 */
+/* http://www-zeus.desy.de/~burow/cfortran/ */
+/* Burkhard Burow burow at desy.de 1990 - 2002. */
+
+#ifndef __CFORTRAN_LOADED
+#define __CFORTRAN_LOADED
+
+/*
+ THIS FILE IS PROPERTY OF BURKHARD BUROW. IF YOU ARE USING THIS FILE YOU
+ SHOULD ALSO HAVE ACCESS TO CFORTRAN.DOC WHICH PROVIDES TERMS FOR USING,
+ MODIFYING, COPYING AND DISTRIBUTING THE CFORTRAN.H PACKAGE.
+*/
+
+/* THIS PACKAGE, I.E. CFORTRAN.H, THIS DOCUMENT, AND THE CFORTRAN.H EXAMPLE
+PROGRAMS ARE PROPERTY OF THE AUTHOR WHO RESERVES ALL RIGHTS. THIS PACKAGE AND
+THE CODE IT PRODUCES MAY BE FREELY DISTRIBUTED WITHOUT FEES, SUBJECT
+(AT YOUR CHOICE) EITHER TO THE GNU LIBRARY GENERAL PUBLIC LICENSE
+AT http://www.gnu.org/licenses/lgpl.html OR TO THE FOLLOWING RESTRICTIONS:
+- YOU MUST ACCOMPANY ANY COPIES OR DISTRIBUTION WITH THIS (UNALTERED) NOTICE.
+- YOU MAY NOT RECEIVE MONEY FOR THE DISTRIBUTION OR FOR ITS MEDIA
+ (E.G. TAPE, DISK, COMPUTER, PAPER.)
+- YOU MAY NOT PREVENT OTHERS FROM COPYING IT FREELY.
+- YOU MAY NOT DISTRIBUTE MODIFIED VERSIONS WITHOUT CLEARLY DOCUMENTING YOUR
+ CHANGES AND NOTIFYING THE AUTHOR.
+- YOU MAY NOT MISREPRESENTED THE ORIGIN OF THIS SOFTWARE, EITHER BY EXPLICIT
+ CLAIM OR BY OMISSION.
+
+THE INTENT OF THE ABOVE TERMS IS TO ENSURE THAT THE CFORTRAN.H PACKAGE NOT BE
+USED FOR PROFIT MAKING ACTIVITIES UNLESS SOME ROYALTY ARRANGEMENT IS ENTERED
+INTO WITH ITS AUTHOR.
+
+THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST
+OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. THE AUTHOR IS NOT RESPONSIBLE
+FOR ANY SUPPORT OR SERVICE OF THE CFORTRAN.H PACKAGE.
+
+ Burkhard Burow
+ burow at desy.de
+*/
+
+/* The following modifications were made by the authors of CFITSIO or by me.
+ * They are flagged below with CFITSIO, the author's initials, or KMCCARTY.
+ * PDW = Peter Wilson
+ * DM = Doug Mink
+ * LEB = Lee E Brotzman
+ * MR = Martin Reinecke
+ * WDP = William D Pence
+ * BR = Bastien ROUCARIES
+ * -- Kevin McCarty, for Debian (19 Dec. 2005) */
+
+/*******
+ Modifications:
+ Oct 1997: Changed symbol name extname to appendus (PDW/HSTX)
+ (Conflicted with a common variable name in FTOOLS)
+ Nov 1997: If g77Fortran defined, also define f2cFortran (PDW/HSTX)
+ Feb 1998: Let VMS see the NUM_ELEMS code. Lets programs treat
+ single strings as vectors with single elements
+ Nov 1999: If macintoxh defined, also define f2cfortran (for Mac OS-X)
+ Apr 2000: If WIN32 defined, also define PowerStationFortran and
+ VISUAL_CPLUSPLUS (Visual C++)
+ Jun 2000: If __GNUC__ and linux defined, also define f2cFortran
+ (linux/gcc environment detection)
+ Apr 2002: If __CYGWIN__ is defined, also define f2cFortran
+ Nov 2002: If __APPLE__ defined, also define f2cfortran (for Mac OS-X)
+
+ Nov 2003: If __INTEL_COMPILER or INTEL_COMPILER defined, also define
+ f2cFortran (KMCCARTY)
+ Dec 2005: If f2cFortran is defined, enforce REAL functions in FORTRAN
+ returning "double" in C. This was one of the items on
+ Burkhard's TODO list. (KMCCARTY)
+ Dec 2005: Modifications to support 8-byte integers. (MR)
+ USE AT YOUR OWN RISK!
+ Feb 2006 Added logic to typedef the symbol 'LONGLONG' to an appropriate
+ intrinsic 8-byte integer datatype (WDP)
+ Apr 2006: Modifications to support gfortran (and g77 with -fno-f2c flag)
+ since by default it returns "float" for FORTRAN REAL function.
+ (KMCCARTY)
+ May 2008: Revert commenting out of "extern" in COMMON_BLOCK_DEF macro.
+ Add braces around do-nothing ";" in 3 empty while blocks to
+ get rid of compiler warnings. Thanks to ROOT developers
+ Jacek Holeczek and Rene Brun for these suggestions. (KMCCARTY)
+ Aug 2008: If __GNUC__ is defined and no FORTRAN compiler is specified
+ via a #define or -D, default to gfortran behavior rather than
+ g77 behavior. (KMCCARTY)
+ Oct 2009: Add warning if guessing default fortran. Move g77 above guessing bloc
+ *******/
+
+/*
+ Avoid symbols already used by compilers and system *.h:
+ __ - OSF1 zukal06 V3.0 347 alpha, cc -c -std1 cfortest.c
+
+*/
+
+/*
+ Determine what 8-byte integer data type is available.
+ 'long long' is now supported by most compilers, but older
+ MS Visual C++ compilers before V7.0 use '__int64' instead. (WDP)
+*/
+
+#ifndef LONGLONG_TYPE /* this may have been previously defined */
+#if defined(_MSC_VER) /* Microsoft Visual C++ */
+
+#if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */
+ typedef __int64 LONGLONG;
+#else /* newer versions do support 'long long' */
+ typedef long long LONGLONG;
+#endif
+
+#else
+ typedef long long LONGLONG;
+#endif
+
+#define LONGLONG_TYPE
+#endif
+
+
+/* First prepare for the C compiler. */
+
+#ifndef ANSI_C_preprocessor /* i.e. user can override. */
+#ifdef __CF__KnR
+#define ANSI_C_preprocessor 0
+#else
+#ifdef __STDC__
+#define ANSI_C_preprocessor 1
+#else
+#define _cfleft 1
+#define _cfright
+#define _cfleft_cfright 0
+#define ANSI_C_preprocessor _cfleft/**/_cfright
+#endif
+#endif
+#endif
+
+#if ANSI_C_preprocessor
+#define _0(A,B) A##B
+#define _(A,B) _0(A,B) /* see cat,xcat of K&R ANSI C p. 231 */
+#define _2(A,B) A##B /* K&R ANSI C p.230: .. identifier is not replaced */
+#define _3(A,B,C) _(A,_(B,C))
+#else /* if it turns up again during rescanning. */
+#define _(A,B) A/**/B
+#define _2(A,B) A/**/B
+#define _3(A,B,C) A/**/B/**/C
+#endif
+
+#if (defined(vax)&&defined(unix)) || (defined(__vax__)&&defined(__unix__))
+#define VAXUltrix
+#endif
+
+#include <stdio.h> /* NULL [in all machines stdio.h] */
+#include <string.h> /* strlen, memset, memcpy, memchr. */
+#if !( defined(VAXUltrix) || defined(sun) || (defined(apollo)&&!defined(__STDCPP__)) )
+#include <stdlib.h> /* malloc,free */
+#else
+#include <malloc.h> /* Had to be removed for DomainOS h105 10.4 sys5.3 425t*/
+#ifdef apollo
+#define __CF__APOLLO67 /* __STDCPP__ is in Apollo 6.8 (i.e. ANSI) and onwards */
+#endif
+#endif
+
+#if !defined(__GNUC__) && !defined(__sun) && (defined(sun)||defined(VAXUltrix)||defined(lynx))
+#define __CF__KnR /* Sun, LynxOS and VAX Ultrix cc only supports K&R. */
+ /* Manually define __CF__KnR for HP if desired/required.*/
+#endif /* i.e. We will generate Kernighan and Ritchie C. */
+/* Note that you may define __CF__KnR before #include cfortran.h, in order to
+generate K&R C instead of the default ANSI C. The differences are mainly in the
+function prototypes and declarations. All machines, except the Apollo, work
+with either style. The Apollo's argument promotion rules require ANSI or use of
+the obsolete std_$call which we have not implemented here. Hence on the Apollo,
+only C calling FORTRAN subroutines will work using K&R style.*/
+
+
+/* Remainder of cfortran.h depends on the Fortran compiler. */
+
+/* 11/29/2003 (KMCCARTY): add *INTEL_COMPILER symbols here */
+/* 04/05/2006 (KMCCARTY): add gFortran symbol here */
+#if defined(CLIPPERFortran) || defined(pgiFortran) || defined(__INTEL_COMPILER) || defined(INTEL_COMPILER) || defined(gFortran)
+#define f2cFortran
+#endif
+
+#if defined(g77Fortran) /* 11/03/97 PDW (CFITSIO) */
+#define f2cFortran
+#endif
+
+/* VAX/VMS does not let us \-split long #if lines. */
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
+/* If no Fortran compiler is given, we choose one for the machines we know. */
+#if defined(__GNUC__) || defined(WIN32) /* 10/2009 BR: warm if guess */
+#warning "Please specify the fortran compiler using -D flags. Try to guess the compiler used"
+#endif
+#if defined(lynx) || defined(VAXUltrix)
+#define f2cFortran /* Lynx: Only support f2c at the moment.
+ VAXUltrix: f77 behaves like f2c.
+ Support f2c or f77 with gcc, vcc with f2c.
+ f77 with vcc works, missing link magic for f77 I/O.*/
+#endif
+/* 04/13/00 DM (CFITSIO): Add these lines for NT */
+/* with PowerStationFortran and and Visual C++ */
+#if defined(WIN32) && !defined(__CYGWIN__)
+#define PowerStationFortran
+#define VISUAL_CPLUSPLUS
+#endif
+#if defined(__CYGWIN__) /* 04/11/02 LEB (CFITSIO) */
+#define f2cFortran
+#define gFortran /* 8/26/08 (KMCCARTY) */
+#endif
+#if defined(__GNUC__) && defined(linux) /* 06/21/00 PDW (CFITSIO) */
+#define f2cFortran
+#define gFortran /* 8/26/08 (KMCCARTY) */
+#endif
+#if defined(macintosh) /* 11/1999 (CFITSIO) */
+#define f2cFortran
+#define gFortran /* 8/26/08 (KMCCARTY) */
+#endif
+#if defined(__APPLE__) /* 11/2002 (CFITSIO) */
+#define f2cFortran
+#define gFortran /* 8/26/08 (KMCCARTY) */
+#endif
+#if defined(__hpux) /* 921107: Use __hpux instead of __hp9000s300 */
+#define hpuxFortran /* Should also allow hp9000s7/800 use.*/
+#endif
+#if defined(apollo)
+#define apolloFortran /* __CF__APOLLO67 also defines some behavior. */
+#endif
+#if defined(sun) || defined(__sun)
+#define sunFortran
+#endif
+#if defined(_IBMR2)
+#define IBMR2Fortran
+#endif
+#if defined(_CRAY)
+#define CRAYFortran /* _CRAYT3E also defines some behavior. */
+#endif
+#if defined(_SX)
+#define SXFortran
+#endif
+#if defined(mips) || defined(__mips)
+#define mipsFortran
+#endif
+#if defined(vms) || defined(__vms)
+#define vmsFortran
+#endif
+#if defined(__alpha) && defined(__unix__)
+#define DECFortran
+#endif
+#if defined(__convex__)
+#define CONVEXFortran
+#endif
+#if defined(VISUAL_CPLUSPLUS)
+#define PowerStationFortran
+#endif
+#endif /* ...Fortran */
+#endif /* ...Fortran */
+
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
+/* If your compiler barfs on ' #error', replace # with the trigraph for # */
+ #error "cfortran.h: Can't find your environment among:\
+ - GNU gcc (gfortran) on Linux. \
+ - MIPS cc and f77 2.0. (e.g. Silicon Graphics, DECstations, ...) \
+ - IBM AIX XL C and FORTRAN Compiler/6000 Version 01.01.0000.0000 \
+ - VAX VMS CC 3.1 and FORTRAN 5.4. \
+ - Alpha VMS DEC C 1.3 and DEC FORTRAN 6.0. \
+ - Alpha OSF DEC C and DEC Fortran for OSF/1 AXP Version 1.2 \
+ - Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7. \
+ - CRAY \
+ - NEC SX-4 SUPER-UX \
+ - CONVEX \
+ - Sun \
+ - PowerStation Fortran with Visual C++ \
+ - HP9000s300/s700/s800 Latest test with: HP-UX A.08.07 A 9000/730 \
+ - LynxOS: cc or gcc with f2c. \
+ - VAXUltrix: vcc,cc or gcc with f2c. gcc or cc with f77. \
+ - f77 with vcc works; but missing link magic for f77 I/O. \
+ - NO fort. None of gcc, cc or vcc generate required names.\
+ - f2c/g77: Use #define f2cFortran, or cc -Df2cFortran \
+ - gfortran: Use #define gFortran, or cc -DgFortran \
+ (also necessary for g77 with -fno-f2c option) \
+ - NAG f90: Use #define NAGf90Fortran, or cc -DNAGf90Fortran \
+ - Absoft UNIX F77: Use #define AbsoftUNIXFortran or cc -DAbsoftUNIXFortran \
+ - Absoft Pro Fortran: Use #define AbsoftProFortran \
+ - Portland Group Fortran: Use #define pgiFortran \
+ - Intel Fortran: Use #define INTEL_COMPILER"
+/* Compiler must throw us out at this point! */
+#endif
+#endif
+
+
+#if defined(VAXC) && !defined(__VAXC)
+#define OLD_VAXC
+#pragma nostandard /* Prevent %CC-I-PARAMNOTUSED. */
+#endif
+
+/* Throughout cfortran.h we use: UN = Uppercase Name. LN = Lowercase Name. */
+
+/* "extname" changed to "appendus" below (CFITSIO) */
+#if defined(f2cFortran) || defined(NAGf90Fortran) || defined(DECFortran) || defined(mipsFortran) || defined(apolloFortran) || defined(sunFortran) || defined(CONVEXFortran) || defined(SXFortran) || defined(appendus)
+#define CFC_(UN,LN) _(LN,_) /* Lowercase FORTRAN symbols. */
+#define orig_fcallsc(UN,LN) CFC_(UN,LN)
+#else
+#if defined(CRAYFortran) || defined(PowerStationFortran) || defined(AbsoftProFortran)
+#ifdef _CRAY /* (UN), not UN, circumvents CRAY preprocessor bug. */
+#define CFC_(UN,LN) (UN) /* Uppercase FORTRAN symbols. */
+#else /* At least VISUAL_CPLUSPLUS barfs on (UN), so need UN. */
+#define CFC_(UN,LN) UN /* Uppercase FORTRAN symbols. */
+#endif
+#define orig_fcallsc(UN,LN) CFC_(UN,LN) /* CRAY insists on arg.'s here. */
+#else /* For following machines one may wish to change the fcallsc default. */
+#define CF_SAME_NAMESPACE
+#ifdef vmsFortran
+#define CFC_(UN,LN) LN /* Either case FORTRAN symbols. */
+ /* BUT we usually use UN for C macro to FORTRAN routines, so use LN here,*/
+ /* because VAX/VMS doesn't do recursive macros. */
+#define orig_fcallsc(UN,LN) UN
+#else /* HP-UX without +ppu or IBMR2 without -qextname. NOT reccomended. */
+#define CFC_(UN,LN) LN /* Lowercase FORTRAN symbols. */
+#define orig_fcallsc(UN,LN) CFC_(UN,LN)
+#endif /* vmsFortran */
+#endif /* CRAYFortran PowerStationFortran */
+#endif /* ....Fortran */
+
+#define fcallsc(UN,LN) orig_fcallsc(UN,LN)
+#define preface_fcallsc(P,p,UN,LN) CFC_(_(P,UN),_(p,LN))
+#define append_fcallsc(P,p,UN,LN) CFC_(_(UN,P),_(LN,p))
+
+#define C_FUNCTION(UN,LN) fcallsc(UN,LN)
+#define FORTRAN_FUNCTION(UN,LN) CFC_(UN,LN)
+
+#ifndef COMMON_BLOCK
+#ifndef CONVEXFortran
+#ifndef CLIPPERFortran
+#if !(defined(AbsoftUNIXFortran)||defined(AbsoftProFortran))
+#define COMMON_BLOCK(UN,LN) CFC_(UN,LN)
+#else
+#define COMMON_BLOCK(UN,LN) _(_C,LN)
+#endif /* AbsoftUNIXFortran or AbsoftProFortran */
+#else
+#define COMMON_BLOCK(UN,LN) _(LN,__)
+#endif /* CLIPPERFortran */
+#else
+#define COMMON_BLOCK(UN,LN) _3(_,LN,_)
+#endif /* CONVEXFortran */
+#endif /* COMMON_BLOCK */
+
+#ifndef DOUBLE_PRECISION
+#if defined(CRAYFortran) && !defined(_CRAYT3E)
+#define DOUBLE_PRECISION long double
+#else
+#define DOUBLE_PRECISION double
+#endif
+#endif
+
+#ifndef FORTRAN_REAL
+#if defined(CRAYFortran) && defined(_CRAYT3E)
+#define FORTRAN_REAL double
+#else
+#define FORTRAN_REAL float
+#endif
+#endif
+
+#ifdef CRAYFortran
+#ifdef _CRAY
+#include <fortran.h>
+#else
+#include "fortran.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+#define FLOATVVVVVVV_cfPP (FORTRAN_REAL *) /* Used for C calls FORTRAN. */
+/* CRAY's double==float but CRAY says pointers to doubles and floats are diff.*/
+#define VOIDP (void *) /* When FORTRAN calls C, we don't know if C routine
+ arg.'s have been declared float *, or double *. */
+#else
+#define FLOATVVVVVVV_cfPP
+#define VOIDP
+#endif
+
+#ifdef vmsFortran
+#if defined(vms) || defined(__vms)
+#include <descrip.h>
+#else
+#include "descrip.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+#endif
+
+#ifdef sunFortran
+#if defined(sun) || defined(__sun)
+#include <math.h> /* Sun's FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT. */
+#else
+#include "math.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+/* At least starting with the default C compiler SC3.0.1 of SunOS 5.3,
+ * FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT are not required and not in
+ * <math.h>, since sun C no longer promotes C float return values to doubles.
+ * Therefore, only use them if defined.
+ * Even if gcc is being used, assume that it exhibits the Sun C compiler
+ * behavior in order to be able to use *.o from the Sun C compiler.
+ * i.e. If FLOATFUNCTIONTYPE, etc. are in math.h, they required by gcc.
+ */
+#endif
+
+#ifndef apolloFortran
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) extern DEFINITION NAME
+#define CF_NULL_PROTO
+#else /* HP doesn't understand #elif. */
+/* Without ANSI prototyping, Apollo promotes float functions to double. */
+/* Note that VAX/VMS, IBM, Mips choke on 'type function(...);' prototypes. */
+#define CF_NULL_PROTO ...
+#ifndef __CF__APOLLO67
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) \
+ DEFINITION NAME __attribute((__section(NAME)))
+#else
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) \
+ DEFINITION NAME #attribute[section(NAME)]
+#endif
+#endif
+
+#ifdef __cplusplus
+#undef CF_NULL_PROTO
+#define CF_NULL_PROTO ...
+#endif
+
+
+#ifndef USE_NEW_DELETE
+#ifdef __cplusplus
+#define USE_NEW_DELETE 1
+#else
+#define USE_NEW_DELETE 0
+#endif
+#endif
+#if USE_NEW_DELETE
+#define _cf_malloc(N) new char[N]
+#define _cf_free(P) delete[] P
+#else
+#define _cf_malloc(N) (char *)malloc(N)
+#define _cf_free(P) free(P)
+#endif
+
+#ifdef mipsFortran
+#define CF_DECLARE_GETARG int f77argc; char **f77argv
+#define CF_SET_GETARG(ARGC,ARGV) f77argc = ARGC; f77argv = ARGV
+#else
+#define CF_DECLARE_GETARG
+#define CF_SET_GETARG(ARGC,ARGV)
+#endif
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define AcfCOMMA ,
+#define AcfCOLON ;
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES USED WITHIN CFORTRAN.H */
+
+#define _cfMIN(A,B) (A<B?A:B)
+
+/* 970211 - XIX.145:
+ firstindexlength - better name is all_but_last_index_lengths
+ secondindexlength - better name is last_index_length
+ */
+#define firstindexlength(A) (sizeof(A[0])==1 ? 1 : (sizeof(A) / sizeof(A[0])) )
+#define secondindexlength(A) (sizeof(A[0])==1 ? sizeof(A) : sizeof(A[0]) )
+
+/* Behavior of FORTRAN LOGICAL. All machines' LOGICAL is same size as C's int.
+Conversion is automatic except for arrays which require F2CLOGICALV/C2FLOGICALV.
+f2c, MIPS f77 [DECstation, SGI], VAX Ultrix f77,
+HP-UX f77 : as in C.
+VAX/VMS FORTRAN, VAX Ultrix fort,
+Absoft Unix Fortran, IBM RS/6000 xlf : LS Bit = 0/1 = TRUE/FALSE.
+Apollo : neg. = TRUE, else FALSE.
+[Apollo accepts -1 as TRUE for function values, but NOT all other neg. values.]
+[DECFortran for Ultrix RISC is also called f77 but is the same as VAX/VMS.]
+[MIPS f77 treats .eqv./.neqv. as .eq./.ne. and hence requires LOGICAL_STRICT.]*/
+
+#if defined(NAGf90Fortran) || defined(f2cFortran) || defined(mipsFortran) || defined(PowerStationFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran) || defined(SXFortran)
+/* SX/PowerStationFortran have 0 and 1 defined, others are neither T nor F. */
+/* hpuxFortran800 has 0 and 0x01000000 defined. Others are unknown. */
+#define LOGICAL_STRICT /* Other Fortran have .eqv./.neqv. == .eq./.ne. */
+#endif
+
+#define C2FLOGICALV(A,I) \
+ do {int __i; for(__i=0;__i<I;__i++) A[__i]=C2FLOGICAL(A[__i]); } while (0)
+#define F2CLOGICALV(A,I) \
+ do {int __i; for(__i=0;__i<I;__i++) A[__i]=F2CLOGICAL(A[__i]); } while (0)
+
+#if defined(apolloFortran)
+#define C2FLOGICAL(L) ((L)?-1:(L)&~((unsigned)1<<sizeof(int)*8-1))
+#define F2CLOGICAL(L) ((L)<0?(L):0)
+#else
+#if defined(CRAYFortran)
+#define C2FLOGICAL(L) _btol(L)
+#define F2CLOGICAL(L) _ltob(&(L)) /* Strangely _ltob() expects a pointer. */
+#else
+#if defined(IBMR2Fortran) || defined(vmsFortran) || defined(DECFortran) || defined(AbsoftUNIXFortran)
+/* How come no AbsoftProFortran ? */
+#define C2FLOGICAL(L) ((L)?(L)|1:(L)&~(int)1)
+#define F2CLOGICAL(L) ((L)&1?(L):0)
+#else
+#if defined(CONVEXFortran)
+#define C2FLOGICAL(L) ((L) ? ~0 : 0 )
+#define F2CLOGICAL(L) (L)
+#else /* others evaluate LOGICALs as for C. */
+#define C2FLOGICAL(L) (L)
+#define F2CLOGICAL(L) (L)
+#ifndef LOGICAL_STRICT
+#undef C2FLOGICALV
+#undef F2CLOGICALV
+#define C2FLOGICALV(A,I)
+#define F2CLOGICALV(A,I)
+#endif /* LOGICAL_STRICT */
+#endif /* CONVEXFortran || All Others */
+#endif /* IBMR2Fortran vmsFortran DECFortran AbsoftUNIXFortran */
+#endif /* CRAYFortran */
+#endif /* apolloFortran */
+
+/* 970514 - In addition to CRAY, there may be other machines
+ for which LOGICAL_STRICT makes no sense. */
+#if defined(LOGICAL_STRICT) && !defined(CRAYFortran)
+/* Force C2FLOGICAL to generate only the values for either .TRUE. or .FALSE.
+ SX/PowerStationFortran only have 0 and 1 defined.
+ Elsewhere, only needed if you want to do:
+ logical lvariable
+ if (lvariable .eq. .true.) then ! (1)
+ instead of
+ if (lvariable .eqv. .true.) then ! (2)
+ - (1) may not even be FORTRAN/77 and that Apollo's f77 and IBM's xlf
+ refuse to compile (1), so you are probably well advised to stay away from
+ (1) and from LOGICAL_STRICT.
+ - You pay a (slight) performance penalty for using LOGICAL_STRICT. */
+#undef C2FLOGICAL
+#ifdef hpuxFortran800
+#define C2FLOGICAL(L) ((L)?0x01000000:0)
+#else
+#if defined(apolloFortran) || defined(vmsFortran) || defined(DECFortran)
+#define C2FLOGICAL(L) ((L)?-1:0) /* These machines use -1/0 for .true./.false.*/
+#else
+#define C2FLOGICAL(L) ((L)? 1:0) /* All others use +1/0 for .true./.false.*/
+#endif
+#endif
+#endif /* LOGICAL_STRICT */
+
+/* Convert a vector of C strings into FORTRAN strings. */
+#ifndef __CF__KnR
+static char *c2fstrv(char* cstr, char *fstr, int elem_len, int sizeofcstr)
+#else
+static char *c2fstrv( cstr, fstr, elem_len, sizeofcstr)
+ char* cstr; char *fstr; int elem_len; int sizeofcstr;
+#endif
+{ int i,j;
+/* elem_len includes \0 for C strings. Fortran strings don't have term. \0.
+ Useful size of string must be the same in both languages. */
+for (i=0; i<sizeofcstr/elem_len; i++) {
+ for (j=1; j<elem_len && *cstr; j++) *fstr++ = *cstr++;
+ cstr += 1+elem_len-j;
+ for (; j<elem_len; j++) *fstr++ = ' ';
+} /* 95109 - Seems to be returning the original fstr. */
+return fstr-sizeofcstr+sizeofcstr/elem_len; }
+
+/* Convert a vector of FORTRAN strings into C strings. */
+#ifndef __CF__KnR
+static char *f2cstrv(char *fstr, char* cstr, int elem_len, int sizeofcstr)
+#else
+static char *f2cstrv( fstr, cstr, elem_len, sizeofcstr)
+ char *fstr; char* cstr; int elem_len; int sizeofcstr;
+#endif
+{ int i,j;
+/* elem_len includes \0 for C strings. Fortran strings don't have term. \0.
+ Useful size of string must be the same in both languages. */
+cstr += sizeofcstr;
+fstr += sizeofcstr - sizeofcstr/elem_len;
+for (i=0; i<sizeofcstr/elem_len; i++) {
+ *--cstr = '\0';
+ for (j=1; j<elem_len; j++) *--cstr = *--fstr;
+} return cstr; }
+
+/* kill the trailing char t's in string s. */
+#ifndef __CF__KnR
+static char *kill_trailing(char *s, char t)
+#else
+static char *kill_trailing( s, t) char *s; char t;
+#endif
+{char *e;
+e = s + strlen(s);
+if (e>s) { /* Need this to handle NULL string.*/
+ while (e>s && *--e==t) {;} /* Don't follow t's past beginning. */
+ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
+} return s; }
+
+#ifndef __CF__KnR
+static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term);
+#endif
+/* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally
+points to the terminating '\0' of s, but may actually point to anywhere in s.
+s's new '\0' will be placed at e or earlier in order to remove any trailing t's.
+If e<s string s is left unchanged. */
+#ifndef __CF__KnR
+static char *kill_trailingn(char *s, char t, char *e)
+#else
+static char *kill_trailingn( s, t, e) char *s; char t; char *e;
+#endif
+{
+if (e==s) *e = '\0'; /* Kill the string makes sense here.*/
+else if (e>s) { /* Watch out for neg. length string.*/
+ while (e>s && *--e==t){;} /* Don't follow t's past beginning. */
+ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
+}
+(void)num_elem; /* to prevent not used warnings in gcc (added by TJ) */
+
+ return s; }
+
+/* Note the following assumes that any element which has t's to be chopped off,
+does indeed fill the entire element. */
+#ifndef __CF__KnR
+static char *vkill_trailing(char* cstr, int elem_len, int sizeofcstr, char t)
+#else
+static char *vkill_trailing( cstr, elem_len, sizeofcstr, t)
+ char* cstr; int elem_len; int sizeofcstr; char t;
+#endif
+{ int i;
+for (i=0; i<sizeofcstr/elem_len; i++) /* elem_len includes \0 for C strings. */
+ kill_trailingn(cstr+elem_len*i,t,cstr+elem_len*(i+1)-1);
+return cstr; }
+
+#ifdef vmsFortran
+typedef struct dsc$descriptor_s fstring;
+#define DSC$DESCRIPTOR_A(DIMCT) \
+struct { \
+ unsigned short dsc$w_length; unsigned char dsc$b_dtype; \
+ unsigned char dsc$b_class; char *dsc$a_pointer; \
+ char dsc$b_scale; unsigned char dsc$b_digits; \
+ struct { \
+ unsigned : 3; unsigned dsc$v_fl_binscale : 1; \
+ unsigned dsc$v_fl_redim : 1; unsigned dsc$v_fl_column : 1; \
+ unsigned dsc$v_fl_coeff : 1; unsigned dsc$v_fl_bounds : 1; \
+ } dsc$b_aflags; \
+ unsigned char dsc$b_dimct; unsigned long dsc$l_arsize; \
+ char *dsc$a_a0; long dsc$l_m [DIMCT]; \
+ struct { \
+ long dsc$l_l; long dsc$l_u; \
+ } dsc$bounds [DIMCT]; \
+}
+typedef DSC$DESCRIPTOR_A(1) fstringvector;
+/*typedef DSC$DESCRIPTOR_A(2) fstringarrarr;
+ typedef DSC$DESCRIPTOR_A(3) fstringarrarrarr;*/
+#define initfstr(F,C,ELEMNO,ELEMLEN) \
+( (F).dsc$l_arsize= ( (F).dsc$w_length =(ELEMLEN) ) \
+ *( (F).dsc$l_m[0]=(F).dsc$bounds[0].dsc$l_u=(ELEMNO) ), \
+ (F).dsc$a_a0 = ( (F).dsc$a_pointer=(C) ) - (F).dsc$w_length ,(F))
+
+#endif /* PDW: 2/10/98 (CFITSIO) -- Let VMS see NUM_ELEMS definitions */
+#define _NUM_ELEMS -1
+#define _NUM_ELEM_ARG -2
+#define NUM_ELEMS(A) A,_NUM_ELEMS
+#define NUM_ELEM_ARG(B) *_2(A,B),_NUM_ELEM_ARG
+#define TERM_CHARS(A,B) A,B
+#ifndef __CF__KnR
+static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term)
+#else
+static int num_elem( strv, elem_len, term_char, num_term)
+ char *strv; unsigned elem_len; int term_char; int num_term;
+#endif
+/* elem_len is the number of characters in each element of strv, the FORTRAN
+vector of strings. The last element of the vector must begin with at least
+num_term term_char characters, so that this routine can determine how
+many elements are in the vector. */
+{
+unsigned num,i;
+if (num_term == _NUM_ELEMS || num_term == _NUM_ELEM_ARG)
+ return term_char;
+if (num_term <=0) num_term = (int)elem_len;
+for (num=0; ; num++) {
+ for (i=0; i<(unsigned)num_term && *strv==term_char; i++,strv++){;}
+ if (i==(unsigned)num_term) break;
+ else strv += elem_len-i;
+}
+/* to prevent not used warnings in gcc (added by ROOT, changed by TJ
+ * because of unreachable warnings from clang) */
+(void)c2fstrv; (void)f2cstrv; (void)kill_trailing;
+(void)vkill_trailing; (void)num_elem;
+return (int)num;
+}
+/* #endif removed 2/10/98 (CFITSIO) */
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO USE STRINGS IN FORTRAN COMMON BLOCKS */
+
+/* C string TO Fortran Common Block STRing. */
+/* DIM is the number of DIMensions of the array in terms of strings, not
+ characters. e.g. char a[12] has DIM = 0, char a[12][4] has DIM = 1, etc. */
+#define C2FCBSTR(CSTR,FSTR,DIM) \
+ c2fstrv((char *)CSTR, (char *)FSTR, sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM))
+
+/* Fortran Common Block string TO C STRing. */
+#define FCB2CSTR(FSTR,CSTR,DIM) \
+ vkill_trailing(f2cstrv((char *)FSTR, (char *)CSTR, \
+ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM)), \
+ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM), ' ')
+
+#define cfDEREFERENCE0
+#define cfDEREFERENCE1 *
+#define cfDEREFERENCE2 **
+#define cfDEREFERENCE3 ***
+#define cfDEREFERENCE4 ****
+#define cfDEREFERENCE5 *****
+#define cfelementsof(A,D) (sizeof(A)/sizeof(_(cfDEREFERENCE,D)(A)))
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO CALL FORTRAN SUBROUTINES */
+
+/* Define lookup tables for how to handle the various types of variables. */
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#define ZTRINGV_NUM(I) I
+#define ZTRINGV_ARGFP(I) (*(_2(A,I))) /* Undocumented. For PINT, etc. */
+#define ZTRINGV_ARGF(I) _2(A,I)
+#ifdef CFSUBASFUN
+#define ZTRINGV_ARGS(I) ZTRINGV_ARGF(I)
+#else
+#define ZTRINGV_ARGS(I) _2(B,I)
+#endif
+
+#define PBYTE_cfVP(A,B) PINT_cfVP(A,B)
+#define PDOUBLE_cfVP(A,B)
+#define PFLOAT_cfVP(A,B)
+#ifdef ZTRINGV_ARGS_allows_Pvariables
+/* This allows Pvariables for ARGS. ARGF machinery is above ARGFP.
+ * B is not needed because the variable may be changed by the Fortran routine,
+ * but because B is the only way to access an arbitrary macro argument. */
+#define PINT_cfVP(A,B) int B = (int)A; /* For ZSTRINGV_ARGS */
+#else
+#define PINT_cfVP(A,B)
+#endif
+#define PLOGICAL_cfVP(A,B) int *B; /* Returning LOGICAL in FUNn and SUBn */
+#define PLONG_cfVP(A,B) PINT_cfVP(A,B)
+#define PSHORT_cfVP(A,B) PINT_cfVP(A,B)
+
+#define VCF_INT_S(T,A,B) _(T,VVVVVVV_cfTYPE) B = A;
+#define VCF_INT_F(T,A,B) _(T,_cfVCF)(A,B)
+/* _cfVCF table is directly mapped to _cfCCC table. */
+#define BYTE_cfVCF(A,B)
+#define DOUBLE_cfVCF(A,B)
+#if !defined(__CF__KnR)
+#define FLOAT_cfVCF(A,B)
+#else
+#define FLOAT_cfVCF(A,B) FORTRAN_REAL B = A;
+#endif
+#define INT_cfVCF(A,B)
+#define LOGICAL_cfVCF(A,B)
+#define LONG_cfVCF(A,B)
+#define SHORT_cfVCF(A,B)
+
+/* 980416
+ Cast (void (*)(CF_NULL_PROTO)) causes SunOS CC 4.2 occasionally to barf,
+ while the following equivalent typedef is fine.
+ For consistency use the typedef on all machines.
+ */
+typedef void (*cfCAST_FUNCTION)(CF_NULL_PROTO);
+
+#define VCF(TN,I) _Icf4(4,V,TN,_(A,I),_(B,I),F)
+#define VVCF(TN,AI,BI) _Icf4(4,V,TN,AI,BI,S)
+#define INT_cfV(T,A,B,F) _(VCF_INT_,F)(T,A,B)
+#define INTV_cfV(T,A,B,F)
+#define INTVV_cfV(T,A,B,F)
+#define INTVVV_cfV(T,A,B,F)
+#define INTVVVV_cfV(T,A,B,F)
+#define INTVVVVV_cfV(T,A,B,F)
+#define INTVVVVVV_cfV(T,A,B,F)
+#define INTVVVVVVV_cfV(T,A,B,F)
+#define PINT_cfV( T,A,B,F) _(T,_cfVP)(A,B)
+#define PVOID_cfV( T,A,B,F)
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define ROUTINE_cfV(T,A,B,F) void (*B)(CF_NULL_PROTO) = (cfCAST_FUNCTION)A;
+#else
+#define ROUTINE_cfV(T,A,B,F)
+#endif
+#define SIMPLE_cfV(T,A,B,F)
+#ifdef vmsFortran
+#define STRING_cfV(T,A,B,F) static struct {fstring f; unsigned clen;} B = \
+ {{0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL},0};
+#define PSTRING_cfV(T,A,B,F) static fstring B={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL};
+#define STRINGV_cfV(T,A,B,F) static fstringvector B = \
+ {sizeof(A),DSC$K_DTYPE_T,DSC$K_CLASS_A,NULL,0,0,{0,0,1,1,1},1,0,NULL,0,{1,0}};
+#define PSTRINGV_cfV(T,A,B,F) static fstringvector B = \
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_A,NULL,0,0,{0,0,1,1,1},1,0,NULL,0,{1,0}};
+#else
+#define STRING_cfV(T,A,B,F) struct {unsigned int clen, flen; char *nombre;} B;
+#define STRINGV_cfV(T,A,B,F) struct {char *s, *fs; unsigned flen; char *nombre;} B;
+#define PSTRING_cfV(T,A,B,F) int B;
+#define PSTRINGV_cfV(T,A,B,F) struct{char *fs; unsigned int sizeofA,flen;}B;
+#endif
+#define ZTRINGV_cfV(T,A,B,F) STRINGV_cfV(T,A,B,F)
+#define PZTRINGV_cfV(T,A,B,F) PSTRINGV_cfV(T,A,B,F)
+
+/* Note that the actions of the A table were performed inside the AA table.
+ VAX Ultrix vcc, and HP-UX cc, didn't evaluate arguments to functions left to
+ right, so we had to split the original table into the current robust two. */
+#define ACF(NAME,TN,AI,I) _(TN,_cfSTR)(4,A,NAME,I,AI,_(B,I),0)
+#define DEFAULT_cfA(M,I,A,B)
+#define LOGICAL_cfA(M,I,A,B) B=C2FLOGICAL(B);
+#define PLOGICAL_cfA(M,I,A,B) A=C2FLOGICAL(A);
+#define STRING_cfA(M,I,A,B) STRING_cfC(M,I,A,B,sizeof(A))
+#define PSTRING_cfA(M,I,A,B) PSTRING_cfC(M,I,A,B,sizeof(A))
+#ifdef vmsFortran
+#define AATRINGV_cfA( A,B, sA,filA,silA) \
+ initfstr(B,_cf_malloc((sA)-(filA)),(filA),(silA)-1), \
+ c2fstrv(A,B.dsc$a_pointer,(silA),(sA));
+#define APATRINGV_cfA( A,B, sA,filA,silA) \
+ initfstr(B,A,(filA),(silA)-1),c2fstrv(A,A,(silA),(sA));
+#else
+#define AATRINGV_cfA( A,B, sA,filA,silA) \
+ (B.s=_cf_malloc((sA)-(filA)),B.fs=c2fstrv(A,B.s,(B.flen=(silA)-1)+1,(sA)));
+#define APATRINGV_cfA( A,B, sA,filA,silA) \
+ B.fs=c2fstrv(A,A,(B.flen=(silA)-1)+1,B.sizeofA=(sA));
+#endif
+#define STRINGV_cfA(M,I,A,B) \
+ AATRINGV_cfA((char *)A,B,sizeof(A),firstindexlength(A),secondindexlength(A))
+#define PSTRINGV_cfA(M,I,A,B) \
+ APATRINGV_cfA((char *)A,B,sizeof(A),firstindexlength(A),secondindexlength(A))
+#define ZTRINGV_cfA(M,I,A,B) AATRINGV_cfA( (char *)A,B, \
+ (_3(M,_ELEMS_,I))*(( _3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)),(_3(M,_ELEMLEN_,I))+1)
+#define PZTRINGV_cfA(M,I,A,B) APATRINGV_cfA( (char *)A,B, \
+ (_3(M,_ELEMS_,I))*(( _3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)),(_3(M,_ELEMLEN_,I))+1)
+
+#define PBYTE_cfAAP(A,B) &A
+#define PDOUBLE_cfAAP(A,B) &A
+#define PFLOAT_cfAAP(A,B) FLOATVVVVVVV_cfPP &A
+#define PINT_cfAAP(A,B) &A
+#define PLOGICAL_cfAAP(A,B) B= &A /* B used to keep a common W table. */
+#define PLONG_cfAAP(A,B) &A
+#define PSHORT_cfAAP(A,B) &A
+
+#define AACF(TN,AI,I,C) _SEP_(TN,C,cfCOMMA) _Icf(3,AA,TN,AI,_(B,I))
+#define INT_cfAA(T,A,B) &B
+#define INTV_cfAA(T,A,B) _(T,VVVVVV_cfPP) A
+#define INTVV_cfAA(T,A,B) _(T,VVVVV_cfPP) A[0]
+#define INTVVV_cfAA(T,A,B) _(T,VVVV_cfPP) A[0][0]
+#define INTVVVV_cfAA(T,A,B) _(T,VVV_cfPP) A[0][0][0]
+#define INTVVVVV_cfAA(T,A,B) _(T,VV_cfPP) A[0][0][0][0]
+#define INTVVVVVV_cfAA(T,A,B) _(T,V_cfPP) A[0][0][0][0][0]
+#define INTVVVVVVV_cfAA(T,A,B) _(T,_cfPP) A[0][0][0][0][0][0]
+#define PINT_cfAA(T,A,B) _(T,_cfAAP)(A,B)
+#define PVOID_cfAA(T,A,B) (void *) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfAA(T,A,B) &B
+#else
+#define ROUTINE_cfAA(T,A,B) (cfCAST_FUNCTION)A
+#endif
+#define STRING_cfAA(T,A,B) STRING_cfCC(T,A,B)
+#define PSTRING_cfAA(T,A,B) PSTRING_cfCC(T,A,B)
+#ifdef vmsFortran
+#define STRINGV_cfAA(T,A,B) &B
+#else
+#ifdef CRAYFortran
+#define STRINGV_cfAA(T,A,B) _cptofcd(B.fs,B.flen)
+#else
+#define STRINGV_cfAA(T,A,B) B.fs
+#endif
+#endif
+#define PSTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+#define ZTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+#define PZTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define JCF(TN,I)
+#define KCF(TN,I)
+#else
+#define JCF(TN,I) _(TN,_cfSTR)(1,J,_(B,I), 0,0,0,0)
+#if defined(AbsoftUNIXFortran)
+#define DEFAULT_cfJ(B) ,0
+#else
+#define DEFAULT_cfJ(B)
+#endif
+#define LOGICAL_cfJ(B) DEFAULT_cfJ(B)
+#define PLOGICAL_cfJ(B) DEFAULT_cfJ(B)
+#define STRING_cfJ(B) ,B.flen
+#define PSTRING_cfJ(B) ,B
+#define STRINGV_cfJ(B) STRING_cfJ(B)
+#define PSTRINGV_cfJ(B) STRING_cfJ(B)
+#define ZTRINGV_cfJ(B) STRING_cfJ(B)
+#define PZTRINGV_cfJ(B) STRING_cfJ(B)
+
+/* KCF is identical to DCF, except that KCF ZTRING is not empty. */
+#define KCF(TN,I) _(TN,_cfSTR)(1,KK,_(B,I), 0,0,0,0)
+#if defined(AbsoftUNIXFortran)
+#define DEFAULT_cfKK(B) , unsigned B
+#else
+#define DEFAULT_cfKK(B)
+#endif
+#define LOGICAL_cfKK(B) DEFAULT_cfKK(B)
+#define PLOGICAL_cfKK(B) DEFAULT_cfKK(B)
+#define STRING_cfKK(B) , unsigned B
+#define PSTRING_cfKK(B) STRING_cfKK(B)
+#define STRINGV_cfKK(B) STRING_cfKK(B)
+#define PSTRINGV_cfKK(B) STRING_cfKK(B)
+#define ZTRINGV_cfKK(B) STRING_cfKK(B)
+#define PZTRINGV_cfKK(B) STRING_cfKK(B)
+#endif
+
+#define WCF(TN,AN,I) _(TN,_cfSTR)(2,W,AN,_(B,I), 0,0,0)
+#define DEFAULT_cfW(A,B)
+#define LOGICAL_cfW(A,B)
+#define PLOGICAL_cfW(A,B) *B=F2CLOGICAL(*B);
+#define STRING_cfW(A,B) (B.nombre=A,B.nombre[B.clen]!='\0'?B.nombre[B.clen]='\0':0); /* A?="constnt"*/
+#define PSTRING_cfW(A,B) kill_trailing(A,' ');
+#ifdef vmsFortran
+#define STRINGV_cfW(A,B) _cf_free(B.dsc$a_pointer);
+#define PSTRINGV_cfW(A,B) \
+ vkill_trailing(f2cstrv((char*)A, (char*)A, \
+ B.dsc$w_length+1, B.dsc$l_arsize+B.dsc$l_m[0]), \
+ B.dsc$w_length+1, B.dsc$l_arsize+B.dsc$l_m[0], ' ');
+#else
+#define STRINGV_cfW(A,B) _cf_free(B.s);
+#define PSTRINGV_cfW(A,B) vkill_trailing( \
+ f2cstrv((char*)A,(char*)A,B.flen+1,B.sizeofA), B.flen+1,B.sizeofA,' ');
+#endif
+#define ZTRINGV_cfW(A,B) STRINGV_cfW(A,B)
+#define PZTRINGV_cfW(A,B) PSTRINGV_cfW(A,B)
+
+#define NCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _Icf(2,N,TN,_(A,I),0)
+#define NNCF(TN,I,C) UUCF(TN,I,C)
+#define NNNCF(TN,I,C) _SEP_(TN,C,cfCOLON) _Icf(2,N,TN,_(A,I),0)
+#define INT_cfN(T,A) _(T,VVVVVVV_cfTYPE) * A
+#define INTV_cfN(T,A) _(T,VVVVVV_cfTYPE) * A
+#define INTVV_cfN(T,A) _(T,VVVVV_cfTYPE) * A
+#define INTVVV_cfN(T,A) _(T,VVVV_cfTYPE) * A
+#define INTVVVV_cfN(T,A) _(T,VVV_cfTYPE) * A
+#define INTVVVVV_cfN(T,A) _(T,VV_cfTYPE) * A
+#define INTVVVVVV_cfN(T,A) _(T,V_cfTYPE) * A
+#define INTVVVVVVV_cfN(T,A) _(T,_cfTYPE) * A
+#define PINT_cfN(T,A) _(T,_cfTYPE) * A
+#define PVOID_cfN(T,A) void * A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfN(T,A) void (**A)(CF_NULL_PROTO)
+#else
+#define ROUTINE_cfN(T,A) void ( *A)(CF_NULL_PROTO)
+#endif
+#ifdef vmsFortran
+#define STRING_cfN(T,A) fstring * A
+#define STRINGV_cfN(T,A) fstringvector * A
+#else
+#ifdef CRAYFortran
+#define STRING_cfN(T,A) _fcd A
+#define STRINGV_cfN(T,A) _fcd A
+#else
+#define STRING_cfN(T,A) char * A
+#define STRINGV_cfN(T,A) char * A
+#endif
+#endif
+#define PSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PNSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PPSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PSTRINGV_cfN(T,A) STRINGV_cfN(T,A)
+#define ZTRINGV_cfN(T,A) STRINGV_cfN(T,A)
+#define PZTRINGV_cfN(T,A) PSTRINGV_cfN(T,A)
+
+
+/* Apollo 6.7, CRAY, old Sun, VAX/Ultrix vcc/cc and new ultrix
+ can't hack more than 31 arg's.
+ e.g. ultrix >= 4.3 gives message:
+ zow35> cc -c -DDECFortran cfortest.c
+ cfe: Fatal: Out of memory: cfortest.c
+ zow35>
+ Old __hpux had the problem, but new 'HP-UX A.09.03 A 9000/735' is fine
+ if using -Aa, otherwise we have a problem.
+ */
+#ifndef MAX_PREPRO_ARGS
+#if !defined(__GNUC__) && (defined(VAXUltrix) || defined(__CF__APOLLO67) || (defined(sun)&&!defined(__sun)) || defined(_CRAY) || defined(__ultrix__) || (defined(__hpux)&&defined(__CF__KnR)))
+#define MAX_PREPRO_ARGS 31
+#else
+#define MAX_PREPRO_ARGS 99
+#endif
+#endif
+
+#if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+/* In addition to explicit Absoft stuff, only Absoft requires:
+ - DEFAULT coming from _cfSTR.
+ DEFAULT could have been called e.g. INT, but keep it for clarity.
+ - M term in CFARGT14 and CFARGT14FS.
+ */
+#define ABSOFT_cf1(T0) _(T0,_cfSTR)(0,ABSOFT1,0,0,0,0,0)
+#define ABSOFT_cf2(T0) _(T0,_cfSTR)(0,ABSOFT2,0,0,0,0,0)
+#define ABSOFT_cf3(T0) _(T0,_cfSTR)(0,ABSOFT3,0,0,0,0,0)
+#define DEFAULT_cfABSOFT1
+#define LOGICAL_cfABSOFT1
+#define STRING_cfABSOFT1 ,MAX_LEN_FORTRAN_FUNCTION_STRING
+#define DEFAULT_cfABSOFT2
+#define LOGICAL_cfABSOFT2
+#define STRING_cfABSOFT2 ,unsigned D0
+#define DEFAULT_cfABSOFT3
+#define LOGICAL_cfABSOFT3
+#define STRING_cfABSOFT3 ,D0
+#else
+#define ABSOFT_cf1(T0)
+#define ABSOFT_cf2(T0)
+#define ABSOFT_cf3(T0)
+#endif
+
+/* _Z introduced to cicumvent IBM and HP silly preprocessor warning.
+ e.g. "Macro CFARGT14 invoked with a null argument."
+ */
+#define _Z
+
+#define CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14)
+#define CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \
+ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \
+ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27)
+
+#define CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CFARGT27FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \
+ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \
+ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+
+#if !(defined(PowerStationFortran)||defined(hpuxFortran800))
+/* Old CFARGT14 -> CFARGT14FS as seen below, for Absoft cross-compile yields:
+ SunOS> cc -c -Xa -DAbsoftUNIXFortran c.c
+ "c.c", line 406: warning: argument mismatch
+ Haven't checked if this is ANSI C or a SunOS bug. SunOS -Xs works ok.
+ Behavior is most clearly seen in example:
+ #define A 1 , 2
+ #define C(X,Y,Z) x=X. y=Y. z=Z.
+ #define D(X,Y,Z) C(X,Y,Z)
+ D(x,A,z)
+ Output from preprocessor is: x = x . y = 1 . z = 2 .
+ #define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+*/
+#define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \
+ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \
+ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+
+#define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \
+ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20)
+#define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \
+ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \
+ S(TB,11) S(TC,12) S(TD,13) S(TE,14)
+#if MAX_PREPRO_ARGS>31
+#define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \
+ F(TJ,AJ,19,1) F(TK,AK,20,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \
+ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \
+ S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) S(TG,16) \
+ S(TH,17) S(TI,18) S(TJ,19) S(TK,20)
+#define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \
+ F(TJ,AJ,19,1) F(TK,AK,20,1) F(TL,AL,21,1) F(TM,AM,22,1) F(TN,AN,23,1) F(TO,AO,24,1) \
+ F(TP,AP,25,1) F(TQ,AQ,26,1) F(TR,AR,27,1) S(T1,1) S(T2,2) S(T3,3) \
+ S(T4,4) S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) \
+ S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) \
+ S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \
+ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27)
+#endif
+#else
+#define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14)
+#define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \
+ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20) \
+ F(TL,21,1) S(TL,21) F(TM,22,1) S(TM,22) F(TN,23,1) S(TN,23) F(TO,24,1) S(TO,24) \
+ F(TP,25,1) S(TP,25) F(TQ,26,1) S(TQ,26) F(TR,27,1) S(TR,27)
+
+#define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \
+ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20)
+#define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14)
+#if MAX_PREPRO_ARGS>31
+#define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \
+ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \
+ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20)
+#define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \
+ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \
+ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20) F(TL,AL,21,1) S(TL,21) \
+ F(TM,AM,22,1) S(TM,22) F(TN,AN,23,1) S(TN,23) F(TO,AO,24,1) S(TO,24) \
+ F(TP,AP,25,1) S(TP,25) F(TQ,AQ,26,1) S(TQ,26) F(TR,AR,27,1) S(TR,27)
+#endif
+#endif
+
+
+#define PROTOCCALLSFSUB1( UN,LN,T1) \
+ PROTOCCALLSFSUB14(UN,LN,T1,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB2( UN,LN,T1,T2) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB3( UN,LN,T1,T2,T3) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB4( UN,LN,T1,T2,T3,T4) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0)
+#define PROTOCCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0)
+
+
+#define PROTOCCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0)
+#define PROTOCCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0)
+
+#define PROTOCCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0)
+#define PROTOCCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0)
+
+
+#ifndef FCALLSC_QUALIFIER
+#ifdef VISUAL_CPLUSPLUS
+#define FCALLSC_QUALIFIER __stdcall
+#else
+#define FCALLSC_QUALIFIER
+#endif
+#endif
+
+#ifdef __cplusplus
+#define CFextern extern "C"
+#else
+#define CFextern extern
+#endif
+
+
+#ifdef CFSUBASFUN
+#define PROTOCCALLSFSUB0(UN,LN) \
+ PROTOCCALLSFFUN0( VOID,UN,LN)
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFFUN14(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\
+ PROTOCCALLSFFUN20(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\
+ PROTOCCALLSFFUN27(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#else
+/* Note: Prevent compiler warnings, null #define PROTOCCALLSFSUB14/20 after
+ #include-ing cfortran.h if calling the FORTRAN wrapper within the same
+ source code where the wrapper is created. */
+#define PROTOCCALLSFSUB0(UN,LN) _(VOID,_cfPU)(CFC_(UN,LN))();
+#ifndef __CF__KnR
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT14(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) );
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT20(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) );
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT27(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) );
+#else
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ PROTOCCALLSFSUB0(UN,LN)
+#endif
+#endif
+
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+
+#define CCALLSFSUB1( UN,LN,T1, A1) \
+ CCALLSFSUB5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0)
+#define CCALLSFSUB2( UN,LN,T1,T2, A1,A2) \
+ CCALLSFSUB5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0)
+#define CCALLSFSUB3( UN,LN,T1,T2,T3, A1,A2,A3) \
+ CCALLSFSUB5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0)
+#define CCALLSFSUB4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\
+ CCALLSFSUB5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0)
+#define CCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0)
+#define CCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0)
+#define CCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0)
+#define CCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0)
+#define CCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0)
+#define CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0)
+#define CCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0)
+#define CCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0)
+#define CCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0)
+
+#ifdef __cplusplus
+#define CPPPROTOCLSFSUB0( UN,LN)
+#define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#else
+#define CPPPROTOCLSFSUB0(UN,LN) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#endif
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB0(UN,LN) CCALLSFFUN0(UN,LN)
+#define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)
+#else
+/* do{...}while(0) allows if(a==b) FORT(); else BORT(); */
+#define CCALLSFSUB0( UN,LN) do{CPPPROTOCLSFSUB0(UN,LN) CFC_(UN,LN)();}while(0)
+#define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) \
+ CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) \
+ ACF(LN,T4,A4,4) ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) \
+ ACF(LN,T8,A8,8) ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) \
+ ACF(LN,TC,AC,12) ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) \
+ CFC_(UN,LN)( CFARGTA14(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) );\
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) \
+ WCF(TB,AB,11) WCF(TC,AC,12) WCF(TD,AD,13) WCF(TE,AE,14) }while(0)
+#endif
+
+
+#if MAX_PREPRO_ARGS>31
+#define CCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,0,0,0,0,0)
+#define CCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,0,0,0,0)
+#define CCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,0,0,0)
+#define CCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,0,0)
+#define CCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,0)
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ CCALLSFFUN20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK)
+#else
+#define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \
+ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \
+ CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \
+ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \
+ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \
+ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \
+ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \
+ CFC_(UN,LN)( CFARGTA20(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) ); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \
+ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \
+ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \
+ WCF(TJ,AJ,19) WCF(TK,AK,20) }while(0)
+#endif
+#endif /* MAX_PREPRO_ARGS */
+
+#if MAX_PREPRO_ARGS>31
+#define CCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,0,0,0,0,0,0)
+#define CCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,0,0,0,0,0)
+#define CCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,0,0,0,0)
+#define CCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,0,0,0)
+#define CCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,0,0)
+#define CCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,0)
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ CCALLSFFUN27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR)
+#else
+#define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \
+ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \
+ VVCF(TL,AL,B21) VVCF(TM,AM,B22) VVCF(TN,AN,B23) VVCF(TO,AO,B24) VVCF(TP,AP,B25) \
+ VVCF(TQ,AQ,B26) VVCF(TR,AR,B27) \
+ CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \
+ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \
+ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \
+ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \
+ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \
+ ACF(LN,TL,AL,21) ACF(LN,TM,AM,22) ACF(LN,TN,AN,23) ACF(LN,TO,AO,24) \
+ ACF(LN,TP,AP,25) ACF(LN,TQ,AQ,26) ACF(LN,TR,AR,27) \
+ CFC_(UN,LN)( CFARGTA27(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,\
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) ); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \
+ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \
+ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \
+ WCF(TJ,AJ,19) WCF(TK,AK,20) WCF(TL,AL,21) WCF(TM,AM,22) WCF(TN,AN,23) WCF(TO,AO,24) \
+ WCF(TP,AP,25) WCF(TQ,AQ,26) WCF(TR,AR,27) }while(0)
+#endif
+#endif /* MAX_PREPRO_ARGS */
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO CALL FORTRAN FUNCTIONS */
+
+/*N.B. PROTOCCALLSFFUNn(..) generates code, whether or not the FORTRAN
+ function is called. Therefore, especially for creator's of C header files
+ for large FORTRAN libraries which include many functions, to reduce
+ compile time and object code size, it may be desirable to create
+ preprocessor directives to allow users to create code for only those
+ functions which they use. */
+
+/* The following defines the maximum length string that a function can return.
+ Of course it may be undefine-d and re-define-d before individual
+ PROTOCCALLSFFUNn(..) as required. It would also be nice to have this derived
+ from the individual machines' limits. */
+#define MAX_LEN_FORTRAN_FUNCTION_STRING 0x4FE
+
+/* The following defines a character used by CFORTRAN.H to flag the end of a
+ string coming out of a FORTRAN routine. */
+#define CFORTRAN_NON_CHAR 0x7F
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#define _SEP_(TN,C,cfCOMMA) _(__SEP_,C)(TN,cfCOMMA)
+#define __SEP_0(TN,cfCOMMA)
+#define __SEP_1(TN,cfCOMMA) _Icf(2,SEP,TN,cfCOMMA,0)
+#define INT_cfSEP(T,B) _(A,B)
+#define INTV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PINT_cfSEP(T,B) INT_cfSEP(T,B)
+#define PVOID_cfSEP(T,B) INT_cfSEP(T,B)
+#define ROUTINE_cfSEP(T,B) INT_cfSEP(T,B)
+#define SIMPLE_cfSEP(T,B) INT_cfSEP(T,B)
+#define VOID_cfSEP(T,B) INT_cfSEP(T,B) /* For FORTRAN calls C subr.s.*/
+#define STRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define STRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define PSTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PNSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define PPSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define ZTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PZTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+
+#if defined(SIGNED_BYTE) || !defined(UNSIGNED_BYTE)
+#ifdef OLD_VAXC
+#define INTEGER_BYTE char /* Old VAXC barfs on 'signed char' */
+#else
+#define INTEGER_BYTE signed char /* default */
+#endif
+#else
+#define INTEGER_BYTE unsigned char
+#endif
+#define BYTEVVVVVVV_cfTYPE INTEGER_BYTE
+#define DOUBLEVVVVVVV_cfTYPE DOUBLE_PRECISION
+#define FLOATVVVVVVV_cfTYPE FORTRAN_REAL
+#define INTVVVVVVV_cfTYPE int
+#define LOGICALVVVVVVV_cfTYPE int
+#define LONGVVVVVVV_cfTYPE long
+#define LONGLONGVVVVVVV_cfTYPE LONGLONG /* added by MR December 2005 */
+#define SHORTVVVVVVV_cfTYPE short
+#define PBYTE_cfTYPE INTEGER_BYTE
+#define PDOUBLE_cfTYPE DOUBLE_PRECISION
+#define PFLOAT_cfTYPE FORTRAN_REAL
+#define PINT_cfTYPE int
+#define PLOGICAL_cfTYPE int
+#define PLONG_cfTYPE long
+#define PLONGLONG_cfTYPE LONGLONG /* added by MR December 2005 */
+#define PSHORT_cfTYPE short
+
+#define CFARGS0(A,T,V,W,X,Y,Z) _3(T,_cf,A)
+#define CFARGS1(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V)
+#define CFARGS2(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W)
+#define CFARGS3(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X)
+#define CFARGS4(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y)
+#define CFARGS5(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y,Z)
+
+#define _Icf(N,T,I,X,Y) _(I,_cfINT)(N,T,I,X,Y,0)
+#define _Icf4(N,T,I,X,Y,Z) _(I,_cfINT)(N,T,I,X,Y,Z)
+#define BYTE_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define DOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INT,B,X,Y,Z,0)
+#define FLOAT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define INT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LOGICAL_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LONGLONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define SHORT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PBYTE_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PDOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,PINT,B,X,Y,Z,0)
+#define PFLOAT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PINT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLOGICAL_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLONGLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define PSHORT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define BYTEV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define DOUBLEV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTV,B,X,Y,Z,0)
+#define DOUBLEVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVV,B,X,Y,Z,0)
+#define DOUBLEVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVV,B,X,Y,Z,0)
+#define DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVVV,B,X,Y,Z,0)
+#define FLOATV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define INTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define LONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGLONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define SHORTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define PVOID_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,B,B,X,Y,Z,0)
+#define ROUTINE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+/*CRAY coughs on the first,
+ i.e. the usual trouble of not being able to
+ define macros to macros with arguments.
+ New ultrix is worse, it coughs on all such uses.
+ */
+/*#define SIMPLE_cfINT PVOID_cfINT*/
+#define SIMPLE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define VOID_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define STRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define STRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PSTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PNSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PPSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define ZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define CF_0_cfINT(N,A,B,X,Y,Z)
+
+
+#define UCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _Icf(2,U,TN,_(A,I),0)
+#define UUCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _SEP_(TN,1,I)
+#define UUUCF(TN,I,C) _SEP_(TN,C,cfCOLON) _Icf(2,U,TN,_(A,I),0)
+#define INT_cfU(T,A) _(T,VVVVVVV_cfTYPE) A
+#define INTV_cfU(T,A) _(T,VVVVVV_cfTYPE) * A
+#define INTVV_cfU(T,A) _(T,VVVVV_cfTYPE) * A
+#define INTVVV_cfU(T,A) _(T,VVVV_cfTYPE) * A
+#define INTVVVV_cfU(T,A) _(T,VVV_cfTYPE) * A
+#define INTVVVVV_cfU(T,A) _(T,VV_cfTYPE) * A
+#define INTVVVVVV_cfU(T,A) _(T,V_cfTYPE) * A
+#define INTVVVVVVV_cfU(T,A) _(T,_cfTYPE) * A
+#define PINT_cfU(T,A) _(T,_cfTYPE) * A
+#define PVOID_cfU(T,A) void *A
+#define ROUTINE_cfU(T,A) void (*A)(CF_NULL_PROTO)
+#define VOID_cfU(T,A) void A /* Needed for C calls FORTRAN sub.s. */
+#define STRING_cfU(T,A) char *A /* via VOID and wrapper. */
+#define STRINGV_cfU(T,A) char *A
+#define PSTRING_cfU(T,A) char *A
+#define PSTRINGV_cfU(T,A) char *A
+#define ZTRINGV_cfU(T,A) char *A
+#define PZTRINGV_cfU(T,A) char *A
+
+/* VOID breaks U into U and UU. */
+#define INT_cfUU(T,A) _(T,VVVVVVV_cfTYPE) A
+#define VOID_cfUU(T,A) /* Needed for FORTRAN calls C sub.s. */
+#define STRING_cfUU(T,A) const char *A
+
+
+#define BYTE_cfPU(A) CFextern INTEGER_BYTE FCALLSC_QUALIFIER A
+#define DOUBLE_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A
+#else
+#define FLOAT_cfPU(A) CFextern FORTRAN_REAL FCALLSC_QUALIFIER A
+#endif
+#else
+#define FLOAT_cfPU(A) CFextern FLOATFUNCTIONTYPE FCALLSC_QUALIFIER A
+#endif
+#define INT_cfPU(A) CFextern int FCALLSC_QUALIFIER A
+#define LOGICAL_cfPU(A) CFextern int FCALLSC_QUALIFIER A
+#define LONG_cfPU(A) CFextern long FCALLSC_QUALIFIER A
+#define SHORT_cfPU(A) CFextern short FCALLSC_QUALIFIER A
+#define STRING_cfPU(A) CFextern void FCALLSC_QUALIFIER A
+#define VOID_cfPU(A) CFextern void FCALLSC_QUALIFIER A
+
+#define BYTE_cfE INTEGER_BYTE A0;
+#define DOUBLE_cfE DOUBLE_PRECISION A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfE FORTRAN_REAL A0;
+#else
+#define FLOAT_cfE FORTRAN_REAL AA0; FLOATFUNCTIONTYPE A0;
+#endif
+#define INT_cfE int A0;
+#define LOGICAL_cfE int A0;
+#define LONG_cfE long A0;
+#define SHORT_cfE short A0;
+#define VOID_cfE
+#ifdef vmsFortran
+#define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ static fstring A0 = \
+ {MAX_LEN_FORTRAN_FUNCTION_STRING,DSC$K_DTYPE_T,DSC$K_CLASS_S,AA0};\
+ memset(AA0, CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\
+ *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';
+#else
+#ifdef CRAYFortran
+#define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ static _fcd A0; *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';\
+ memset(AA0,CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\
+ A0 = _cptofcd(AA0,MAX_LEN_FORTRAN_FUNCTION_STRING);
+#else
+/* 'cc: SC3.0.1 13 Jul 1994' barfs on char A0[0x4FE+1];
+ * char A0[0x4FE +1]; char A0[1+0x4FE]; are both OK. */
+#define STRING_cfE static char A0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ memset(A0, CFORTRAN_NON_CHAR, \
+ MAX_LEN_FORTRAN_FUNCTION_STRING); \
+ *(A0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';
+#endif
+#endif
+/* ESTRING must use static char. array which is guaranteed to exist after
+ function returns. */
+
+/* N.B.i) The diff. for 0 (Zero) and >=1 arguments.
+ ii)That the following create an unmatched bracket, i.e. '(', which
+ must of course be matched in the call.
+ iii)Commas must be handled very carefully */
+#define INT_cfGZ(T,UN,LN) A0=CFC_(UN,LN)(
+#define VOID_cfGZ(T,UN,LN) CFC_(UN,LN)(
+#ifdef vmsFortran
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)(&A0
+#else
+#if defined(CRAYFortran) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0
+#else
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0,MAX_LEN_FORTRAN_FUNCTION_STRING
+#endif
+#endif
+
+#define INT_cfG(T,UN,LN) INT_cfGZ(T,UN,LN)
+#define VOID_cfG(T,UN,LN) VOID_cfGZ(T,UN,LN)
+#define STRING_cfG(T,UN,LN) STRING_cfGZ(T,UN,LN), /*, is only diff. from _cfG*/
+
+#define BYTEVVVVVVV_cfPP
+#define INTVVVVVVV_cfPP /* These complement FLOATVVVVVVV_cfPP. */
+#define DOUBLEVVVVVVV_cfPP
+#define LOGICALVVVVVVV_cfPP
+#define LONGVVVVVVV_cfPP
+#define SHORTVVVVVVV_cfPP
+#define PBYTE_cfPP
+#define PINT_cfPP
+#define PDOUBLE_cfPP
+#define PLOGICAL_cfPP
+#define PLONG_cfPP
+#define PSHORT_cfPP
+#define PFLOAT_cfPP FLOATVVVVVVV_cfPP
+
+#define BCF(TN,AN,C) _SEP_(TN,C,cfCOMMA) _Icf(2,B,TN,AN,0)
+#define INT_cfB(T,A) (_(T,VVVVVVV_cfTYPE)) A
+#define INTV_cfB(T,A) A
+#define INTVV_cfB(T,A) (A)[0]
+#define INTVVV_cfB(T,A) (A)[0][0]
+#define INTVVVV_cfB(T,A) (A)[0][0][0]
+#define INTVVVVV_cfB(T,A) (A)[0][0][0][0]
+#define INTVVVVVV_cfB(T,A) (A)[0][0][0][0][0]
+#define INTVVVVVVV_cfB(T,A) (A)[0][0][0][0][0][0]
+#define PINT_cfB(T,A) _(T,_cfPP)&A
+#define STRING_cfB(T,A) (char *) A
+#define STRINGV_cfB(T,A) (char *) A
+#define PSTRING_cfB(T,A) (char *) A
+#define PSTRINGV_cfB(T,A) (char *) A
+#define PVOID_cfB(T,A) (void *) A
+#define ROUTINE_cfB(T,A) (cfCAST_FUNCTION)A
+#define ZTRINGV_cfB(T,A) (char *) A
+#define PZTRINGV_cfB(T,A) (char *) A
+
+#define SCF(TN,NAME,I,A) _(TN,_cfSTR)(3,S,NAME,I,A,0,0)
+#define DEFAULT_cfS(M,I,A)
+#define LOGICAL_cfS(M,I,A)
+#define PLOGICAL_cfS(M,I,A)
+#define STRING_cfS(M,I,A) ,sizeof(A)
+#define STRINGV_cfS(M,I,A) ,( (unsigned)0xFFFF*firstindexlength(A) \
+ +secondindexlength(A))
+#define PSTRING_cfS(M,I,A) ,sizeof(A)
+#define PSTRINGV_cfS(M,I,A) STRINGV_cfS(M,I,A)
+#define ZTRINGV_cfS(M,I,A)
+#define PZTRINGV_cfS(M,I,A)
+
+#define HCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA, H,_(C,I),0,0)
+#define HHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA,HH,_(C,I),0,0)
+#define HHHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOLON, H,_(C,I),0,0)
+#define H_CF_SPECIAL unsigned
+#define HH_CF_SPECIAL
+#define DEFAULT_cfH(M,I,A)
+#define LOGICAL_cfH(S,U,B)
+#define PLOGICAL_cfH(S,U,B)
+#define STRING_cfH(S,U,B) _(A,S) _(U,_CF_SPECIAL) B
+#define STRINGV_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PSTRINGV_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PNSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PPSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define ZTRINGV_cfH(S,U,B)
+#define PZTRINGV_cfH(S,U,B)
+
+/* Need VOID_cfSTR because Absoft forced function types go through _cfSTR. */
+/* No spaces inside expansion. They screws up macro catenation kludge. */
+#define VOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,LOGICAL,A,B,C,D,E)
+#define LONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define SHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGLONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define SHORTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PBYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PDOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PFLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PINT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PLOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PLOGICAL,A,B,C,D,E)
+#define PLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PLONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define PSHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define STRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRING,A,B,C,D,E)
+#define PSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRING,A,B,C,D,E)
+#define STRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRINGV,A,B,C,D,E)
+#define PSTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRINGV,A,B,C,D,E)
+#define PNSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PNSTRING,A,B,C,D,E)
+#define PPSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PPSTRING,A,B,C,D,E)
+#define PVOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define ROUTINE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SIMPLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define ZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,ZTRINGV,A,B,C,D,E)
+#define PZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PZTRINGV,A,B,C,D,E)
+#define CF_0_cfSTR(N,T,A,B,C,D,E)
+
+/* See ACF table comments, which explain why CCF was split into two. */
+#define CCF(NAME,TN,I) _(TN,_cfSTR)(5,C,NAME,I,_(A,I),_(B,I),_(C,I))
+#define DEFAULT_cfC(M,I,A,B,C)
+#define LOGICAL_cfC(M,I,A,B,C) A=C2FLOGICAL( A);
+#define PLOGICAL_cfC(M,I,A,B,C) *A=C2FLOGICAL(*A);
+#ifdef vmsFortran
+#define STRING_cfC(M,I,A,B,C) (B.clen=strlen(A),B.f.dsc$a_pointer=A, \
+ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.f.dsc$w_length=B.clen: \
+ (memset((A)+B.clen,' ',C-B.clen-1),A[B.f.dsc$w_length=C-1]='\0'));
+ /* PSTRING_cfC to beware of array A which does not contain any \0. */
+#define PSTRING_cfC(M,I,A,B,C) (B.dsc$a_pointer=A, C==sizeof(char*) ? \
+ B.dsc$w_length=strlen(A): (A[C-1]='\0',B.dsc$w_length=strlen(A), \
+ (unsigned)memset((A)+B.dsc$w_length,' ',C-B.dsc$w_length-1), B.dsc$w_length=C-1));
+#else
+#define STRING_cfC(M,I,A,B,C) (B.nombre=A,B.clen=(unsigned)strlen(A), \
+ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.flen=B.clen: \
+ (unsigned)(memset(B.nombre+B.clen,' ',C-B.clen-1),B.nombre[B.flen=C-1]='\0'));
+#define PSTRING_cfC(M,I,A,B,C) (C==sizeof(char*)? B=strlen(A): \
+ (A[C-1]='\0',B=strlen(A),memset((A)+B,' ',C-B-1),B=C-1));
+#endif
+ /* For CRAYFortran for (P)STRINGV_cfC, B.fs is set, but irrelevant. */
+#define STRINGV_cfC(M,I,A,B,C) \
+ AATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF)
+#define PSTRINGV_cfC(M,I,A,B,C) \
+ APATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF)
+#define ZTRINGV_cfC(M,I,A,B,C) \
+ AATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 )
+#define PZTRINGV_cfC(M,I,A,B,C) \
+ APATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 )
+
+#define BYTE_cfCCC(A,B) &A
+#define DOUBLE_cfCCC(A,B) &A
+#if !defined(__CF__KnR)
+#define FLOAT_cfCCC(A,B) &A
+ /* Although the VAX doesn't, at least the */
+#else /* HP and K&R mips promote float arg.'s of */
+#define FLOAT_cfCCC(A,B) &B /* unprototyped functions to double. Cannot */
+#endif /* use A here to pass the argument to FORTRAN. */
+#define INT_cfCCC(A,B) &A
+#define LOGICAL_cfCCC(A,B) &A
+#define LONG_cfCCC(A,B) &A
+#define SHORT_cfCCC(A,B) &A
+#define PBYTE_cfCCC(A,B) A
+#define PDOUBLE_cfCCC(A,B) A
+#define PFLOAT_cfCCC(A,B) A
+#define PINT_cfCCC(A,B) A
+#define PLOGICAL_cfCCC(A,B) B=A /* B used to keep a common W table. */
+#define PLONG_cfCCC(A,B) A
+#define PSHORT_cfCCC(A,B) A
+
+#define CCCF(TN,I,M) _SEP_(TN,M,cfCOMMA) _Icf(3,CC,TN,_(A,I),_(B,I))
+#define INT_cfCC(T,A,B) _(T,_cfCCC)(A,B)
+#define INTV_cfCC(T,A,B) A
+#define INTVV_cfCC(T,A,B) A
+#define INTVVV_cfCC(T,A,B) A
+#define INTVVVV_cfCC(T,A,B) A
+#define INTVVVVV_cfCC(T,A,B) A
+#define INTVVVVVV_cfCC(T,A,B) A
+#define INTVVVVVVV_cfCC(T,A,B) A
+#define PINT_cfCC(T,A,B) _(T,_cfCCC)(A,B)
+#define PVOID_cfCC(T,A,B) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfCC(T,A,B) &A
+#else
+#define ROUTINE_cfCC(T,A,B) A
+#endif
+#define SIMPLE_cfCC(T,A,B) A
+#ifdef vmsFortran
+#define STRING_cfCC(T,A,B) &B.f
+#define STRINGV_cfCC(T,A,B) &B
+#define PSTRING_cfCC(T,A,B) &B
+#define PSTRINGV_cfCC(T,A,B) &B
+#else
+#ifdef CRAYFortran
+#define STRING_cfCC(T,A,B) _cptofcd(A,B.flen)
+#define STRINGV_cfCC(T,A,B) _cptofcd(B.s,B.flen)
+#define PSTRING_cfCC(T,A,B) _cptofcd(A,B)
+#define PSTRINGV_cfCC(T,A,B) _cptofcd(A,B.flen)
+#else
+#define STRING_cfCC(T,A,B) A
+#define STRINGV_cfCC(T,A,B) B.fs
+#define PSTRING_cfCC(T,A,B) A
+#define PSTRINGV_cfCC(T,A,B) B.fs
+#endif
+#endif
+#define ZTRINGV_cfCC(T,A,B) STRINGV_cfCC(T,A,B)
+#define PZTRINGV_cfCC(T,A,B) PSTRINGV_cfCC(T,A,B)
+
+#define BYTE_cfX return A0;
+#define DOUBLE_cfX return A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfX return A0;
+#else
+#define FLOAT_cfX ASSIGNFLOAT(AA0,A0); return AA0;
+#endif
+#define INT_cfX return A0;
+#define LOGICAL_cfX return F2CLOGICAL(A0);
+#define LONG_cfX return A0;
+#define SHORT_cfX return A0;
+#define VOID_cfX return ;
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define STRING_cfX return kill_trailing( \
+ kill_trailing(AA0,CFORTRAN_NON_CHAR),' ');
+#else
+#define STRING_cfX return kill_trailing( \
+ kill_trailing( A0,CFORTRAN_NON_CHAR),' ');
+#endif
+
+#define CFFUN(NAME) _(__cf__,NAME)
+
+/* Note that we don't use LN here, but we keep it for consistency. */
+#define CCALLSFFUN0(UN,LN) CFFUN(UN)()
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define CCALLSFFUN1( UN,LN,T1, A1) \
+ CCALLSFFUN5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0)
+#define CCALLSFFUN2( UN,LN,T1,T2, A1,A2) \
+ CCALLSFFUN5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0)
+#define CCALLSFFUN3( UN,LN,T1,T2,T3, A1,A2,A3) \
+ CCALLSFFUN5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0)
+#define CCALLSFFUN4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\
+ CCALLSFFUN5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0)
+#define CCALLSFFUN5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0)
+#define CCALLSFFUN6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0)
+#define CCALLSFFUN7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0)
+#define CCALLSFFUN8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0)
+#define CCALLSFFUN9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0)
+#define CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0)
+#define CCALLSFFUN11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0)
+#define CCALLSFFUN12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0)
+#define CCALLSFFUN13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0)
+
+#define CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+((CFFUN(UN)( BCF(T1,A1,0) BCF(T2,A2,1) BCF(T3,A3,1) BCF(T4,A4,1) BCF(T5,A5,1) \
+ BCF(T6,A6,1) BCF(T7,A7,1) BCF(T8,A8,1) BCF(T9,A9,1) BCF(TA,AA,1) \
+ BCF(TB,AB,1) BCF(TC,AC,1) BCF(TD,AD,1) BCF(TE,AE,1) \
+ SCF(T1,LN,1,A1) SCF(T2,LN,2,A2) SCF(T3,LN,3,A3) SCF(T4,LN,4,A4) \
+ SCF(T5,LN,5,A5) SCF(T6,LN,6,A6) SCF(T7,LN,7,A7) SCF(T8,LN,8,A8) \
+ SCF(T9,LN,9,A9) SCF(TA,LN,10,AA) SCF(TB,LN,11,AB) SCF(TC,LN,12,AC) \
+ SCF(TD,LN,13,AD) SCF(TE,LN,14,AE))))
+
+/* N.B. Create a separate function instead of using (call function, function
+value here) because in order to create the variables needed for the input
+arg.'s which may be const.'s one has to do the creation within {}, but these
+can never be placed within ()'s. Therefore one must create wrapper functions.
+gcc, on the other hand may be able to avoid the wrapper functions. */
+
+/* Prototypes are needed to correctly handle the value returned correctly. N.B.
+Can only have prototype arg.'s with difficulty, a la G... table since FORTRAN
+functions returning strings have extra arg.'s. Don't bother, since this only
+causes a compiler warning to come up when one uses FCALLSCFUNn and CCALLSFFUNn
+for the same function in the same source code. Something done by the experts in
+debugging only.*/
+
+#define PROTOCCALLSFFUN0(F,UN,LN) \
+_(F,_cfPU)( CFC_(UN,LN))(CF_NULL_PROTO); \
+static _Icf(2,U,F,CFFUN(UN),0)() {_(F,_cfE) _Icf(3,GZ,F,UN,LN) ABSOFT_cf1(F));_(F,_cfX)}
+
+#define PROTOCCALLSFFUN1( T0,UN,LN,T1) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN2( T0,UN,LN,T1,T2) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN3( T0,UN,LN,T1,T2,T3) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,CF_0,CF_0)
+#define PROTOCCALLSFFUN4( T0,UN,LN,T1,T2,T3,T4) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,T4,CF_0)
+#define PROTOCCALLSFFUN5( T0,UN,LN,T1,T2,T3,T4,T5) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN6( T0,UN,LN,T1,T2,T3,T4,T5,T6) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN7( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN8( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0)
+#define PROTOCCALLSFFUN9( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0)
+#define PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN11(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN12(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0)
+#define PROTOCCALLSFFUN13(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0)
+
+/* HP/UX 9.01 cc requires the blank between '_Icf(3,G,T0,UN,LN) CCCF(T1,1,0)' */
+
+#ifndef __CF__KnR
+#define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \
+ CFARGT14FS(UCF,HCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \
+{ CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \
+ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \
+ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \
+ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \
+ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \
+ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)}
+#else
+#define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \
+ CFARGT14FS(UUCF,HHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \
+ CFARGT14FS(UUUCF,HHHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ; \
+{ CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \
+ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \
+ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \
+ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \
+ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \
+ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR FORTRAN TO CALL C ROUTINES */
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define DCF(TN,I)
+#define DDCF(TN,I)
+#define DDDCF(TN,I)
+#else
+#define DCF(TN,I) HCF(TN,I)
+#define DDCF(TN,I) HHCF(TN,I)
+#define DDDCF(TN,I) HHHCF(TN,I)
+#endif
+
+#define QCF(TN,I) _(TN,_cfSTR)(1,Q,_(B,I), 0,0,0,0)
+#define DEFAULT_cfQ(B)
+#define LOGICAL_cfQ(B)
+#define PLOGICAL_cfQ(B)
+#define STRINGV_cfQ(B) char *B; unsigned int _(B,N);
+#define STRING_cfQ(B) char *B=NULL;
+#define PSTRING_cfQ(B) char *B=NULL;
+#define PSTRINGV_cfQ(B) STRINGV_cfQ(B)
+#define PNSTRING_cfQ(B) char *B=NULL;
+#define PPSTRING_cfQ(B)
+
+#ifdef __sgi /* Else SGI gives warning 182 contrary to its C LRM A.17.7 */
+#define ROUTINE_orig *(void**)&
+#else
+#define ROUTINE_orig (void *)
+#endif
+
+#define ROUTINE_1 ROUTINE_orig
+#define ROUTINE_2 ROUTINE_orig
+#define ROUTINE_3 ROUTINE_orig
+#define ROUTINE_4 ROUTINE_orig
+#define ROUTINE_5 ROUTINE_orig
+#define ROUTINE_6 ROUTINE_orig
+#define ROUTINE_7 ROUTINE_orig
+#define ROUTINE_8 ROUTINE_orig
+#define ROUTINE_9 ROUTINE_orig
+#define ROUTINE_10 ROUTINE_orig
+#define ROUTINE_11 ROUTINE_orig
+#define ROUTINE_12 ROUTINE_orig
+#define ROUTINE_13 ROUTINE_orig
+#define ROUTINE_14 ROUTINE_orig
+#define ROUTINE_15 ROUTINE_orig
+#define ROUTINE_16 ROUTINE_orig
+#define ROUTINE_17 ROUTINE_orig
+#define ROUTINE_18 ROUTINE_orig
+#define ROUTINE_19 ROUTINE_orig
+#define ROUTINE_20 ROUTINE_orig
+#define ROUTINE_21 ROUTINE_orig
+#define ROUTINE_22 ROUTINE_orig
+#define ROUTINE_23 ROUTINE_orig
+#define ROUTINE_24 ROUTINE_orig
+#define ROUTINE_25 ROUTINE_orig
+#define ROUTINE_26 ROUTINE_orig
+#define ROUTINE_27 ROUTINE_orig
+
+#define TCF(NAME,TN,I,M) _SEP_(TN,M,cfCOMMA) _(TN,_cfT)(NAME,I,_(A,I),_(B,I),_(C,I))
+#define BYTE_cfT(M,I,A,B,D) *A
+#define DOUBLE_cfT(M,I,A,B,D) *A
+#define FLOAT_cfT(M,I,A,B,D) *A
+#define INT_cfT(M,I,A,B,D) *A
+#define LOGICAL_cfT(M,I,A,B,D) F2CLOGICAL(*A)
+#define LONG_cfT(M,I,A,B,D) *A
+#define LONGLONG_cfT(M,I,A,B,D) *A /* added by MR December 2005 */
+#define SHORT_cfT(M,I,A,B,D) *A
+#define BYTEV_cfT(M,I,A,B,D) A
+#define DOUBLEV_cfT(M,I,A,B,D) A
+#define FLOATV_cfT(M,I,A,B,D) VOIDP A
+#define INTV_cfT(M,I,A,B,D) A
+#define LOGICALV_cfT(M,I,A,B,D) A
+#define LONGV_cfT(M,I,A,B,D) A
+#define LONGLONGV_cfT(M,I,A,B,D) A /* added by MR December 2005 */
+#define SHORTV_cfT(M,I,A,B,D) A
+#define BYTEVV_cfT(M,I,A,B,D) (void *)A /* We have to cast to void *,*/
+#define BYTEVVV_cfT(M,I,A,B,D) (void *)A /* since we don't know the */
+#define BYTEVVVV_cfT(M,I,A,B,D) (void *)A /* dimensions of the array. */
+#define BYTEVVVVV_cfT(M,I,A,B,D) (void *)A /* i.e. Unfortunately, can't */
+#define BYTEVVVVVV_cfT(M,I,A,B,D) (void *)A /* check that the type */
+#define BYTEVVVVVVV_cfT(M,I,A,B,D) (void *)A /* matches the prototype. */
+#define DOUBLEVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGLONGVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define SHORTVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define PBYTE_cfT(M,I,A,B,D) A
+#define PDOUBLE_cfT(M,I,A,B,D) A
+#define PFLOAT_cfT(M,I,A,B,D) VOIDP A
+#define PINT_cfT(M,I,A,B,D) A
+#define PLOGICAL_cfT(M,I,A,B,D) ((*A=F2CLOGICAL(*A)),A)
+#define PLONG_cfT(M,I,A,B,D) A
+#define PLONGLONG_cfT(M,I,A,B,D) A /* added by MR December 2005 */
+#define PSHORT_cfT(M,I,A,B,D) A
+#define PVOID_cfT(M,I,A,B,D) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) (*A)
+#else
+#define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) A
+#endif
+/* A == pointer to the characters
+ D == length of the string, or of an element in an array of strings
+ E == number of elements in an array of strings */
+#define TTSTR( A,B,D) \
+ ((B=_cf_malloc(D+1))[D]='\0', memcpy(B,A,D), kill_trailing(B,' '))
+#define TTTTSTR( A,B,D) (!(D<4||A[0]||A[1]||A[2]||A[3]))?NULL: \
+ memchr(A,'\0',D) ?A : TTSTR(A,B,D)
+#define TTTTSTRV( A,B,D,E) (_(B,N)=E,B=_cf_malloc(_(B,N)*(D+1)), (void *) \
+ vkill_trailing(f2cstrv(A,B,D+1, _(B,N)*(D+1)), D+1,_(B,N)*(D+1),' '))
+#ifdef vmsFortran
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A->dsc$a_pointer, B, \
+ A->dsc$w_length , A->dsc$l_m[0])
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define PPSTRING_cfT(M,I,A,B,D) A->dsc$a_pointer
+#else
+#ifdef CRAYFortran
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( _fcdtocp(A),B,_fcdlen(A))
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(_fcdtocp(A),B,_fcdlen(A), \
+ num_elem(_fcdtocp(A),_fcdlen(A),_3(M,_STRV_A,I)))
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( _fcdtocp(A),B,_fcdlen(A))
+#define PPSTRING_cfT(M,I,A,B,D) _fcdtocp(A)
+#else
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( A,B,D)
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A,B,D, num_elem(A,D,_3(M,_STRV_A,I)))
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( A,B,D)
+#define PPSTRING_cfT(M,I,A,B,D) ((void)D, A)
+#endif
+#endif
+#define PNSTRING_cfT(M,I,A,B,D) STRING_cfT(M,I,A,B,D)
+#define PSTRINGV_cfT(M,I,A,B,D) STRINGV_cfT(M,I,A,B,D)
+#define CF_0_cfT(M,I,A,B,D)
+
+#define RCF(TN,I) _(TN,_cfSTR)(3,R,_(A,I),_(B,I),_(C,I),0,0)
+#define DEFAULT_cfR(A,B,D)
+#define LOGICAL_cfR(A,B,D)
+#define PLOGICAL_cfR(A,B,D) *A=C2FLOGICAL(*A);
+#define STRING_cfR(A,B,D) if (B) _cf_free(B);
+#define STRINGV_cfR(A,B,D) _cf_free(B);
+/* A and D as defined above for TSTRING(V) */
+#define RRRRPSTR( A,B,D) if (B) memcpy(A,B, _cfMIN(strlen(B),D)), \
+ (D>strlen(B)?memset(A+strlen(B),' ', D-strlen(B)):0), _cf_free(B);
+#define RRRRPSTRV(A,B,D) c2fstrv(B,A,D+1,(D+1)*_(B,N)), _cf_free(B);
+#ifdef vmsFortran
+#define PSTRING_cfR(A,B,D) RRRRPSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A->dsc$a_pointer,B,A->dsc$w_length)
+#else
+#ifdef CRAYFortran
+#define PSTRING_cfR(A,B,D) RRRRPSTR( _fcdtocp(A),B,_fcdlen(A))
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(_fcdtocp(A),B,_fcdlen(A))
+#else
+#define PSTRING_cfR(A,B,D) RRRRPSTR( A,B,D)
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A,B,D)
+#endif
+#endif
+#define PNSTRING_cfR(A,B,D) PSTRING_cfR(A,B,D)
+#define PPSTRING_cfR(A,B,D)
+
+#define BYTE_cfFZ(UN,LN) INTEGER_BYTE FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define DOUBLE_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define INT_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LOGICAL_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LONG_cfFZ(UN,LN) long FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LONGLONG_cfFZ(UN,LN) LONGLONG FCALLSC_QUALIFIER fcallsc(UN,LN)( /* added by MR December 2005 */
+#define SHORT_cfFZ(UN,LN) short FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define VOID_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#ifndef __CF__KnR
+/* The void is req'd by the Apollo, to make this an ANSI function declaration.
+ The Apollo promotes K&R float functions to double. */
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(void
+#else
+#define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(void
+#endif
+#ifdef vmsFortran
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(fstring *AS
+#else
+#ifdef CRAYFortran
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(_fcd AS
+#else
+#if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS
+#else
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS, unsigned D0
+#endif
+#endif
+#endif
+#else
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#else
+#define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#else
+#define FLOAT_cfFZ(UN,LN) FLOATFUNCTIONTYPE FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#if defined(vmsFortran) || defined(CRAYFortran) || defined(AbsoftUNIXFortran)
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS
+#else
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS, D0
+#endif
+#endif
+
+#define BYTE_cfF(UN,LN) BYTE_cfFZ(UN,LN)
+#define DOUBLE_cfF(UN,LN) DOUBLE_cfFZ(UN,LN)
+#ifndef __CF_KnR
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfF(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#else
+#define FLOAT_cfF(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#else
+#define FLOAT_cfF(UN,LN) FLOAT_cfFZ(UN,LN)
+#endif
+#define INT_cfF(UN,LN) INT_cfFZ(UN,LN)
+#define LOGICAL_cfF(UN,LN) LOGICAL_cfFZ(UN,LN)
+#define LONG_cfF(UN,LN) LONG_cfFZ(UN,LN)
+#define LONGLONG_cfF(UN,LN) LONGLONG_cfFZ(UN,LN) /* added by MR December 2005 */
+#define SHORT_cfF(UN,LN) SHORT_cfFZ(UN,LN)
+#define VOID_cfF(UN,LN) VOID_cfFZ(UN,LN)
+#define STRING_cfF(UN,LN) STRING_cfFZ(UN,LN),
+
+#define INT_cfFF
+#define VOID_cfFF
+#ifdef vmsFortran
+#define STRING_cfFF fstring *AS;
+#else
+#ifdef CRAYFortran
+#define STRING_cfFF _fcd AS;
+#else
+#define STRING_cfFF char *AS; unsigned D0;
+#endif
+#endif
+
+#define INT_cfL A0=
+#define STRING_cfL A0=
+#define VOID_cfL
+
+#define INT_cfK
+#define VOID_cfK
+/* KSTRING copies the string into the position provided by the caller. */
+#ifdef vmsFortran
+#define STRING_cfK \
+ memcpy(AS->dsc$a_pointer,A0,_cfMIN(AS->dsc$w_length,(A0==NULL?0:strlen(A0))));\
+ AS->dsc$w_length>(A0==NULL?0:strlen(A0))? \
+ memset(AS->dsc$a_pointer+(A0==NULL?0:strlen(A0)),' ', \
+ AS->dsc$w_length-(A0==NULL?0:strlen(A0))):0;
+#else
+#ifdef CRAYFortran
+#define STRING_cfK \
+ memcpy(_fcdtocp(AS),A0, _cfMIN(_fcdlen(AS),(A0==NULL?0:strlen(A0))) ); \
+ _fcdlen(AS)>(A0==NULL?0:strlen(A0))? \
+ memset(_fcdtocp(AS)+(A0==NULL?0:strlen(A0)),' ', \
+ _fcdlen(AS)-(A0==NULL?0:strlen(A0))):0;
+#else
+#define STRING_cfK memcpy(AS,A0, _cfMIN(D0,(A0==NULL?0:strlen(A0))) ); \
+ D0>(A0==NULL?0:strlen(A0))?memset(AS+(A0==NULL?0:strlen(A0)), \
+ ' ', D0-(A0==NULL?0:strlen(A0))):0;
+#endif
+#endif
+
+/* Note that K.. and I.. can't be combined since K.. has to access data before
+R.., in order for functions returning strings which are also passed in as
+arguments to work correctly. Note that R.. frees and hence may corrupt the
+string. */
+#define BYTE_cfI return A0;
+#define DOUBLE_cfI return A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfI return A0;
+#else
+#define FLOAT_cfI RETURNFLOAT(A0);
+#endif
+#define INT_cfI return A0;
+#ifdef hpuxFortran800
+/* Incredibly, functions must return true as 1, elsewhere .true.==0x01000000. */
+#define LOGICAL_cfI return ((A0)?1:0);
+#else
+#define LOGICAL_cfI return C2FLOGICAL(A0);
+#endif
+#define LONG_cfI return A0;
+#define LONGLONG_cfI return A0; /* added by MR December 2005 */
+#define SHORT_cfI return A0;
+#define STRING_cfI return ;
+#define VOID_cfI return ;
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define FCALLSCSUB0( CN,UN,LN) FCALLSCFUN0(VOID,CN,UN,LN)
+#define FCALLSCSUB1( CN,UN,LN,T1) FCALLSCFUN1(VOID,CN,UN,LN,T1)
+#define FCALLSCSUB2( CN,UN,LN,T1,T2) FCALLSCFUN2(VOID,CN,UN,LN,T1,T2)
+#define FCALLSCSUB3( CN,UN,LN,T1,T2,T3) FCALLSCFUN3(VOID,CN,UN,LN,T1,T2,T3)
+#define FCALLSCSUB4( CN,UN,LN,T1,T2,T3,T4) \
+ FCALLSCFUN4(VOID,CN,UN,LN,T1,T2,T3,T4)
+#define FCALLSCSUB5( CN,UN,LN,T1,T2,T3,T4,T5) \
+ FCALLSCFUN5(VOID,CN,UN,LN,T1,T2,T3,T4,T5)
+#define FCALLSCSUB6( CN,UN,LN,T1,T2,T3,T4,T5,T6) \
+ FCALLSCFUN6(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6)
+#define FCALLSCSUB7( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ FCALLSCFUN7(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7)
+#define FCALLSCSUB8( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ FCALLSCFUN8(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8)
+#define FCALLSCSUB9( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ FCALLSCFUN9(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9)
+#define FCALLSCSUB10(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ FCALLSCFUN10(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA)
+#define FCALLSCSUB11(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ FCALLSCFUN11(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB)
+#define FCALLSCSUB12(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ FCALLSCFUN12(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC)
+#define FCALLSCSUB13(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ FCALLSCFUN13(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD)
+#define FCALLSCSUB14(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ FCALLSCFUN14(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define FCALLSCSUB15(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \
+ FCALLSCFUN15(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF)
+#define FCALLSCSUB16(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \
+ FCALLSCFUN16(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG)
+#define FCALLSCSUB17(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \
+ FCALLSCFUN17(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH)
+#define FCALLSCSUB18(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \
+ FCALLSCFUN18(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI)
+#define FCALLSCSUB19(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \
+ FCALLSCFUN19(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ)
+#define FCALLSCSUB20(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ FCALLSCFUN20(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define FCALLSCSUB21(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \
+ FCALLSCFUN21(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL)
+#define FCALLSCSUB22(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \
+ FCALLSCFUN22(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM)
+#define FCALLSCSUB23(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \
+ FCALLSCFUN23(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN)
+#define FCALLSCSUB24(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \
+ FCALLSCFUN24(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO)
+#define FCALLSCSUB25(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \
+ FCALLSCFUN25(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP)
+#define FCALLSCSUB26(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \
+ FCALLSCFUN26(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ)
+#define FCALLSCSUB27(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ FCALLSCFUN27(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+
+
+#define FCALLSCFUN1( T0,CN,UN,LN,T1) \
+ FCALLSCFUN5 (T0,CN,UN,LN,T1,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN2( T0,CN,UN,LN,T1,T2) \
+ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,CF_0,CF_0,CF_0)
+#define FCALLSCFUN3( T0,CN,UN,LN,T1,T2,T3) \
+ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,T3,CF_0,CF_0)
+#define FCALLSCFUN4( T0,CN,UN,LN,T1,T2,T3,T4) \
+ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,T3,T4,CF_0)
+#define FCALLSCFUN5( T0,CN,UN,LN,T1,T2,T3,T4,T5) \
+ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN6( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6) \
+ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN7( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0)
+#define FCALLSCFUN8( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0)
+#define FCALLSCFUN9( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0)
+#define FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN11(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0)
+#define FCALLSCFUN12(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0)
+#define FCALLSCFUN13(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0)
+
+
+#define FCALLSCFUN15(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \
+ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN16(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \
+ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN17(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \
+ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0)
+#define FCALLSCFUN18(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \
+ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0)
+#define FCALLSCFUN19(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \
+ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0)
+#define FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN21(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN22(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN23(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0)
+#define FCALLSCFUN24(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0)
+#define FCALLSCFUN25(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0)
+#define FCALLSCFUN26(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \
+ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0)
+
+
+#ifndef __CF__KnR
+#define FCALLSCFUN0(T0,CN,UN,LN) CFextern _(T0,_cfFZ)(UN,LN) ABSOFT_cf2(T0)) \
+ {_Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN(); _Icf(0,K,T0,0,0) _(T0,_cfI)}
+
+#define FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ CFextern _(T0,_cfF)(UN,LN) \
+ CFARGT14(NCF,DCF,ABSOFT_cf2(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \
+ { CFARGT14S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \
+ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \
+ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \
+ TCF(LN,TD,13,1) TCF(LN,TE,14,1) ); _Icf(0,K,T0,0,0) \
+ CFARGT14S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfI) }
+
+#define FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ CFextern _(T0,_cfF)(UN,LN) \
+ CFARGT27(NCF,DCF,ABSOFT_cf2(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) ) \
+ { CFARGT27S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \
+ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \
+ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \
+ TCF(LN,TD,13,1) TCF(LN,TE,14,1) TCF(LN,TF,15,1) TCF(LN,TG,16,1) TCF(LN,TH,17,1) \
+ TCF(LN,TI,18,1) TCF(LN,TJ,19,1) TCF(LN,TK,20,1) TCF(LN,TL,21,1) TCF(LN,TM,22,1) \
+ TCF(LN,TN,23,1) TCF(LN,TO,24,1) TCF(LN,TP,25,1) TCF(LN,TQ,26,1) TCF(LN,TR,27,1) ); _Icf(0,K,T0,0,0) \
+ CFARGT27S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) _(T0,_cfI) }
+
+#else
+#define FCALLSCFUN0(T0,CN,UN,LN) CFextern _(T0,_cfFZ)(UN,LN) ABSOFT_cf3(T0)) _Icf(0,FF,T0,0,0)\
+ {_Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN(); _Icf(0,K,T0,0,0) _(T0,_cfI)}
+
+#define FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ CFextern _(T0,_cfF)(UN,LN) \
+ CFARGT14(NNCF,DDCF,ABSOFT_cf3(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)) _Icf(0,FF,T0,0,0) \
+ CFARGT14FS(NNNCF,DDDCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE); \
+ { CFARGT14S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \
+ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \
+ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \
+ TCF(LN,TD,13,1) TCF(LN,TE,14,1) ); _Icf(0,K,T0,0,0) \
+ CFARGT14S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfI)}
+
+#define FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ CFextern _(T0,_cfF)(UN,LN) \
+ CFARGT27(NNCF,DDCF,ABSOFT_cf3(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)) _Icf(0,FF,T0,0,0) \
+ CFARGT27FS(NNNCF,DDDCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR); \
+ { CFARGT27S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \
+ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \
+ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \
+ TCF(LN,TD,13,1) TCF(LN,TE,14,1) TCF(LN,TF,15,1) TCF(LN,TG,16,1) TCF(LN,TH,17,1) \
+ TCF(LN,TI,18,1) TCF(LN,TJ,19,1) TCF(LN,TK,20,1) TCF(LN,TL,21,1) TCF(LN,TM,22,1) \
+ TCF(LN,TN,23,1) TCF(LN,TO,24,1) TCF(LN,TP,25,1) TCF(LN,TQ,26,1) TCF(LN,TR,27,1) ); _Icf(0,K,T0,0,0) \
+ CFARGT27S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) _(T0,_cfI)}
+
+#endif
+
+
+#endif /* __CFORTRAN_LOADED */
diff --git a/src/cmortable_parser.cc b/src/cmortable_parser.cc
index 6174c47..4cce3cf 100644
--- a/src/cmortable_parser.cc
+++ b/src/cmortable_parser.cc
@@ -32,7 +32,7 @@ char *readLineFromBuffer(char *buffer, size_t *buffersize, char *line, size_t le
line[ipos++] = ichar;
if ( ipos >= len )
{
- fprintf(stderr, "readLineFromBuffer: end of line not found (maxlen = %ld)!\n", len);
+ fprintf(stderr, "readLineFromBuffer: end of line not found (maxlen = %zu)!\n", len);
break;
}
}
diff --git a/src/compare.h b/src/compare.h
index 76f9340..eb24cc2 100644
--- a/src/compare.h
+++ b/src/compare.h
@@ -15,11 +15,11 @@
GNU General Public License for more details.
*/
-#ifndef _COMPARE_H
-#define _COMPARE_H
+#ifndef COMPARE_H
+#define COMPARE_H
-#if defined(HAVE_CONFIG_H)
-# include "config.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#include <math.h>
@@ -52,4 +52,4 @@
#define STR_IS_EQ(x,y) ((*x)==(*y) && strcmp(x,y) == 0)
-#endif /* _COMPARE_H */
+#endif /* COMPARE_H */
diff --git a/src/config.h.in b/src/config.h.in
index c527e4d..3c78bf3 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -18,9 +18,21 @@
/* Define to 1 for DATA support */
#undef ENABLE_DATA
+/* Define to 1 for nearpt3 support */
+#undef ENABLE_NEARPT3
+
+/* F77 Compiler */
+#undef F77_COMPILER
+
+/* F77 Compiler version */
+#undef F77_VERSION
+
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
+/* Defined to 1 if C / Fortran interface cfortran.h works */
+#undef HAVE_CF_INTERFACE
+
/* Define to 1 if you have the <cmor.h> header file. */
#undef HAVE_CMOR_H
@@ -276,6 +288,11 @@
/* Version number of package */
#undef VERSION
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
diff --git a/src/ecacore.cc b/src/ecacore.cc
index 244c098..5bb9dbf 100644
--- a/src/ecacore.cc
+++ b/src/ecacore.cc
@@ -36,7 +36,7 @@ void eca1(const ECA_REQUEST_1 *request)
{
const int operatorID = cdoOperatorID();
- int nmiss;
+ size_t nmiss;
int cmplen;
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
int gridsize;
@@ -403,7 +403,7 @@ void eca2(const ECA_REQUEST_2 *request)
{
const int operatorID = cdoOperatorID();
- int nmiss;
+ size_t nmiss;
int cmplen;
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
int gridsize;
@@ -792,7 +792,7 @@ void eca3(const ECA_REQUEST_3 *request)
{
const int operatorID = cdoOperatorID();
- int nmiss;
+ size_t nmiss;
int cmplen;
char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
int gridsize;
@@ -999,7 +999,7 @@ void eca4(const ECA_REQUEST_4 *request)
{
const int operatorID = cdoOperatorID();
- int nmiss;
+ size_t nmiss;
int yearcnt = 0;
int nrecs;
int varID, levelID;
diff --git a/src/ecautil.cc b/src/ecautil.cc
index 03d1fb6..65c8fd6 100644
--- a/src/ecautil.cc
+++ b/src/ecautil.cc
@@ -147,16 +147,16 @@ unsigned long day_of_year(int date)
*/
static void count(field_type *field1, const field_type *field2, double mode)
{
- int i, len;
+ size_t i;
const int grid1 = field1->grid;
- const int nmiss1 = field1->nmiss;
+ const size_t nmiss1 = field1->nmiss;
const double missval1 = field1->missval;
double *array1 = field1->ptr;
const int grid2 = field2->grid;
const double missval2 = field2->missval;
const double *array2 = field2->ptr;
- len = gridInqSize(grid1);
+ size_t len = gridInqSize(grid1);
if ( len != gridInqSize(grid2) )
cdoAbort("Fields have different gridsize (%s)", __func__);
@@ -231,17 +231,17 @@ static void count(field_type *field1, const field_type *field2, double mode)
*/
static void selcomp(field_type *field1, const field_type *field2, int (*compare)(double, double))
{
- int i, len;
+ size_t i;
const int grid1 = field1->grid;
- const int nmiss1 = field1->nmiss;
+ const size_t nmiss1 = field1->nmiss;
const double missval1 = field1->missval;
double *array1 = field1->ptr;
const int grid2 = field2->grid;
- const int nmiss2 = field2->nmiss;
+ const size_t nmiss2 = field2->nmiss;
const double missval2 = field2->missval;
const double *array2 = field2->ptr;
- len = gridInqSize(grid1);
+ size_t len = gridInqSize(grid1);
if ( len != gridInqSize(grid2) )
cdoAbort("Fields have different gridsize (%s)", __func__);
@@ -282,13 +282,13 @@ static void selcomp(field_type *field1, const field_type *field2, int (*compare)
*/
static void selcompc(field_type *field, double c, int (*compare)(double, double))
{
- int i, len;
+ size_t i;
const int grid = field->grid;
- const int nmiss = field->nmiss;
+ const size_t nmiss = field->nmiss;
const double missval = field->missval;
double *array = field->ptr;
- len = gridInqSize(grid);
+ size_t len = gridInqSize(grid);
if ( DBL_IS_EQUAL(c, missval) )
{
@@ -370,16 +370,16 @@ void farnum3(field_type *field1, field_type field2, double n)
void farsel(field_type *field1, field_type field2)
{
- int i, len;
+ size_t i;
const int grid1 = field1->grid;
const double missval1 = field1->missval;
double *array1 = field1->ptr;
const int grid2 = field2.grid;
- const int nmiss2 = field2.nmiss;
+ const size_t nmiss2 = field2.nmiss;
const double missval2 = field2.missval;
const double *array2 = field2.ptr;
- len = gridInqSize(grid1);
+ size_t len = gridInqSize(grid1);
if ( len != gridInqSize(grid2) )
cdoAbort("Fields have different gridsize (%s)", __func__);
diff --git a/src/expr.cc b/src/expr.cc
index 0fdbdab..5c1b51c 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -58,6 +58,7 @@ enum {FT_STD, FT_CONST, FT_FLD, FT_VERT, FT_COORD, FT_1C};
#define MVCOMPAND(x,y) (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPAND(x,y))
#define MVCOMPOR(x,y) (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPOR(x,y))
+static double f_float(double x) { return (float)(x); }
static double f_int(double x) { return (int)(x); }
static double f_nint(double x) { return round(x); }
static double f_sqr(double x) { return x*x; }
@@ -101,6 +102,7 @@ static func_t fun_sym_tbl[] =
{FT_STD, 0, "acosh", (double (*)()) (double (*)(double)) acosh},
{FT_STD, 0, "atanh", (double (*)()) (double (*)(double)) atanh},
{FT_STD, 0, "gamma", (double (*)()) (double (*)(double)) tgamma},
+ {FT_STD, 0, "float", (double (*)()) f_float},
{FT_STD, 0, "int", (double (*)()) f_int},
{FT_STD, 0, "nint", (double (*)()) f_nint},
{FT_STD, 0, "sqr", (double (*)()) f_sqr},
@@ -185,10 +187,17 @@ int get_funcID(const char *fun)
}
static
+bool isCompare(int oper)
+{
+ return oper==LEG||oper==GE||oper==LE||oper==EQ||oper==NE||oper==GT||oper==LT;
+}
+
+static
void param_meta_copy(paramType *out, paramType *in)
{
out->gridID = in->gridID;
out->zaxisID = in->zaxisID;
+ out->datatype = in->datatype;
out->steptype = in->steptype;
out->ngp = in->ngp;
out->nlev = in->nlev;
@@ -450,6 +459,7 @@ nodeType *expr_con_var(int init, int oper, nodeType *p1, nodeType *p2)
size_t ngp = p2->param.ngp;
size_t nlev = p2->param.nlev;
size_t nmiss = p2->param.nmiss;
+ int datatype = p2->param.datatype;
double missval1 = p2->param.missval;
double missval2 = p2->param.missval;
@@ -469,6 +479,7 @@ nodeType *expr_con_var(int init, int oper, nodeType *p1, nodeType *p2)
double *restrict odat = p->param.data;
const double *restrict idat = p2->param.data;
double cval = p1->u.con.value;
+ if ( datatype == CDI_DATATYPE_FLT32 && isCompare(oper) ) cval = (float) cval;
oper_expr_con_var(oper, nmiss>0, n, missval1, missval2, odat, cval, idat);
@@ -488,6 +499,7 @@ nodeType *expr_var_con(int init, int oper, nodeType *p1, nodeType *p2)
size_t ngp = p1->param.ngp;
size_t nlev = p1->param.nlev;
size_t nmiss = p1->param.nmiss;
+ int datatype = p1->param.datatype;
double missval1 = p1->param.missval;
double missval2 = p1->param.missval;
@@ -507,6 +519,7 @@ nodeType *expr_var_con(int init, int oper, nodeType *p1, nodeType *p2)
double *restrict odat = p->param.data;
const double *restrict idat = p1->param.data;
double cval = p2->u.con.value;
+ if ( datatype == CDI_DATATYPE_FLT32 && isCompare(oper) ) cval = (float) cval;
oper_expr_var_con(oper, nmiss>0, n, missval1, missval2, odat, idat, cval);
@@ -584,7 +597,7 @@ nodeType *expr_var_var(int init, int oper, nodeType *p1, nodeType *p2)
}
p->param.name = p->u.var.nm;
- //printf("%s %s nmiss %ld %ld\n", p->u.var.nm, px->param.name, nmiss1, nmiss2);
+ //printf("%s %s nmiss %zu %zu\n", p->u.var.nm, px->param.name, nmiss1, nmiss2);
if ( ! init )
{
@@ -601,7 +614,7 @@ nodeType *expr_var_var(int init, int oper, nodeType *p1, nodeType *p2)
const double *restrict idat1 = p1->param.data+loff1;
const double *restrict idat2 = p2->param.data+loff2;
double *restrict odat = p->param.data+loff;
- int nmiss = nmiss1 > 0 || nmiss2 > 0;
+ size_t nmiss = nmiss1 > 0 || nmiss2 > 0;
if ( ngp1 != ngp2 )
{
@@ -629,7 +642,7 @@ nodeType *expr_var_var(int init, int oper, nodeType *p1, nodeType *p2)
static
void ex_copy_var(int init, nodeType *p2, nodeType *p1)
{
- if ( cdoVerbose ) cdoPrint("\t%s\tcopy\t%s[L%lu][N%lu] = %s[L%lu][N%lu]",
+ if ( cdoVerbose ) cdoPrint("\t%s\tcopy\t%s[L%zu][N%zu] = %s[L%zu][N%zu]",
ExIn[init], p2->param.name, p2->param.nlev, p2->param.ngp, p1->param.name, p2->param.nlev, p2->param.ngp);
size_t ngp = p1->param.ngp;
@@ -662,7 +675,7 @@ void ex_copy_con(int init, nodeType *p2, nodeType *p1)
{
double cval = p1->u.con.value;
- if ( cdoVerbose ) cdoPrint("\t%s\tcopy\t%s[L%lu][N%lu] = %g", ExIn[init], p2->param.name, p2->param.nlev, p2->param.ngp, cval);
+ if ( cdoVerbose ) cdoPrint("\t%s\tcopy\t%s[L%zu][N%zu] = %g", ExIn[init], p2->param.name, p2->param.nlev, p2->param.ngp, cval);
size_t ngp = p2->param.ngp;
assert(ngp > 0);
@@ -722,19 +735,19 @@ nodeType *expr(int init, int oper, nodeType *p1, nodeType *p2)
{
p = expr_var_var(init, oper, p1, p2);
if ( cdoVerbose )
- cdoPrint("\t%s\tarith\t%s[L%lu][N%lu] = %s %s %s", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.var.nm, coper, p2->u.var.nm);
+ cdoPrint("\t%s\tarith\t%s[L%zu][N%zu] = %s %s %s", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.var.nm, coper, p2->u.var.nm);
}
else if ( p1->type == typeVar && p2->type == typeCon )
{
p = expr_var_con(init, oper, p1, p2);
if ( cdoVerbose )
- cdoPrint("\t%s\tarith\t%s[L%lu][N%lu] = %s %s %g", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.var.nm, coper, p2->u.con.value);
+ cdoPrint("\t%s\tarith\t%s[L%zu][N%zu] = %s %s %g", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.var.nm, coper, p2->u.con.value);
}
else if ( p1->type == typeCon && p2->type == typeVar )
{
p = expr_con_var(init, oper, p1, p2);
if ( cdoVerbose )
- cdoPrint("\t%s\tarith\t%s[L%lu][N%lu] = %g %s %s", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.con.value, coper, p2->u.var.nm);
+ cdoPrint("\t%s\tarith\t%s[L%zu][N%zu] = %g %s %s", ExIn[init], p->u.var.nm, p->param.nlev, p->param.ngp, p1->u.con.value, coper, p2->u.var.nm);
}
else if ( p1->type == typeCon && p2->type == typeCon )
{
@@ -969,7 +982,7 @@ nodeType *fun1c(int init, int funcID, nodeType *p1, double value, parse_param_t
{
long ilevidx = lround(value);
if ( ilevidx < 1 || ilevidx > (long)nlev )
- cdoAbort("%s(): level index %ld out of range (range: 1-%lu)!", funcname, ilevidx, nlev);
+ cdoAbort("%s(): level index %ld out of range (range: 1-%zu)!", funcname, ilevidx, nlev);
levidx = (size_t) ilevidx - 1;
}
else if ( strcmp(funcname, "sellevel") == 0 )
@@ -1137,15 +1150,15 @@ nodeType *ex_ifelse(int init, nodeType *p1, nodeType *p2, nodeType *p3)
if ( cdoVerbose )
{
- fprintf(stderr, "cdo expr:\t%s\tifelse\t%s[L%lu][N%lu] ? ", ExIn[init], p1->u.var.nm, p1->param.nlev, p1->param.ngp);
+ fprintf(stderr, "cdo expr:\t%s\tifelse\t%s[L%zu][N%zu] ? ", ExIn[init], p1->u.var.nm, p1->param.nlev, p1->param.ngp);
if ( p2->type == typeCon )
fprintf(stderr, "%g : ", p2->u.con.value);
else
- fprintf(stderr, "%s[L%lu][N%lu] : ", p2->u.var.nm, p2->param.nlev, p2->param.ngp);
+ fprintf(stderr, "%s[L%zu][N%zu] : ", p2->u.var.nm, p2->param.nlev, p2->param.ngp);
if ( p3->type == typeCon )
fprintf(stderr, "%g\n", p3->u.con.value);
else
- fprintf(stderr, "%s[L%lu][N%lu]\n", p3->u.var.nm, p3->param.nlev, p3->param.ngp);
+ fprintf(stderr, "%s[L%zu][N%zu]\n", p3->u.var.nm, p3->param.nlev, p3->param.ngp);
}
size_t nmiss1 = p1->param.nmiss;
@@ -1377,9 +1390,9 @@ nodeType *expr_run(nodeType *p, parse_param_t *parse_arg)
if ( i < maxout || (ngp > maxout && i >= (ngp-maxout)) )
{
if ( steptype == TIME_CONSTANT )
- fprintf(stdout, " %s[lev=%lu:gp=%lu] = %g\n", vname, k+1, i+1, data[k*ngp+i]);
+ fprintf(stdout, " %s[lev=%zu:gp=%zu] = %g\n", vname, k+1, i+1, data[k*ngp+i]);
else
- fprintf(stdout, " %s[ts=%ld:lev=%lu:gp=%lu] = %g\n", vname, tsID, k+1, i+1, data[k*ngp+i]);
+ fprintf(stdout, " %s[ts=%ld:lev=%zu:gp=%zu] = %g\n", vname, tsID, k+1, i+1, data[k*ngp+i]);
}
else if ( i == maxout )
{
@@ -1514,7 +1527,7 @@ nodeType *expr_run(nodeType *p, parse_param_t *parse_arg)
p->param.nmiss = params[varID].nmiss;
}
- if ( parse_arg->debug ) cdoPrint("\tpush\tvar\t%s[L%lu][N%lu]", vnm, p->param.nlev, p->param.ngp);
+ if ( parse_arg->debug ) cdoPrint("\tpush\tvar\t%s[L%zu][N%zu]", vnm, p->param.nlev, p->param.ngp);
rnode = p;
@@ -1577,7 +1590,7 @@ nodeType *expr_run(nodeType *p, parse_param_t *parse_arg)
if ( parse_arg->debug )
{
if ( rnode && rnode->type == typeVar)
- cdoPrint("\tpop\tvar\t%s[L%lu][N%lu]", varname2, rnode->param.nlev, rnode->param.ngp);
+ cdoPrint("\tpop\tvar\t%s[L%zu][N%zu]", varname2, rnode->param.nlev, rnode->param.ngp);
else
cdoPrint("\tpop\tconst\t%s", varname2);
}
diff --git a/src/expr.h b/src/expr.h
index b7fc437..278c38b 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -73,6 +73,7 @@ typedef struct {
int coord;
int gridID;
int zaxisID;
+ int datatype;
int steptype;
size_t ngp;
size_t nlev;
diff --git a/src/expr_lex.cc b/src/expr_lex.cc
index bf0929b..948162e 100644
--- a/src/expr_lex.cc
+++ b/src/expr_lex.cc
@@ -1,6 +1,6 @@
-#line 2 "expr_lex.cc"
+#line 1 "expr_lex.cc"
-#line 4 "expr_lex.cc"
+#line 3 "expr_lex.cc"
#define YY_INT_ALIGNED short int
@@ -9,11 +9,23 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 1
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
+#ifdef yyget_lval
+#define yyget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval yyget_lval
+#endif
+
+#ifdef yyset_lval
+#define yyset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval yyset_lval
+#endif
+
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
@@ -84,10 +96,16 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
+/* begin standard C++ headers. */
+
/* TODO: this is always defined, so inline it */
#define yyconst const
@@ -100,12 +118,10 @@ typedef unsigned int flex_uint32_t;
/* Returned upon end-of-file. */
#define YY_NULL 0
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -129,20 +145,16 @@ typedef void* yyscan_t;
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
@@ -175,7 +187,7 @@ typedef size_t yy_size_t;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
#define YY_LESS_LINENO(n)
#define YY_LINENO_REWIND_TO(ptr)
@@ -192,7 +204,6 @@ typedef size_t yy_size_t;
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -235,7 +246,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -269,73 +280,67 @@ struct yy_buffer_state
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void yypop_buffer_state (yyscan_t yyscanner );
-
-static void yyensure_buffer_stack (yyscan_t yyscanner );
-static void yy_load_buffer_state (yyscan_t yyscanner );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
-void *yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void yyfree (void * ,yyscan_t yyscanner );
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
#define yy_new_buffer yy_create_buffer
-
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
/* Begin user sect3 */
#define yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
typedef int yy_state_type;
#define yytext_ptr yytext_r
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
@@ -346,7 +351,6 @@ static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-
#define YY_NUM_RULES 25
#define YY_END_OF_BUFFER 26
/* This struct is not used in this scanner,
@@ -356,7 +360,7 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_acclist[164] =
+static const flex_int16_t yy_acclist[164] =
{ 0,
4, 4, 26, 24, 25, 23, 24, 25, 23, 25,
24, 25, 1, 24, 25, 24, 25, 11, 24, 25,
@@ -378,7 +382,7 @@ static yyconst flex_int16_t yy_acclist[164] =
16391, 5, 8199
} ;
-static yyconst flex_int16_t yy_accept[76] =
+static const flex_int16_t yy_accept[76] =
{ 0,
1, 2, 3, 4, 6, 9, 11, 13, 16, 18,
21, 25, 28, 31, 34, 37, 40, 43, 48, 54,
@@ -390,7 +394,7 @@ static yyconst flex_int16_t yy_accept[76] =
157, 159, 162, 164, 164
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
@@ -422,7 +426,7 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[35] =
+static const YY_CHAR yy_meta[35] =
{ 0,
1, 1, 2, 3, 1, 1, 1, 3, 1, 1,
4, 5, 1, 1, 1, 1, 1, 6, 6, 6,
@@ -430,7 +434,7 @@ static yyconst YY_CHAR yy_meta[35] =
6, 6, 6, 1
} ;
-static yyconst flex_uint16_t yy_base[80] =
+static const flex_int16_t yy_base[80] =
{ 0,
0, 0, 134, 135, 33, 36, 118, 0, 125, 135,
29, 31, 135, 116, 115, 114, 135, 49, 51, 34,
@@ -442,7 +446,7 @@ static yyconst flex_uint16_t yy_base[80] =
135, 50, 135, 135, 97, 100, 104, 106, 46
} ;
-static yyconst flex_int16_t yy_def[80] =
+static const flex_int16_t yy_def[80] =
{ 0,
74, 1, 74, 74, 74, 74, 74, 75, 74, 74,
74, 76, 74, 74, 74, 74, 74, 77, 77, 19,
@@ -454,7 +458,7 @@ static yyconst flex_int16_t yy_def[80] =
74, 19, 74, 0, 74, 74, 74, 74, 74
} ;
-static yyconst flex_uint16_t yy_nxt[170] =
+static const flex_int16_t yy_nxt[170] =
{ 0,
4, 5, 6, 5, 7, 8, 9, 10, 10, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
@@ -476,7 +480,7 @@ static yyconst flex_uint16_t yy_nxt[170] =
74, 74, 74, 74, 74, 74, 74, 74, 74
} ;
-static yyconst flex_int16_t yy_chk[170] =
+static const flex_int16_t yy_chk[170] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -532,6 +536,7 @@ goto find_rule; \
#include "expr.h"
#include "expr_yacc.h"
+#line 539 "expr_lex.cc"
/* Definitions: LMB92 p. 153
Definitions are named regular expressions, e.g., DGT [0-9]
Definitions enclosed in braces in rules section, e.g. {DGT}, are interpreted literally
@@ -539,7 +544,7 @@ goto find_rule; \
LPH [A-Za-z_] Alphabetic character
LPHDGT [A-Za-z0-9_] Alphanumeric character
XPN [eE][+-]?[0-9]+ Real number Exponent */
-#line 543 "expr_lex.cc"
+#line 547 "expr_lex.cc"
#define INITIAL 0
@@ -602,7 +607,7 @@ struct yyguts_t
}; /* end struct yyguts_t */
-static int yy_init_globals (yyscan_t yyscanner );
+static int yy_init_globals ( yyscan_t yyscanner );
/* This must go here because YYSTYPE and YYLTYPE are included
* from bison output in section 1.*/
@@ -610,44 +615,44 @@ static int yy_init_globals (yyscan_t yyscanner );
int yylex_init (yyscan_t* scanner);
-int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int yylex_destroy (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-int yyget_debug (yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-FILE *yyget_in (yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
-void yyset_in (FILE * _in_str ,yyscan_t yyscanner );
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
-FILE *yyget_out (yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
-void yyset_out (FILE * _out_str ,yyscan_t yyscanner );
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
- int yyget_leng (yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
-char *yyget_text (yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
-int yyget_lineno (yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
-void yyset_lineno (int _line_number ,yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
-int yyget_column (yyscan_t yyscanner );
+int yyget_column ( yyscan_t yyscanner );
-void yyset_column (int _column_no ,yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
-YYSTYPE * yyget_lval (yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
-void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -655,9 +660,9 @@ void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int yywrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int yywrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
@@ -666,19 +671,18 @@ extern int yywrap (yyscan_t yyscanner );
#endif
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
#endif
@@ -709,7 +713,7 @@ static int input (yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -722,7 +726,7 @@ static int input (yyscan_t yyscanner );
else \
{ \
errno=0; \
- while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -764,7 +768,7 @@ static int input (yyscan_t yyscanner );
#define YY_DECL_IS_OURS 1
extern int yylex \
- (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+ (YYSTYPE * yylval_param , yyscan_t yyscanner);
#define YY_DECL int yylex \
(YYSTYPE * yylval_param , yyscan_t yyscanner)
@@ -806,7 +810,7 @@ YY_DECL
/* Create the reject buffer large enough to save one state per allowed character. */
if ( ! yyg->yy_state_buf )
- yyg->yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ,yyscanner);
+ yyg->yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE , yyscanner);
if ( ! yyg->yy_state_buf )
YY_FATAL_ERROR( "out of dynamic memory in yylex()" );
@@ -822,17 +826,17 @@ YY_DECL
if ( ! YY_CURRENT_BUFFER ) {
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
#line 36 "expr_lex.l"
-#line 836 "expr_lex.cc"
+#line 839 "expr_lex.cc"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -859,9 +863,9 @@ yy_match:
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 75 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
*yyg->yy_state_ptr++ = yy_current_state;
++yy_cp;
}
@@ -1066,7 +1070,7 @@ YY_RULE_SETUP
#line 104 "expr_lex.l"
ECHO;
YY_BREAK
-#line 1070 "expr_lex.cc"
+#line 1073 "expr_lex.cc"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1144,7 +1148,7 @@ ECHO;
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( yywrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1212,7 +1216,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1241,7 +1245,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1280,7 +1284,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -1294,12 +1298,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -1331,9 +1338,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 75 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
*yyg->yy_state_ptr++ = yy_current_state;
}
@@ -1355,9 +1362,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 75 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 74);
if ( ! yy_is_jam )
*yyg->yy_state_ptr++ = yy_current_state;
@@ -1395,7 +1402,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1412,13 +1419,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
/* Reset buffer status. */
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( yywrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
@@ -1457,11 +1464,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( ! YY_CURRENT_BUFFER ){
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- yy_load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
/** Switch to a different input buffer.
@@ -1490,7 +1497,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
@@ -1519,22 +1526,22 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- yy_init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
@@ -1554,9 +1561,9 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- yyfree((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- yyfree((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
/* Initializes or reinitializes a buffer.
@@ -1569,7 +1576,7 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
@@ -1613,7 +1620,7 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
@@ -1645,7 +1652,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = new_buffer;
/* copied from yy_switch_to_buffer. */
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
@@ -1659,13 +1666,13 @@ void yypop_buffer_state (yyscan_t yyscanner)
if (!YY_CURRENT_BUFFER)
return;
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
@@ -1675,7 +1682,7 @@ void yypop_buffer_state (yyscan_t yyscanner)
*/
static void yyensure_buffer_stack (yyscan_t yyscanner)
{
- int num_to_alloc;
+ yy_size_t num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!yyg->yy_buffer_stack) {
@@ -1690,9 +1697,9 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -1721,7 +1728,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
@@ -1733,11 +1740,11 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
/* They forgot to leave room for the EOB's. */
return NULL;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
b->yy_input_file = NULL;
@@ -1747,7 +1754,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- yy_switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
@@ -1760,10 +1767,10 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
* @note If you want to scan bytes that may contain NUL values, then use
* yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return yy_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -1773,16 +1780,16 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = (yy_size_t) _yybytes_len + 2;
- buf = (char *) yyalloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@@ -1791,7 +1798,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = yy_scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
@@ -1807,11 +1814,11 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
#define YY_EXIT_FAILURE 2
#endif
-static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -1849,7 +1856,7 @@ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -1862,7 +1869,7 @@ int yyget_lineno (yyscan_t yyscanner)
int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -1996,9 +2003,7 @@ void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
int yylex_init(yyscan_t* ptr_yy_globals)
-
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
@@ -2025,9 +2030,7 @@ int yylex_init(yyscan_t* ptr_yy_globals)
* The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
@@ -2037,20 +2040,20 @@ int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
errno = EINVAL;
return 1;
}
-
+
*ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+
return yy_init_globals ( *ptr_yy_globals );
}
@@ -2099,17 +2102,17 @@ int yylex_destroy (yyscan_t yyscanner)
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- yyfree(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
yyfree ( yyg->yy_state_buf , yyscanner);
@@ -2130,7 +2133,7 @@ int yylex_destroy (yyscan_t yyscanner)
*/
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2142,7 +2145,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -2186,4 +2189,3 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#line 104 "expr_lex.l"
-
diff --git a/src/expr_yacc.cc b/src/expr_yacc.cc
index b5a9650..e692378 100644
--- a/src/expr_yacc.cc
+++ b/src/expr_yacc.cc
@@ -416,16 +416,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 186
+#define YYLAST 204
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 32
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 7
/* YYNRULES -- Number of rules. */
-#define YYNRULES 36
+#define YYNRULES 37
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 77
+#define YYNSTATES 79
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
@@ -476,7 +476,7 @@ static const yytype_uint8 yyrline[] =
0, 60, 60, 64, 65, 69, 70, 71, 72, 73,
74, 75, 76, 80, 81, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 104, 105, 108
+ 100, 101, 102, 103, 104, 105, 106, 109
};
#endif
@@ -519,14 +519,14 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- -25, 2, 34, -25, -25, -21, -24, 7, 10, 41,
- -25, 34, 41, -25, 133, -25, 41, 41, 13, 14,
- -25, 24, -25, 27, 100, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, -25,
- 84, 9, 62, 26, 33, -25, -25, -25, 162, 162,
- 46, 46, 46, 46, 46, 46, 46, -12, -12, 24,
- 24, 24, 41, -25, -25, -25, 30, -25, -25, 118,
- 22, 12, 41, -25, 42, 149, -25
+ -25, 2, 41, -25, -25, -21, -24, 7, 10, 59,
+ -25, 41, 59, -25, 151, -25, 59, 59, -11, 8,
+ -25, 14, -25, 28, 80, 13, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ -25, 120, 16, 98, 17, 18, -25, -25, 59, -25,
+ -25, 180, 180, 53, 53, 53, 53, 53, 53, 53,
+ -12, -12, 14, 14, 14, -25, -25, -25, 31, -25,
+ -25, 136, 20, 12, 59, -25, 25, 167, -25
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -537,23 +537,23 @@ static const yytype_uint8 yydefact[] =
4, 0, 2, 1, 15, 16, 0, 0, 0, 0,
5, 0, 0, 3, 0, 9, 0, 0, 0, 0,
16, 17, 13, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 12, 14, 32, 30, 31,
- 29, 25, 26, 28, 27, 23, 22, 18, 19, 20,
- 21, 24, 0, 7, 8, 35, 0, 10, 11, 0,
- 0, 0, 0, 34, 0, 36, 33
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 12, 14, 0, 32,
+ 33, 30, 31, 29, 25, 26, 28, 27, 23, 22,
+ 18, 19, 20, 21, 24, 7, 8, 36, 0, 10,
+ 11, 0, 0, 0, 0, 35, 0, 37, 34
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -25, -25, -25, -10, -25, -9, -25
+ -25, -25, -25, -10, -25, -9, 38
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 1, 2, 13, 23, 14, 41
+ -1, 1, 2, 13, 23, 14, 25
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -561,48 +561,52 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 21, 22, 3, 24, 15, 16, 17, 40, 42, 36,
- 37, 18, 38, 46, 19, 74, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 4, 5, 6, 70, 64, 7, 8, 4, 5, 6,
- 43, 44, 7, 8, 4, 20, 6, 9, 38, 73,
- 71, 67, 10, 69, 9, 11, 45, 12, 68, 10,
- 0, 9, 11, 75, 12, 34, 35, 36, 37, 76,
- 38, 12, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 0, 38, 0, 0, 65,
- 62, 0, 0, 66, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 0, 38, 63,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 0, 38, 72, 0, 47, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 0, 38, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 0, 38, 39, 25,
+ 21, 22, 3, 24, 15, 16, 17, 41, 43, 37,
+ 38, 18, 39, 47, 19, 76, 44, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 4, 5, 6, 72, 45, 7, 8, 39, 71,
+ 50, 66, 69, 70, 4, 5, 6, 75, 9, 7,
+ 8, 73, 78, 10, 42, 0, 11, 46, 12, 0,
+ 0, 9, 4, 20, 6, 77, 10, 0, 0, 11,
+ 0, 12, 35, 36, 37, 38, 0, 39, 0, 9,
+ 0, 0, 0, 0, 0, 0, 48, 0, 0, 12,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 0, 38, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 0, 38
+ 36, 37, 38, 0, 39, 0, 0, 49, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 0, 39, 0, 0, 67, 48, 0, 0, 68,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 74, 39, 65, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 0,
+ 39, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 0, 39, 40, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 0, 39, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 0, 39
};
static const yytype_int8 yycheck[] =
{
9, 11, 0, 12, 25, 26, 30, 16, 17, 21,
- 22, 4, 24, 23, 4, 3, 25, 26, 27, 28,
+ 22, 4, 24, 23, 4, 3, 27, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 3, 4, 5, 3, 25, 8, 9, 3, 4, 5,
- 27, 27, 8, 9, 3, 4, 5, 20, 24, 27,
- 20, 25, 25, 62, 20, 28, 29, 30, 25, 25,
- -1, 20, 28, 72, 30, 19, 20, 21, 22, 27,
- 24, 30, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, -1, 24, -1, -1, 27,
- 6, -1, -1, 31, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, -1, 24, 25,
+ 39, 3, 4, 5, 3, 27, 8, 9, 24, 48,
+ 27, 25, 25, 25, 3, 4, 5, 27, 20, 8,
+ 9, 20, 27, 25, 16, -1, 28, 29, 30, -1,
+ -1, 20, 3, 4, 5, 74, 25, -1, -1, 28,
+ -1, 30, 19, 20, 21, 22, -1, 24, -1, 20,
+ -1, -1, -1, -1, -1, -1, 6, -1, -1, 30,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, -1, 24, 7, -1, 27, 10, 11,
+ 20, 21, 22, -1, 24, -1, -1, 27, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, -1, 24, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, -1, 24, 25, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, -1, 24, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, -1, 24
+ 22, -1, 24, -1, -1, 27, 6, -1, -1, 31,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 7, 24, 25, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, -1,
+ 24, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, -1, 24, 25, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ -1, 24, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, -1, 24
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -611,12 +615,12 @@ static const yytype_uint8 yystos[] =
{
0, 33, 34, 0, 3, 4, 5, 8, 9, 20,
25, 28, 30, 35, 37, 25, 26, 30, 4, 4,
- 4, 37, 35, 36, 37, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 24, 25,
- 37, 38, 37, 27, 27, 29, 35, 27, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 6, 25, 25, 27, 31, 25, 25, 37,
- 3, 20, 7, 27, 3, 37, 27
+ 4, 37, 35, 36, 37, 38, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 24,
+ 25, 37, 38, 37, 27, 27, 29, 35, 6, 27,
+ 27, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 25, 25, 27, 31, 25,
+ 25, 37, 3, 20, 7, 27, 3, 37, 27
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -625,7 +629,7 @@ static const yytype_uint8 yyr1[] =
0, 32, 33, 34, 34, 35, 35, 35, 35, 35,
35, 35, 35, 36, 36, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 38
+ 37, 37, 37, 37, 37, 37, 37, 38
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -634,7 +638,7 @@ static const yytype_uint8 yyr2[] =
0, 2, 1, 2, 0, 1, 2, 4, 4, 2,
4, 4, 3, 1, 2, 1, 1, 2, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 7, 6, 4, 5
+ 3, 3, 3, 3, 7, 6, 4, 5
};
@@ -1321,209 +1325,215 @@ yyreduce:
case 2:
#line 60 "expr_yacc.y" /* yacc.c:1646 */
{ return 0; }
-#line 1325 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1329 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 3:
#line 64 "expr_yacc.y" /* yacc.c:1646 */
{ expr_run((yyvsp[0].nPtr), (parse_param_t *) parse_arg); freeNode((yyvsp[0].nPtr)); }
-#line 1331 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1335 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 5:
#line 69 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(';', 2, NULL, NULL); }
-#line 1337 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1341 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 6:
#line 70 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1343 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1347 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 7:
#line 71 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-3].varnm)), (yyvsp[-1].nPtr)); }
-#line 1349 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1353 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 8:
#line 72 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-3].varnm)), (yyvsp[-1].nPtr)); }
-#line 1355 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1359 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 9:
#line 73 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-1].varnm)), expr_var((yyvsp[-1].varnm))); }
-#line 1361 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1365 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 10:
#line 74 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_com("remove", (yyvsp[-2].varnm)); }
-#line 1367 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1371 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 11:
#line 75 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_com("print", (yyvsp[-2].varnm)); }
-#line 1373 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1377 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 12:
#line 76 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1379 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1383 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 13:
#line 80 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = (yyvsp[0].nPtr); }
-#line 1385 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1389 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 14:
#line 81 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(';', 2, (yyvsp[-1].nPtr), (yyvsp[0].nPtr)); }
-#line 1391 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1395 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 15:
#line 85 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_con((yyvsp[0].cvalue)); }
-#line 1397 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1401 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 16:
#line 86 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_var((yyvsp[0].varnm)); }
-#line 1403 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1407 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 17:
#line 87 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(UMINUS, 1, (yyvsp[0].nPtr)); }
-#line 1409 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1413 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 18:
#line 88 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('+', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1415 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1419 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 19:
#line 89 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('-', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1421 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1425 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 20:
#line 90 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('*', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1427 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1431 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 21:
#line 91 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('/', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1433 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1437 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 22:
#line 92 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(LT, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1439 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1443 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 23:
#line 93 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(GT, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1445 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1449 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 24:
#line 94 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('^', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1451 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1455 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 25:
#line 95 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(GE, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1457 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1461 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 26:
#line 96 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(LE, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1463 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1467 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 27:
#line 97 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(NE, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1469 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1473 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 28:
#line 98 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(EQ, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1475 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1479 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 29:
#line 99 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(LEG, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1481 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1485 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 30:
#line 100 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(AND, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1487 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1491 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 31:
#line 101 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr(OR, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1493 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1497 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 32:
#line 102 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1499 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1503 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 33:
#line 103 "expr_yacc.y" /* yacc.c:1646 */
- { (yyval.nPtr) = expr_fun1c((yyvsp[-6].fname), (yyvsp[-4].nPtr), - (yyvsp[-1].cvalue)); }
-#line 1505 "expr_yacc.cc" /* yacc.c:1646 */
+ { (yyval.nPtr) = (yyvsp[-1].nPtr); }
+#line 1509 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 34:
#line 104 "expr_yacc.y" /* yacc.c:1646 */
- { (yyval.nPtr) = expr_fun1c((yyvsp[-5].fname), (yyvsp[-3].nPtr), (yyvsp[-1].cvalue)); }
-#line 1511 "expr_yacc.cc" /* yacc.c:1646 */
+ { (yyval.nPtr) = expr_fun1c((yyvsp[-6].fname), (yyvsp[-4].nPtr), - (yyvsp[-1].cvalue)); }
+#line 1515 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 35:
#line 105 "expr_yacc.y" /* yacc.c:1646 */
- { (yyval.nPtr) = expr_fun((yyvsp[-3].fname), (yyvsp[-1].nPtr)); }
-#line 1517 "expr_yacc.cc" /* yacc.c:1646 */
+ { (yyval.nPtr) = expr_fun1c((yyvsp[-5].fname), (yyvsp[-3].nPtr), (yyvsp[-1].cvalue)); }
+#line 1521 "expr_yacc.cc" /* yacc.c:1646 */
break;
case 36:
-#line 108 "expr_yacc.y" /* yacc.c:1646 */
+#line 106 "expr_yacc.y" /* yacc.c:1646 */
+ { (yyval.nPtr) = expr_fun((yyvsp[-3].fname), (yyvsp[-1].nPtr)); }
+#line 1527 "expr_yacc.cc" /* yacc.c:1646 */
+ break;
+
+ case 37:
+#line 109 "expr_yacc.y" /* yacc.c:1646 */
{ (yyval.nPtr) = expr_opr('?', 3, (yyvsp[-4].nPtr), (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1523 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1533 "expr_yacc.cc" /* yacc.c:1646 */
break;
-#line 1527 "expr_yacc.cc" /* yacc.c:1646 */
+#line 1537 "expr_yacc.cc" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1751,7 +1761,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 111 "expr_yacc.y" /* yacc.c:1906 */
+#line 112 "expr_yacc.y" /* yacc.c:1906 */
#define SIZEOF_NODETYPE ((char *)&p->u.con - (char *)p)
diff --git a/src/features.cc b/src/features.cc
index 07713c8..e56f7a8 100644
--- a/src/features.cc
+++ b/src/features.cc
@@ -23,13 +23,9 @@
#endif
#if defined(HAVE_LIBCMOR)
-#ifdef __cplusplus
- extern "C" {
-#endif
+extern "C" {
#include "cmor.h"
-#ifdef __cplusplus
- }
-#endif
+}
#endif
#include <stdio.h>
@@ -37,9 +33,21 @@
#include "cdo_int.h" // HAVE_OPENMP4
+extern "C" {
+size_t getMemorySize(void);
+}
+
void printFeatures(void)
{
fprintf(stderr, "Features:");
+ size_t memory_size = getMemorySize();
+ memory_size /= 1024;
+ memory_size /= 1024;
+ memory_size /= 1024;
+ if ( memory_size > 0 ) fprintf(stderr, " %zuGB", memory_size);
+#if defined(HAVE_CF_INTERFACE)
+ fprintf(stderr, " Fortran");
+#endif
#if defined(ENABLE_DATA)
fprintf(stderr, " DATA");
#endif
diff --git a/src/field.cc b/src/field.cc
index 3cb9031..40dd87b 100644
--- a/src/field.cc
+++ b/src/field.cc
@@ -63,7 +63,7 @@ double fldrank(field_type field)
double *array = &(field.ptr[1]);
double val = array[-1];
const double missval = field.missval;
- int nmiss = field.nmiss;
+ size_t nmiss = field.nmiss;
const size_t len = field.size-1;
size_t j;
@@ -92,7 +92,7 @@ double fldroc(field_type field)
double fldcrps(field_type field)
{
const size_t len = field.size;
- const int nmiss = field.nmiss;
+ const size_t nmiss = field.nmiss;
double *array = field.ptr;
if ( nmiss > 0 )
@@ -112,7 +112,7 @@ double fldcrps(field_type field)
double fldbrs(field_type field)
{
- const int nmiss = field.nmiss;
+ const size_t nmiss = field.nmiss;
const size_t len = field.size;
double *array = field.ptr;
const double missval = field.missval;
@@ -145,7 +145,7 @@ double fldbrs(field_type field)
double fldrange(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
const double *restrict array = field.ptr;
@@ -186,7 +186,7 @@ double fldrange(field_type field)
double fldmin(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
const double *restrict array = field.ptr;
@@ -215,7 +215,7 @@ double fldmin(field_type field)
double fldmax(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
const double *restrict array = field.ptr;
@@ -243,7 +243,7 @@ double fldmax(field_type field)
double fldsum(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
const double *restrict array = field.ptr;
@@ -276,7 +276,7 @@ double fldsum(field_type field)
double fldmean(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval1 = field.missval;
const double missval2 = field.missval;
@@ -307,7 +307,7 @@ double fldmean(field_type field)
double fldmeanw(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval1 = field.missval;
const double missval2 = field.missval;
@@ -340,7 +340,7 @@ double fldmeanw(field_type field)
double fldavg(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval1 = field.missval;
const double missval2 = field.missval;
@@ -371,7 +371,7 @@ double fldavg(field_type field)
double fldavgw(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval1 = field.missval;
const double missval2 = field.missval;
@@ -406,7 +406,7 @@ double fldavgw(field_type field)
}
static
-void prevarsum(const double *restrict array, size_t len, int nmiss,
+void prevarsum(const double *restrict array, size_t len, size_t nmiss,
double missval, double *rsum, double *rsumw, double *rsumq, double *rsumwq)
{
assert(array!=NULL);
@@ -445,7 +445,7 @@ void prevarsum(const double *restrict array, size_t len, int nmiss,
double fldvar(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
double rsum, rsumw;
@@ -462,7 +462,7 @@ double fldvar(field_type field)
double fldvar1(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
double rsum, rsumw;
@@ -477,7 +477,7 @@ double fldvar1(field_type field)
}
static
-void prevarsumw(const double *restrict array, const double *restrict w, size_t len, int nmiss,
+void prevarsumw(const double *restrict array, const double *restrict w, size_t len, size_t nmiss,
double missval, double *rsum, double *rsumw, double *rsumq, double *rsumwq)
{
assert(array!=NULL);
@@ -517,7 +517,7 @@ void prevarsumw(const double *restrict array, const double *restrict w, size_t l
double fldvarw(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
double rsum, rsumw;
@@ -534,7 +534,7 @@ double fldvarw(field_type field)
double fldvar1w(field_type field)
{
- const int nmiss = field.nmiss > 0;
+ const size_t nmiss = field.nmiss > 0;
const size_t len = field.size;
const double missval = field.missval;
double rsum, rsumw;
@@ -594,12 +594,12 @@ void fldrms(field_type field, field_type field2, field_type *field3)
{
size_t i;
size_t len;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid1 = field.grid;
- // int nmiss1 = field.nmiss;
+ // size_t nmiss1 = field.nmiss;
double *array1 = field.ptr;
int grid2 = field2.grid;
- // int nmiss2 = field2.nmiss;
+ // size_t nmiss2 = field2.nmiss;
double *array2 = field2.ptr;
const double missval1 = field.missval;
const double missval2 = field2.missval;
@@ -645,13 +645,13 @@ void fldrms(field_type field, field_type field2, field_type *field3)
void varrms(field_type field, field_type field2, field_type *field3)
{
size_t i, k, nlev, len;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int zaxis = field.zaxis;
int grid1 = field.grid;
- // int nmiss1 = field.nmiss;
+ // size_t nmiss1 = field.nmiss;
double *array1 = field.ptr;
int grid2 = field2.grid;
- // int nmiss2 = field2.nmiss;
+ // size_t nmiss2 = field2.nmiss;
double *array2 = field2.ptr;
const double missval1 = field.missval;
const double missval2 = field2.missval;
@@ -699,7 +699,7 @@ void varrms(field_type field, field_type field2, field_type *field3)
double fldpctl(field_type field, const double pn)
{
const size_t len = field.size;
- const int nmiss = field.nmiss;
+ const size_t nmiss = field.nmiss;
const double missval = field.missval;
double *array = field.ptr;
double pctl = missval;
diff --git a/src/field2.cc b/src/field2.cc
index c1a2058..6390875 100644
--- a/src/field2.cc
+++ b/src/field2.cc
@@ -42,13 +42,13 @@ void farfun(field_type *field1, field_type field2, int function)
}
static
-int farsetnmiss(int len, double *restrict array, double missval)
+int farsetnmiss(size_t len, double *restrict array, double missval)
{
- int nmiss = 0;
+ size_t nmiss = 0;
if ( DBL_IS_NAN(missval) )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array[i], missval) || array[i] < 0 )
{
array[i] = missval;
@@ -57,7 +57,7 @@ int farsetnmiss(int len, double *restrict array, double missval)
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( IS_EQUAL(array[i], missval) || array[i] < 0 )
{
array[i] = missval;
@@ -72,8 +72,8 @@ int farsetnmiss(int len, double *restrict array, double missval)
void farcpy(field_type *field1, field_type field2)
{
int nwpv = field1->nwpv;
- int gridsize1 = field1->size;
- int gridsize2 = field2.size;
+ size_t gridsize1 = field1->size;
+ size_t gridsize2 = field2.size;
double *restrict array1 = field1->ptr;
const double *restrict array2 = field2.ptr;
const float *restrict array2f = field2.ptrf;
@@ -83,15 +83,14 @@ void farcpy(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridsize1;
-
+ size_t len = nwpv*gridsize1;
if ( len != nwpv*gridsize2 )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( field2.memtype == MEMTYPE_FLOAT )
- for ( int i = 0; i < len; i++ ) array1[i] = array2f[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] = array2f[i];
else
- for ( int i = 0; i < len; i++ ) array1[i] = array2[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] = array2[i];
}
@@ -100,8 +99,8 @@ void faradd(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -110,25 +109,24 @@ void faradd(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = ADDMN(array1[i], array2[i]);
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
if ( field2.memtype == MEMTYPE_FLOAT )
{
- for ( int i = 0; i < len; i++ ) array1[i] += array2f[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] += array2f[i];
}
else
{
@@ -141,10 +139,10 @@ void faradd(field_type *field1, field_type field2)
void farsum(field_type *field1, field_type field2)
{
int nwpv = field1->nwpv;
- int gridsize1 = field1->size;
- int gridsize2 = field2.size;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t gridsize1 = field1->size;
+ size_t gridsize2 = field2.size;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -156,14 +154,14 @@ void farsum(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridsize1;
+ size_t len = nwpv*gridsize1;
if ( len != nwpv*gridsize2 )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
{
if ( !DBL_IS_EQUAL(array1[i], missval1) )
@@ -173,14 +171,14 @@ void farsum(field_type *field1, field_type field2)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
if ( field2.memtype == MEMTYPE_FLOAT )
{
- for ( int i = 0; i < len; i++ ) array1[i] += array2f[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] += array2f[i];
}
else
{
@@ -195,8 +193,8 @@ void farsumw(field_type *field1, field_type field2, double w)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -204,14 +202,13 @@ void farsumw(field_type *field1, field_type field2, double w)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
{
if ( !DBL_IS_EQUAL(array1[i], missval1) )
@@ -221,7 +218,7 @@ void farsumw(field_type *field1, field_type field2, double w)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
@@ -229,7 +226,7 @@ void farsumw(field_type *field1, field_type field2, double w)
#if defined(_OPENMP)
#pragma omp parallel for default(none) shared(array1,array2,w,len)
#endif
- for ( int i = 0; i < len; i++ ) array1[i] += w*array2[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] += w*array2[i];
}
}
@@ -248,8 +245,7 @@ void farsumtr(field_type *occur, field_type field, const double refval)
double *restrict oarray = occur->ptr;
double *restrict farray = field.ptr;
- int len = gridInqSize(occur->grid);
-
+ size_t len = gridInqSize(occur->grid);
if ( len != gridInqSize(field.grid) )
cdoAbort("Fields have different gridsize (%s)", __func__);
@@ -258,7 +254,7 @@ void farsumtr(field_type *occur, field_type field, const double refval)
#if defined(_OPENMP)
#pragma omp parallel for default(shared) schedule(static)
#endif
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(farray[i], fmissval) )
{
if ( !DBL_IS_EQUAL(oarray[i], omissval) )
@@ -273,7 +269,7 @@ void farsumtr(field_type *occur, field_type field, const double refval)
}
occur->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(oarray[i], omissval) ) occur->nmiss++;
}
else
@@ -281,7 +277,7 @@ void farsumtr(field_type *occur, field_type field, const double refval)
#if defined(_OPENMP)
#pragma omp parallel for default(shared)
#endif
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
oarray[i] = (DBL_IS_EQUAL(farray[i], refval)) ? 0.0 : oarray[i] + 1.0;
}
}
@@ -292,8 +288,8 @@ void farsumq(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -302,14 +298,13 @@ void farsumq(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
{
if ( !DBL_IS_EQUAL(array1[i], missval1) )
@@ -319,18 +314,18 @@ void farsumq(field_type *field1, field_type field2)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
if ( field2.memtype == MEMTYPE_FLOAT )
{
- for ( int i = 0; i < len; i++ ) array1[i] += ((double)array2f[i])*array2f[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] += ((double)array2f[i])*array2f[i];
}
else
{
- for ( int i = 0; i < len; i++ ) array1[i] += array2[i]*array2[i];
+ for ( size_t i = 0; i < len; i++ ) array1[i] += array2[i]*array2[i];
}
}
}
@@ -341,8 +336,8 @@ void farsumqw(field_type *field1, field_type field2, double w)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -350,14 +345,13 @@ void farsumqw(field_type *field1, field_type field2, double w)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
{
if ( !DBL_IS_EQUAL(array1[i], missval1) )
@@ -367,12 +361,12 @@ void farsumqw(field_type *field1, field_type field2, double w)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] += w*array2[i]*array2[i];
}
}
@@ -383,8 +377,8 @@ void farsub(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -392,23 +386,22 @@ void farsub(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = SUBMN(array1[i], array2[i]);
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] -= array2[i];
}
}
@@ -419,8 +412,8 @@ void farmul(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -428,22 +421,22 @@ void farmul(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = MULMN(array1[i], array2[i]);
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] *= array2[i];
}
}
@@ -461,15 +454,15 @@ void fardiv(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = DIVMN(array1[i], array2[i]);
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
@@ -486,16 +479,15 @@ void faratan2(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = DBL_IS_EQUAL(array1[i],missval1) || DBL_IS_EQUAL(array2[i],missval2) ? missval1 : atan2(array1[i], array2[i]);
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
@@ -505,24 +497,24 @@ void farsetmiss(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
+ size_t nmiss1 = field1->nmiss;
double missval1 = field1->missval;
double *restrict array1 = field1->ptr;
const double *restrict array2 = field2.ptr;
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = DBL_IS_EQUAL(array1[i],missval1) ? array2[i] : array1[i];
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
}
@@ -533,8 +525,8 @@ void farmin(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -542,14 +534,13 @@ void farmin(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
array1[i] = DBL_IS_EQUAL(array2[i], missval2) ? array1[i] :
DBL_IS_EQUAL(array1[i], missval1) ? array2[i] :
@@ -557,12 +548,12 @@ void farmin(field_type *field1, field_type field2)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = MIN(array1[i], array2[i]);
}
}
@@ -573,8 +564,8 @@ void farmax(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -582,14 +573,13 @@ void farmax(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
array1[i] = DBL_IS_EQUAL(array2[i], missval2) ? array1[i] :
DBL_IS_EQUAL(array1[i], missval1) ? array2[i] :
@@ -597,12 +587,12 @@ void farmax(field_type *field1, field_type field2)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = MAX(array1[i], array2[i]);
}
}
@@ -613,8 +603,8 @@ void farvar(field_type *field1, field_type field2, field_type field3, int diviso
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -624,14 +614,13 @@ void farvar(field_type *field1, field_type field2, field_type field3, int diviso
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( (nmiss1 || nmiss2) /*&& (DBL_IS_NAN(missval1) || DBL_IS_NAN(missval2))*/ )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
temp = DIV( MULMN(array1[i], array1[i]), array3[i]);
array1[i] = DIV( SUBMN(array2[i], temp), array3[i]-divisor);
@@ -640,7 +629,7 @@ void farvar(field_type *field1, field_type field2, field_type field3, int diviso
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
temp = DIV( MUL(array1[i], array1[i]), array3[i]);
array1[i] = DIV( SUB(array2[i], temp), array3[i]-divisor);
@@ -662,15 +651,14 @@ void farstd(field_type *field1, field_type field2, field_type field3, int diviso
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
farvar(field1, field2, field3, divisor);
- int nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
{
array1[i] = missval1;
@@ -689,8 +677,8 @@ void farcvar(field_type *field1, field_type field2, int nsets, int divisor)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
const int nsetx = nsets - divisor;
double missval1 = field1->missval;
double missval2 = field2.missval;
@@ -700,18 +688,17 @@ void farcvar(field_type *field1, field_type field2, int nsets, int divisor)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nsetx == 0 )
{
- for ( int i = 0; i < len; i++ ) array1[i] = missval1;
+ for ( size_t i = 0; i < len; i++ ) array1[i] = missval1;
}
else if ( (nmiss1 || nmiss2) /*&& (DBL_IS_NAN(missval1) || DBL_IS_NAN(missval2))*/ )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
temp = MULMN(array1[i], array1[i]) / nsets;
array1[i] = SUBMN(array2[i], temp) / nsetx;
@@ -720,7 +707,7 @@ void farcvar(field_type *field1, field_type field2, int nsets, int divisor)
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
{
temp = MUL(array1[i], array1[i]) / nsets;
array1[i] = SUB(array2[i], temp) / nsetx;
@@ -742,15 +729,14 @@ void farcstd(field_type *field1, field_type field2, int nsets, int divisor)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
farcvar(field1, field2, nsets, divisor);
- int nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
{
array1[i] = missval1;
@@ -769,7 +755,7 @@ void farmoq(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss2 = field2.nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -777,26 +763,25 @@ void farmoq(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
array1[i] = array2[i]*array2[i];
else
array1[i] = missval1;
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = array2[i]*array2[i];
}
}
@@ -807,7 +792,7 @@ void farmoqw(field_type *field1, field_type field2, double w)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss2 = field2.nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -815,26 +800,25 @@ void farmoqw(field_type *field1, field_type field2, double w)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
array1[i] = w*array2[i]*array2[i];
else
array1[i] = missval1;
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] = w*array2[i]*array2[i];
}
}
@@ -857,8 +841,8 @@ void farcount(field_type *field1, field_type field2)
int nwpv = field1->nwpv;
int grid1 = field1->grid;
int grid2 = field2.grid;
- int nmiss1 = field1->nmiss;
- int nmiss2 = field2.nmiss;
+ size_t nmiss1 = field1->nmiss;
+ size_t nmiss2 = field2.nmiss;
double missval1 = field1->missval;
double missval2 = field2.missval;
double *restrict array1 = field1->ptr;
@@ -866,14 +850,13 @@ void farcount(field_type *field1, field_type field2)
if ( nwpv != 2 ) nwpv = 1;
- int len = nwpv*gridInqSize(grid1);
-
+ size_t len = nwpv*gridInqSize(grid1);
if ( len != (nwpv*gridInqSize(grid2)) )
cdoAbort("Fields have different gridsize (%s)", __func__);
if ( nmiss1 > 0 || nmiss2 > 0 )
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( !DBL_IS_EQUAL(array2[i], missval2) )
{
if ( !DBL_IS_EQUAL(array1[i], missval1) )
@@ -883,12 +866,12 @@ void farcount(field_type *field1, field_type field2)
}
field1->nmiss = 0;
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
}
else
{
- for ( int i = 0; i < len; i++ )
+ for ( size_t i = 0; i < len; i++ )
array1[i] += 1.0;
}
}
diff --git a/src/fieldc.cc b/src/fieldc.cc
index 5bef4b5..1affa15 100644
--- a/src/fieldc.cc
+++ b/src/fieldc.cc
@@ -38,7 +38,7 @@ void farcmul(field_type *field, double rconst)
int i, len;
int nwpv = field->nwpv;
int grid = field->grid;
- int nmiss = field->nmiss;
+ size_t nmiss = field->nmiss;
double missval1 = field->missval;
double missval2 = field->missval;
double *array = field->ptr;
@@ -69,7 +69,7 @@ void farcdiv(field_type *field, double rconst)
{
int i, len;
int grid = field->grid;
- int nmiss = field->nmiss;
+ size_t nmiss = field->nmiss;
double missval1 = field->missval;
double missval2 = field->missval;
double *array = field->ptr;
@@ -95,7 +95,7 @@ void farcadd(field_type *field, double rconst)
{
int i, len;
int grid = field->grid;
- int nmiss = field->nmiss;
+ size_t nmiss = field->nmiss;
double missval1 = field->missval;
double missval2 = field->missval;
double *array = field->ptr;
diff --git a/src/fieldmer.cc b/src/fieldmer.cc
index 784a22b..8c67792 100644
--- a/src/fieldmer.cc
+++ b/src/fieldmer.cc
@@ -43,9 +43,9 @@ void merfun(field_type field1, field_type *field2, int function)
void mermin(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmin = 0;
@@ -85,9 +85,9 @@ void mermin(field_type field1, field_type *field2)
void mermax(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmax = 0;
@@ -127,9 +127,9 @@ void mermax(field_type field1, field_type *field2)
void merrange(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmin = 0;
@@ -186,9 +186,9 @@ void mersum(field_type field1, field_type *field2)
{
long i, j, nx, ny;
long nvals = 0;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rsum = 0;
@@ -232,9 +232,9 @@ void mersum(field_type field1, field_type *field2)
void mermeanw(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double missval2 = field1.missval;
double *array = field1.ptr;
@@ -281,9 +281,9 @@ void mermeanw(field_type field1, field_type *field2)
void meravgw(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double missval2 = field1.missval;
double *array = field1.ptr;
@@ -326,7 +326,7 @@ void meravgw(field_type field1, field_type *field2)
}
static
-void prevarsum_merw(const double *restrict array, const double *restrict w, int nx, int ny, int nmiss,
+void prevarsum_merw(const double *restrict array, const double *restrict w, int nx, int ny, size_t nmiss,
double missval, double *restrict rsum, double *restrict rsumw, double *restrict rsumq, double *restrict rsumwq)
{
*rsum = 0;
@@ -361,9 +361,9 @@ void prevarsum_merw(const double *restrict array, const double *restrict w, int
void mervarw(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double *w = field1.weight;
@@ -391,9 +391,9 @@ void mervarw(field_type field1, field_type *field2)
void mervar1w(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double *w = field1.weight;
@@ -421,7 +421,7 @@ void mervar1w(field_type field1, field_type *field2)
void merstdw(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
double missval = field1.missval;
double rstd;
@@ -445,7 +445,7 @@ void merstdw(field_type field1, field_type *field2)
void merstd1w(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
double missval = field1.missval;
double rstd;
@@ -470,9 +470,9 @@ void merstd1w(field_type field1, field_type *field2)
void merpctl(field_type field1, field_type *field2, int p)
{
long i, j, l;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
diff --git a/src/fieldzon.cc b/src/fieldzon.cc
index 3474338..944530e 100644
--- a/src/fieldzon.cc
+++ b/src/fieldzon.cc
@@ -43,9 +43,9 @@ void zonfun(field_type field1, field_type *field2, int function)
void zonmin(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmin = 0;
@@ -85,9 +85,9 @@ void zonmin(field_type field1, field_type *field2)
void zonmax(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmax = 0;
@@ -127,9 +127,9 @@ void zonmax(field_type field1, field_type *field2)
void zonrange(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rmin = 0;
@@ -186,9 +186,9 @@ void zonsum(field_type field1, field_type *field2)
{
long i, j, nx, ny;
long nvals = 0;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
double rsum = 0;
@@ -232,9 +232,9 @@ void zonsum(field_type field1, field_type *field2)
void zonmean(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double missval2 = field1.missval;
double *array = field1.ptr;
@@ -279,9 +279,9 @@ void zonmean(field_type field1, field_type *field2)
void zonavg(field_type field1, field_type *field2)
{
long i, j, nx, ny;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double missval2 = field1.missval;
double *array = field1.ptr;
@@ -322,7 +322,7 @@ void zonavg(field_type field1, field_type *field2)
}
static
-void prevarsum_zon(const double *restrict array, int nx, int nmiss, double missval,
+void prevarsum_zon(const double *restrict array, int nx, size_t nmiss, double missval,
double *rsum, double *rsumw, double *rsumq, double *rsumwq)
{
double w = 1./nx;
@@ -358,9 +358,9 @@ void prevarsum_zon(const double *restrict array, int nx, int nmiss, double miss
void zonvar(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double *array = field1.ptr;
double rsum = 0, rsumw = 0, rvar = 0;
@@ -387,9 +387,9 @@ void zonvar(field_type field1, field_type *field2)
void zonvar1(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval1 = field1.missval;
double *array = field1.ptr;
double rsum = 0, rsumw = 0, rvar = 0;
@@ -416,7 +416,7 @@ void zonvar1(field_type field1, field_type *field2)
void zonstd(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
double missval = field1.missval;
double rstd;
@@ -440,7 +440,7 @@ void zonstd(field_type field1, field_type *field2)
void zonstd1(field_type field1, field_type *field2)
{
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
double missval = field1.missval;
double rstd;
@@ -465,9 +465,9 @@ void zonstd1(field_type field1, field_type *field2)
void zonpctl(field_type field1, field_type *field2, int p)
{
long i, j, l;
- int rnmiss = 0;
+ size_t rnmiss = 0;
int grid = field1.grid;
- int nmiss = field1.nmiss;
+ size_t nmiss = field1.nmiss;
double missval = field1.missval;
double *array = field1.ptr;
diff --git a/src/getMemorySize.c b/src/getMemorySize.c
new file mode 100644
index 0000000..4b15ac7
--- /dev/null
+++ b/src/getMemorySize.c
@@ -0,0 +1,97 @@
+/*
+ * Author: David Robert Nadeau
+ * Site: http://NadeauSoftware.com/
+ * License: Creative Commons Attribution 3.0 Unported License
+ * http://creativecommons.org/licenses/by/3.0/deed.en_US
+ */
+
+#if defined(_WIN32)
+#include <Windows.h>
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#if defined(BSD)
+#include <sys/sysctl.h>
+#endif
+
+#else
+#error "Unable to define getMemorySize( ) for an unknown OS."
+#endif
+
+
+
+/**
+ * Returns the size of physical memory (RAM) in bytes.
+ */
+size_t getMemorySize(void)
+{
+#if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__))
+ /* Cygwin under Windows. ------------------------------------ */
+ /* New 64-bit MEMORYSTATUSEX isn't available. Use old 32.bit */
+ MEMORYSTATUS status;
+ status.dwLength = sizeof(status);
+ GlobalMemoryStatus( &status );
+ return (size_t)status.dwTotalPhys;
+
+#elif defined(_WIN32)
+ /* Windows. ------------------------------------------------- */
+ /* Use new 64-bit MEMORYSTATUSEX, not old 32-bit MEMORYSTATUS */
+ MEMORYSTATUSEX status;
+ status.dwLength = sizeof(status);
+ GlobalMemoryStatusEx( &status );
+ return (size_t)status.ullTotalPhys;
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+ /* UNIX variants. ------------------------------------------- */
+ /* Prefer sysctl() over sysconf() except sysctl() HW_REALMEM and HW_PHYSMEM */
+
+#if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64))
+ int mib[2];
+ mib[0] = CTL_HW;
+#if defined(HW_MEMSIZE)
+ mib[1] = HW_MEMSIZE; /* OSX. --------------------- */
+#elif defined(HW_PHYSMEM64)
+ mib[1] = HW_PHYSMEM64; /* NetBSD, OpenBSD. --------- */
+#endif
+ int64_t size = 0; /* 64-bit */
+ size_t len = sizeof( size );
+ if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
+ return (size_t)size;
+ return 0L; /* Failed? */
+
+#elif defined(_SC_AIX_REALMEM)
+ /* AIX. ----------------------------------------------------- */
+ return (size_t)sysconf( _SC_AIX_REALMEM ) * (size_t)1024L;
+
+#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
+ /* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */
+ return (size_t)sysconf( _SC_PHYS_PAGES ) *
+ (size_t)sysconf( _SC_PAGESIZE );
+
+#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE)
+ /* Legacy. -------------------------------------------------- */
+ return (size_t)sysconf( _SC_PHYS_PAGES ) *
+ (size_t)sysconf( _SC_PAGE_SIZE );
+
+#elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM))
+ /* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */
+ int mib[2];
+ mib[0] = CTL_HW;
+#if defined(HW_REALMEM)
+ mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */
+#elif defined(HW_PYSMEM)
+ mib[1] = HW_PHYSMEM; /* Others. ------------------ */
+#endif
+ unsigned int size = 0; /* 32-bit */
+ size_t len = sizeof( size );
+ if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
+ return (size_t)size;
+ return 0L; /* Failed? */
+#endif /* sysctl and sysconf variants */
+
+#else
+ return 0L; /* Unknown OS. */
+#endif
+}
diff --git a/src/getRSS.c b/src/getRSS.c
new file mode 100644
index 0000000..574d373
--- /dev/null
+++ b/src/getRSS.c
@@ -0,0 +1,122 @@
+/*
+ * Author: David Robert Nadeau
+ * Site: http://NadeauSoftware.com/
+ * License: Creative Commons Attribution 3.0 Unported License
+ * http://creativecommons.org/licenses/by/3.0/deed.en_US
+ */
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <psapi.h>
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#include <sys/resource.h>
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <mach/mach.h>
+
+#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
+#include <fcntl.h>
+#include <procfs.h>
+
+#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
+#include <stdio.h>
+
+#endif
+
+#else
+#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
+#endif
+
+
+
+
+
+/**
+ * Returns the peak (maximum so far) resident set size (physical
+ * memory use) measured in bytes, or zero if the value cannot be
+ * determined on this OS.
+ */
+size_t getPeakRSS( )
+{
+#if defined(_WIN32)
+ /* Windows -------------------------------------------------- */
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.PeakWorkingSetSize;
+
+#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
+ /* AIX and Solaris ------------------------------------------ */
+ struct psinfo psinfo;
+ int fd = -1;
+ if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
+ return (size_t)0L; /* Can't open? */
+ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
+ {
+ close( fd );
+ return (size_t)0L; /* Can't read? */
+ }
+ close( fd );
+ return (size_t)(psinfo.pr_rssize * 1024L);
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+ /* BSD, Linux, and OSX -------------------------------------- */
+ struct rusage rusage;
+ getrusage( RUSAGE_SELF, &rusage );
+#if defined(__APPLE__) && defined(__MACH__)
+ return (size_t)rusage.ru_maxrss;
+#else
+ return (size_t)(rusage.ru_maxrss * 1024L);
+#endif
+
+#else
+ /* Unknown OS ----------------------------------------------- */
+ return (size_t)0L; /* Unsupported. */
+#endif
+}
+
+
+
+
+
+/**
+ * Returns the current resident set size (physical memory use) measured
+ * in bytes, or zero if the value cannot be determined on this OS.
+ */
+size_t getCurrentRSS( )
+{
+#if defined(_WIN32)
+ /* Windows -------------------------------------------------- */
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.WorkingSetSize;
+
+#elif defined(__APPLE__) && defined(__MACH__)
+ /* OSX ------------------------------------------------------ */
+ struct mach_task_basic_info info;
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+ if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
+ (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
+ return (size_t)0L; /* Can't access? */
+ return (size_t)info.resident_size;
+
+#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
+ /* Linux ---------------------------------------------------- */
+ long rss = 0L;
+ FILE* fp = NULL;
+ if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
+ return (size_t)0L; /* Can't open? */
+ if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
+ {
+ fclose( fp );
+ return (size_t)0L; /* Can't read? */
+ }
+ fclose( fp );
+ return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
+
+#else
+ /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
+ return (size_t)0L; /* Unsupported. */
+#endif
+}
diff --git a/src/grid.cc b/src/grid.cc
index 486cce7..64059f6 100644
--- a/src/grid.cc
+++ b/src/grid.cc
@@ -683,7 +683,7 @@ int qu2reg_subarea(size_t gridsize, int np, double xfirst, double xlast,
}
-void field2regular(int gridID1, int gridID2, double missval, double *array, int nmiss, int lnearest)
+void field2regular(int gridID1, int gridID2, double missval, double *array, size_t nmiss, int lnearest)
{
int gridtype = gridInqType(gridID1);
if ( gridtype != GRID_GAUSSIAN_REDUCED ) cdoAbort("Not a reduced Gaussian grid!");
@@ -691,7 +691,7 @@ void field2regular(int gridID1, int gridID2, double missval, double *array, int
int lmiss = nmiss > 0;
int lperio = 1;
- int ny = gridInqYsize(gridID1);
+ size_t ny = gridInqYsize(gridID1);
int np = gridInqNP(gridID1);
int *rowlon = (int*) Malloc(ny*sizeof(int));
@@ -703,7 +703,7 @@ void field2regular(int gridID1, int gridID2, double missval, double *array, int
double xlast = xfirstandlast[1];
int iret;
- int nx = 0;
+ size_t nx = 0;
if ( fabs(xfirst) > 0 || (np > 0 && fabs(xlast - (360.0-90.0/np)) > 90.0/np) )
{
nx = qu2reg_subarea(gridInqSize(gridID1), np, xfirst, xlast, array, rowlon, ny, missval, &iret, lmiss, lperio, lnearest);
@@ -1531,7 +1531,7 @@ int gridGenWeights(int gridID, double *grid_area, double *grid_wgts)
int *grid_mask = NULL;
int gridtype = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
if ( gridtype == GRID_GME )
{
@@ -1542,7 +1542,7 @@ int gridGenWeights(int gridID, double *grid_area, double *grid_wgts)
double total_area = 0;
int nvals = 0;
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( grid_mask )
if ( grid_mask[i] == 0 ) continue;
@@ -1552,7 +1552,7 @@ int gridGenWeights(int gridID, double *grid_area, double *grid_wgts)
if ( cdoVerbose ) cdoPrint("Total area = %g", total_area);
- for ( int i = 0; i < gridsize; i++ )
+ for ( size_t i = 0; i < gridsize; i++ )
{
if ( grid_mask )
if ( grid_mask[i] == 0 )
@@ -1653,7 +1653,7 @@ int gridWeights(int gridID, double *grid_wgts)
int w_status = 1;
int a_status = 0;
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
int gridtype = gridInqType(gridID);
int projtype = (gridtype == GRID_PROJECTION) ? gridInqProjType(gridID) : -1;
@@ -1690,7 +1690,7 @@ int gridWeights(int gridID, double *grid_wgts)
}
else
{
- for ( int i = 0; i < gridsize; ++i ) grid_wgts[i] = 1./gridsize;
+ for ( size_t i = 0; i < gridsize; ++i ) grid_wgts[i] = 1./gridsize;
}
/*
for ( i = 0; i < gridsize; ++i )
diff --git a/src/grid.h b/src/grid.h
index a8a52b9..4da6e48 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -65,7 +65,7 @@ int gridToUnstructuredSelecton(int gridID1, size_t selectionSize, int *selection
int gridToCurvilinear(int gridID, int lbounds);
int gridCurvilinearToRegular(int gridID);
int gridToRegular(int gridID);
-void field2regular(int gridID1, int gridID2, double missval, double *array, int nmiss, int lnearest);
+void field2regular(int gridID1, int gridID2, double missval, double *array, size_t nmiss, int lnearest);
/* GME grid */
struct cart {
diff --git a/src/grid_area.cc b/src/grid_area.cc
index b6f6ba7..3586eb8 100644
--- a/src/grid_area.cc
+++ b/src/grid_area.cc
@@ -286,9 +286,8 @@ int gridGenArea(int gridID, double* area)
int status = 0;
bool lgrid_gen_bounds = false;
bool lgriddestroy = false;
- long nv;
- long gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
int gridtype = gridInqType(gridID);
int projtype = (gridtype == GRID_PROJECTION) ? gridInqProjType(gridID) : -1;
@@ -340,10 +339,7 @@ int gridGenArea(int gridID, double* area)
gridtype = gridInqType(gridID);
- if ( gridtype == GRID_UNSTRUCTURED )
- nv = gridInqNvertex(gridID);
- else
- nv = 4;
+ size_t nv = ( gridtype == GRID_UNSTRUCTURED ) ? gridInqNvertex(gridID) : 4;
if ( gridInqYvals(gridID, NULL) == 0 || gridInqXvals(gridID, NULL) == 0 )
{
@@ -382,8 +378,8 @@ int gridGenArea(int gridID, double* area)
{
if ( lgrid_gen_bounds )
{
- int nlon = gridInqXsize(gridID);
- int nlat = gridInqYsize(gridID);
+ size_t nlon = gridInqXsize(gridID);
+ size_t nlat = gridInqYsize(gridID);
double dlon = 0;
if ( nlon == 1 ) dlon = 1;
@@ -413,7 +409,7 @@ int gridGenArea(int gridID, double* area)
#pragma omp parallel for default(none) \
shared(findex,gridsize,area,nv,grid_corner_lon,grid_corner_lat,grid_center_lon,grid_center_lat)
#endif
- for ( long i = 0; i < gridsize; ++i )
+ for ( size_t i = 0; i < gridsize; ++i )
{
int lprogress = 1;
if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -434,16 +430,16 @@ int gridGenArea(int gridID, double* area)
if ( cdoVerbose )
{
double total_area = 0;
- for ( long i = 0; i < gridsize; ++i ) total_area += area[i];
+ for ( size_t i = 0; i < gridsize; ++i ) total_area += area[i];
cdoPrint("Total area = %g steradians", total_area);
}
if ( gridsize < 20 )
{
double total_area = 0;
- for ( long i = 0; i < gridsize; ++i ) total_area += area[i];
+ for ( size_t i = 0; i < gridsize; ++i ) total_area += area[i];
int nzero = 0;
- for ( long i = 0; i < gridsize; ++i ) if ( IS_EQUAL(area[i], 0.) ) nzero++;
+ for ( size_t i = 0; i < gridsize; ++i ) if ( IS_EQUAL(area[i], 0.) ) nzero++;
if ( IS_EQUAL(total_area, 0.) ) status = 2;
}
diff --git a/src/grid_from_name.cc b/src/grid_from_name.cc
index 2b94d14..6164218 100644
--- a/src/grid_from_name.cc
+++ b/src/grid_from_name.cc
@@ -90,14 +90,14 @@ void gen_grid_lonlat(griddes_t *grid, const char *pline, double inc, double lon1
if ( lon1 >= lon2 || lat1 >= lat2 )
cdoAbort("Invalid grid box: lon1=%g lon2=%g lat1=%g lat2=%g", lon1, lon2, lat1, lat2);
- int nlon = (int) ((lon2 - lon1)/inc + 0.5);
- int nlat = (int) ((lat2 - lat1)/inc + 0.5);
+ size_t nlon = (size_t) ((lon2 - lon1)/inc + 0.5);
+ size_t nlat = (size_t) ((lat2 - lat1)/inc + 0.5);
double *xvals = (double*) Malloc(nlon*sizeof(double));
double *yvals = (double*) Malloc(nlat*sizeof(double));
- for ( int i = 0; i < nlon; ++i ) xvals[i] = lon1 + inc/2 + i*inc;
- for ( int i = 0; i < nlat; ++i ) yvals[i] = lat1 + inc/2 + i*inc;
+ for ( size_t i = 0; i < nlon; ++i ) xvals[i] = lon1 + inc/2 + i*inc;
+ for ( size_t i = 0; i < nlat; ++i ) yvals[i] = lat1 + inc/2 + i*inc;
if ( gridtype == GRID_LONLAT )
{
@@ -110,11 +110,11 @@ void gen_grid_lonlat(griddes_t *grid, const char *pline, double inc, double lon1
}
else
{
- double gridsize = nlon*nlat;
+ size_t gridsize = nlon*nlat;
double *xvals2D = (double*) Malloc(gridsize*sizeof(double));
double *yvals2D = (double*) Malloc(gridsize*sizeof(double));
- for ( int j = 0; j < nlat; j++ )
- for ( int i = 0; i < nlon; i++ )
+ for ( size_t j = 0; j < nlat; j++ )
+ for ( size_t i = 0; i < nlon; i++ )
{
xvals2D[j*nlon+i] = xvals[i];
yvals2D[j*nlon+i] = yvals[j];
diff --git a/src/grid_print.cc b/src/grid_print.cc
index c805616..52df415 100644
--- a/src/grid_print.cc
+++ b/src/grid_print.cc
@@ -139,18 +139,18 @@ void grid_print_attributes(FILE *fp, int gridID)
static
void grid_print_kernel(int gridID, int opt, FILE *fp)
{
- int xdim, ydim;
+ size_t xdim, ydim;
char attstr[CDI_MAX_NAME];
char attstr2[CDI_MAX_NAME];
- size_t nxvals = (size_t) gridInqXvals(gridID, NULL);
- size_t nyvals = (size_t) gridInqYvals(gridID, NULL);
+ size_t nxvals = gridInqXvals(gridID, NULL);
+ size_t nyvals = gridInqYvals(gridID, NULL);
size_t nxbounds = (size_t) gridInqXbounds(gridID, NULL);
size_t nybounds = (size_t) gridInqYbounds(gridID, NULL);
+ size_t gridsize = gridInqSize(gridID);
+ size_t xsize = gridInqXsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
int type = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
- int xsize = gridInqXsize(gridID);
- int ysize = gridInqYsize(gridID);
int nvertex = gridInqNvertex(gridID);
int prec = gridInqDatatype(gridID);
int xstrlen = gridInqXIsc(gridID);
@@ -159,35 +159,35 @@ void grid_print_kernel(int gridID, int opt, FILE *fp)
char **xcvals = NULL;
if ( xstrlen )
{
- xcvals = (char **) Malloc(xsize * sizeof(char *));
- for ( int i = 0; i < xsize; i++ ) xcvals[i] = (char*) Malloc((xstrlen+1) * sizeof(char));
+ xcvals = (char **) Malloc(xsize*sizeof(char *));
+ for ( size_t i = 0; i < xsize; i++ ) xcvals[i] = (char*) Malloc((xstrlen+1)*sizeof(char));
gridInqXCvals(gridID, xcvals);
- for ( int i = 0; i < xsize; i++ ) xcvals[i][xstrlen] = 0;
- for ( int i = 0; i < xsize; i++ )
+ for ( size_t i = 0; i < xsize; i++ ) xcvals[i][xstrlen] = 0;
+ for ( size_t i = 0; i < xsize; i++ )
for ( int k = xstrlen-1; k; k-- ) if ( xcvals[i][k] == ' ' ) xcvals[i][k] = 0; else break;
}
char **ycvals = NULL;
if ( ystrlen )
{
- ycvals = (char **) Malloc(ysize * sizeof(char *));
- for ( int i = 0; i < ysize; i++ ) ycvals[i] = (char*) Malloc((ystrlen+1) * sizeof(char));
+ ycvals = (char **) Malloc(ysize*sizeof(char *));
+ for ( size_t i = 0; i < ysize; i++ ) ycvals[i] = (char*) Malloc((ystrlen+1)*sizeof(char));
gridInqYCvals(gridID, ycvals);
- for ( int i = 0; i < ysize; i++ ) ycvals[i][ystrlen] = 0;
- for ( int i = 0; i < ysize; i++ )
+ for ( size_t i = 0; i < ysize; i++ ) ycvals[i][ystrlen] = 0;
+ for ( size_t i = 0; i < ysize; i++ )
for ( int k = ystrlen-1; k; k-- ) if ( ycvals[i][k] == ' ' ) ycvals[i][k] = 0; else break;
}
int dig = (prec == CDI_DATATYPE_FLT64) ? CDO_dbl_digits : CDO_flt_digits;
- fprintf(fp, "gridtype = %s\n" "gridsize = %d\n", gridNamePtr(type), gridsize);
+ fprintf(fp, "gridtype = %s\n" "gridsize = %zu\n", gridNamePtr(type), gridsize);
if ( type != GRID_GME )
{
if ( type != GRID_UNSTRUCTURED && type != GRID_SPECTRAL && type != GRID_FOURIER )
{
- if ( xsize > 0 ) fprintf(fp, "xsize = %d\n", xsize);
- if ( ysize > 0 ) fprintf(fp, "ysize = %d\n", ysize);
+ if ( xsize > 0 ) fprintf(fp, "xsize = %zu\n", xsize);
+ if ( ysize > 0 ) fprintf(fp, "ysize = %zu\n", ysize);
}
if ( nxvals > 0 || xcvals )
@@ -312,11 +312,11 @@ void grid_print_kernel(int gridID, int opt, FILE *fp)
fprintf(fp, "x%ss = \"%.*s\"", attstr, xstrlen, xcvals[0]);
else
fprintf(fp, "xstrings = \"%.*s\"", xstrlen, xcvals[0]);
- for ( int i = 1; i < xsize; i++ )
+ for ( size_t i = 1; i < xsize; i++ )
fprintf(fp, ", \"%.*s\"", xstrlen, xcvals[i]);
fprintf(fp, "\n");
- for ( int i = 0; i < xsize; i++ ) Free(xcvals[i]);
+ for ( size_t i = 0; i < xsize; i++ ) Free(xcvals[i]);
Free(xcvals);
}
@@ -362,11 +362,11 @@ void grid_print_kernel(int gridID, int opt, FILE *fp)
fprintf(fp, "x%ss = \"%.*s\"", attstr, ystrlen, ycvals[0]);
else
fprintf(fp, "ystrings = \"%.*s\"", ystrlen, ycvals[0]);
- for ( int i = 1; i < ysize; i++ )
+ for ( size_t i = 1; i < ysize; i++ )
fprintf(fp, ", \"%.*s\"", ystrlen, ycvals[i]);
fprintf(fp, "\n");
- for ( int i = 0; i < ysize; i++ ) Free(ycvals[i]);
+ for ( size_t i = 0; i < ysize; i++ ) Free(ycvals[i]);
Free(ycvals);
}
diff --git a/src/grid_read.cc b/src/grid_read.cc
index b2c44c9..8da1f02 100644
--- a/src/grid_read.cc
+++ b/src/grid_read.cc
@@ -101,11 +101,11 @@ void grid_read_data(size_t ikv, size_t nkv, kvmap_t *kvmap, griddes_t *grid, siz
else if ( STR_IS_EQ(datatype, "float") ) grid->datatype = CDI_DATATYPE_FLT32;
else cdoAbort("Invalid datatype : %s (zaxis description file: %s)", datatype, dname);
}
- else if ( STR_IS_EQ(key, "gridsize") ) grid->size = parameter2int(value);
- else if ( STR_IS_EQ(key, "xsize") ) grid->xsize = parameter2int(value);
- else if ( STR_IS_EQ(key, "nlon") ) grid->xsize = parameter2int(value);
- else if ( STR_IS_EQ(key, "ysize") ) grid->ysize = parameter2int(value);
- else if ( STR_IS_EQ(key, "nlat") ) grid->ysize = parameter2int(value);
+ else if ( STR_IS_EQ(key, "gridsize") ) grid->size = parameter2sizet(value);
+ else if ( STR_IS_EQ(key, "xsize") ) grid->xsize = parameter2sizet(value);
+ else if ( STR_IS_EQ(key, "nlon") ) grid->xsize = parameter2sizet(value);
+ else if ( STR_IS_EQ(key, "ysize") ) grid->ysize = parameter2sizet(value);
+ else if ( STR_IS_EQ(key, "nlat") ) grid->ysize = parameter2sizet(value);
else if ( STR_IS_EQ(key, "truncation") ) grid->ntr = parameter2int(value);
else if ( STR_IS_EQ(key, "np") ) grid->np = parameter2int(value);
else if ( STR_IS_EQ(key, "complexpacking") ) grid->lcomplex = parameter2int(value);
diff --git a/src/grid_search.cc b/src/grid_search.cc
index e3e24e1..9388225 100644
--- a/src/grid_search.cc
+++ b/src/grid_search.cc
@@ -1,4 +1,4 @@
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -69,6 +69,7 @@ float distance(const float *restrict a, const float *restrict b)
void gridsearch_set_method(const char *methodstr)
{
if ( strcmp(methodstr, "kdtree") == 0 ) gridsearch_method_nn = GS_KDTREE;
+ else if ( strcmp(methodstr, "kdsph") == 0 ) gridsearch_method_nn = GS_KDSPH;
else if ( strcmp(methodstr, "nearpt3") == 0 ) gridsearch_method_nn = GS_NEARPT3;
else if ( strcmp(methodstr, "full") == 0 ) gridsearch_method_nn = GS_FULL;
else
@@ -76,15 +77,25 @@ void gridsearch_set_method(const char *methodstr)
}
-struct gridsearch *gridsearch_create_reg2d(bool lcyclic, size_t nx, size_t ny, const double *restrict lons, const double *restrict lats)
+void gridsearch_extrapolate(struct gridsearch *gs)
+{
+ gs->extrapolate = true;
+}
+
+
+struct gridsearch *gridsearch_create_reg2d(bool is_cyclic, size_t dims[2], const double *restrict lons, const double *restrict lats)
{
struct gridsearch *gs = (struct gridsearch *) Calloc(1, sizeof(struct gridsearch));
- gs->nx = nx;
- gs->ny = ny;
+ gs->is_cyclic = is_cyclic;
+ gs->is_reg2d = true;
+ gs->dims[0] = dims[0];
+ gs->dims[1] = dims[1];
+ size_t nx = dims[0];
+ size_t ny = dims[0];
- unsigned nxm = nx;
- if ( lcyclic ) nxm++;
+ size_t nxm = nx;
+ if ( is_cyclic ) nxm++;
double *reg2d_center_lon = (double *) Malloc(nxm*sizeof(double));
double *reg2d_center_lat = (double *) Malloc(ny*sizeof(double));
@@ -156,6 +167,39 @@ struct kdNode *gs_create_kdtree(size_t n, const double *restrict lons, const dou
}
+struct kdNode *gs_create_kdsph(size_t n, const double *restrict lons, const double *restrict lats)
+{
+ struct kd_point *pointlist = (struct kd_point *) Malloc(n * sizeof(struct kd_point)); // kd_point contains 3d point
+ // see example_cartesian.c
+ if ( cdoVerbose ) printf("kdtree lib spherical init: n=%zu nthreads=%d\n", n, ompNumThreads);
+ kdata_t min[2], max[2];
+ min[0] = min[1] = 1e9;
+ max[0] = max[1] = -1e9;
+ kdata_t *restrict point;
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+ for ( size_t i = 0; i < n; i++ )
+ {
+ point = pointlist[i].point;
+ point[0] = lons[i];
+ point[1] = lats[i];
+ point[2] = 0; // dummy
+ for ( size_t j = 0; j < 2; ++j )
+ {
+ min[j] = point[j] < min[j] ? point[j] : min[j];
+ max[j] = point[j] > max[j] ? point[j] : max[j];
+ }
+ pointlist[i].index = i;
+ }
+
+ struct kdNode *kdt = kd_sph_buildTree(pointlist, n, min, max, ompNumThreads);
+ if ( pointlist ) Free(pointlist);
+
+ return kdt;
+}
+
+
void gs_destroy_nearpt3(struct gsNear *near)
{
if ( near )
@@ -274,6 +318,7 @@ struct gridsearch *gridsearch_create_nn(size_t n, const double *restrict lons, c
if ( n == 0 ) return gs;
if ( gs->method_nn == GS_KDTREE ) gs->kdt = gs_create_kdtree(n, lons, lats);
+ else if ( gs->method_nn == GS_KDSPH ) gs->kdt = gs_create_kdsph(n, lons, lats);
else if ( gs->method_nn == GS_NEARPT3 ) gs->near = gs_create_nearpt3(n, lons, lats);
else if ( gs->method_nn == GS_FULL ) gs->full = gs_create_full(n, lons, lats);
@@ -320,10 +365,11 @@ double gs_set_range(double *prange)
return range;
}
-
-kdNode *gs_nearest_kdtree(kdNode *kdt, double lon, double lat, double *prange)
+static
+size_t gs_nearest_kdtree(kdNode *kdt, double lon, double lat, double *prange)
{
- if ( kdt == NULL ) return NULL;
+ size_t index = GS_NOT_FOUND;
+ if ( kdt == NULL ) return index;
float range0 = gs_set_range(prange);
kdata_t range = KDATA_SCALE(range0);
@@ -337,11 +383,37 @@ kdNode *gs_nearest_kdtree(kdNode *kdt, double lon, double lat, double *prange)
if ( !(frange < range0) ) node = NULL;
if ( prange ) *prange = frange;
- return node;
+ if ( node ) index = node->index;
+
+ return index;
+}
+
+static
+size_t gs_nearest_kdsph(kdNode *kdt, double lon, double lat, double *prange)
+{
+ size_t index = GS_NOT_FOUND;
+ if ( kdt == NULL ) return index;
+
+ float range0 = gs_set_range(prange);
+ kdata_t range = KDATA_SCALE(range0);
+
+ kdata_t point[2];
+ point[0] = lon;
+ point[1] = lat;
+
+ kdNode *node = kd_nearest(kdt, point, &range, 3);
+
+ float frange = KDATA_INVSCALE(range);
+ if ( !(frange < range0) ) node = NULL;
+ if ( prange ) *prange = frange;
+
+ if ( node ) index = node->index;
+
+ return index;
}
-unsigned gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double *prange)
+size_t gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double *prange)
{
size_t index = GS_NOT_FOUND;
if ( near == NULL ) return index;
@@ -367,7 +439,7 @@ unsigned gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double
float range = distance(point, point0);
if ( range < range0 )
{
- index = (unsigned) closestpt;
+ index = (size_t) closestpt;
*prange = range;
}
}
@@ -424,23 +496,13 @@ size_t gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double
if ( gs )
{
- if ( gs->method_nn == GS_KDTREE )
- {
- kdNode *node = gs_nearest_kdtree(gs->kdt, lon, lat, prange);
- if ( node ) index = (int) node->index;
- }
- else if ( gs->method_nn == GS_NEARPT3 )
- {
- index = gs_nearest_nearpt3(gs->near, lon, lat, prange);
- }
- else if ( gs->method_nn == GS_FULL )
- {
- index = gs_nearest_full(gs->full, lon, lat, prange);
- }
- else
- {
- cdoAbort("gridsearch_nearest::method_nn undefined!");
- }
+ // clang-format off
+ if ( gs->method_nn == GS_KDTREE ) index = gs_nearest_kdtree(gs->kdt, lon, lat, prange);
+ else if ( gs->method_nn == GS_KDSPH ) index = gs_nearest_kdsph(gs->kdt, lon, lat, prange);
+ else if ( gs->method_nn == GS_NEARPT3 ) index = gs_nearest_nearpt3(gs->near, lon, lat, prange);
+ else if ( gs->method_nn == GS_FULL ) index = gs_nearest_full(gs->full, lon, lat, prange);
+ else cdoAbort("gridsearch_nearest::method_nn undefined!");
+ // clang-format on
}
return index;
@@ -527,7 +589,7 @@ void knn_check_distance(size_t num_neighbors, const size_t *restrict nbr_add, do
void gridsearch_knn_init(struct gsknn *knn)
{
- unsigned ndist = knn->ndist;
+ size_t ndist = knn->ndist;
size_t *restrict add = knn->add;
double *restrict dist = knn->dist;
diff --git a/src/grid_search.h b/src/grid_search.h
index a9eaf92..289bf03 100644
--- a/src/grid_search.h
+++ b/src/grid_search.h
@@ -2,24 +2,23 @@
#define _GRID_SEARCH_H_
#include <stdbool.h>
-#include <limits.h>
#include "kdtreelib/kdtree.h"
#include "nearpt3c.h"
-#define GS_NOT_FOUND ULONG_MAX
+#define GS_NOT_FOUND SIZE_MAX
-enum T_GRIDSEARCH_METHOD_NN {GS_FULL=1, GS_KDTREE, GS_NEARPT3};
+enum T_GRIDSEARCH_METHOD_NN {GS_FULL=1, GS_KDTREE, GS_KDSPH, GS_NEARPT3};
struct gsFull {
- unsigned n;
+ size_t n;
const double *plons;
const double *plats;
float **pts;
};
struct gsNear {
- unsigned n;
+ size_t n;
const double *plons;
const double *plats;
Coord_T **pts;
@@ -27,9 +26,12 @@ struct gsNear {
};
struct gridsearch {
+ bool extrapolate;
+ bool is_cyclic;
+ bool is_reg2d;
int method_nn;
size_t n;
- size_t nx, ny;
+ size_t dims[2];
struct gsNear *near;
struct kdNode *kdt;
@@ -44,8 +46,8 @@ struct gridsearch {
};
struct gsknn {
- unsigned ndist;
- unsigned size;
+ size_t ndist;
+ size_t size;
bool *mask;
size_t *add;
size_t *tmpadd;
@@ -57,11 +59,12 @@ struct gsknn *gridsearch_knn_new(size_t size);
void gridsearch_knn_delete(struct gsknn *knn);
size_t gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double plat);
-struct gridsearch *gridsearch_create_reg2d(bool lcyclic, size_t nx, size_t ny, const double *restrict lons, const double *restrict lats);
+struct gridsearch *gridsearch_create_reg2d(bool is_cyclic, size_t dims[2], const double *restrict lons, const double *restrict lats);
struct gridsearch *gridsearch_create(size_t n, const double *restrict lons, const double *restrict lats);
struct gridsearch *gridsearch_create_nn(size_t n, const double *restrict lons, const double *restrict lats);
void gridsearch_delete(struct gridsearch *gs);
size_t gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double *range);
struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat, double *prange, size_t nnn);
+void gridsearch_extrapolate(struct gridsearch *gs);
#endif
diff --git a/src/griddes.cc b/src/griddes.cc
index 70d5b66..52702f7 100644
--- a/src/griddes.cc
+++ b/src/griddes.cc
@@ -140,13 +140,13 @@ int gridDefine(griddes_t grid)
if ( grid.ysize == 0 ) Error("ysize undefined!");
}
- if ( grid.size == 0 ) grid.size = (long)grid.xsize*grid.ysize;
+ if ( grid.size == 0 ) grid.size = grid.xsize*grid.ysize;
- if ( grid.size != (long)grid.xsize*grid.ysize )
- Error("Inconsistent grid declaration: xsize*ysize!=gridsize (xsize=%d ysize=%d gridsize=%d)",
+ if ( grid.size != grid.xsize*grid.ysize )
+ Error("Inconsistent grid declaration: xsize*ysize!=gridsize (xsize=%zu ysize=%zu gridsize=%zu)",
grid.xsize, grid.ysize, grid.size);
- if ( grid.size < 0 || grid.size > INT_MAX ) Error("grid size (%ld) out of bounds (0 - %d)!", grid.size, INT_MAX);
+ //if ( grid.size < 0 || grid.size > INT_MAX ) Error("grid size (%ld) out of bounds (0 - %d)!", grid.size, INT_MAX);
gridID = gridCreate(grid.type, grid.size);
@@ -166,7 +166,7 @@ int gridDefine(griddes_t grid)
{
grid.nvertex = 2;
grid.xbounds = (double*) Malloc(grid.xsize*grid.nvertex*sizeof(double));
- for ( int i = 0; i < (int) grid.xsize-1; i++ )
+ for ( size_t i = 0; i < grid.xsize-1; ++i )
{
grid.xbounds[2*i+1] = 0.5*(grid.xvals[i] + grid.xvals[i+1]);
grid.xbounds[2*(i+1)] = 0.5*(grid.xvals[i] + grid.xvals[i+1]);
@@ -186,7 +186,7 @@ int gridDefine(griddes_t grid)
{
grid.nvertex = 2;
grid.ybounds = (double*) Malloc(grid.ysize*grid.nvertex*sizeof(double));
- for ( int i = 0; i < (int) grid.ysize-1; i++ )
+ for ( size_t i = 0; i < grid.ysize-1; ++i )
{
grid.ybounds[2*i+1] = 0.5*(grid.yvals[i] + grid.yvals[i+1]);
grid.ybounds[2*(i+1)] = 0.5*(grid.yvals[i] + grid.yvals[i+1]);
diff --git a/src/griddes.h b/src/griddes.h
index 99f3da7..45b1e7c 100644
--- a/src/griddes.h
+++ b/src/griddes.h
@@ -30,9 +30,9 @@ typedef struct {
int *rowlon;
bool genBounds;
int nvertex;
- long size;
- int xsize;
- int ysize;
+ size_t size;
+ size_t xsize;
+ size_t ysize;
int np;
int lcomplex;
bool def_xfirst;
diff --git a/src/griddes_h5.cc b/src/griddes_h5.cc
index 9839715..7e102d4 100644
--- a/src/griddes_h5.cc
+++ b/src/griddes_h5.cc
@@ -1,11 +1,11 @@
-#if defined(HAVE_CONFIG_H)
-# include "config.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#define H5_USE_16_API
-#if defined(HAVE_LIBHDF5)
-# include "hdf5.h"
+#ifdef HAVE_LIBHDF5
+#include "hdf5.h"
#endif
#include <cdi.h>
@@ -42,7 +42,7 @@ herr_t obj_info(hid_t loc_id, const char *name, void *objname)
/*cdoAbort(" Unable to identify an object %s", name);*/
break;
}
- }
+ }
return lexist;
}
@@ -58,10 +58,10 @@ int h5find_object(hid_t file_id, const char *name)
#endif
static
-void fill_gridvals(int xsize, int ysize, double *xvals, double *yvals)
+void fill_gridvals(size_t xsize, size_t ysize, double *xvals, double *yvals)
{
- int i, j, ii, jj;
- int index, index2;
+ size_t i, j, ii, jj;
+ size_t index, index2;
double xmin = -180;
double xmax = 180;
@@ -361,8 +361,8 @@ int gridFromH5file(const char *gridfile)
}
H5Tclose(native_type);
- grid.xsize = (int)dims_out[1];
- grid.ysize = (int)dims_out[0];
+ grid.xsize = dims_out[1];
+ grid.ysize = dims_out[0];
grid.size = grid.xsize*grid.ysize;
grid.xvals = (double*) Malloc(grid.size*sizeof(double));
@@ -377,9 +377,9 @@ int gridFromH5file(const char *gridfile)
{
int *iarray = (int*) Malloc(grid.size*sizeof(int));
status = H5Dread(lon_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
- for ( int i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
+ for ( size_t i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
status = H5Dread(lat_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
- for ( int i = 0; i < grid.size; ++i ) grid.yvals[i] = iarray[i];
+ for ( size_t i = 0; i < grid.size; ++i ) grid.yvals[i] = iarray[i];
Free(iarray);
}
@@ -401,7 +401,7 @@ int gridFromH5file(const char *gridfile)
double xscale = 1, yscale = 1;
double xoffset = 0, yoffset = 0;
hid_t grp_id;
- int i;
+ size_t i;
grp_id = H5Gopen(file_id, "/where/lon/what");
if ( grp_id >= 0 )
@@ -483,8 +483,8 @@ int gridFromH5file(const char *gridfile)
}
H5Tclose(native_type);
- grid.xsize = (int)dims_out[1];
- grid.ysize = (int)dims_out[0];
+ grid.xsize = dims_out[1];
+ grid.ysize = dims_out[0];
grid.size = grid.xsize*grid.ysize;
grid.xvals = (double*) Malloc(grid.size*sizeof(double));
@@ -499,9 +499,9 @@ int gridFromH5file(const char *gridfile)
{
int *iarray = (int*) Malloc(grid.size*sizeof(int));
status = H5Dread(lon_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
- for ( int i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
+ for ( size_t i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
status = H5Dread(lat_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
- for ( int i = 0; i < grid.size; ++i ) grid.yvals[i] = iarray[i];
+ for ( size_t i = 0; i < grid.size; ++i ) grid.yvals[i] = iarray[i];
Free(iarray);
}
diff --git a/src/griddes_nc.cc b/src/griddes_nc.cc
index 488bec3..403c767 100644
--- a/src/griddes_nc.cc
+++ b/src/griddes_nc.cc
@@ -72,7 +72,7 @@ int gridFromNCfile(const char *gridfile)
nc_inq_dimid(nc_file_id, "grid_rank", &nc_gridrank_id) == NC_NOERR &&
nc_inq_dimid(nc_file_id, "grid_corners", &nc_gridcorn_id) == NC_NOERR )
{
- nce(nc_inq_dimlen(nc_file_id, nc_gridsize_id, &grid_size)); grid.size = (int) grid_size;
+ nce(nc_inq_dimlen(nc_file_id, nc_gridsize_id, &grid_size)); grid.size = grid_size;
nce(nc_inq_dimlen(nc_file_id, nc_gridrank_id, &grid_rank));
nce(nc_inq_dimlen(nc_file_id, nc_gridcorn_id, &grid_nvertex)); grid.nvertex = (int) grid_nvertex;
@@ -125,7 +125,7 @@ int gridFromNCfile(const char *gridfile)
if ( nc_inq_varid(nc_file_id, "grid_imask", &nc_gridmask_id) == NC_NOERR )
{
- int i;
+ size_t i;
grid.mask = (int*) Malloc(grid.size*sizeof(int));
nce(nc_get_var_int(nc_file_id, nc_gridmask_id, grid.mask));
for ( i = 0; i < grid.size; ++i )
@@ -173,7 +173,7 @@ void writeNCgrid(const char *gridfile, int gridID, int *grid_imask)
int gridtype = gridInqType(gridID);
- int gridsize = gridInqSize(gridID);
+ size_t gridsize = gridInqSize(gridID);
nc_type xtype = (gridInqDatatype(gridID) == CDI_DATATYPE_FLT64) ? NC_DOUBLE : NC_FLOAT;
diff --git a/src/gridreference.cc b/src/gridreference.cc
index a210611..344a941 100644
--- a/src/gridreference.cc
+++ b/src/gridreference.cc
@@ -217,7 +217,7 @@ int referenceToGrid(int gridID1)
{
if ( cdoVerbose ) cdoPrint("Horizontal grid file used: %s", gridpath);
- int gridsize = gridInqSize(gridID1);
+ size_t gridsize = gridInqSize(gridID1);
// int number = gridInqNumber(gridID1);
int position = gridInqPosition(gridID1);
@@ -233,7 +233,7 @@ int referenceToGrid(int gridID1)
if ( gridInqSize(gridID) == gridsize )
gridID2 = gridDuplicate(gridID);
else
- cdoWarning("Grid size %d on position %d do not match! Reference=%s", gridsize, position, gridpath);
+ cdoWarning("Grid size %zu on position %d do not match! Reference=%s", gridsize, position, gridpath);
}
else if ( position == 0 )
{
diff --git a/src/interpol.cc b/src/interpol.cc
index b300e39..e58b9d5 100644
--- a/src/interpol.cc
+++ b/src/interpol.cc
@@ -202,18 +202,18 @@ double intlinarr2p(long nxm, long nym, double **fieldm, const double *xm, const
static
void intlinarr2(double missval, int lon_is_circular,
- long nxm, long nym, const double *restrict fieldm, const double *restrict xm, const double *restrict ym,
- long gridsize2, double *field, const double *restrict x, const double *restrict y)
+ size_t nxm, size_t nym, const double *restrict fieldm, const double *restrict xm, const double *restrict ym,
+ size_t gridsize2, double *field, const double *restrict x, const double *restrict y)
{
- long nlon1 = nxm;
+ size_t nlon1 = nxm;
double findex = 0;
if ( lon_is_circular ) nlon1--;
- long gridsize1 = nlon1*nym;
+ size_t gridsize1 = nlon1*nym;
bool *grid1_mask = (bool*) Malloc(gridsize1*sizeof(bool));
- for ( long jj = 0; jj < nym; ++jj )
- for ( long ii = 0; ii < nlon1; ++ii )
+ for ( size_t jj = 0; jj < nym; ++jj )
+ for ( size_t ii = 0; ii < nlon1; ++ii )
grid1_mask[jj*nlon1+ii] = !DBL_IS_EQUAL(fieldm[jj*nlon1+ii], missval);
progressInit();
@@ -222,9 +222,9 @@ void intlinarr2(double missval, int lon_is_circular,
#pragma omp parallel for default(none) \
shared(ompNumThreads, field, fieldm, x, y, xm, ym, nxm, nym, gridsize2, missval, findex, nlon1, lon_is_circular, grid1_mask)
#endif
- for ( int i = 0; i < gridsize2; ++i )
+ for ( size_t i = 0; i < gridsize2; ++i )
{
- int src_add[4]; /* address for the four source points */
+ size_t src_add[4]; /* address for the four source points */
int lprogress = 1;
if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -241,7 +241,7 @@ void intlinarr2(double missval, int lon_is_circular,
if ( lfound )
{
- long iix = ii;
+ size_t iix = ii;
if ( lon_is_circular && iix == (nxm-1) ) iix = 0;
src_add[0] = (jj-1)*nlon1+(ii-1);
src_add[1] = (jj-1)*nlon1+(iix);
@@ -325,8 +325,8 @@ void intgridbil(field_type *field1, field_type *field2)
double *array2 = field2->ptr;
double missval = field1->missval;
- int nlon1 = gridInqXsize(gridID1);
- int nlat1 = gridInqYsize(gridID1);
+ size_t nlon1 = gridInqXsize(gridID1);
+ size_t nlat1 = gridInqYsize(gridID1);
int lon_is_circular = 0;
@@ -334,7 +334,7 @@ void intgridbil(field_type *field1, field_type *field2)
if ( grid_is_distance_generic(gridID1) && grid_is_distance_generic(gridID2) ) lgeorefgrid = false;
double **array1_2D = (double **) Malloc(nlat1*sizeof(double *));
- for ( int ilat = 0; ilat < nlat1; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat1; ilat++ )
array1_2D[ilat] = array1 + ilat*nlon1;
if ( lgeorefgrid )
@@ -364,8 +364,8 @@ void intgridbil(field_type *field1, field_type *field2)
if ( lon_is_circular ) lon1[nlon1-1] = lon1[0] + 2*M_PI;
}
- int xsize2 = gridInqXsize(gridID2);
- int ysize2 = gridInqYsize(gridID2);
+ size_t xsize2 = gridInqXsize(gridID2);
+ size_t ysize2 = gridInqYsize(gridID2);
if ( xsize2 == 1 && ysize2 == 1 )
{
@@ -387,7 +387,7 @@ void intgridbil(field_type *field1, field_type *field2)
lon1 = (double*) Realloc(lon1, (nlon1+1)*sizeof(double));
double *array = (double*) Malloc(nlat1*(nlon1+1)*sizeof(double));
- for ( int ilat = 0; ilat < nlat1; ilat++ )
+ for ( size_t ilat = 0; ilat < nlat1; ilat++ )
{
array1_2D[ilat] = array + ilat*(nlon1+1);
memcpy(array1_2D[ilat], field[ilat], nlon1*sizeof(double));
@@ -424,7 +424,7 @@ void intgridbil(field_type *field1, field_type *field2)
cdoAbort("Target grid has no coordinate values!");
}
- int gridsize2 = gridInqSize(gridID2);
+ size_t gridsize2 = gridInqSize(gridID2);
double *xvals2 = (double*) Malloc(gridsize2*sizeof(double));
double *yvals2 = (double*) Malloc(gridsize2*sizeof(double));
@@ -439,7 +439,7 @@ void intgridbil(field_type *field1, field_type *field2)
grid_to_radian(xunits, gridsize2, xvals2, "grid2 center lon");
grid_to_radian(xunits, gridsize2, yvals2, "grid2 center lat");
- for ( int i = 0; i < gridsize2; ++i )
+ for ( size_t i = 0; i < gridsize2; ++i )
{
if ( xvals2[i] < lon1[0] ) xvals2[i] += 2*M_PI;
if ( xvals2[i] > lon1[nlon1-1] ) xvals2[i] -= 2*M_PI;
@@ -453,8 +453,8 @@ void intgridbil(field_type *field1, field_type *field2)
gridInqXvals(gridID2, xcoord);
gridInqYvals(gridID2, ycoord);
- for ( int j = 0; j < ysize2; ++j )
- for ( int i = 0; i < xsize2; ++i )
+ for ( size_t j = 0; j < ysize2; ++j )
+ for ( size_t i = 0; i < xsize2; ++i )
{
xvals2[j*xsize2+i] = xcoord[i];
yvals2[j*xsize2+i] = ycoord[j];
@@ -468,8 +468,8 @@ void intgridbil(field_type *field1, field_type *field2)
nlon1, nlat1, array1, lon1, lat1,
gridsize2, array2, xvals2, yvals2);
- int nmiss = 0;
- for ( int i = 0; i < gridsize2; ++i )
+ size_t nmiss = 0;
+ for ( size_t i = 0; i < gridsize2; ++i )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
field2->nmiss = nmiss;
@@ -496,7 +496,7 @@ void interpolate(field_type *field1, field_type *field2)
int gridIDo;
double *arrayOut;
double missval;
- int nmiss;
+ size_t nmiss;
long ilon, ilat, nxlon, nxlat, olon, olat;
long l11, l12, l21, l22, l1, l2;
double volon1, volon2, volat1, volat2;
diff --git a/src/kdtreelib/kdtree.h b/src/kdtreelib/kdtree.h
index 74638a0..47d3af4 100644
--- a/src/kdtreelib/kdtree.h
+++ b/src/kdtreelib/kdtree.h
@@ -10,10 +10,11 @@
changed *min to min[KD_MAX_DIM]
changed *max to max[KD_MAX_DIM]
_compPoints: compare index if points[axis] are equal
- replace qsortR by libc:qsort (speedup 25%)
+ 20171102: renamed kd_buildArg() to kd_initArg(), changed interface and memory handling
+ changed data pointer to size_t
*/
-#ifndef _KDTREE_H_
-#define _KDTREE_H_
+#ifndef KDTREE_H_
+#define KDTREE_H_
#include <math.h>
#include <pthread.h>
@@ -59,7 +60,7 @@ typedef long kdata_t;
typedef struct kd_point {
kdata_t point[KD_MAX_DIM];
- unsigned index;
+ size_t index;
} kd_point;
@@ -84,7 +85,7 @@ typedef struct kdNode {
kdata_t min[KD_MAX_DIM]; /*!<vector to the min coordinates of the hyperrectangle */
kdata_t max[KD_MAX_DIM]; /*!<vector to the max coordinates of the hyperrectangle */
int split; /*!<axis along which the tree bifurcates */
- unsigned index; /*!<optional index value */
+ size_t index; /*!<optional index value */
} kdNode;
/*!
@@ -102,9 +103,9 @@ typedef struct resItem {
*/
typedef struct pqueue {
struct resItem **d; /*!<pointer to an array of result items */
- uint32_t size; /*!<current length of the queue */
- uint32_t avail; /*!<currently allocated queue elements */
- uint32_t step; /*!<step size in which new elements are allocated */
+ size_t size; /*!<current length of the queue */
+ size_t avail; /*!<currently allocated queue elements */
+ size_t step; /*!<step size in which new elements are allocated */
} pqueue;
/*!
@@ -115,7 +116,7 @@ typedef struct kd_thread_data {
struct kd_point *points;
kdata_t min[KD_MAX_DIM];
kdata_t max[KD_MAX_DIM];
- unsigned long nPoints;
+ size_t nPoints;
int max_threads;
int depth;
int dim;
@@ -126,7 +127,7 @@ typedef struct kd_thread_data {
#define KD_UNORDERED (0)
/* functions for the priority queue */
-struct pqueue *pqinit(struct pqueue *q, uint32_t n);
+struct pqueue *pqinit(struct pqueue *q, size_t n);
int pqinsert(struct pqueue *q, struct resItem *d);
struct resItem **pqremove_min(struct pqueue *q, struct resItem **d);
struct resItem **pqremove_max(struct pqueue *q, struct resItem **d);
@@ -152,22 +153,16 @@ void kd_printNode(struct kdNode *node);
void kd_printTree(struct kdNode *node);
/* Functions for building and destroying trees */
-void kd_freeNode(kdNode * node);
-struct kdNode *kd_allocNode(struct kd_point *points, unsigned long pivot,
+struct kdNode *kd_allocNode(struct kd_point *points, size_t pivot,
kdata_t *min, kdata_t *max, int dim, int axis);
void kd_destroyTree(struct kdNode *node);
-struct kd_thread_data *kd_buildArg(struct kd_point *points,
- unsigned long nPoints,
- kdata_t *min, kdata_t *max,
- int depth, int max_threads,
- int dim);
-struct kdNode *kd_buildTree(struct kd_point *points, unsigned long nPoints,
+void kd_initArg(struct kd_thread_data *d, struct kd_point *points, size_t nPoints,
+ kdata_t *min, kdata_t *max, int depth, int max_threads, int dim);
+struct kdNode *kd_buildTree(struct kd_point *points, size_t nPoints,
kdata_t *min, kdata_t *max, int dim, int max_threads);
void *kd_doBuildTree(void *threadarg);
-struct kdNode *kd_sph_buildTree(struct kd_point *points,
- unsigned long nPoints,
- kdata_t *min, kdata_t *max,
- int max_threads);
+struct kdNode *kd_sph_buildTree(struct kd_point *points, size_t nPoints,
+ kdata_t *min, kdata_t *max, int max_threads);
void *kd_sph_doBuildTree(void *threadarg);
/* Functions for range searches
@@ -180,12 +175,11 @@ struct pqueue *kd_ortRangeSearch(struct kdNode *node, kdata_t *min, kdata_t *max
int dim);
int kd_doOrtRangeSearch(struct kdNode *node, kdata_t *min, kdata_t *max, int dim,
struct pqueue *res);
-struct kdNode *kd_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
- int dim);
+struct kdNode *kd_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq, int dim);
struct pqueue *kd_qnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, int dim);
+ kdata_t *max_dist_sq, size_t q, int dim);
int kd_doQnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, int dim,
+ kdata_t *max_dist_sq, size_t q, int dim,
struct pqueue *res);
struct pqueue *kd_range(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
int dim, int ordered);
@@ -202,9 +196,9 @@ int kd_sph_doOrtRangeSearch(struct kdNode *node, kdata_t *min, kdata_t *max,
struct kdNode *kd_sph_nearest(struct kdNode *node, kdata_t *p,
kdata_t *max_dist_sq);
struct pqueue *kd_sph_qnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q);
+ kdata_t *max_dist_sq, size_t q);
int kd_sph_doQnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, struct pqueue *res);
+ kdata_t *max_dist_sq, size_t q, struct pqueue *res);
struct pqueue *kd_sph_range(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
int ordered);
int kd_sph_doRange(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
@@ -214,4 +208,4 @@ int kd_sph_doRange(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
int kd_insertResTree(struct kdNode *node, struct pqueue *res);
-#endif /* _KDTREE_H_ */
+#endif /* KDTREE_H_ */
diff --git a/src/kdtreelib/kdtree_cartesian.cc b/src/kdtreelib/kdtree_cartesian.cc
index faef76a..b1e7e83 100644
--- a/src/kdtreelib/kdtree_cartesian.cc
+++ b/src/kdtreelib/kdtree_cartesian.cc
@@ -24,10 +24,10 @@ kdata_t square(const kdata_t x)
static constexpr
kdata_t kd_dist_sq(const kdata_t *restrict a, const kdata_t *restrict b)
{
- return (square((a[0]-b[0]))+square((a[1]-b[1]))+square((a[2]-b[2])));
+ return square((a[0]-b[0]))+square((a[1]-b[1]))+square((a[2]-b[2]));
}
-inline
+
kdata_t kd_min(kdata_t x, kdata_t y)
{
return x < y ? x : y;
@@ -70,16 +70,13 @@ kdata_t kd_min(kdata_t x, kdata_t y)
* \return root node of the tree
*/
struct kdNode *
-kd_buildTree(struct kd_point *points, unsigned long nPoints,
+kd_buildTree(struct kd_point *points, size_t nPoints,
kdata_t *min, kdata_t *max, int dim, int max_threads)
{
- struct kd_thread_data *my_data;
- struct kdNode *tree;
-
- my_data = kd_buildArg(points, nPoints, min, max, 0, max_threads, dim);
- tree = (kdNode *)kd_doBuildTree(my_data);
- free(my_data);
- return tree;
+ struct kd_thread_data my_data;
+ kd_initArg(&my_data, points, nPoints, min, max, 0, max_threads, dim);
+ struct kdNode *tree = (kdNode *)kd_doBuildTree(&my_data);
+ return tree;
}
@@ -163,12 +160,11 @@ struct pqueue *
kd_ortRangeSearch(struct kdNode *node, kdata_t *min, kdata_t *max, int dim)
{
struct pqueue *res;
- uint32_t i;
if ((res = pqinit(NULL, 1)) == NULL)
return NULL;
if (!kd_doOrtRangeSearch(node, min, max, dim, res)) {
- for(i = 0; i < res->size; i++) {
+ for(size_t i = 0; i < res->size; i++) {
free(res->d[i]);
}
free(res->d);
@@ -304,13 +300,13 @@ kd_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq, int dim)
*/
struct pqueue *
kd_qnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, int dim)
+ kdata_t *max_dist_sq, size_t q, int dim)
{
struct pqueue *res = pqinit(NULL, q + 2);
if ( res == NULL) return NULL;
if ( !kd_doQnearest(node, p, max_dist_sq, q + 1, dim, res) ) {
- for ( uint32_t i = 0; i < res->size; ++i ) free(res->d[i]);
+ for ( size_t i = 0; i < res->size; ++i ) free(res->d[i]);
free(res->d);
free(res);
return NULL;
@@ -329,73 +325,75 @@ kd_qnearest(struct kdNode *node, kdata_t *p,
* return 1 if okay, zero in case of problems
*/
// Uwe Schulzweida: extract kd_check_dist() from kd_doQnearest()
-static int
+static bool
kd_check_dist(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, struct pqueue *res)
+ kdata_t *max_dist_sq, size_t q, struct pqueue *res)
{
- kdata_t dist_sq = kd_dist_sq(node->location, p);
- if ( dist_sq < *max_dist_sq && kd_isleaf(node) ) {
- struct resItem *point = (struct resItem *) kd_malloc(sizeof(struct resItem), "kd_doQnearest: ");
- if ( point == NULL) return 0;
- point->node = node;
- point->dist_sq = dist_sq;
- pqinsert(res, point);
+ kdata_t dist_sq = kd_dist_sq(node->location, p);
+ if ( dist_sq < *max_dist_sq && kd_isleaf(node) )
+ {
+ struct resItem *point = (struct resItem *) kd_malloc(sizeof(struct resItem), "kd_doQnearest: ");
+ if ( point == NULL) return false;
+ point->node = node;
+ point->dist_sq = dist_sq;
+ pqinsert(res, point);
}
- if ( res->size > q ) {
- struct resItem *item;
- pqremove_max(res, &item);
- free(item);
- if ( res->size > 1 ) {
- /*
- * Only inspect the queue if there are items left
- */
- pqpeek_max(res, &item);
- *max_dist_sq = item->dist_sq;
- } else {
- /*
- * Nothing was found within the max search radius
- */
- *max_dist_sq = 0;
+ if ( res->size > q )
+ {
+ struct resItem *item;
+ pqremove_max(res, &item);
+ free(item);
+ if ( res->size > 1 )
+ {
+ // Only inspect the queue if there are items left
+ pqpeek_max(res, &item);
+ *max_dist_sq = item->dist_sq;
+ }
+ else
+ {
+ // Nothing was found within the max search radius
+ *max_dist_sq = 0;
}
}
- return 1;
+ return true;
}
int
kd_doQnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q, int dim, struct pqueue *res)
+ kdata_t *max_dist_sq, size_t q, int dim, struct pqueue *res)
{
- if ( !node ) return 1;
+ if ( !node ) return 1;
- if ( !kd_check_dist(node, p, max_dist_sq, q, res) ) return 0;
+ if ( !kd_check_dist(node, p, max_dist_sq, q, res) ) return 0;
- struct kdNode *nearer, *further;
- if ( p[node->split] < node->location[node->split] ) {
- nearer = node->left;
- further = node->right;
- } else {
- nearer = node->right;
- further = node->left;
- }
- if ( !kd_doQnearest(nearer, p, max_dist_sq, q, dim, res) ) return 0;
+ struct kdNode *nearer, *further;
+ if ( p[node->split] < node->location[node->split] ) {
+ nearer = node->left;
+ further = node->right;
+ } else {
+ nearer = node->right;
+ further = node->left;
+ }
+ if ( !kd_doQnearest(nearer, p, max_dist_sq, q, dim, res) ) return 0;
- if ( !further ) return 1;
+ if ( !further ) return 1;
- kdata_t dx = kd_min(KDATA_ABS(p[node->split] - further->min[node->split]),
- KDATA_ABS(p[node->split] - further->max[node->split]));
+ kdata_t dx = kd_min(KDATA_ABS(p[node->split] - further->min[node->split]),
+ KDATA_ABS(p[node->split] - further->max[node->split]));
- if ( *max_dist_sq > kd_sqr(dx) ) {
- /*
- * some part of the further hyper-rectangle is in the search
- * radius, search the further node
- */
- if (!kd_doQnearest(further, p, max_dist_sq, q, dim, res)) return 0;
+ if ( *max_dist_sq > kd_sqr(dx) ) {
+ /*
+ * some part of the further hyper-rectangle is in the search
+ * radius, search the further node
+ */
+ if (!kd_doQnearest(further, p, max_dist_sq, q, dim, res)) return 0;
- if (!kd_check_dist(node, p, max_dist_sq, q, res)) return 0;
- }
- return 1;
+ if (!kd_check_dist(node, p, max_dist_sq, q, res)) return 0;
+ }
+
+ return 1;
}
@@ -423,7 +421,7 @@ kd_range(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
if ( res == NULL ) return NULL;
if ( !kd_doRange(node, p, max_dist_sq, dim, res, ordered) ) {
- for( uint32_t i = 0; i < res->size; ++i ) {
+ for( size_t i = 0; i < res->size; ++i ) {
free(res->d[i]);
}
free(res->d);
diff --git a/src/kdtreelib/kdtree_common.cc b/src/kdtreelib/kdtree_common.cc
index 559e758..6ef19fd 100644
--- a/src/kdtreelib/kdtree_common.cc
+++ b/src/kdtreelib/kdtree_common.cc
@@ -59,7 +59,7 @@ kd_printNode(struct kdNode *node)
printf("Corners: (%f, %f)\t(%f, %f)\n", node->min[0], node->min[1],
node->max[0], node->max[1]);
printf("Children: %p\t%p\n", (void *) node->left, (void *) node->right);
- printf("Index: %u\n", node->index);
+ printf("Index: %zu\n", node->index);
printf("\n");
}
@@ -79,6 +79,18 @@ kd_printTree(struct kdNode *node)
/* End helper functions */
+void kd_initArg(struct kd_thread_data *d, struct kd_point *points, size_t nPoints,
+ kdata_t *min, kdata_t *max, int depth, int max_threads, int dim)
+{
+ d->points = points;
+ d->nPoints = nPoints;
+ memcpy(d->min, min, dim*sizeof(kdata_t));
+ memcpy(d->max, max, dim*sizeof(kdata_t));
+ d->depth = depth;
+ d->max_threads = max_threads;
+ d->dim = dim;
+}
+
/* ******************************************************************
Functions for building and destroying trees
@@ -87,15 +99,15 @@ kd_printTree(struct kdNode *node)
void *kd_doBuildTree(void *threadarg)
{
- kdata_t tmpMinLeft[KD_MAX_DIM], tmpMaxLeft[KD_MAX_DIM], tmpMinRight[KD_MAX_DIM], tmpMaxRight[KD_MAX_DIM];
+ kdata_t tmpMaxLeft[KD_MAX_DIM], tmpMinRight[KD_MAX_DIM];
struct kdNode *node;
pthread_t threads[2];
pthread_attr_t attr;
- struct kd_thread_data *argleft, *argright;
+ struct kd_thread_data argleft, argright;
struct kd_thread_data *my_data = (struct kd_thread_data *) threadarg;
struct kd_point *points = my_data->points;
- unsigned long nPoints = my_data->nPoints;
+ size_t nPoints = my_data->nPoints;
kdata_t *min = my_data->min;
kdata_t *max = my_data->max;
int depth = my_data->depth;
@@ -120,25 +132,19 @@ void *kd_doBuildTree(void *threadarg)
*/
pmergesort(points, nPoints, sortaxis, max_threads);
- unsigned long pivot = nPoints / 2;
+ size_t pivot = nPoints / 2;
if ((node = kd_allocNode(points, pivot, min, max, sortaxis, dim)) == NULL)
return NULL;
- memcpy(tmpMinLeft, min, dim * sizeof(kdata_t));
memcpy(tmpMaxLeft, max, dim * sizeof(kdata_t));
tmpMaxLeft[sortaxis] = node->location[sortaxis];
- argleft = kd_buildArg(points, pivot, tmpMinLeft, tmpMaxLeft,
- depth + 1, max_threads / 2, dim);
- if (!argleft) {
- kd_destroyTree(node);
- return NULL;
- }
+ kd_initArg(&argleft, points, pivot, min, tmpMaxLeft,
+ depth + 1, max_threads / 2, dim);
if (max_threads > 1) {
- pthread_create(&threads[0], &attr, kd_doBuildTree, (void *) argleft);
+ pthread_create(&threads[0], &attr, kd_doBuildTree, (void *) &argleft);
} else {
- node->left = (kdNode *)kd_doBuildTree((void *) argleft);
- free(argleft);
+ node->left = (kdNode *)kd_doBuildTree((void *) &argleft);
if (!node->left) {
kd_destroyTree(node);
return NULL;
@@ -146,21 +152,14 @@ void *kd_doBuildTree(void *threadarg)
}
memcpy(tmpMinRight, min, dim * sizeof(kdata_t));
- memcpy(tmpMaxRight, max, dim * sizeof(kdata_t));
tmpMinRight[sortaxis] = node->location[sortaxis];
- argright = kd_buildArg(&points[pivot], nPoints - pivot,
- tmpMinRight, tmpMaxRight, depth + 1,
- max_threads / 2, dim);
- if (!argright) {
- kd_destroyTree(node);
- return NULL;
- }
+ kd_initArg(&argright, &points[pivot], nPoints - pivot, tmpMinRight, max,
+ depth + 1, max_threads / 2, dim);
if (max_threads > 1) {
- pthread_create(&threads[1], &attr, kd_doBuildTree, (void *) argright);
+ pthread_create(&threads[1], &attr, kd_doBuildTree, (void *) &argright);
} else {
- node->right = (kdNode *)kd_doBuildTree((void *) argright);
- free(argright);
+ node->right = (kdNode *)kd_doBuildTree((void *) &argright);
if (!node->right) {
kd_destroyTree(node);
return NULL;
@@ -169,9 +168,7 @@ void *kd_doBuildTree(void *threadarg)
if (max_threads > 1) {
pthread_join(threads[0], (void **) (&node->left));
- free(argleft);
pthread_join(threads[1], (void **) (&node->right));
- free(argright);
if (!node->left || !node->right) {
kd_destroyTree(node);
return NULL;
@@ -181,40 +178,15 @@ void *kd_doBuildTree(void *threadarg)
return (void *) node;
}
-
-void
-kd_freeNode(kdNode *node)
+static
+void kd_freeNode(kdNode *node)
{
if ( node ) free(node);
- return;
-}
-
-
-struct kd_thread_data *
-kd_buildArg(struct kd_point *points,
- unsigned long nPoints,
- kdata_t *min, kdata_t *max,
- int depth, int max_threads, int dim)
-{
- struct kd_thread_data *d;
-
- if ((d = (kd_thread_data *)kd_malloc(sizeof(kd_thread_data), "kd_thread_data")) == NULL)
- return NULL;
-
- d->points = points;
- d->nPoints = nPoints;
- memcpy(d->min, min, dim*sizeof(kdata_t));
- memcpy(d->max, max, dim*sizeof(kdata_t));
- d->depth = depth;
- d->max_threads = max_threads;
- d->dim = dim;
-
- return d;
}
struct kdNode *
-kd_allocNode(struct kd_point *points, unsigned long pivot,
+kd_allocNode(struct kd_point *points, size_t pivot,
kdata_t *min, kdata_t *max, int axis, int dim)
{
struct kdNode *node;
diff --git a/src/kdtreelib/kdtree_spherical.cc b/src/kdtreelib/kdtree_spherical.cc
index ff41230..5aa0d1e 100644
--- a/src/kdtreelib/kdtree_spherical.cc
+++ b/src/kdtreelib/kdtree_spherical.cc
@@ -128,16 +128,13 @@ kd_sph_orth_dist(kdata_t *p1, kdata_t *p2, int split)
* \return root node of the tree
*/
struct kdNode *
-kd_sph_buildTree(struct kd_point *points, unsigned long nPoints,
+kd_sph_buildTree(struct kd_point *points, size_t nPoints,
kdata_t *min, kdata_t *max, int max_threads)
{
- struct kd_thread_data *my_data;
- struct kdNode *tree;
-
- my_data = kd_buildArg(points, nPoints, min, max, 0,max_threads, 2);
- tree = (kdNode *)kd_doBuildTree(my_data);
- free(my_data);
- return tree;
+ struct kd_thread_data my_data;
+ kd_initArg(&my_data, points, nPoints, min, max, 0,max_threads, 2);
+ struct kdNode *tree = (kdNode *)kd_doBuildTree(&my_data);
+ return tree;
}
@@ -277,12 +274,11 @@ struct pqueue *
kd_sph_ortRangeSearch(struct kdNode *node, kdata_t *min, kdata_t *max)
{
struct pqueue *res;
- uint32_t i;
if ((res = pqinit(NULL, 1)) == NULL)
return NULL;
if (!kd_sph_doOrtRangeSearch(node, min, max, res)) {
- for(i = 0; i < res->size; i++) {
+ for(size_t i = 0; i < res->size; i++) {
free(res->d[i]);
}
free(res->d);
@@ -432,15 +428,14 @@ kd_sph_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq)
*/
struct pqueue *
kd_sph_qnearest(struct kdNode *node, kdata_t *p,
- kdata_t *max_dist_sq, unsigned int q)
+ kdata_t *max_dist_sq, size_t q)
{
struct pqueue *res;
- uint32_t i;
if ((res = pqinit(NULL, q + 2)) == NULL)
return NULL;
if (!kd_sph_doQnearest(node, p, max_dist_sq, q + 1, res)) {
- for(i = 0; i < res->size; i++) {
+ for(size_t i = 0; i < res->size; i++) {
free(res->d[i]);
}
free(res->d);
@@ -461,7 +456,7 @@ kd_sph_qnearest(struct kdNode *node, kdata_t *p,
*/
int
kd_sph_doQnearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
- unsigned int q, struct pqueue *res)
+ size_t q, struct pqueue *res)
{
struct kdNode *nearer, *further;
struct resItem *point, *item;
@@ -588,12 +583,11 @@ struct pqueue *
kd_sph_range(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq, int ordered)
{
struct pqueue *res;
- uint32_t i;
if ((res = pqinit(NULL, 1)) == NULL)
return NULL;
if (!kd_sph_doRange(node, p, max_dist_sq, res, ordered)) {
- for(i = 0; i < res->size; i++) {
+ for(size_t i = 0; i < res->size; i++) {
free(res->d[i]);
}
free(res->d);
diff --git a/src/kdtreelib/pmergesort.cc b/src/kdtreelib/pmergesort.cc
index 57e6968..895a012 100644
--- a/src/kdtreelib/pmergesort.cc
+++ b/src/kdtreelib/pmergesort.cc
@@ -25,13 +25,15 @@ void *mergesort_t(void *args);
int pmergesort(struct kd_point *base, size_t nmemb, int axis, int max_threads)
{
- struct kd_point *tmp;
- param_t args;
+ struct kd_point *tmp = NULL;
- if ((tmp = (struct kd_point*)calloc(nmemb, sizeof(struct kd_point))) == NULL) {
+ if ( max_threads > 1 )
+ if ((tmp = (struct kd_point*)calloc(nmemb, sizeof(struct kd_point))) == NULL) {
perror("malloc");
return 0;
- }
+ }
+
+ param_t args;
args.a = base;
args.b = tmp;
args.first = 0;
@@ -41,7 +43,8 @@ int pmergesort(struct kd_point *base, size_t nmemb, int axis, int max_threads)
mergesort_t(&args);
- free(tmp);
+ if (tmp) free(tmp);
+
return 1;
}
diff --git a/src/kdtreelib/pqueue.cc b/src/kdtreelib/pqueue.cc
index 9fdfc2c..7881985 100644
--- a/src/kdtreelib/pqueue.cc
+++ b/src/kdtreelib/pqueue.cc
@@ -22,9 +22,9 @@
Ripped off wikipedia.
*/
inline int
-floorLog2(uint32_t n)
+floorLog2(size_t n)
{
- uint32_t pos = 0;
+ size_t pos = 0;
if (n >= 1 << 16) {
n >>= 16;
pos += 16;
@@ -54,7 +54,7 @@ floorLog2(uint32_t n)
(min-sorted level).
*/
inline int
-is_max_level(int i)
+is_max_level(size_t i)
{
return floorLog2(i) % 2;
}
@@ -63,7 +63,7 @@ is_max_level(int i)
/* Swap nodes i and j in the priority queue q */
void
-pq_swap_nodes(struct pqueue *q, uint32_t i, uint32_t j)
+pq_swap_nodes(struct pqueue *q, size_t i, size_t j)
{
struct resItem *tmp;
@@ -74,11 +74,11 @@ pq_swap_nodes(struct pqueue *q, uint32_t i, uint32_t j)
/* Return the array index of the maximum node */
-uint32_t
+size_t
get_max_index(struct pqueue *q)
{
- uint32_t i;
+ size_t i;
if (!q)
return 0;
@@ -128,7 +128,7 @@ get_max_index(struct pqueue *q)
/* Move a node up the tree */
void
-bubble_up_min(struct pqueue *q, uint32_t i)
+bubble_up_min(struct pqueue *q, size_t i)
{
/*
* if node has a grandparent
@@ -141,7 +141,7 @@ bubble_up_min(struct pqueue *q, uint32_t i)
void
-bubble_up_max(struct pqueue *q, uint32_t i)
+bubble_up_max(struct pqueue *q, size_t i)
{
/*
* if node has a grandparent
@@ -154,7 +154,7 @@ bubble_up_max(struct pqueue *q, uint32_t i)
void
-bubble_up(struct pqueue *q, uint32_t i)
+bubble_up(struct pqueue *q, size_t i)
{
if (!is_max_level(i)) {
if (i > 1 && PQPRIO(q->d[i]) > PQPRIO(q->d[i / 2])) {
@@ -182,10 +182,10 @@ bubble_up(struct pqueue *q, uint32_t i)
/* Get index of the smallest child or grandchild of q->d[i].
Caller must ensure that q->d[i] has at least one child. */
-uint32_t
-pq_get_min_child_index(struct pqueue *q, uint32_t i)
+size_t
+pq_get_min_child_index(struct pqueue *q, size_t i)
{
- uint32_t m;
+ size_t m;
/*
* First Child
@@ -226,10 +226,10 @@ pq_get_min_child_index(struct pqueue *q, uint32_t i)
/* Get index of the largest children and grandchildren of q->d[i].
Caller must ensure that q->d[i] has at least one child. */
-uint32_t
-pq_get_max_child_index(struct pqueue * q, uint32_t i)
+size_t
+pq_get_max_child_index(struct pqueue * q, size_t i)
{
- uint32_t m;
+ size_t m;
/*
* First Child
@@ -271,7 +271,7 @@ pq_get_max_child_index(struct pqueue * q, uint32_t i)
/* Move a node down the tree */
void
-trickle_down(struct pqueue *q, uint32_t i)
+trickle_down(struct pqueue *q, size_t i)
{
if (is_max_level(i))
trickle_down_max(q, i);
@@ -281,9 +281,9 @@ trickle_down(struct pqueue *q, uint32_t i)
void
-trickle_down_max(struct pqueue *q, uint32_t i)
+trickle_down_max(struct pqueue *q, size_t i)
{
- uint32_t m;
+ size_t m;
/*
* if A[i] has children
@@ -313,9 +313,9 @@ trickle_down_max(struct pqueue *q, uint32_t i)
}
void
-trickle_down_min(struct pqueue *q, uint32_t i)
+trickle_down_min(struct pqueue *q, size_t i)
{
- uint32_t m;
+ size_t m;
/*
* if A[i] has children
@@ -369,7 +369,7 @@ trickle_down_min(struct pqueue *q, uint32_t i)
*
*/
struct pqueue *
-pqinit(struct pqueue *q, uint32_t n)
+pqinit(struct pqueue *q, size_t n)
{
struct pqueue *tmp = q;
@@ -403,7 +403,7 @@ int
pqinsert(struct pqueue *q, struct resItem *d)
{
struct resItem **tmp;
- uint32_t i, newsize;
+ size_t i, newsize;
if (!q)
return 0;
@@ -473,7 +473,7 @@ pqremove_min(struct pqueue *q, struct resItem **d)
struct resItem **
pqremove_max(struct pqueue *q, struct resItem **d)
{
- uint32_t i;
+ size_t i;
if (!q || q->size == 1)
return NULL;
diff --git a/src/kdtreelib/pqueue.h b/src/kdtreelib/pqueue.h
index 68d85df..5f5406b 100644
--- a/src/kdtreelib/pqueue.h
+++ b/src/kdtreelib/pqueue.h
@@ -8,17 +8,17 @@
#define PQPRIO(p) (p->dist_sq)
-int floorLog2(uint32_t n);
+int floorLog2(size_t n);
int is_max_level(int i);
-uint32_t get_max_index(struct pqueue *q);
-uint32_t pq_get_min_child_index(struct pqueue *q, uint32_t i);
-uint32_t pq_get_max_child_index(struct pqueue *q, uint32_t i);
-void pq_swap_nodes(struct pqueue *q, uint32_t i, uint32_t j);
-void trickle_down(struct pqueue *q, uint32_t i);
-void trickle_down_min(struct pqueue *q, uint32_t i);
-void trickle_down_max(struct pqueue *q, uint32_t i);
-void bubble_up(struct pqueue *q, uint32_t i);
-void bubble_up_min(struct pqueue *q, uint32_t i);
-void bubble_up_max(struct pqueue *q, uint32_t i);
+size_t get_max_index(struct pqueue *q);
+size_t pq_get_min_child_index(struct pqueue *q, size_t i);
+size_t pq_get_max_child_index(struct pqueue *q, size_t i);
+void pq_swap_nodes(struct pqueue *q, size_t i, size_t j);
+void trickle_down(struct pqueue *q, size_t i);
+void trickle_down_min(struct pqueue *q, size_t i);
+void trickle_down_max(struct pqueue *q, size_t i);
+void bubble_up(struct pqueue *q, size_t i);
+void bubble_up_min(struct pqueue *q, size_t i);
+void bubble_up_max(struct pqueue *q, size_t i);
#endif
diff --git a/src/lib/ncl/Makefile.am b/src/lib/ncl/Makefile.am
new file mode 100644
index 0000000..1d3ed60
--- /dev/null
+++ b/src/lib/ncl/Makefile.am
@@ -0,0 +1,6 @@
+## Process this file with automake to produce Makefile.in
+#
+if USE_F77
+noinst_LTLIBRARIES = libncl.la
+libncl_la_SOURCES = rvdv.f
+endif
diff --git a/contrib/Makefile.in b/src/lib/ncl/Makefile.in
similarity index 69%
copy from contrib/Makefile.in
copy to src/lib/ncl/Makefile.in
index a9577ba..2d99e94 100644
--- a/contrib/Makefile.in
+++ b/src/lib/ncl/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -13,8 +13,19 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
+
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -77,11 +88,11 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = contrib
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs COPYING
+subdir = src/lib/ncl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -90,10 +101,21 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libncl_la_LIBADD =
+am__libncl_la_SOURCES_DIST = rvdv.f
+ at USE_F77_TRUE@am_libncl_la_OBJECTS = rvdv.lo
+libncl_la_OBJECTS = $(am_libncl_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+ at USE_F77_TRUE@am_libncl_la_rpath =
AM_V_P = $(am__v_P_ at AM_V@)
am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
am__v_P_0 = false
@@ -106,14 +128,50 @@ AM_V_at = $(am__v_at_ at AM_V@)
am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
-SOURCES =
-DIST_SOURCES =
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src
+F77COMPILE = $(F77) $(AM_FFLAGS) $(FFLAGS)
+LTF77COMPILE = $(LIBTOOL) $(AM_V_lt) --tag=F77 $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS)
+AM_V_F77 = $(am__v_F77_ at AM_V@)
+am__v_F77_ = $(am__v_F77_ at AM_DEFAULT_V@)
+am__v_F77_0 = @echo " F77 " $@;
+am__v_F77_1 =
+F77LD = $(F77)
+F77LINK = $(LIBTOOL) $(AM_V_lt) --tag=F77 $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(F77LD) $(AM_FFLAGS) $(FFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_F77LD = $(am__v_F77LD_ at AM_V@)
+am__v_F77LD_ = $(am__v_F77LD_ at AM_DEFAULT_V@)
+am__v_F77LD_0 = @echo " F77LD " $@;
+am__v_F77LD_1 =
+SOURCES = $(libncl_la_SOURCES)
+DIST_SOURCES = $(am__libncl_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -156,18 +214,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -243,6 +305,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -290,11 +353,14 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-EXTRA_DIST = makecompl.rb cdoCompletion.bash cdoCompletion.tcsh cdoCompletion.zsh
-CLEANFILES = `ls cdoCompletion.*`
+
+#
+ at USE_F77_TRUE@noinst_LTLIBRARIES = libncl.la
+ at USE_F77_TRUE@libncl_la_SOURCES = rvdv.f
all: all-am
.SUFFIXES:
+.SUFFIXES: .f .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -304,10 +370,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib/ncl/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign contrib/Makefile
-.PRECIOUS: Makefile
+ $(AUTOMAKE) --foreign src/lib/ncl/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -326,17 +391,92 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libncl.la: $(libncl_la_OBJECTS) $(libncl_la_DEPENDENCIES) $(EXTRA_libncl_la_DEPENDENCIES)
+ $(AM_V_F77LD)$(F77LINK) $(am_libncl_la_rpath) $(libncl_la_OBJECTS) $(libncl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.f.o:
+ $(AM_V_F77)$(F77COMPILE) -c -o $@ $<
+
+.f.obj:
+ $(AM_V_F77)$(F77COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.f.lo:
+ $(AM_V_F77)$(LTF77COMPILE) -c -o $@ $<
+
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-tags TAGS:
-
-ctags CTAGS:
-cscope cscopelist:
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -370,7 +510,7 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile all-local
+all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
@@ -394,7 +534,6 @@ install-strip:
mostlyclean-generic:
clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -405,11 +544,13 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool mostlyclean-am
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
distclean: distclean-am
-rm -f Makefile
-distclean-am: clean-am distclean-generic
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
dvi: dvi-am
@@ -457,7 +598,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
pdf: pdf-am
@@ -471,38 +613,22 @@ uninstall-am:
.MAKE: install-am install-strip
-.PHONY: all all-am all-local check check-am clean clean-generic \
- clean-libtool cscopelist-am ctags-am distclean \
- distclean-generic distclean-libtool distdir dvi dvi-am html \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
- uninstall-am
-
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
-completions:
- if hash ruby >/dev/null 2>&1 ; then \
- ruby -KN $(srcdir)/makecompl.rb -o cdoCompletion; \
- fi
-
-cdoCompletion.bash cdoCompletion.zsh cdoCompletion.tcsh: completions
-
-test:
- if hash ruby >/dev/null 2>&1 ; then \
- cd ruby;ruby test/test_cdo.rb \
- fi
- if hash python >/dev/null 2>&1 ; then \
- cd python; python test/test_cdo.py \
- fi
+.PRECIOUS: Makefile
-#if MAINTAINER_MODE
-all-local: completions
-#endif
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/lib/ncl/rvdv.f b/src/lib/ncl/rvdv.f
new file mode 100644
index 0000000..82fd5f1
--- /dev/null
+++ b/src/lib/ncl/rvdv.f
@@ -0,0 +1,456 @@
+C NCLFORTSTART
+ SUBROUTINE DVRFIDF(U,V,GLAT,GLON,MLON,NLAT,XMSG,IOPT,RV,IER)
+ IMPLICIT NONE
+
+c relative vorticity via finite differences
+c NCL: rv = uv2vr_cfd (u,v,lat,lon,cyclic)
+
+c xmsg = u at _FillValue
+c nlat,mlon = dimsizes (u)
+c iopt= cyclic
+
+c relative vorticity via centered finite difference approach (rv)
+c . rv = dv/dx-du/dy+(u/a)tan(lat) where "d" means partial derivitive
+c reference: Bluestein p113-114 [was not the original reference]
+c Halt-Martin p314 [ nothing on rv]
+
+c assumptions:
+c . (1) latitudes monotonically increasing [eg: glat(2) > glat(1)]
+c . latitudes may be unequally spaced
+c . (2) longitudes monotonically increasing [eg: glon(2) > glon(1)]
+c . longitudes are assmed to be equally spaced
+c . (3) if iopt=1 then the grids are cyclic in x
+c . eg: for T42 grid mlon=128, nlat=64
+c . cyclic point should NOT be included
+c .
+c ! INPUT
+ INTEGER MLON,NLAT
+ DOUBLE PRECISION U(MLON,NLAT),V(MLON,NLAT),GLAT(NLAT),GLON(MLON),
+ + XMSG
+ INTEGER IOPT
+
+c ! OUTPUT
+ DOUBLE PRECISION RV(MLON,NLAT)
+ INTEGER IER
+C NCLEND
+c ! LOCAL (dynamic/adjustable)
+ DOUBLE PRECISION CLAT(NLAT),DX(NLAT),DLON,DX2(NLAT),DLON2,
+ + DY2(NLAT),DYTOP,DYBOT,RE,RAD,RCON,
+ + POLAT,TLATRE(NLAT)
+ INTEGER ML,NL,MLSTRT,MLEND,MLM1,MLP1,JOPT
+
+c ! error chk stuff
+ IER = 0
+ IF (MLON.LT.1 .OR. NLAT.LT.1) THEN
+ IER = 1
+ RETURN
+ END IF
+ IF (ABS(GLAT(1)).gt.90.D0 .OR. ABS(GLAT(NLAT)).GT.90.D0) THEN
+ IER = 2
+ RETURN
+ END IF
+
+
+ RE = 6.37122D06
+ RAD = 4.D0*ATAN(1.D0)/180.D0
+ RCON = RE*RAD
+ JOPT = ABS(IOPT)
+c ! pre-compute cos(lat)
+ DO NL = 1,NLAT
+ CLAT(NL) = COS(RAD*GLAT(NL))
+ END DO
+c ! pre-compute tan(lat)/re
+c ! pole pts will not be used below
+ DO NL = 1,NLAT
+ IF (ABS(GLAT(NL)).LT.90.D0) THEN
+ TLATRE(NL) = TAN(RAD*GLAT(NL))/RE
+ ELSE
+ IF (GLAT(NL).EQ.90.D0) THEN
+ POLAT = 0.5*(GLAT(NL)+GLAT(NL-1))
+ TLATRE(NL) = TAN(RAD*POLAT)/RE
+ ELSE
+ POLAT = 0.5*(GLAT(NL)+GLAT(NL+1))
+ TLATRE(NL) = TAN(RAD*POLAT)/RE
+ END IF
+ END IF
+ END DO
+
+c ! initialize to msg
+ DO NL = 1,NLAT
+ DO ML = 1,MLON
+ RV(ML,NL) = XMSG
+ END DO
+ END DO
+c ! calculate "1/dy" [bot, top]
+ DYBOT = 1.D0/ (RCON* (GLAT(2)-GLAT(1)))
+ DYTOP = 1.D0/ (RCON* (GLAT(NLAT)-GLAT(NLAT-1)))
+c ! calculate "1/(2*dy)"
+ DO NL = 2,NLAT - 1
+ DY2(NL) = 1.D0/ (RCON* (GLAT(NL+1)-GLAT(NL-1)))
+ END DO
+c ! calculate "1/dx" [left, right]
+c ! and "1/(2*dx)
+ DLON = GLON(2) - GLON(1)
+ DLON2 = GLON(3) - GLON(1)
+
+ DO NL = 1,NLAT
+ IF (ABS(GLAT(NL)).NE.90.D0) THEN
+ DX(NL) = 1.D0/ (RCON*DLON*CLAT(NL))
+ DX2(NL) = 1.D0/ (RCON*DLON2*CLAT(NL))
+ ELSE
+ DX(NL) = 0.0D0
+ DX2(NL) = 0.0D0
+ END IF
+ END DO
+c ! set subscript range
+ IF (JOPT.EQ.1 .OR. JOPT.EQ.3) THEN
+ MLSTRT = 1
+ MLEND = MLON
+ ELSE
+ MLSTRT = 2
+ MLEND = MLON - 1
+ END IF
+c ! longitude loop
+ DO ML = MLSTRT,MLEND
+c ! iopt=0 or 1
+ MLM1 = ML - 1
+ MLP1 = ML + 1
+ IF (ML.EQ.1) MLM1 = MLON
+ IF (ML.EQ.MLON) MLP1 = 1
+c ! rv in grid body
+ DO NL = 2,NLAT - 1
+ IF (V(MLP1,NL).NE.XMSG .AND. V(MLM1,NL).NE.XMSG .AND.
+ + U(ML,NL+1).NE.XMSG .AND. U(ML,NL-1).NE.XMSG .AND.
+ + U(ML,NL) .NE.XMSG) THEN
+
+ RV(ML,NL) = (V(MLP1,NL)-V(MLM1,NL))*DX2(NL) -
+ + (U(ML,NL+1)-U(ML,NL-1))*DY2(NL) +
+ + U(ML,NL)*TLATRE(NL)
+
+ END IF
+ END DO
+
+ IF (JOPT.GE.2) THEN
+c ! bottom bound (nl=1)
+ IF (V(MLP1,1).NE.XMSG .AND. V(MLM1,1).NE.XMSG .AND.
+ + U(ML,2) .NE.XMSG .AND. U(ML,1) .NE.XMSG) THEN
+
+ RV(ML,1) = (V(MLP1,1)-V(MLM1,1))*DX2(1) -
+ + (U(ML,2)-U(ML,1))*DYBOT +
+ + U(ML,1)*TLATRE(1)
+ END IF
+c ! top bound (nl=nlat)
+ IF (V(MLP1,NLAT).NE.XMSG .AND. V(MLM1,NLAT).NE.XMSG .AND.
+ + U(ML,NLAT) .NE.XMSG .AND. U(ML,NLAT-1).NE.XMSG)THEN
+
+ RV(ML,NLAT) = (V(MLP1,NLAT)-V(MLM1,NLAT))*DX2(NLAT) -
+ + (U(ML,NLAT)-U(ML,NLAT-1))*DYTOP +
+ + U(ML,NLAT)*TLATRE(NLAT)
+ END IF
+ END IF
+ END DO
+c ! ?left/right bound?
+ IF (JOPT.EQ.2) THEN
+ DO NL = 2,NLAT - 1
+c ! left bound (ml=1)
+ IF (V(2,NL).NE.XMSG .AND. V(1,NL) .NE.XMSG .AND.
+ + U(1,NL+1).NE.XMSG .AND. U(1,NL-1).NE.XMSG .AND.
+ + U(1,NL) .NE.XMSG) THEN
+
+ RV(1,NL) = (V(2,NL)-V(1,NL))*DX(NL) -
+ + (U(1,NL+1)-U(1,NL-1))*DY2(NL) +
+ + U(1,NL)*TLATRE(NL)
+ END IF
+c ! right bound (ml=mlon)
+ IF (V(MLON,NL) .NE.XMSG .AND. V(MLON-1,NL).NE.XMSG .AND.
+ + U(MLON,NL+1).NE.XMSG .AND. U(MLON,NL-1).NE.XMSG .AND.
+ + U(MLON,NL) .NE.XMSG) THEN
+
+ RV(MLON,NL) = (V(MLON,NL)-V(MLON-1,NL))*DX(NL) -
+ + (U(MLON,NL+1)-U(MLON,NL-1))*DY2(NL) +
+ + U(MLON,NL)*TLATRE(NL)
+ END IF
+ END DO
+ END IF
+c ! special at +/-90 use average
+ DO NL = 1,NLAT,NLAT - 1
+ IF (ABS(GLAT(NL)).EQ.90.D0) CALL DUSEAVE(RV(1,NL),MLON,XMSG)
+ END DO
+c ! special for corners (jopt=2 only)
+c ! use linear extrapolation from
+c ! two directions
+ IF (JOPT.EQ.2) THEN
+ CALL DLNEXTRP(RV,MLON,NLAT,XMSG)
+ END IF
+
+ RETURN
+ END
+
+c NCLFORTSTART
+ SUBROUTINE DDVFIDF(U,V,GLAT,GLON,MLON,NLAT,XMSG,IOPT,DV,IER)
+ IMPLICIT NONE
+
+c divergence via centered finite differences
+c . div = dv/dy+du/dx-(v/re)*tan(lat) where "d" ==> partial derivitive
+c
+c reference: Bluestein p113-114
+c Halt-Martin p314
+
+c NCL: dv = uv2dv_cfd (u,v,lat,lon,cyclic)
+c xmsg = u at _FillValue
+c nlat,mlon = dimsizes (u)
+c iopt= cyclic
+
+c assumptions:
+c . (1) latitudes monotonically increasing [eg: glat(2) > glat(1)]
+c . latitudes may be unequally spaced
+c . (2) longitudes monotonically increasing [eg: glon(2) > glon(1)]
+c . longitudes are assmed to be equally spaced
+c . (3) if iopt=1 then the grids are cyclic in x
+c . eg: for T42 grid mlon=128, nlat=64
+c . cyclic point should NOT be included
+c .
+
+c ! INPUT
+ INTEGER MLON,NLAT
+ DOUBLE PRECISION U(MLON,NLAT),V(MLON,NLAT),GLAT(NLAT),GLON(MLON),
+ + XMSG
+ INTEGER IOPT
+
+c ! OUTPUT
+ DOUBLE PRECISION DV(MLON,NLAT)
+ INTEGER IER
+C NCLEND
+c ! LOCAL (dynamic/adjustable)
+ DOUBLE PRECISION CLAT(NLAT),DX(NLAT),DLON,DX2(NLAT),DLON2,
+ + DY2(NLAT),DYTOP,DYBOT,RE,RAD,RCON,
+ + POLAT,TLATRE(NLAT)
+ INTEGER ML,NL,MLSTRT,MLEND,MLM1,MLP1,JOPT
+
+c ! error chk stuff
+ IER = 0
+ IF (MLON.LT.1 .OR. NLAT.LT.1) THEN
+ IER = 1
+ RETURN
+ END IF
+ IF (ABS(GLAT(1)).gt.90.D0 .OR. ABS(GLAT(NLAT)).GT.90.D0) THEN
+ IER = 2
+ RETURN
+ END IF
+
+ RE = 6.37122D06
+ RAD = 4.D0*ATAN(1.D0)/180.D0
+ RCON = RE*RAD
+ JOPT = ABS(IOPT)
+c ! pre-compute cos(lat)
+ DO NL = 1,NLAT
+ CLAT(NL) = COS(RAD*GLAT(NL))
+ END DO
+c ! pre-compute tan(lat)/re
+c ! pole pts will not be used below
+ DO NL = 1,NLAT
+ IF (ABS(GLAT(NL)).LT.90.D0) THEN
+ TLATRE(NL) = TAN(RAD*GLAT(NL))/RE
+ ELSE
+ IF (GLAT(NL).EQ.90.D0) THEN
+ POLAT = 0.5*(GLAT(NL)+GLAT(NL-1))
+ TLATRE(NL) = TAN(RAD*POLAT)/RE
+ ELSE
+ POLAT = 0.5*(GLAT(NL)+GLAT(NL+1))
+ TLATRE(NL) = TAN(RAD*POLAT)/RE
+ END IF
+ END IF
+ END DO
+c ! initialize to msg
+ DO NL = 1,NLAT
+ DO ML = 1,MLON
+ DV(ML,NL) = XMSG
+ END DO
+ END DO
+c ! calculate "1/dy" [bot, top]
+ DYBOT = 1.D0/ (RCON* (GLAT(2)-GLAT(1)))
+ DYTOP = 1.D0/ (RCON* (GLAT(NLAT)-GLAT(NLAT-1)))
+c ! calculate "1/(2*dy)"
+ DO NL = 2,NLAT - 1
+ DY2(NL) = 1.D0/ (RCON* (GLAT(NL+1)-GLAT(NL-1)))
+ END DO
+c ! calculate "1/dx" [left, right]
+c ! and "1/(2*dx)
+ DLON = GLON(2) - GLON(1)
+ DLON2 = GLON(3) - GLON(1)
+
+ DO NL = 1,NLAT
+ IF (ABS(GLAT(NL)).NE.90.D0) THEN
+ DX(NL) = 1.D0/ (RCON*DLON*CLAT(NL))
+ DX2(NL) = 1.D0/ (RCON*DLON2*CLAT(NL))
+ ELSE
+ DX(NL) = 0.0D0
+ DX2(NL) = 0.0D0
+ END IF
+ END DO
+c ! set subscript range
+ IF (JOPT.EQ.1 .OR. JOPT.EQ.3) THEN
+ MLSTRT = 1
+ MLEND = MLON
+ ELSE
+ MLSTRT = 2
+ MLEND = MLON - 1
+ END IF
+
+ DO ML = MLSTRT,MLEND
+ MLM1 = ML - 1
+ MLP1 = ML + 1
+ IF (ML.EQ.1) MLM1 = MLON
+ IF (ML.EQ.MLON) MLP1 = 1
+c ! dv in grid body
+ DO NL = 2,NLAT - 1
+ IF (V(ML,NL+1).NE.XMSG .AND. V(ML,NL-1).NE.XMSG .AND.
+ + U(MLP1,NL).NE.XMSG .AND. U(MLM1,NL).NE.XMSG .AND.
+ + V(ML,NL) .NE.XMSG) THEN
+
+ DV(ML,NL) = (V(ML,NL+1)-V(ML,NL-1))*DY2(NL) +
+ + (U(MLP1,NL)-U(MLM1,NL))*DX2(NL) -
+ + V(ML,NL)*TLATRE(NL)
+ END IF
+ END DO
+c ! ?bottom/top bound?
+ IF (JOPT.GE.2) THEN
+c ! bottom bound (nl=1)
+ IF (V(ML,2) .NE.XMSG .AND. V(ML,1) .NE.XMSG .AND.
+ + U(MLP1,2).NE.XMSG .AND. U(MLM1,1).NE.XMSG) THEN
+
+ DV(ML,1) = (V(ML,2)-V(ML,1))*DYBOT +
+ + (U(MLP1,1)-U(MLM1,1))*DX2(1) -
+ + V(ML,1)*TLATRE(1)
+ END IF
+c ! top bound (nl=nlat)
+ IF (V(ML,NLAT).NE.XMSG .AND. V(ML,NLAT-1).NE.XMSG .AND.
+ + U(MLP1,NLAT).NE.XMSG .AND. U(MLM1,NLAT).NE.XMSG) THEN
+
+ DV(ML,NLAT) = (V(ML,NLAT)-V(ML,NLAT-1))*DYTOP +
+ + (U(MLP1,NLAT)-U(MLM1,NLAT))*DX2(NLAT)-
+ + V(ML,NLAT)*TLATRE(NLAT)
+ END IF
+ END IF
+ END DO
+c ! ?left/right bound?
+ IF (JOPT.EQ.2) THEN
+ DO NL = 2,NLAT - 1
+c ! left bound (ml=1)
+ IF (V(1,NL+1).NE.XMSG .AND. V(1,NL-1).NE.XMSG .AND.
+ + U(2,NL) .NE.XMSG .AND. U(1,NL) .NE.XMSG .AND.
+ + V(1,NL) .NE.XMSG) THEN
+
+ DV(1,NL) = (V(1,NL+1)-V(1,NL-1))*DY2(NL) +
+ + (U(2,NL)-U(1,NL))*DX(NL) -
+ + V(1,NL)*TLATRE(NL)
+ END IF
+c ! right bound (ml=mlon)
+ IF (V(MLON,NL+1).NE.XMSG .AND. V(MLON,NL-1).NE.XMSG .AND.
+ + U(MLON,NL) .NE.XMSG .AND. U(MLON-1,NL).NE.XMSG .AND.
+ + V(MLON,NL) .NE.XMSG) THEN
+
+ DV(MLON,NL) = (V(MLON,NL+1)-V(MLON,NL-1))*DY2(NL) +
+ + (U(MLON,NL)-U(MLON-1,NL))*DX(NL) -
+ + V(MLON,NL)*TLATRE(NL)
+ END IF
+ END DO
+ END IF
+c ! special at +/-90 use average
+ DO NL = 1,NLAT,NLAT - 1
+ IF (ABS(GLAT(NL)).EQ.90.D0) CALL DUSEAVE(DV(1,NL),MLON,XMSG)
+ END DO
+c ! special for corners (jopt=2 only)
+c ! use linear extrapolation from
+c ! two directions
+ IF (JOPT.EQ.2) THEN
+ CALL DLNEXTRP(DV,MLON,NLAT,XMSG)
+ END IF
+
+ RETURN
+ END
+
+ SUBROUTINE DLNEXTRP(X,MLON,NLAT,XMSG)
+ IMPLICIT NONE
+
+c linearly extrapolate from two directions [take average]
+c . for the corner pts
+
+ INTEGER MLON,NLAT
+ DOUBLE PRECISION X(MLON,NLAT),XMSG
+
+ INTEGER ML,NL
+
+ DO NL = 1,NLAT,NLAT - 1
+ DO ML = 1,MLON,MLON - 1
+ IF (X(ML,NL).EQ.XMSG) THEN
+ IF (NL.EQ.1 .AND. ML.EQ.1) THEN
+ IF (X(ML,NL+1).NE.XMSG .AND.
+ + X(ML,NL+2).NE.XMSG .AND.
+ + X(ML+1,NL).NE.XMSG .AND.
+ + X(ML+2,NL).NE.XMSG) THEN
+ X(ML,NL) = (2.D0*X(ML,NL+1)-X(ML,NL+2)+
+ + 2.D0*X(ML+1,NL)-X(ML+2,NL))*0.5D0
+ END IF
+ END IF
+ IF (NL.EQ.1 .AND. ML.EQ.MLON) THEN
+ IF (X(ML,NL+1).NE.XMSG .AND.
+ + X(ML,NL+2).NE.XMSG .AND.
+ + X(ML-1,NL).NE.XMSG .AND.
+ + X(ML-2,NL).NE.XMSG) THEN
+ X(ML,NL) = (2.D0*X(ML,NL+1)-X(ML,NL+2)+
+ + 2.D0*X(ML-1,NL)-X(ML-2,NL))*0.5D0
+ END IF
+ END IF
+ IF (NL.EQ.NLAT .AND. ML.EQ.1) THEN
+ IF (X(ML,NL-1).NE.XMSG .AND.
+ + X(ML,NL-2).NE.XMSG .AND.
+ + X(ML+1,NL).NE.XMSG .AND.
+ + X(ML+2,NL).NE.XMSG) THEN
+ X(ML,NL) = (2.D0*X(ML,NL-1)-X(ML,NL-2)+
+ + 2.D0*X(ML+1,NL)-X(ML+2,NL))*0.5D0
+ END IF
+ END IF
+ IF (NL.EQ.NLAT .AND. ML.EQ.MLON) THEN
+ IF (X(ML,NL-1).NE.XMSG .AND.
+ + X(ML,NL-2).NE.XMSG .AND.
+ + X(ML-1,NL).NE.XMSG .AND.
+ + X(ML-2,NL).NE.XMSG) THEN
+ X(ML,NL) = (2.D0*X(ML,NL-1)-X(ML,NL-2)+
+ + 2.D0*X(ML-1,NL)-X(ML-2,NL))*0.5D0
+ END IF
+ END IF
+ END IF
+ END DO
+ END DO
+
+ RETURN
+ END
+
+ SUBROUTINE DUSEAVE(X,MLON,XMSG)
+ IMPLICIT NONE
+c calculate average and use at all input grid points: +/- 90 only
+ INTEGER MLON
+ DOUBLE PRECISION X(MLON),XMSG
+c ! local
+ INTEGER ML
+ DOUBLE PRECISION AVE,CNT
+
+ AVE = 0.0D0
+ CNT = 0.0D0
+ DO ML = 1,MLON
+ IF (X(ML).NE.XMSG) THEN
+ AVE = AVE + X(ML)
+ CNT = CNT + 1.0D0
+ END IF
+ END DO
+
+ IF (CNT.NE.0.0D0) THEN
+ AVE = AVE/CNT
+ DO ML = 1,MLON
+ X(ML) = AVE
+ END DO
+ END IF
+
+ RETURN
+ END
diff --git a/src/libncl.h b/src/libncl.h
new file mode 100644
index 0000000..3db3876
--- /dev/null
+++ b/src/libncl.h
@@ -0,0 +1,26 @@
+#ifndef LIBNCL_H
+#define LIBNCL_H
+
+#include "cf_interface.h"
+/*
+void DCFINDIF(double *,double *,int *,double *,
+ double *,int *,int *, double *,
+ double *,int *,double *,int *);
+
+void DVRFIDF(double *, double *, double *, double *, int, int, double, int, double *, int *);
+void DDVFIDF(double *, double *, double *, double *, int, int, double, int, double *, int *);
+*/
+
+// LIBNCL Fortran routines
+
+#ifdef HAVE_CF_INTERFACE
+
+PROTOCCALLSFSUB10(DDVFIDF, ddvfidf, DOUBLEV, DOUBLEV, DOUBLEV, DOUBLEV, INT, INT, DOUBLE, INT, DOUBLEV, PINT)
+#define DDVFIDF(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) CCALLSFSUB10(DDVFIDF, ddvfidf, DOUBLEV, DOUBLEV, DOUBLEV, DOUBLEV, INT, INT, DOUBLE, INT, DOUBLEV, PINT, A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)
+
+PROTOCCALLSFSUB10(DVRFIDF, dvrfidf, DOUBLEV, DOUBLEV, DOUBLEV, DOUBLEV, INT, INT, DOUBLE, INT, DOUBLEV, PINT)
+#define DVRFIDF(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) CCALLSFSUB10(DVRFIDF, dvrfidf, DOUBLEV, DOUBLEV, DOUBLEV, DOUBLEV, INT, INT, DOUBLE, INT, DOUBLEV, PINT, A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)
+
+#endif
+
+#endif
diff --git a/src/modules.cc b/src/modules.cc
index 18ef3fc..ac79b86 100644
--- a/src/modules.cc
+++ b/src/modules.cc
@@ -15,7 +15,7 @@
GNU General Public License for more details.
*/
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -123,6 +123,7 @@ void *Merstat(void *argument);
void *Monarith(void *argument);
void *Mrotuv(void *argument);
void *Mrotuvb(void *argument);
+void *NCL_wind(void *argument);
void *Ninfo(void *argument);
void *Nmldump(void *argument);
void *Output(void *argument);
@@ -376,6 +377,7 @@ void *Samplegrid(void *argument); // "samplegrid", "subgrid"
#define MonarithOperators {"monadd", "monsub", "monmul", "mondiv"}
#define MrotuvOperators {"mrotuv"}
#define MrotuvbOperators {"mrotuvb"}
+#define NCL_windOperators {"uv2dv_cfd", "uv2vr_cfd"}
#define NinfoOperators {"nyear", "nmon", "ndate", "ntime", "ncode", "npar", "nlevel", "ngridpoints", "ngrids"}
#define NmldumpOperators {"nmldump", "kvldump"}
#define OutputOperators {"output", "outputint", "outputsrv", "outputext", "outputf", "outputts", \
@@ -893,6 +895,7 @@ void init_modules()
add_module("Monarith" , {Monarith , MonarithHelp , MonarithOperators , 1 , CDI_REAL , 2 , 1 });
add_module("Mrotuv" , {Mrotuv , {} , MrotuvOperators , 1 , CDI_REAL , 1 , 2 });
add_module("Mrotuvb" , {Mrotuvb , {} , MrotuvbOperators , 1 , CDI_REAL , 2 , 1 });
+ add_module("NCL_wind" , {NCL_wind , NCL_windHelp , NCL_windOperators , 1 , CDI_REAL , 1 , 1 });
add_module("Ninfo" , {Ninfo , NinfoHelp , NinfoOperators , 1 , CDI_BOTH , 1 , 0 });
add_module("Nmldump" , {Nmldump , {} , NmldumpOperators , 0 , CDI_REAL , 0 , 0 });
add_module("Output" , {Output , OutputHelp , OutputOperators , 1 , CDI_REAL , -1 , 0 });
diff --git a/src/nearpt3c.cc b/src/nearpt3c.cc
new file mode 100644
index 0000000..1e807e1
--- /dev/null
+++ b/src/nearpt3c.cc
@@ -0,0 +1,32 @@
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#if defined(ENABLE_NEARPT3)
+#include "nearpt3x.h"
+#endif
+
+#include "nearpt3c.h"
+
+void *nearpt3_preprocess(const int nfixpts, Coord_T **pts)
+{
+#if defined(ENABLE_NEARPT3)
+ return (void *) nearpt3::Preprocess(nfixpts, pts);
+#endif
+}
+
+
+int nearpt3_query(void *g, const Coord_T *q)
+{
+#if defined(ENABLE_NEARPT3)
+ return nearpt3::Query((nearpt3::Grid_T<Coord_T> *) g, q);
+#endif
+}
+
+
+void nearpt3_destroy(void *g)
+{
+#if defined(ENABLE_NEARPT3)
+ nearpt3::Destroy((nearpt3::Grid_T<Coord_T> *) g);
+#endif
+}
diff --git a/src/nearpt3c.h b/src/nearpt3c.h
index 867db6e..eafa20c 100644
--- a/src/nearpt3c.h
+++ b/src/nearpt3c.h
@@ -6,12 +6,6 @@ typedef float Coord_T;
#define NPT3SFACT 32000
#define NPT3SCALE(x) (0.5+(x+1)*NPT3SFACT)
-#if defined(__cplusplus)
-extern "C" {
-#endif
void *nearpt3_preprocess(const int nfixpts, Coord_T **pts);
int nearpt3_query(void *g, const Coord_T *q);
void nearpt3_destroy(void *g);
-#if defined(__cplusplus)
-}
-#endif
diff --git a/src/nearpt3x.h b/src/nearpt3x.h
new file mode 100644
index 0000000..f405636
--- /dev/null
+++ b/src/nearpt3x.h
@@ -0,0 +1,645 @@
+// Time-stamp: </wrf/c/nearpt3/nearpt3.cc, Mon, 5 Dec 2005, 23:00:33 EST, http://wrfranklin.org/>
+
+// Nearest point query in E3.
+
+// There are 2 user-callable subroutines:
+// preprocess: insert fixed points into a uniform grid.
+// query: find the closest fixed point to a query point.
+
+// W. Randolph Franklin
+// nearpt3 AT wrfranklin.org (Plaintext preferred; attachments deprecated)
+// http://www.ecse.rpi.edu/Homepages/wrf/
+
+// Uwe Schulzweida: replaced boost arrays by C arrays
+// replaced boost vector by C arrays
+// changed square and Distance2 to float
+
+
+#include <algorithm>
+//#include <boost/multi_array.hpp>
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+#include <math.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <limits.h>
+#include <float.h>
+
+#include "compare.h"
+
+
+using namespace std;
+//using boost::array;
+
+// Print an expression's name then its value, possibly followed by a comma or endl.
+// Ex: cout << PRINTC(x) << PRINTN(y);
+
+#define PRINT(arg) #arg "=" << (arg)
+#define PRINTC(arg) #arg "=" << (arg) << ", "
+#define PRINTN(arg) #arg "=" << (arg) << endl
+
+
+// clamp_USI Convert to an unsigned short int while clamping
+
+template <typename T>
+unsigned short int clamp_USI(T a) {
+ const unsigned short int m(USHRT_MAX);
+ const T mm(static_cast<T>(m));
+ return
+ static_cast<unsigned short int>(a > mm ? mm : (a > 0 ? static_cast<unsigned short int>(a) : 0));
+}
+
+
+namespace nearpt3 { // start of namespace nearpt3
+
+ double ng_factor = 1.6; // ng = ng_factor* cbrt(nfixpts)
+
+#ifdef STATS
+ static const int Cells_Checked_to_Closest_Point_Per_Query_Size(5000);
+#endif
+
+ float square(const float x) {
+ return x*x;
+ }
+
+ template <typename Coord_T>
+ float Distance2(const Coord_T a[3], const Coord_T b[3]) {
+ return (square((a[0]-b[0]))+square((a[1]-b[1]))+square((a[2]-b[2])));
+ }
+
+
+ // cellsearchorder:
+ // First 3 elements of each row: the order in which to search (one 48th-ant of the) cells adjacent to the current cell.
+ // 4th element: where, in cellsearchorder, to stop searching after the first point is found.
+ const static int cellsearchorder[][4] = {
+#include "cellsearchorder.h"
+ };
+ // Number of cells in cellsearchorder (before expanding symmetries).
+ const static int ncellsearchorder =
+ sizeof(nearpt3::cellsearchorder) / sizeof(nearpt3::cellsearchorder[0][0])/4;
+
+ typedef short int Cell3_Index_T; // Type of a cell index
+ class Cell3 { // Cell ID, expressed as a triple.of Cell3_Index_T.
+ public:
+ Cell3_Index_T c[3];
+
+ Cell3(const Cell3_Index_T x, const Cell3_Index_T y, const Cell3_Index_T z) {
+ c[0] = x; c[1] = y; c[2] = z; }
+
+ Cell3(const Cell3 &a) { c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; }
+
+ Cell3() { c[0] = -1; c[1] = -1; c[2] = -1; }
+
+ Cell3_Index_T & operator[] (const int i) { return c[i]; }
+
+ const Cell3_Index_T & operator[] (const int i) const { return c[i]; }
+
+ const Cell3 operator+(const Cell3 &d) const {
+ Cell3 r;
+ r[0] = c[0]+d[0];
+ r[1] = c[1]+d[1];
+ r[2] = c[2]+d[2];
+ return r;
+ }
+
+ const Cell3 operator*(const int *d) const {
+ Cell3 r;
+ r[0] = c[0]*d[0];
+ r[1] = c[1]*d[1];
+ r[2] = c[2]*d[2];
+ return r;
+ }
+
+ bool operator==(const Cell3 &d) const {
+ return c[0]==d[0] && c[1]==d[1] && c[2]==d[2];
+ }
+
+ // const Cell3 operator*(const int *) const;
+ };
+
+ // ostream& operator<<(ostream&, const Cell3& );
+
+
+
+
+ void write(ostream &o, const Cell3& c) {
+ o << '(' << c[0] << ',' << c[1] << ',' << c[2] << ") ";
+ }
+
+
+ // Grid_T is the main data structure to store the preprocessed points in a grid, plus auxiliary info.
+
+ template<typename Coord_T>
+ class Grid_T{
+ public: // start of Grid_T
+ int ng; // Number of grid cells on a side
+ int ng3; // ng*ng*ng
+ double r_cell; // cellindex = coord*r_cell+d_cell;
+ double d_cell[3];
+ int nfixpts; // number of fixed points.
+ // const array<Coord_T,3> * pts; // pointer to user-supplied points.
+ Coord_T **pts; // pointer to user-supplied points.
+ int *cells; // The indices (in pts) of the points in each cell, for all the cells.
+ int *base; // Dope vector pointing to the start of each cell, in cells. The i-th point of
+ // the j-th cell is cells[base[j]+i]. Also, initially this is used to count the number of points per cell.
+
+#ifdef STATS
+ int Max_Cells_Checked_to_1st_Point_Per_Query;
+ float Average_Cells_Checked_to_1st_Point_Per_Query;
+ int Tot_Cells_Checked_to_1st_Point_Per_Query;
+ int *Cells_Checked_to_1st_Point_Per_Query;
+ int *Cells_Checked_to_Closest_Point_Per_Query;
+ int *Points_Checked_Per_Query;
+#endif
+
+ // check and clip cannot be members of Cell3 since they need access to ng.
+
+ // Check if this is a legal cell.
+ bool check(const Cell3 a) const;
+
+ // clip is needed because roundoff errors may cause a number to be slightly outside the legal range.
+ void clip(Cell3 &a);
+
+ template<typename T>
+ void Check_Range(const string msg, const int i, const T x, const T lo, const T hi);
+
+ void Check_Range(const string msg, const int i, const Cell3 x);
+
+ // cellid_to_int: Convert Cell ID from 3 short ints to one int. The following static_casts are
+ // to prevent an overflow during the multiplication in case ng is short int. If the arg is out
+ // of range, as might happen for a query, then return -1.
+
+ int cellid_to_int(const Cell3 a) const;
+
+
+ // Compute_Cell_Containing_Point: Return the cell number containing point p. Note the p is a
+ // array<Coord_T, 3>, not an id of a point. This is necessary since
+ // Compute_Cell_Containing_Point is used for both fixed and query points.
+
+ const Cell3 Compute_Cell_Containing_Point(const Coord_T p[3]);
+
+ // N_Points_in_This_Cell: Return the number of fixed points in cell ic. If the arg is out of
+ // range, as will happen for a really distant query, then return 0.
+
+ int N_Points_in_This_Cell(const int ic);
+
+ // querythiscell: Query cell thiscell with query point querypt. Return closestpt, the index of
+ // the closest fixed point in the cell, and dist2, the square of the distance. Return -1 if
+ // there are no points in this cell.
+
+ void querythiscell(const Cell3 thiscell, const Coord_T querypt[3],
+ int &closestpt, double &dist2);
+
+ // Query_Fast_Case: Return the id of the closest fixed point to query point iq, for the fast case
+ // of the query point cell containing at least one fixed point.
+
+ // If that cell has no fixed point, then return -1.
+
+ int Query_Fast_Case(const Coord_T q[3], const Cell3 querycell);
+
+ }; // End of Grid_T
+
+
+#ifdef STATS
+ int N_Cells_Checked_to_1st_Point_This_Query;
+ int N_Points_Checked_This_Query;
+#endif
+ int N_Cells_Checked_to_Closest_Point_This_Query;
+
+ // Check if this is a legal cell.
+ template<typename Coord_T> bool nearpt3::Grid_T<Coord_T>::check(const Cell3 a) const {
+ if (a[0] < 0 || a[0] >= ng ) return false;
+ if (a[1] < 0 || a[1] >= ng ) return false;
+ if (a[2] < 0 || a[2] >= ng ) return false;
+ return true;
+ }
+
+ // clip is needed because roundoff errors may cause a number to be slightly outside the legal range.
+ template<typename Coord_T> void nearpt3::Grid_T<Coord_T>:: clip(Cell3 &a) {
+
+ // a[0] = min(ng-1, max(0, a[0]));
+
+ if (a[0] < 0) a[0] = 0;
+ if (a[0] >= ng) a[0] = ng-1;
+ if (a[1] < 0) a[1] = 0;
+ if (a[1] >= ng) a[1] = ng-1;
+ if (a[2] < 0) a[2] = 0;
+ if (a[2] >= ng) a[2] = ng-1;
+ }
+
+ template<typename T>
+ void Check_Range(const string msg, const int i, const T x, const T lo, const T hi) {
+ if (x<lo || x>hi) {
+ cout << "ERROR, number out of range: " << msg << ' ' << PRINTC(i) << PRINTC(x) << PRINTC(lo) << PRINTN(hi);
+ throw "Number out of range";
+ }
+ }
+
+ template<typename Coord_T> void nearpt3::Grid_T<Coord_T> ::
+ Check_Range(const string msg, const int i, const Cell3 x) {
+ if (!check(x)) {
+ cout << "ERROR, cell3 out of the range [0,ng): " << msg << ' ' << PRINTC(i) << PRINTC(x[0]) << PRINTC(x[1]) << PRINTC(x[2]) << PRINTN(ng);
+ throw "Cell3 out of range";
+ }
+ }
+
+
+ // cellid_to_int: Convert Cell ID from 3 short ints to one int. The following static_casts are
+ // to prevent an overflow during the multiplication in case ng is short int. If the arg is out
+ // of range, as might happen for a query, then return -1.
+
+ template<typename Coord_T> int nearpt3::Grid_T<Coord_T>::
+ cellid_to_int(const Cell3 a) const {
+ if (a[0]<0 || a[0] >=ng || a[1]<0 || a[1] >=ng || a[2]<0 || a[2] >=ng) return -1;
+ return (static_cast<int> (a[0])*ng + static_cast<int>(a[1]))*ng + a[2];
+ }
+
+
+
+ // Compute_Cell_Containing_Point: Return the cell number containing point p. Note the p is a
+ // array<Coord_T, 3>, not an id of a point. This is necessary since
+ // Compute_Cell_Containing_Point is used for both fixed and query points.
+
+ template<typename Coord_T> const nearpt3::Cell3 nearpt3::Grid_T<Coord_T>::
+ Compute_Cell_Containing_Point(const Coord_T p[3]) {
+ const short int ix = static_cast<short int>(static_cast<double>(p[0])*r_cell+d_cell[0]); // This must truncate not round.
+ const short int iy = static_cast<short int>(static_cast<double>(p[1])*r_cell+d_cell[1]);
+ const short int iz = static_cast<short int>(static_cast<double>(p[2])*r_cell+d_cell[2]);
+ Cell3 c(ix, iy, iz);
+ return c;
+ }
+
+ // N_Points_in_This_Cell: Return the number of fixed points in cell ic. If the arg is out of
+ // range, as will happen for a really distant query, then return 0.
+
+ template<typename Coord_T> int nearpt3::Grid_T<Coord_T> ::
+ N_Points_in_This_Cell(const int ic) {
+ if (ic<0) return 0;
+ return base[ic+1] - base[ic];
+ }
+
+
+ // querythiscell: Query cell thiscell with query point querypt. Return closestpt, the index of
+ // the closest fixed point in the cell, and dist2, the square of the distance. Return -1 if
+ // there are no points in this cell.
+
+ template<typename Coord_T> void nearpt3::Grid_T<Coord_T> ::
+ querythiscell(const Cell3 thiscell, const Coord_T querypt[3],
+ int &closestpt, double &dist2) {
+ closestpt = -1;
+ dist2 = FLT_MAX;
+ int ic = cellid_to_int(thiscell);
+ const int ppc = N_Points_in_This_Cell(ic);
+ for (int i=0; i<ppc; i++) {
+ const int ip = base[ic]+i;
+ const double d2 = (double) Distance2(pts[cells[ip]], querypt);
+ if (d2 < dist2 || (d2<=dist2 && cells[ip]<closestpt)) {
+ dist2 = d2;
+ closestpt = cells[ip];
+ }
+ }
+ return;
+ }
+
+
+
+ // Query_Fast_Case: Return the index of the closest fixed point to query point iq, for the fast case
+ // of the query point cell containing at least one fixed point.
+
+ // If that cell has no fixed point, then return -1.
+
+ template<typename Coord_T> int nearpt3::Grid_T<Coord_T> ::
+ Query_Fast_Case(const Coord_T q[3], const Cell3 querycell)
+ { // Query_Fast_Case
+ const int queryint(cellid_to_int(querycell));
+ const int npitc(N_Points_in_This_Cell(queryint));
+ if (npitc<=0) return -1; // Are there any points in this cell?
+ // Find the closest point in this cell.
+ int closestpt = -1;
+ double dist2 = FLT_MAX;
+ for (int i=base[queryint]; i<base[queryint+1]; i++) {
+ const double d2 = (double) Distance2(pts[cells[i]], q);
+ if (d2 < dist2 || (d2<=dist2 && cells[i]<closestpt)) {
+ dist2 = d2;
+ closestpt = cells[i];
+ }
+ }
+
+ const double distf = sqrt(dist2) * 1.00001; // fudge factor for roundoff error
+
+ // cerr /* << PRINTC(q) */ << PRINTC(querycell[0])<< PRINTC(querycell[1])<< PRINTC(querycell[2]) << PRINTN(dist2);
+
+ Coord_T lopt[3], hipt[3];
+ for (int i=0; i<3; i++) {
+ lopt[i] = static_cast<unsigned short int> (clamp_USI(static_cast<double>(q[i]) - distf));
+ hipt[i] = static_cast<unsigned short int> (clamp_USI(static_cast<double>(q[i]) + distf + 1.0));
+ }
+
+ // cerr << PRINTC(lopt) << PRINTN(hipt);
+ Cell3 locell(Compute_Cell_Containing_Point(lopt));
+ Cell3 hicell(Compute_Cell_Containing_Point(hipt));
+
+ clip(locell); // If the block of cells around the query goes outside the universe,...
+ clip(hicell); // then clip it.
+
+ // cerr << PRINTC(locell[0]) << PRINTC(locell[1]) << PRINTC(locell[2]) << PRINTC(hicell[0])<< PRINTC(hicell[2])<< PRINTC(hicell[2]);
+
+#ifdef STATS
+ N_Cells_Checked_to_1st_Point_This_Query = 1;
+ N_Cells_Checked_to_Closest_Point_This_Query =
+ (hicell[0]-locell[0]+1)*(hicell[1]-locell[1]+1)*(hicell[2]-locell[2]+1);
+#endif
+
+ if (locell == querycell && hicell == querycell) return closestpt;
+
+ for (Coord_T x=locell[0]; x<=hicell[0]; x++)
+ for (Coord_T y=locell[1]; y<=hicell[1]; y++) {
+ // Do a whole z-row of cells at once.
+ const int i01 = (static_cast<int>(x)*ng + static_cast<int>(y))*ng;
+ const int i0 = i01 + locell[2];
+ const int i1 = i01 + hicell[2];
+ const int hibase=base[i1+1];
+ for (int i=base[i0]; i<hibase; i++) {
+ const double d2 = (double) Distance2(pts[cells[i]], q);
+ if (d2 < dist2 || (IS_EQUAL(d2,dist2) && cells[i]<closestpt)) {
+ dist2 = d2;
+ closestpt = cells[i];
+ }
+ }
+ }
+ if (closestpt<0) throw "closestpt<0 at end of Query_Fast_Case but this cell has a point";
+ return closestpt;
+ } // Query_Fast_Case
+
+
+
+ // PREPROCESS
+
+ template<typename Coord_T> Grid_T<Coord_T> *
+ // Preprocess(const int nfixpts, const array<Coord_T, 3> pts[]) { // preprocess
+ Preprocess(const int nfixpts, Coord_T **pts) { // preprocess
+ Grid_T<Coord_T> *g;
+ g = new Grid_T<Coord_T>;
+ g->nfixpts = nfixpts;
+ int &ng = g->ng;
+ ng = static_cast<int> (ng_factor * cbrt(static_cast<double>(nfixpts)));
+
+ ng = min(2000, max(1, ng));
+ g->ng3 = ng * ng * ng;
+ g->pts = pts;
+
+
+ // The following check might catch a scrambled cellsearchorder file.
+ for (int i=1; i< ncellsearchorder; i++)
+ if (nearpt3::cellsearchorder[i-1][3] > nearpt3::cellsearchorder[i][3])
+ throw "cellsearchorder is not monotonic";
+
+ double lo[3];
+ double hi[3];
+ for(int i=0;i<3;i++) {
+ lo[i] = DBL_MAX;
+ hi[i] = -1.e300;
+ }
+ for (int n=0; n<nfixpts; n++) {
+ for(int i=0;i<3;i++) {
+ lo[i] = min(lo[i], static_cast<double>(pts[n][i]));
+ hi[i] = max(hi[i], static_cast<double>(pts[n][i]));
+ }
+ }
+ double s[3];
+ for(int i=0; i<3; i++) {
+ s[i] = 0.99 * ng / (hi[i]-lo[i]); // allow for a little future roundoff error.
+ }
+ g->r_cell = min(min(s[0], s[1]), s[2]);
+
+ for(int i=0; i<3; i++) {
+ g->d_cell[i] = ((ng-1)-(lo[i]+hi[i])*g->r_cell) * 0.5;
+ }
+
+
+ // Initially use base to count the number of points per cell.
+ g->base = 0;
+ g->base = new int[g->ng3+1];
+ for (int ic=0; ic < g->ng3; ic++) g->base[ic] = 0;
+
+ for (int ip=0; ip<nfixpts; ip++) { // Count number of points in each cell.
+ const nearpt3::Cell3 c(g->Compute_Cell_Containing_Point(pts[ip]));
+ g->Check_Range("Cell in pointspercell++", ip, c);
+ const int k = g->cellid_to_int(c);
+#ifdef DEBUG
+ cout << PRINTC(ip) << PRINTC(pts[ip]) << PRINTN(c.c);
+#endif
+ if (k<0) throw "illegal k in Preprocess";
+ g->base[k]++;
+ if (g->base[k] > 1000000) { // Catch an error
+ throw "base entry unreasonably large";
+ }
+ }
+
+ // Now change base[i] from storing the number of points in cell #i to storing the number of
+ // points before cell #i.
+
+#ifdef STATS
+ const float Average_Points_Per_Cell
+ (static_cast<float>(nfixpts)/static_cast<float>(g->ng3));
+ int Max_Points_Per_Cell(0);
+ const int Points_Per_Cell_Size(500);
+ int Points_Per_Cell[Points_Per_Cell_Size];
+ for ( int i = 0; i < 500; ++i ) Points_Per_Cell[i] = 0;
+#endif
+
+ int k = g->base[0];
+ g->base[0] = 0;
+ for (int ic=1; ic< g->ng3; ic++) {
+ int ppc = g->base[ic];
+#ifdef STATS
+ Max_Points_Per_Cell = max(Max_Points_Per_Cell, ppc);
+ Points_Per_Cell[min(ppc,Points_Per_Cell_Size-1)]++;
+#endif
+ g->base[ic] = g->base[ic-1] + k;
+ k = ppc;
+ }
+ g->base[g->ng3] = g->base[g->ng3-1]+k;
+ if (g->base[g->ng3] != nfixpts) {
+ cout << "ERROR: Internal inconsistency; wrong " << PRINTN(g->base[g->ng3]);
+ throw "Internal inconsistency";
+ }
+
+ g->cells = 0;
+ g->cells = new int[nfixpts];
+
+ // Set the last point of each cell to count how many points have been inserted into that cell so far.
+ for (int i=1; i<= g->ng3; i++)
+ if ( (g->base)[i]-1 >= 0 ) // Uwe Schulzweida: check bounds
+ (g->cells)[(g->base)[i]-1] = 0;
+
+ // Insert the points into the grid.
+
+ for (int ip=0; ip<nfixpts; ip++) {
+ const int ic(g->cellid_to_int(g->Compute_Cell_Containing_Point(pts[ip])));
+ const int Points_In_This_Cell = g->cells[g->base[ic+1]-1]++;
+ g->cells[g->base[ic]+Points_In_This_Cell] = ip;
+ }
+
+#ifdef STATS
+ cout << PRINTC(nfixpts) << PRINTC(ng) << PRINTC(Average_Points_Per_Cell)
+ << PRINTN(Max_Points_Per_Cell);
+ cout << "Histogram of the number of cells containing K points, 0<=K<" << Points_Per_Cell_Size << ":\n";
+ for(int i=0; i< Points_Per_Cell_Size; i++) {
+ if (Points_Per_Cell[i]>0) cout << i << ": " << Points_Per_Cell[i] << endl;
+ }
+ g->Cells_Checked_to_Closest_Point_Per_Query = new int[Cells_Checked_to_Closest_Point_Per_Query_Size];
+ g->Cells_Checked_to_1st_Point_Per_Query = new int[Cells_Checked_to_Closest_Point_Per_Query_Size];
+ g->Points_Checked_Per_Query = new int[Cells_Checked_to_Closest_Point_Per_Query_Size];
+#endif
+
+#ifdef DEBUG
+ cout << PRINTN(ng);
+ cout << "base: ";
+ for (int i=0; i<= g->ng3; i++) cout << i << ':' << g->base[i] << ' ';
+ cout << endl << "cells: ";
+ for (int i=0; i<nfixpts; i++) cout << i << ':' << g->cells[i] << ' ';
+ cout << endl;
+#endif
+
+ return g;
+
+ } // preprocess
+
+
+ template <typename Coord_T>
+ void Destroy( Grid_T<Coord_T> *g ) { // Destroy
+ delete(g->cells);
+ delete(g->base);
+ delete(g);
+ }
+
+ // QUERY: Return the id of the closest fixed point to query point iq.
+
+ template <typename Coord_T>
+ int Query( Grid_T<Coord_T> *g, const Coord_T q[3]) { // Query
+
+#ifdef STATS
+ N_Points_Checked_This_Query = 0;
+#endif
+
+ nearpt3::Cell3 querycell(g->Compute_Cell_Containing_Point(q));
+
+ // Usually the cell containing the query point has a fixed point. This is faster to handle.
+
+ int closestpt(g->Query_Fast_Case(q, querycell));
+ if (closestpt>=0) {
+#ifdef STATS
+ g->Cells_Checked_to_Closest_Point_Per_Query[min(Cells_Checked_to_Closest_Point_Per_Query_Size-1, N_Cells_Checked_to_Closest_Point_This_Query)]++;
+#endif
+ return closestpt;
+ }
+
+ double dist(DBL_MAX);
+ bool foundit(false); // Did we find a fixed point yet?
+ int nstop(ncellsearchorder);
+ N_Cells_Checked_to_Closest_Point_This_Query = 0;
+#ifdef STATS
+ N_Cells_Checked_to_1st_Point_This_Query = 0;
+#endif
+
+ // Query cells in the order given in cellsearchorder until we find a cell with a point. Then
+ // keep querying out a little farther in case there is a closer point in another cell.
+
+ // nstop will be changed inside the loop.
+
+ for (int isort=0; isort<nstop; isort++) { // isort loop
+ int thisclosest;
+ double thisdist;
+ Cell3 s (cellsearchorder[isort][0], cellsearchorder[isort][1],
+ cellsearchorder[isort][2]);
+
+ // Derive the 47 other reflected cells from a particular cell being // searched. That is, from
+ // cell (1,2,3), generate (1,3,2), (1,3,-2), etc
+
+ for (int isign=0; isign<8; isign++) { // Iterate over all combinations of signs;
+ static const int sign3[8][3] = {{1,1,1},{1,1,-1},{1,-1,1},{1,-1,-1},{-1,1,1},
+ {-1,1,-1},{-1,-1,1},{-1,-1,-1}};
+ if (s[0]==0 && sign3[isign][0]== -1) continue;
+ if (s[1]==0 && sign3[isign][1]== -1) continue;
+ if (s[2]==0 && sign3[isign][2]== -1) continue;
+
+ const Cell3 s2(s*sign3[isign]);
+
+ for (int iperm=0; iperm<6; iperm++) { // Iterate over all permutations of coordinates.
+ switch (iperm) {
+ case 1:
+ if (s[1]==s[2]) continue;
+ break;
+ case 2:
+ if (s[0]==s[1]) continue;
+ break;
+ case 3:
+ case 4:
+ if (s[0]==s[1] && s[0]==s[2]) continue;
+ break;
+ case 5:
+ if (s[0]==s[2]) continue;
+ break;
+ }
+ static const int perm3[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};
+ const Cell3 s3(s2[perm3[iperm][0]], s2[perm3[iperm][1]], s2[perm3[iperm][2]]);
+ const Cell3 c2(querycell+s3);
+ if (!g->check(c2)) continue; // outside the universe?
+ N_Cells_Checked_to_Closest_Point_This_Query++;
+ g->querythiscell(c2, q, thisclosest, thisdist);
+ if (thisclosest < 0) continue;
+
+ // If two fixed points are the same distance from the query, then return the one with the
+ // smallest index. This removes ambiguities, but complicates the code in several places.
+
+ if (thisdist<dist || (IS_EQUAL(thisdist,dist) && thisclosest<closestpt)) {
+ dist = thisdist;
+ closestpt = thisclosest;
+ if (!foundit) {
+ foundit = true;
+ nstop = cellsearchorder[isort][3];
+ if (nstop >= ncellsearchorder) {
+ // It took so long to find any cell with a point that cellsearchorder doesn't have
+ // enough cells to be sure of finding the closest point. Fall back to naive
+ // exhaustive searching.
+ goto L_end_isort;
+ }
+ }
+ }
+ }
+ }
+ }
+ L_end_isort: if (closestpt>=0) {
+#ifdef STATS
+ g->Cells_Checked_to_Closest_Point_Per_Query[min(Cells_Checked_to_Closest_Point_Per_Query_Size-1, N_Cells_Checked_to_Closest_Point_This_Query)]++;
+#endif
+ return closestpt;
+ }
+ // No nearby points, so exhaustively search over all the fixed points.
+ for (int i=0; i< g->nfixpts; i++) {
+ double d = (double) Distance2(q, g->pts[i]);
+ if (d< dist || (IS_EQUAL(d,dist) && i < closestpt)) {
+ dist = d;
+ closestpt = i;
+ }
+ }
+ return closestpt;
+ }
+
+} // end of namespace nearpt3
+
+
+/*
+template<typename Coord_T>
+ostream &operator<<(ostream &o, const array<Coord_T,3> &c) {
+ o << '(' << c[0] << ',' << c[1] << ',' << c[2] << ')';
+ return o;
+}
+*/
diff --git a/src/operator_help.h b/src/operator_help.h
index c519612..b549df1 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -1502,6 +1502,7 @@ std::vector<std::string> ExprHelp = {
" abs(x) " " Absolute value of x",
" floor(x)" " Round to largest integral value not greater than x",
" ceil(x) " " Round to smallest integral value not less than x",
+ " float(x)" " 32-bit float value of x",
" int(x) " " Integer value of x",
" nint(x) " " Nearest integer value of x",
" sqr(x) " " Square of x",
@@ -5146,12 +5147,39 @@ std::vector<std::string> CMORliteHelp = {
" convert STRING Converts the units if necessary",
};
+std::vector<std::string> NCL_windHelp = {
+ "NAME",
+ " uv2vr_cfd, uv2dv_cfd - Wind transformation",
+ "",
+ "SYNOPSIS",
+ " <operator>[,u,v,boundOpt,outMode] infile outfile",
+ "",
+ "DESCRIPTION",
+ " This module contains CDO operators with an interface to NCL functions.",
+ " The corresponding NCL functions have the same name. A more detailed description",
+ " of those NCL function can be found on the NCL homepage https://www.ncl.ucar.edu.",
+ "",
+ "OPERATORS",
+ " uv2vr_cfd U and V wind to relative vorticity",
+ " Computes relative vorticity for a latitude-longitude grid using centered finite differences.",
+ " The grid need not be global and missing values are allowed.",
+ " uv2dv_cfd U and V wind to divergence",
+ " Computes divergence for a latitude-longitude grid using centered finite differences.",
+ " The grid need not be global and missing values are allowed.",
+ "",
+ "PARAMETER",
+ " u STRING Name of variable u (default: u)",
+ " v STRING Name of variable v (default: v)",
+ " boundOpt INTEGER Boundary condition option (0-3) (default: 0/1 for cyclic grids)",
+ " outMode STRING Output mode new/append (default: new)",
+};
+
std::vector<std::string> CMORHelp = {
"NAME",
" cmor - Climate Model Output Rewriting to produce CMIP-compliant data",
"",
"SYNOPSIS",
- " cmor,MIPtable[,cmor_name=VarList,[key=value,...]] infile",
+ " cmor,MIPtable[,cmor_name=VarList[,key=value[,...]]] infile",
"",
"DESCRIPTION",
" ",
diff --git a/src/par_io.cc b/src/par_io.cc
index 0e68a76..0dbf971 100644
--- a/src/par_io.cc
+++ b/src/par_io.cc
@@ -17,7 +17,8 @@
void *readRecord(void *arg)
{
int streamID;
- int *varID, *levelID, *nmiss;
+ int *varID, *levelID;
+ size_t *nmiss;
double *array;
read_arg_t *read_arg = (read_arg_t *) arg;
@@ -36,7 +37,7 @@ void *readRecord(void *arg)
}
-void parReadRecord(int streamID, int *varID, int *levelID, double *array, int *nmiss, par_io_t *parIO)
+void parReadRecord(int streamID, int *varID, int *levelID, double *array, size_t *nmiss, par_io_t *parIO)
{
int lpario = FALSE;
int recID = 0, nrecs = 0;
diff --git a/src/par_io.h b/src/par_io.h
index 3b59c5a..a3c20e4 100644
--- a/src/par_io.h
+++ b/src/par_io.h
@@ -1,5 +1,5 @@
-#ifndef _PAR_IO_H
-#define _PAR_IO_H
+#ifndef PAR_IO_H
+#define PAR_IO_H
#if defined(HAVE_CONFIG_H)
# include "config.h"
@@ -12,14 +12,16 @@
typedef struct {
int streamID;
- int *varID, *levelID, *nmiss;
+ int *varID, *levelID;
+ size_t *nmiss;
double *array;
}
read_arg_t;
typedef struct {
- int varID, levelID, nmiss;
+ int varID, levelID;
+ size_t nmiss;
double *array;
int array_size;
int recID, nrecs;
@@ -32,6 +34,6 @@ typedef struct {
par_io_t;
-void parReadRecord(int streamID, int *varID, int *levelID, double *array, int *nmiss, par_io_t *parIO);
+void parReadRecord(int streamID, int *varID, int *levelID, double *array, size_t *nmiss, par_io_t *parIO);
-#endif /* _PAR_IO_H */
+#endif /* PAR_IO_H */
diff --git a/src/pipe.cc b/src/pipe.cc
index b0797e8..bc4d094 100644
--- a/src/pipe.cc
+++ b/src/pipe.cc
@@ -402,12 +402,12 @@ pipe_t::pipeDefRecord(int p_varID, int p_levelID)
* @param pipe pipe that has the wanted data
*/
void
-pipe_t::pipeReadPipeRecord(double *p_data, int vlistID, int *p_nmiss)
+pipe_t::pipeReadPipeRecord(double *p_data, int vlistID, size_t *p_nmiss)
{
if (!p_data)
Error("No data pointer for %s", name.c_str());
- int datasize = gridInqSize(vlistInqVarGrid(vlistID, varID));
+ size_t datasize = gridInqSize(vlistInqVarGrid(vlistID, varID));
nvals += datasize;
if (vlistNumber(vlistID) != CDI_REAL)
datasize *= 2;
@@ -443,7 +443,7 @@ pipeGetReadTarget(pstream_t *pstreamptr, pstream_t *pstreamptr_in)
}
*/
void
-pipe_t::pipeReadRecord(int p_vlistID, double *data, int *nmiss)
+pipe_t::pipeReadRecord(int p_vlistID, double *data, size_t *nmiss)
{
*nmiss = 0;
@@ -477,7 +477,7 @@ pipe_t::pipeReadRecord(int p_vlistID, double *data, int *nmiss)
}
void
-pipe_t::pipeWriteRecord(double *p_data, int p_nmiss)
+pipe_t::pipeWriteRecord(double *p_data, size_t p_nmiss)
{
/*
if ( ! usedata ) return;
diff --git a/src/pipe.h b/src/pipe.h
index 4ace564..d208acb 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -53,9 +53,9 @@ public:
int pipeInqTimestep(int p_tsID);
int pipeInqRecord(int *varID, int *levelID);
- void pipeWriteRecord(double *p_data, int p_nmiss);
- void pipeReadRecord(int p_vlistID, double *data, int *nmiss);
- void pipeReadPipeRecord(double *data, int vlistID, int *p_nmiss);
+ void pipeWriteRecord(double *p_data, size_t p_nmiss);
+ void pipeReadRecord(int p_vlistID, double *data, size_t *nmiss);
+ void pipeReadPipeRecord(double *data, int vlistID, size_t *p_nmiss);
bool EOP;
bool usedata;
@@ -63,10 +63,10 @@ public:
int nrecs;
int varID, levelID;
int recIDr, recIDw, tsIDr, tsIDw;
- int nmiss;
+ size_t nmiss;
double *data;
// pstream_t *pstreamptr_in;
- /* unsigned long */ off_t nvals;
+ size_t nvals;
std::mutex m_mutex;
std::condition_variable tsDef, tsInq, vlistDef, isclosed;
diff --git a/src/printinfo.h b/src/printinfo.h
index 052055b..c916acf 100644
--- a/src/printinfo.h
+++ b/src/printinfo.h
@@ -125,7 +125,7 @@ void printFiletype(int streamID, int vlistID)
static
void print_xvals(int gridID, int dig)
{
- int xsize = gridInqXsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
if ( xsize > 0 && gridInqXvals(gridID, NULL) )
{
char xname[CDI_MAX_NAME], xunits[CDI_MAX_NAME];
@@ -151,7 +151,7 @@ void print_xvals(int gridID, int dig)
static
void print_yvals(int gridID, int dig)
{
- int ysize = gridInqYsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
if ( ysize > 0 && gridInqYvals(gridID, NULL) )
{
char yname[CDI_MAX_NAME], yunits[CDI_MAX_NAME];
@@ -209,23 +209,23 @@ void print_xyvals2D(int gridID, int dig)
int gridtype = gridInqType(gridID);
if ( gridtype == GRID_CURVILINEAR )
{
- int xsize = gridInqXsize(gridID);
+ size_t xsize = gridInqXsize(gridID);
if ( xsize > 1 )
{
double *xvals = (double*) malloc((size_t)xsize*sizeof(double));
- for ( int i = 0; i < xsize; ++i ) xvals[i] = xvals2D[i];
+ for ( size_t i = 0; i < xsize; ++i ) xvals[i] = xvals2D[i];
xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
- for ( int i = 2; i < xsize; i++ )
+ for ( size_t i = 2; i < xsize; i++ )
if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc ) { xinc = 0; break; }
free(xvals);
}
- int ysize = gridInqYsize(gridID);
+ size_t ysize = gridInqYsize(gridID);
if ( ysize > 1 )
{
double *yvals = (double*) malloc((size_t)ysize*sizeof(double));
- for ( int i = 0; i < ysize; ++i ) yvals[i] = yvals2D[i*xsize];
+ for ( size_t i = 0; i < ysize; ++i ) yvals[i] = yvals2D[i*xsize];
yinc = fabs(yvals[ysize-1] - yvals[0])/(ysize-1);
- for ( int i = 2; i < ysize; i++ )
+ for ( size_t i = 2; i < ysize; i++ )
if ( fabs(fabs(yvals[i-1] - yvals[i]) - yinc) > 0.01*yinc ) { yinc = 0; break; }
free(yvals);
}
diff --git a/src/process.cc b/src/process.cc
index 21f9a10..307994f 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -43,6 +43,7 @@
#include "pthread.h"
#include <map>
+#include <stack>
#if defined(HAVE_LIBPTHREAD)
pthread_mutex_t processMutex = PTHREAD_MUTEX_INITIALIZER;
@@ -50,12 +51,44 @@ pthread_mutex_t processMutex = PTHREAD_MUTEX_INITIALIZER;
constexpr bool PROCESS_DEBUG = false;
+static process_t *root_process;
static std::map<int, process_t> Process;
static int NumProcess = 0;
static int NumProcessActive = 0;
-process_t::process_t(int p_ID) : m_ID(p_ID) { initProcess(); }
+process_t::process_t(int p_ID, char *operatorCommand) : m_ID(p_ID)
+{
+ initProcess();
+ operatorName = getOperatorName(operatorCommand);
+ setOperatorArgv(operatorCommand);
+ m_operatorCommand = operatorCommand;
+
+ defPrompt(); // has to be called after get operatorName
+
+ m_module = getModule(operatorName);
+}
+
+void
+process_t::setOperatorArgv(char *operatorArguments)
+{
+ if (operatorArguments)
+ {
+ char *operatorArg = operatorArguments;
+ // fprintf(stderr, "processDefArgument: %d %s\n", oargc, operatorArg);
+
+ while ((operatorArg = strchr(operatorArg, ',')) != NULL)
+ {
+ *operatorArg = '\0';
+ *operatorArg++;
+ if (strlen(operatorArg))
+ {
+ oargv.push_back(operatorArg);
+ }
+ }
+ }
+ oargc = oargv.size();
+}
void
process_t::initProcess()
@@ -70,15 +103,14 @@ process_t::initProcess()
a_utime = 0;
a_stime = 0;
cputime = 0;
- nvals = NULL;
- nvars = NULL;
- ntimesteps = NULL;
+ nvals = 0;
+ nvars = 0;
+ ntimesteps = 0;
- streamCnt = 0;
+ m_streamCnt = 0;
oargc = 0;
- xoperator = "UNINITALIZED";
- operatorName = "UNINITALIZED";
+ m_operatorCommand = "UNINITALIZED";
operatorArg = "UNINITALIZED";
noper = 0;
@@ -95,15 +127,15 @@ process_t::getOutStreamCnt()
return outputStreams.size();
}
-int
-processCreate(void)
+process_t *
+processCreate(char *command)
{
#if defined(HAVE_LIBPTHREAD)
pthread_mutex_lock(&processMutex);
#endif
int processID = NumProcess++;
- Process.insert(std::make_pair(processID, process_t(processID)));
+ Process.insert(std::make_pair(processID, process_t(processID, command)));
NumProcessActive++;
@@ -114,7 +146,7 @@ processCreate(void)
if (processID >= MAX_PROCESS)
Error("Limit of %d processes reached!", MAX_PROCESS);
- return processID;
+ return &Process.find(processID)->second;
}
process_t &
@@ -125,7 +157,7 @@ processSelf(void)
pthread_mutex_lock(&processMutex);
- for ( auto &id_process_pair : Process)
+ for (auto &id_process_pair : Process)
if (id_process_pair.second.l_threadID)
{
if (pthread_equal(id_process_pair.second.threadID, thID))
@@ -135,11 +167,9 @@ processSelf(void)
}
}
- std::cout << "returning the 0th process" << std::endl;
pthread_mutex_unlock(&processMutex);
#endif
- std::cout << "returning the std process 0" << std::endl;
return Process.find(0)->second;
}
@@ -176,12 +206,12 @@ processNumsActive(void)
}
void
-processAddNvals(off_t nvals)
+processAddNvals(size_t nvals)
{
processSelf().nvals += nvals;
}
-off_t
+size_t
processInqNvals(int processID)
{
return Process.find(processID)->second.nvals;
@@ -302,14 +332,12 @@ processInqOpername(void)
}
void
-processDefPrompt(const char *opername)
+process_t::defPrompt()
{
- process_t &process = processSelf();
-
- if (process.m_ID == 0)
- sprintf(process.prompt, "%s %s", Progname, opername);
+ if (m_ID == 0)
+ sprintf(prompt, "%s %s", CDO_progname, operatorName);
else
- sprintf(process.prompt, "%s(%d) %s", Progname, process.m_ID + 1, opername);
+ sprintf(prompt, "%s(%d) %s", CDO_progname, m_ID + 1, operatorName);
}
const char *
@@ -385,7 +413,7 @@ glob_pattern(const char *restrict string)
int
cdoStreamCnt(void)
{
- int cnt = processSelf().streamCnt;
+ int cnt = processSelf().m_streamCnt;
return cnt;
}
@@ -394,7 +422,7 @@ cdoStreamName(int cnt)
{
process_t &process = processSelf();
- if (cnt > process.streamCnt || cnt < 0)
+ if (cnt > process.m_streamCnt || cnt < 0)
Error("count %d out of range!", cnt);
return &(process.streamNames[cnt]);
@@ -403,13 +431,13 @@ cdoStreamName(int cnt)
const char *
processOperator(void)
{
- return processSelf().xoperator;
+ return processSelf().m_operatorCommand;
}
-static int skipInputStreams(int argc, std::vector<char *> &argv, int globArgc, int nstreams);
+static int skipInputStreams(int argc, std::vector<char *> &argv, int globArgc, int nstreams);
static int
-getGlobArgc(int argc, std::vector<char *> &argv, int globArgc)
+getGlobArgc(int argc, std::vector<char *> &argv, int globArgc)
{
char *opername = &argv[globArgc][1];
char *comma_position = strchr(opername, ',');
@@ -436,7 +464,7 @@ getGlobArgc(int argc, std::vector<char *> &argv, int globArgc)
}
static int
-skipInputStreams(int argc, std::vector<char*>& argv, int globArgc, int nstreams)
+skipInputStreams(int argc, std::vector<char *> &argv, int globArgc, int nstreams)
{
while (nstreams > 0)
{
@@ -459,7 +487,7 @@ skipInputStreams(int argc, std::vector<char*>& argv, int globArgc, int nstreams)
}
static int
-getStreamCnt(int argc, std::vector<char *>& argv)
+getStreamCnt(int argc, std::vector<char *> &argv)
{
int streamCnt = 0;
int globArgc = 1;
@@ -479,10 +507,49 @@ getStreamCnt(int argc, std::vector<char *>& argv)
return streamCnt;
}
-static void
-setStreamNames(int argc, std::vector<char *> &argv)
+/*
+static void setStreamNames(int argc, std::vector<char *> *argv)
+{
+ //check for output of first
+ int current_argv_entry;
+ std::vector<pstream_t*> ¤t_instreams = root_process->inputStreams;
+ std::vector<pstream_t*> ¤t_outstreams = root_process->outputStreams;
+
+}
+*/
+void
+process_t::setStreams(int argc, std::vector<char *> &argv)
+{
+ int streamCnt = getStreamCnt(argc, argv);
+
+ nvals = 0;
+ nvars = 0;
+ ntimesteps = 0;
+
+ m_streamCnt = 0; /* filled in setStreamNames */
+ if (streamCnt)
+ streamNames = std::vector<argument_t>(streamCnt);
+ for (int i = 0; i < streamCnt; i++)
+ {
+ streamNames[i].argc = 0;
+ streamNames[i].args = NULL;
+ }
+
+ setStreamNames(argc, argv);
+
+ int status = checkStreamCnt();
+
+ if (status == 0 && streamCnt != streamCnt)
+ Error("Internal problem with stream count %d %d", streamCnt, streamCnt);
+ /*
+ for ( i = 0; i < streamCnt; i++ )
+ fprintf(stderr, "setStreams: stream %d %s\n", i+1, process.streamNames[i].args);
+ */
+}
+
+void
+process_t::setStreamNames(int argc, std::vector<char *> &argv)
{
- process_t &process = processSelf();
int i, ac;
int globArgc = 1;
int globArgcStart;
@@ -498,25 +565,34 @@ setStreamNames(int argc, std::vector<char *> &argv)
globArgc = getGlobArgc(argc, argv, globArgc);
len = 0;
for (i = globArgcStart; i < globArgc; i++)
- len += strlen(argv[i]) + 1;
+ {
+ len += strlen(argv[i]) + 1;
+ }
streamname = (char *) Calloc(1, len);
for (i = globArgcStart; i < globArgc; i++)
{
strcat(streamname, argv[i]);
if (i < globArgc - 1)
- strcat(streamname, " ");
+ {
+ strcat(streamname, " ");
+ }
}
for (i = 1; i < len - 1; i++)
- if (streamname[i] == '\0')
- streamname[i] = ' ';
- process.streamNames[process.streamCnt].args = streamname;
+ {
+ if (streamname[i] == '\0')
+ {
+ streamname[i] = ' ';
+ }
+ }
+
+ streamNames[m_streamCnt].args = streamname;
ac = globArgc - globArgcStart;
// printf("setStreamNames: ac %d streamname1: %s\n", ac, streamname);
- process.streamNames[process.streamCnt].argv.resize(ac);
+ streamNames[m_streamCnt].argv.resize(ac);
for (i = 0; i < ac; ++i)
- process.streamNames[process.streamCnt].argv[i] = argv[i + globArgcStart];
- process.streamNames[process.streamCnt].argc = ac;
- process.streamCnt++;
+ streamNames[m_streamCnt].argv[i] = argv[i + globArgcStart];
+ streamNames[m_streamCnt].argc = ac;
+ m_streamCnt++;
// printf("setStreamNames: streamname1: %s\n", streamname);
}
else
@@ -524,13 +600,13 @@ setStreamNames(int argc, std::vector<char *> &argv)
len = strlen(argv[globArgc]) + 1;
streamname = (char *) Malloc(len);
strcpy(streamname, argv[globArgc]);
- process.streamNames[process.streamCnt].args = streamname;
+ streamNames[m_streamCnt].args = streamname;
ac = 1;
- process.streamNames[process.streamCnt].argv.resize(ac);
- process.streamNames[process.streamCnt].argv[0] = argv[globArgc];
- process.streamNames[process.streamCnt].argc = ac;
- process.streamNames[process.streamCnt].args = streamname;
- process.streamCnt++;
+ streamNames[m_streamCnt].argv.resize(ac);
+ streamNames[m_streamCnt].argv[0] = argv[globArgc];
+ streamNames[m_streamCnt].argc = ac;
+ streamNames[m_streamCnt].args = streamname;
+ m_streamCnt++;
// printf("setStreamNames: streamname2: %s\n", streamname);
globArgc++;
}
@@ -610,7 +686,7 @@ expand_wildcards(process_t &process, int streamCnt)
process.streamNames.resize(streamCnt);
// move output streams to the end
- for (int i = 1; i < process.streamCnt; ++i)
+ for (int i = 1; i < process.m_streamCnt; ++i)
process.streamNames[i + glob_arg->argc - 1] = process.streamNames[i];
for (int i = 0; i < glob_arg->argc; ++i)
@@ -624,7 +700,7 @@ expand_wildcards(process_t &process, int streamCnt)
cdoPrint(" >%s<", glob_arg->argv[i]);
}
- process.streamCnt = streamCnt;
+ process.m_streamCnt = streamCnt;
}
Free(glob_arg);
@@ -633,7 +709,7 @@ expand_wildcards(process_t &process, int streamCnt)
return 1;
}
-static int
+int
checkStreamCnt(void)
{
process_t &process = processSelf();
@@ -661,29 +737,29 @@ checkStreamCnt(void)
// printf(" streamInCnt, streamOutCnt %d %d\n", streamInCnt, streamOutCnt);
if (streamInCnt == -1)
{
- streamInCnt = process.streamCnt - streamOutCnt;
+ streamInCnt = process.m_streamCnt - streamOutCnt;
if (streamInCnt < 1)
cdoAbort("Input streams missing!");
}
if (streamOutCnt == -1)
{
- streamOutCnt = process.streamCnt - streamInCnt;
+ streamOutCnt = process.m_streamCnt - streamInCnt;
if (streamOutCnt < 1)
cdoAbort("Output streams missing!");
}
// printf(" streamInCnt, streamOutCnt %d %d\n", streamInCnt, streamOutCnt);
streamCnt = streamInCnt + streamOutCnt;
- // printf(" streamCnt %d %d\n", process.streamCnt, streamCnt);
+ // printf(" streamCnt %d %d\n", process.m_streamCnt, streamCnt);
- if (process.streamCnt > streamCnt)
+ if (process.m_streamCnt > streamCnt)
cdoAbort("Too many streams!"
" Operator needs %d input and %d output streams.",
streamInCnt,
streamOutCnt);
- if (process.streamCnt < streamCnt)
+ if (process.m_streamCnt < streamCnt)
cdoAbort("Too few streams specified!"
" Operator needs %d input and %d output streams.",
streamInCnt,
@@ -712,62 +788,120 @@ checkStreamCnt(void)
return status;
}
-static void
-setStreams(int argc, std::vector<char *> &argv)
+bool
+process_t::hasAllInputs()
{
- process_t &process = processSelf();
- int streamCnt = getStreamCnt(argc, argv);
+ // std::cout << m_module.streamInCnt << " " << childProcesses.size() + inputStreams.size() << std::endl;
+ return m_module.streamInCnt == (childProcesses.size() + inputStreams.size());
+}
- process.nvals = 0;
- process.nvars = 0;
- process.ntimesteps = 0;
+#include <fstream>
+void print_creation_results(std::ofstream &p_outfile)
+{
+ p_outfile << std::endl << "RESULTS:" << std::endl;
+ for (auto &process : Process)
+ {
+ p_outfile << "process: " << process.second.operatorName << " has children: " << std::endl;
+ for (auto child : process.second.childProcesses)
+ {
+ p_outfile << child->m_ID << ", ";
+ }
+ for (auto outstream : process.second.inputStreams)
+ {
+ p_outfile << "S: " << outstream->self << " ";
+ }
+ }
+ p_outfile << std::endl;
- process.streamCnt = 0; /* filled in setStreamNames */
- if (streamCnt)
- process.streamNames = std::vector<argument_t>(streamCnt);
- for (int i = 0; i < streamCnt; i++)
+}
+
+void
+createProcesses(int argc, char **argv)
+{
+ std::ofstream outfile("processCreation.txt");
+
+ for (int i = 0; i < argc; i++)
{
- process.streamNames[i].argc = 0;
- process.streamNames[i].args = NULL;
+ outfile << argv[i] << " ";
}
+ outfile << std::endl;
- setStreamNames(argc, argv);
+ root_process = processCreate(argv[0]);
- int status = checkStreamCnt();
+ process_t *current_process;
+ process_t *parent_process;
- if (status == 0 && process.streamCnt != streamCnt)
- Error("Internal problem with stream count %d %d", process.streamCnt, streamCnt);
- /*
- for ( i = 0; i < streamCnt; i++ )
- fprintf(stderr, "setStreams: stream %d %s\n", i+1, process.streamNames[i].args);
- */
+ int idx = 1;
+ std::stack<process_t *> call_stack;
+
+ call_stack.push(root_process);
+ current_process = call_stack.top();
+ // root_process.addOutputStream();
+ do
+ {
+ outfile << "iteration " << idx << " start" << std::endl
+ << "current argv: " << argv[idx] << " current_process: " << current_process->operatorName << std::endl;
+ if (argv[idx][0] == '-')
+ {
+ outfile << "found new operator: creating process: ";
+ parent_process = current_process;
+ current_process = processCreate(argv[idx]);
+ parent_process->addChild(current_process);
+ current_process->addParent(parent_process);
+ call_stack.push(current_process);
+ outfile << current_process->operatorName << std::endl;
+ }
+ else
+ {
+ outfile << "added file " << argv[idx] << std::endl;
+ pstream_t *new_pstream = create_pstream();
+ // new_pstream->pstreamOpenReadFile(argv[i]);
+ current_process->inputStreams.push_back(new_pstream);
+ }
+ while (current_process->hasAllInputs() && current_process != root_process)
+ {
+ outfile << "process " << current_process->operatorName << "poped" << std::endl;
+ call_stack.pop();
+ current_process = call_stack.top();
+ }
+ outfile << "iteration " << idx << " end"
+ << "current_process: " << current_process->operatorName << std::endl;
+ idx++;
+ }
+ while ((current_process != root_process || !root_process->hasAllInputs()) && idx < argc - 1);
+
+ print_creation_results(outfile);
+ outfile.close();
}
void
processDefArgument(void *vargument)
{
+ /*
+process_t &process = processSelf();
+char *operatorArg;
+char *commapos;
+std::vector< char*> &oargv = process.oargv;
+*/
process_t &process = processSelf();
- char *operatorArg;
- char *commapos;
std::vector<char*> &oargv = process.oargv;
- int argc = ((argument_t *) vargument)->argc;
- std::vector<char *> &argv = ((argument_t *) vargument)->argv;
+ /*
- process.xoperator = argv[0];
- process.operatorName = getOperatorName(process.xoperator);
- process.operatorArg = getOperatorArg(process.xoperator);
+ process.m_operatorCommand = argv[0];
+ process.operatorName = getOperatorName(process.m_operatorCommand);
+ process.operatorArg = getOperatorArg(process.m_operatorCommand);
operatorArg = process.operatorArg;
if (operatorArg)
{
- oargv.push_back(operatorArg);
+ orgv.push_back(operatorArg);
// fprintf(stderr, "processDefArgument: %d %s\n", oargc, operatorArg);
- commapos = operatorArg;
+ char *commapos = operatorArg;
while ((commapos = strchr(commapos, ',')) != NULL)
{
*commapos = '\0';
- *commapos++;
+ commapos++;
if (strlen(commapos))
{
oargv.push_back(commapos);
@@ -778,9 +912,7 @@ processDefArgument(void *vargument)
processDefPrompt(process.operatorName);
- process.module = getModule(process.operatorName);
-
- setStreams(argc, argv);
+*/
}
void
@@ -1013,22 +1145,21 @@ process_t::print_process()
std::cout << " nOutStream : " << nOutStream << std::endl;
for (int i = 0; i < nInStream; i++)
{
- std::cout << " " << inputStreams[i]->self << std::endl;
+ std::cout << " " << childProcesses[i]->m_ID << std::endl;
}
for (int i = 0; i < nOutStream; i++)
{
- std::cout << " " << outputStreams[i]->self << std::endl;
+ std::cout << " " << parentProcesses[i]->m_ID << std::endl;
}
- if (s_utime)
+ if ( s_utime > 0 )
{
std::cout << " s_utime : " << s_utime << std::endl;
}
else
{
- std::cout << " s_utime : "
- << "UNINITALIZED" << std::endl;
+ std::cout << " s_utime : " << "UNINITALIZED" << std::endl;
}
- if (s_stime)
+ if ( s_stime > 0 )
{
std::cout << " s_stime : " << s_stime << std::endl;
}
@@ -1073,9 +1204,9 @@ process_t::print_process()
<< "UNINITALIZED" << std::endl;
}
std::cout << " ntimesteps : " << ntimesteps << std::endl;
- std::cout << " streamCnt : " << streamCnt << std::endl;
+ std::cout << " streamCnt : " << m_streamCnt << std::endl;
// std::cout << " streamNames : " << streamNames << std::endl;
- std::cout << " xoperator : " << xoperator << std::endl;
+ std::cout << " m_operatorCommand : " << m_operatorCommand << std::endl;
std::cout << " operatorName : " << operatorName << std::endl;
std::cout << " operatorArg : " << operatorArg << std::endl;
std::cout << " oargc : " << oargc << std::endl;
@@ -1106,10 +1237,13 @@ processClosePipes(void)
Message("process %d stream %d close streamID %d", processSelf().m_ID, sindex, pstreamptr->self);
if (pstreamptr)
- pstreamptr->close();
+ pstreamptr->close();
}
}
+extern "C" {
+size_t getPeakRSS( );
+}
void
cdoFinish(void)
@@ -1138,7 +1272,7 @@ cdoFinish(void)
reset_text_color(stderr);
if (nvals > 0)
{
- if (sizeof(int64_t) > sizeof(long))
+ if (sizeof(int64_t) > sizeof(size_t))
#if defined(_WIN32)
fprintf(stderr,
"Processed %I64d value%s from %d variable%s",
@@ -1152,8 +1286,8 @@ cdoFinish(void)
ADD_PLURAL(nvars));
else
fprintf(stderr,
- "Processed %ld value%s from %d variable%s",
- (long) nvals,
+ "Processed %zu value%s from %d variable%s",
+ (size_t) nvals,
ADD_PLURAL(nvals),
nvars,
ADD_PLURAL(nvars));
@@ -1197,9 +1331,8 @@ cdoFinish(void)
{
int mu[] = { 'b', 'k', 'm', 'g', 't' };
int muindex = 0;
- long memmax;
-
- memmax = memTotal();
+ // size_t memmax = memTotal();
+ size_t memmax = getPeakRSS();
while (memmax > 9999)
{
memmax /= 1024;
@@ -1207,7 +1340,7 @@ cdoFinish(void)
}
if (memmax)
- snprintf(memstring, sizeof(memstring), " %ld%c ", memmax, mu[muindex]);
+ snprintf(memstring, sizeof(memstring), " %zu%c", memmax, mu[muindex]);
processEndTime(&p_usertime, &p_systime);
p_cputime = p_usertime + p_systime;
@@ -1222,11 +1355,11 @@ cdoFinish(void)
#if defined(HAVE_SYS_TIMES_H)
if (cdoBenchmark)
- fprintf(stderr, " ( %.2fs %.2fs %.2fs %s)\n", c_usertime, c_systime, c_cputime, memstring);
+ fprintf(stderr, " ( %.2fs %.2fs %.2fs%s )\n", c_usertime, c_systime, c_cputime, memstring);
else
{
if (!cdoSilentMode)
- fprintf(stderr, " ( %.2fs )\n", c_cputime);
+ fprintf(stderr, " ( %.2fs%s )\n", c_cputime, memstring);
}
if (cdoBenchmark && processID == 0)
fprintf(stderr, "total: user %.2fs sys %.2fs cpu %.2fs mem%s\n", p_usertime, p_systime, p_cputime, memstring);
@@ -1238,3 +1371,23 @@ cdoFinish(void)
processDelete();
}
+
+void
+process_t::addChild(process_t *childProcess)
+{
+ childProcesses.push_back(childProcess);
+ nchild = childProcesses.size();
+}
+
+void
+process_t::addParent(process_t *parentProcess)
+{
+ parentProcesses.push_back(parentProcess);
+}
+void
+clearProcesses()
+{
+ Process.clear();
+ NumProcess = 0;
+ NumProcessActive = 0;
+}
diff --git a/src/process.h b/src/process.h
index 509ae2f..8ac08a1 100644
--- a/src/process.h
+++ b/src/process.h
@@ -18,7 +18,6 @@
#ifndef _PROCESS_H
#define _PROCESS_H
-#include <sys/types.h> /* off_t */
#include <vector>
#include "util.h"
#include "pstream.h"
@@ -27,73 +26,85 @@
#include <vector>
#include <iostream>
-constexpr int MAX_PROCESS = 128;
-constexpr int MAX_STREAM = 64;
-constexpr int MAX_OPERATOR = 128;
-constexpr int MAX_OARGC = 4096;
-constexpr int MAX_FILES = 65536;
+constexpr int MAX_PROCESS = 128;
+constexpr int MAX_STREAM = 64;
+constexpr int MAX_OPERATOR = 128;
+constexpr int MAX_OARGC = 4096;
+constexpr int MAX_FILES = 65536;
-
-typedef struct {
- int f1;
- int f2;
+typedef struct
+{
+ int f1;
+ int f2;
const char *name;
const char *enter;
-}
-oper_t;
+} oper_t;
-class process_t {
- public:
- int m_ID;
+class process_t
+{
+public:
+ int m_ID;
#if defined(HAVE_LIBPTHREAD)
- pthread_t threadID;
- int l_threadID;
+ pthread_t threadID;
+ int l_threadID;
#endif
- short nchild;
- std::vector<pstream_t*> inputStreams;
- std::vector<pstream_t*> outputStreams;
- double s_utime;
- double s_stime;
- double a_utime;
- double a_stime;
- double cputime;
-
- off_t nvals;
- short nvars;
- int ntimesteps;
- short streamCnt;
+ short nchild;
+ std::vector<process_t *> childProcesses;
+ std::vector<process_t *> parentProcesses;
+ std::vector<pstream_t *> inputStreams;
+ std::vector<pstream_t *> outputStreams;
+ double s_utime;
+ double s_stime;
+ double a_utime;
+ double a_stime;
+ double cputime;
+
+ size_t nvals;
+ short nvars;
+ int ntimesteps;
+ short m_streamCnt;
std::vector<argument_t> streamNames;
- char *xoperator;
+ char *m_operatorCommand;
const char *operatorName;
- char *operatorArg;
- int oargc;
+ char *operatorArg;
+ int oargc;
std::vector<char *> oargv;
- char prompt[64];
- short noper;
- oper_t oper[MAX_OPERATOR];
+ char prompt[64];
+ short noper;
+ oper_t oper[MAX_OPERATOR];
- modules_t module;
+ modules_t m_module;
int getInStreamCnt();
int getOutStreamCnt();
void initProcess();
void print_process();
- process_t(int ID);
- private:
+ void defArgument();
+ process_t(int p_ID, char *operatorCommand);
+ void setOperatorArgv(char *operatorArguments);
+ void setStreams(int argc, std::vector<char *> &argv);
+ void addChild(process_t *child_process);
+ void addParent(process_t *parent_process);
+ bool hasAllInputs();
+
+private:
+ void defPrompt();
process_t();
void OpenRead(int p_input_idx);
void OpenWrite(int p_input_idx);
void OpenAppend(int p_input_idx);
+ void setStreamNames(int argc, std::vector<char *> &argv);
};
- pstream_t* processInqInputStream(int streamindex);
- pstream_t* processInqOutputStream(int streamindex);
- process_t& processSelf(void);
-int processCreate(void);
+pstream_t *processInqInputStream(int streamindex);
+pstream_t *processInqOutputStream(int streamindex);
+process_t &processSelf(void);
+process_t *processCreate(void);
+process_t *processCreate(char *command);
void processDelete(void);
-int processInqTimesteps(void);
+int processInqTimesteps(void);
void processDefTimesteps(int streamID);
-int processInqVarNum(void);
+int processInqVarNum(void);
int processInqInputStreamNum(void);
int processInqOutputStreamNum(void);
void processAddInputStream(pstream_t *p_pstream_ptr);
@@ -109,11 +120,11 @@ void processAccuTime(double utime, double stime);
void processDefCputime(int processID, double cputime);
double processInqCputime(int processID);
-void processAddNvals(off_t nvals);
-off_t processInqNvals(int processID);
+void processAddNvals(size_t nvals);
+size_t processInqNvals(int processID);
int processNums(void);
-int processInqChildNum(void);
+int processInqChildNum(void);
const char *processOperatorArg(void);
const char *processInqOpername(void);
@@ -121,5 +132,8 @@ const char *processInqOpername2(int processID);
const char *processInqPrompt(void);
const argument_t *cdoStreamName(int cnt);
+int checkStreamCnt();
+void createProcesses(int argc, char **argv);
+void clearProcesses();
-#endif /* _PROCESS_H */
+#endif /* _PROCESS_H */
diff --git a/src/pstream.cc b/src/pstream.cc
index f297795..db17a6d 100644
--- a/src/pstream.cc
+++ b/src/pstream.cc
@@ -16,12 +16,13 @@
*/
-#include <thread>
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#if defined(_OPENMP)
+#include <thread>
+
+#ifdef _OPENMP
#include <omp.h>
#endif
@@ -43,8 +44,8 @@ int pclose(FILE *stream);
#include "util.h"
#include "pipe.h"
#include "error.h"
+#include "cdoDebugOutput.h"
-static int PSTREAM_Debug = 0;
//#define MAX_PSTREAMS 4096
@@ -135,7 +136,7 @@ pstream_init_pointer(void)
}
*/
-static pstream_t *create_pstream()
+ pstream_t *create_pstream()
{
PSTREAM_LOCK();
auto new_entry = _pstream_map.insert(
@@ -200,7 +201,7 @@ pstream_from_pointer(pstream_t *ptr)
idx = newptr->idx;
newptr->ptr = ptr;
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
Message("Pointer %p has idx %d from pstream list", ptr, idx);
}
else
@@ -252,8 +253,8 @@ pstream_delete_entry(pstream_t *pstreamptr)
PSTREAM_UNLOCK();
- if (PSTREAM_Debug)
- Message("Removed idx %d from pstream list", idx);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("Removed idx ", idx," from pstream list");
}
/*
static void
@@ -266,13 +267,13 @@ pstream_initialize(void)
char *env = getenv("PSTREAM_DEBUG");
if (env)
- PSTREAM_Debug = atoi(env);
+ CdoDebug::PSTREAM = atoi(env);
env = getenv("PSTREAM_MAX");
if (env)
_pstream_max = atoi(env);
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
Message("PSTREAM_MAX = %d", _pstream_max);
pstream_list_new();
@@ -384,8 +385,8 @@ pstream_t::pstreamOpenReadPipe(const char *pipename)
/* Free(operatorName); */
/* pipeInqInfo(pstreamID); */
- if (PSTREAM_Debug)
- Message("pipe %s", pipename);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("pipe ", pipename, " %s");
#else
cdoAbort("Cannot use pipes, pthread support not compiled in!");
#endif
@@ -533,8 +534,8 @@ pstream_t::pstreamOpenReadFile(const char* p_args)
filename = std::string(p_args);
}
- if (PSTREAM_Debug)
- Message("file %s", filename.c_str());
+ if (CdoDebug::PSTREAM)
+ MESSAGE("file ", filename.c_str());
#if defined(HAVE_LIBPTHREAD)
if (cdoLockIO)
@@ -577,6 +578,11 @@ void createPipeName(char *pipename, int pnlen)
int
pstreamOpenRead(const argument_t *argument)
{
+ if(CdoDebug::PSTREAM)
+ {
+ MESSAGE("Opening new pstream for reading with argument:");
+ MESSAGE(print_argument((argument_t*)argument));
+ }
pstream_t *pstreamptr = create_pstream();
if (!pstreamptr)
@@ -680,9 +686,9 @@ pstreamOpenWritePipe(const argument_t *argument, int filetype)
int pstreamID = -1;
#if defined(HAVE_LIBPTHREAD)
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("pipe %s", argument->args);
+ MESSAGE("pipe ", argument->args);
}
pstreamID = pstreamFindID(argument->args);
if (pstreamID == -1)
@@ -746,8 +752,8 @@ pstreamOpenWriteFile(const argument_t *argument, int filetype)
int pstreamID = pstreamptr->self;
- if (PSTREAM_Debug)
- Message("file %s", argument->args);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("file ", argument->args);
if (filetype == CDI_UNDEFID)
filetype = CDI_FILETYPE_GRB;
@@ -834,9 +840,9 @@ pstreamOpenAppend(const argument_t *argument)
if (ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("pipe %s", argument->args);
+ MESSAGE("pipe ", argument->args);
}
cdoAbort("this operator doesn't work with pipes!");
}
@@ -844,10 +850,10 @@ pstreamOpenAppend(const argument_t *argument)
pstream_t *pstreamptr = create_pstream();
if (!pstreamptr)
- Error("No memory");
+ ERROR("No memory");
- if (PSTREAM_Debug)
- Message("file %s", argument->args);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("file ", argument->args);
pstreamptr->openAppend(argument->args);
@@ -908,8 +914,8 @@ pstreamCloseChildStream(pstream_t *pstreamptr)
pipe_t *pipe = pstreamptr->pipe;
pthread_mutex_lock(pipe->m_mutex);
pipe->EOP = true;
- if (PSTREAM_Debug)
- Message("%s read closed", pstreamptr->m_name.c_str());
+ if (CdoDebug::PSTREAM)
+ MESSAGE(pstreamptr->m_name.c_str(), " read closed");
pthread_mutex_unlock(pipe->m_mutex);
pthread_cond_signal(pipe->tsDef);
pthread_cond_signal(pipe->tsInq);
@@ -942,8 +948,8 @@ pstreamCloseParentStream(pstream_t *pstreamptr)
pipe_t *pipe = pstreamptr->pipe;
pthread_mutex_lock(pipe->m_mutex);
pipe->EOP = true;
- if (PSTREAM_Debug)
- Message("%s write closed", pstreamptr->m_name.c_str());
+ if (CdoDebug::PSTREAM)
+ MESSAGE(pstreamptr->m_name.c_str(), " write closed");
pthread_mutex_unlock(pipe->m_mutex);
pthread_cond_signal(pipe->tsDef);
pthread_cond_signal(pipe->tsInq);
@@ -951,8 +957,8 @@ pstreamCloseParentStream(pstream_t *pstreamptr)
std::unique_lock<std::mutex> locked_mutex(pipe->m_mutex);
while (pstreamptr->isopen)
{
- if (PSTREAM_Debug)
- Message("wait of read close");
+ if (CdoDebug::PSTREAM)
+ MESSAGE("wait of read close");
pthread_cond_wait(pipe->isclosed, locked_mutex);
}
locked_mutex.unlock();
@@ -964,7 +970,7 @@ pstreamClose(int pstreamID)
pstream_t *pstreamptr = pstream_to_pointer(pstreamID);
if (pstreamptr == NULL)
- Error("Internal problem, stream %d not open!", pstreamID);
+ ERROR("Internal problem, stream ", pstreamID ," not open!");
pstreamptr->close();
@@ -985,7 +991,7 @@ void pstream_t::close(){
else if (pthread_equal(threadID, wthreadID))
pstreamCloseParentStream(this);
else
- Error("Internal problem! Close pipe %s", m_name.c_str());
+ Error("Internal problem! Close pipe ", m_name.c_str());
// processDelStream(pstreamID);
#else
@@ -994,8 +1000,8 @@ void pstream_t::close(){
}
else
{
- if (PSTREAM_Debug)
- Message("%s fileID %d", m_name.c_str(), m_fileID);
+ if (CdoDebug::PSTREAM)
+ MESSAGE(m_name.c_str(), " fileID ", m_fileID);
if (mode == 'r')
{
@@ -1170,8 +1176,8 @@ void pstream_t::defVlist(int p_vlistID){
#if defined(HAVE_LIBPTHREAD)
if (ispipe)
{
- if (PSTREAM_Debug)
- Message("%s pstreamID %d", m_name.c_str(), self);
+ if (CdoDebug::PSTREAM)
+ MESSAGE(m_name.c_str()," pstreamID ", self);
int vlistIDcp = vlistDuplicate(p_vlistID);
/* pipeDefVlist(pstreamptr, p_vlistID);*/
pipe->pipeDefVlist(m_vlistID, vlistIDcp);
@@ -1245,9 +1251,9 @@ pstreamInqRecord(int pstreamID, int *varID, int *levelID)
#if defined(HAVE_LIBPTHREAD)
if (pstreamptr->ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pstreamptr->pipe->name.c_str(), pstreamptr->self);
+ MESSAGE( pstreamptr->pipe->name.c_str()," pstreamID ", pstreamptr->self);
}
pstreamptr->pipe->pipeInqRecord(varID, levelID);
}
@@ -1286,9 +1292,9 @@ pstreamDefRecord(int pstreamID, int varID, int levelID)
if (pstreamptr->ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamid %d", pstreamptr->m_name.c_str(), pstreamptr->self);
+ MESSAGE( pstreamptr->m_name.c_str()," pstreamid ", pstreamptr->self);
}
pstreamptr->pipe->pipeDefRecord(varID, levelID);
}
@@ -1312,7 +1318,7 @@ pstreamDefRecord(int pstreamID, int varID, int levelID)
}
void
-pstreamReadRecord(int pstreamID, double *data, int *nmiss)
+pstreamReadRecord(int pstreamID, double *data, size_t *nmiss)
{
if (data == NULL)
cdoAbort("Data pointer not allocated (pstreamReadRecord)!");
@@ -1322,9 +1328,9 @@ pstreamReadRecord(int pstreamID, double *data, int *nmiss)
#if defined(HAVE_LIBPTHREAD)
if (pstreamptr->ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pstreamptr->pipe->name.c_str(), pstreamptr->self);
+ MESSAGE( pstreamptr->pipe->name.c_str()," pstreamID ", pstreamptr->self);
}
pstreamptr->pipe->pipeReadRecord(pstreamptr->m_vlistID, data, nmiss);
}
@@ -1348,7 +1354,7 @@ pstreamReadRecord(int pstreamID, double *data, int *nmiss)
}
void
-pstreamReadRecordF(int pstreamID, float *data, int *nmiss)
+pstreamReadRecordF(int pstreamID, float *data, size_t *nmiss)
{
if (data == NULL)
cdoAbort("Data pointer not allocated (pstreamReadRecord)!");
@@ -1381,7 +1387,7 @@ pstreamReadRecordF(int pstreamID, float *data, int *nmiss)
}
void
-pstreamCheckDatarange(pstream_t *pstreamptr, int varID, double *array, int nmiss)
+pstreamCheckDatarange(pstream_t *pstreamptr, int varID, double *array, size_t nmiss)
{
long i;
long gridsize = pstreamptr->m_varlist[varID].gridsize;
@@ -1457,7 +1463,7 @@ pstreamCheckDatarange(pstream_t *pstreamptr, int varID, double *array, int nmiss
}
void
-pstreamWriteRecord(int pstreamID, double *data, int nmiss)
+pstreamWriteRecord(int pstreamID, double *data, size_t nmiss)
{
if (data == NULL)
cdoAbort("Data pointer not allocated (%s)!", __func__);
@@ -1467,9 +1473,9 @@ pstreamWriteRecord(int pstreamID, double *data, int nmiss)
#if defined(HAVE_LIBPTHREAD)
if (pstreamptr->ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pstreamptr->pipe->name.c_str(), pstreamptr->self);
+ MESSAGE(pstreamptr->pipe->name.c_str()," pstreamID ", pstreamptr->self);
}
pstreamptr->pipe->pipeWriteRecord(data, nmiss);
}
@@ -1500,7 +1506,7 @@ pstreamWriteRecord(int pstreamID, double *data, int nmiss)
}
void
-pstreamWriteRecordF(int pstreamID, float *data, int nmiss)
+pstreamWriteRecordF(int pstreamID, float *data, size_t nmiss)
{
if (data == NULL)
cdoAbort("Data pointer not allocated (%s)!", __func__);
@@ -1511,9 +1517,9 @@ pstreamWriteRecordF(int pstreamID, float *data, int nmiss)
if (pstreamptr->ispipe)
{
cdoAbort("pipeWriteRecord not implemented for memtype float!");
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pstreamptr->pipe->name.c_str(), pstreamptr->self);
+ MESSAGE( pstreamptr->pipe->name.c_str()," pstreamID ", pstreamptr->self);
}
// pipeWriteRecord(pstreamptr, data, nmiss);
}
@@ -1552,9 +1558,9 @@ pstreamInqTimestep(int pstreamID, int tsID)
#if defined(HAVE_LIBPTHREAD)
if (pstreamptr->ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pstreamptr->pipe->name.c_str(), pstreamptr->self);
+ MESSAGE(pstreamptr->pipe->name.c_str(), " pstreamID ", pstreamptr->self);
}
nrecs = pstreamptr->pipe->pipeInqTimestep(tsID);
}
@@ -1664,9 +1670,9 @@ pstream_t::defTimestep(int p_tsID)
#if defined(HAVE_LIBPTHREAD)
if (ispipe)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
{
- Message("%s pstreamID %d", pipe->name.c_str(), self);
+ MESSAGE(pipe->name.c_str()," pstreamID ", self);
}
pipe->pipeDefTimestep(m_vlistID, p_tsID);
}
@@ -1702,8 +1708,8 @@ pstream_t::defTimestep(int p_tsID)
void
pstreamCopyRecord(int pstreamIDdest, int pstreamIDsrc)
{
- if (PSTREAM_Debug)
- Message("pstreamIDdest = %d pstreamIDsrc = %d", pstreamIDdest, pstreamIDsrc);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("pstreamIDdest = ",pstreamIDdest," pstreamIDsrc = ", pstreamIDsrc);
pstream_t *pstreamptr_dest = pstream_to_pointer(pstreamIDdest);
pstream_t *pstreamptr_src = pstream_to_pointer(pstreamIDsrc);
@@ -1725,24 +1731,26 @@ pstreamCopyRecord(int pstreamIDdest, int pstreamIDsrc)
void
pstreamDebug(int debug)
{
- PSTREAM_Debug = debug;
+ CdoDebug::PSTREAM = debug;
}
void
cdoInitialize(void *argument)
{
+ argument_t* argu = (argument_t *)argument;
#if defined(_OPENMP)
omp_set_num_threads(ompNumThreads); /* Have to be called for every module (pthread)! */
#endif
- processCreate();
+ process_t* process = processCreate(argu->argv[0]);
+ process->setStreams(argu->argc, argu->argv);
+
#if defined(HAVE_LIBPTHREAD)
- if (PSTREAM_Debug)
- Message("process %d thread %ld", processSelf().m_ID, pthread_self());
+ if (CdoDebug::PSTREAM)
+ MESSAGE("process ", processSelf().m_ID," thread ", pthread_self());
#endif
- processDefArgument(argument);
}
void
@@ -1752,8 +1760,8 @@ pstreamCloseAll()
{
if ( pstream_iter.second.m_fileID != CDI_UNDEFID )
{
- if (PSTREAM_Debug)
- Message("Close file %s id %d", pstream_iter.second.m_name.c_str(), pstream_iter.second.m_fileID);
+ if (CdoDebug::PSTREAM)
+ MESSAGE("Close file ", pstream_iter.second.m_name," id ", pstream_iter.second.m_fileID);
streamClose(pstream_iter.second.m_fileID);
}
}
@@ -1772,7 +1780,7 @@ pstreamCloseAll(void)
{
if (!pstreamptr->ispipe && pstreamptr->m_fileID != CDI_UNDEFID)
{
- if (PSTREAM_Debug)
+ if (CdoDebug::PSTREAM)
Message("Close file %s id %d", pstreamptr->m_name.c_str(), pstreamptr->m_fileID);
streamClose(pstreamptr->m_fileID);
}
diff --git a/src/pstream.h b/src/pstream.h
index ab7bbec..9f727d8 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -18,6 +18,10 @@
#ifndef PSTREAM_H
#define PSTREAM_H
+#ifdef HAVE_CONFIG_H
+#include "config.h" /* _FILE_OFFSET_BITS influence off_t */
+#endif
+
#include "pstream_write.h"
#include "varlist.h"
#include "argument.h"
@@ -81,8 +85,8 @@ int pstreamInqTimestep(int pstreamID, int tsID);
int pstreamInqRecord(int pstreamID, int *varID, int *levelID);
-void pstreamReadRecord(int pstreamID, double *data, int *nmiss);
-void pstreamReadRecordF(int pstreamID, float *data, int *nmiss);
+void pstreamReadRecord(int pstreamID, double *data, size_t *nmiss);
+void pstreamReadRecordF(int pstreamID, float *data, size_t *nmiss);
void pstreamCopyRecord(int pstreamIDdest, int pstreamIDsrc);
void pstreamInqGRIBinfo(int pstreamID, int *intnum, float *fltnum, off_t *bignum);
@@ -92,5 +96,6 @@ int pstreamFileID(int pstreamID);
void cdoVlistCopyFlag(int vlistID2, int vlistID1);
const int &getPthreadScope();
+pstream_t *create_pstream();
#endif /* PSTREAM_H */
diff --git a/src/pstream_write.h b/src/pstream_write.h
index f55a2bc..78c13f9 100644
--- a/src/pstream_write.h
+++ b/src/pstream_write.h
@@ -28,7 +28,7 @@ void pstreamDefTimestep(int pstreamID, int tsID);
void pstreamDefRecord(int pstreamID, int varID, int levelID);
-void pstreamWriteRecord(int pstreamID, double *data, int nmiss);
-void pstreamWriteRecordF(int pstreamID, float *data, int nmiss);
+void pstreamWriteRecord(int pstreamID, double *data, size_t nmiss);
+void pstreamWriteRecordF(int pstreamID, float *data, size_t nmiss);
#endif /* PSTREAM_WRITE_H */
diff --git a/src/remap.h b/src/remap.h
index 582217b..cc80312 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -1,6 +1,7 @@
-#ifndef _REMAP_H
-#define _REMAP_H
+#ifndef REMAP_H
+#define REMAP_H
+#include <stdint.h>
#include <math.h>
#ifndef M_PI
@@ -86,7 +87,7 @@ typedef struct {
bool non_global;
bool is_cyclic;
- int dims[2]; /* size of grid dimension */
+ size_t dims[2]; /* size of grid dimension */
int nvgp; /* size of vgpm */
int* vgpm; /* flag which cells are valid */
@@ -151,7 +152,7 @@ typedef struct {
int nused;
int gridID;
size_t gridsize;
- int nmiss;
+ size_t nmiss;
remapgrid_t src_grid;
remapgrid_t tgt_grid;
remapvars_t vars;
@@ -197,7 +198,7 @@ void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt
void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
-void resize_remap_vars(remapvars_t *rv, int increment);
+void resize_remap_vars(remapvars_t *rv, int64_t increment);
void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv, const double *restrict array1,
const double *restrict array2, double missval);
@@ -222,11 +223,11 @@ int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double
const double *restrict src_center_lat, const double *restrict src_center_lon);
int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats,
- double *restrict src_lons, double plat, double plon, const int *restrict src_grid_dims,
+ double *restrict src_lons, double plat, double plon, const size_t *restrict src_grid_dims,
const double *restrict src_center_lat, const double *restrict src_center_lon);
int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats,
- double *restrict src_lons, double plat, double plon, const int *restrict src_grid_dims,
+ double *restrict src_lons, double plat, double plon, const size_t *restrict src_grid_dims,
const double *restrict src_center_lat, const double *restrict src_center_lon,
const restr_t *restrict src_grid_bound_box, const size_t *restrict src_bin_add);
@@ -238,4 +239,4 @@ void remapgrid_get_lonlat(remapgrid_t *grid, size_t cell_add, double *plon, doub
void remapCheckArea(size_t grid_size, double *restrict cell_area, const char *name);
void remapCheckWeights(size_t num_links, size_t num_wts, int norm_opt, size_t *src_cell_add, size_t *tgt_cell_add, double *wts);
-#endif /* _REMAP_H */
+#endif /* REMAP_H */
diff --git a/src/remap_bicubic_scrip.cc b/src/remap_bicubic_scrip.cc
index b793129..e6c3f11 100644
--- a/src/remap_bicubic_scrip.cc
+++ b/src/remap_bicubic_scrip.cc
@@ -32,12 +32,12 @@ void set_bicubic_weights(double iw, double jw, double wgts[4][4])
wgts[3][3] = iw*(iw-1.)*(iw-1.) * jw*jw*(jw-1.);
}
-int num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4]);
+unsigned num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4]);
static
void renormalize_weights(const double src_lats[4], double wgts[4][4])
{
- int n;
+ unsigned n;
double sum_wgts = 0.0; /* sum of weights for normalization */
/* 2012-05-08 Uwe Schulzweida: using absolute value of src_lats (bug fix) */
for ( n = 0; n < 4; ++n ) sum_wgts += fabs(src_lats[n]);
@@ -50,11 +50,11 @@ void renormalize_weights(const double src_lats[4], double wgts[4][4])
static
void bicubic_warning(void)
{
- static int lwarn = TRUE;
+ static bool lwarn = true;
if ( cdoVerbose || lwarn )
{
- lwarn = FALSE;
+ lwarn = false;
// cdoWarning("Iteration for iw,jw exceed max iteration count of %d!", remap_max_iter);
cdoWarning("Bicubic interpolation failed for some grid points - used a distance-weighted average instead!");
}
@@ -65,7 +65,7 @@ void bicubic_remap(double* restrict tgt_point, const double* restrict src_array,
const double* restrict grad1, const double* restrict grad2, const double* restrict grad3)
{
*tgt_point = 0.;
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
*tgt_point += src_array[src_add[n]]*wgts[n][0] +
grad1[src_add[n]]*wgts[n][1] +
grad2[src_add[n]]*wgts[n][2] +
@@ -81,13 +81,6 @@ void bicubic_remap(double* restrict tgt_point, const double* restrict src_array,
*/
void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
{
- /* Local variables */
- int search_result;
- size_t src_add[4]; /* address for the four source points */
- double src_lats[4]; /* latitudes of four bilinear corners */
- double src_lons[4]; /* longitudes of four bilinear corners */
- double wgts[4][4]; /* bicubic weights for four corners */
- double plat, plon; /* lat/lon coords of destination point */
extern int timer_remap_bic;
int remap_grid_type = src_grid->remap_grid_type;
@@ -102,7 +95,7 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
if ( src_grid->rank != 2 )
cdoAbort("Can not do bicubic interpolation when source grid rank != 2");
- long tgt_grid_size = tgt_grid->size;
+ size_t tgt_grid_size = tgt_grid->size;
weightlinks4_t *weightlinks = (weightlinks4_t *) Malloc(tgt_grid_size*sizeof(weightlinks4_t));
weightlinks[0].addweights = (addweight4_t *) Malloc(4*tgt_grid_size*sizeof(addweight4_t));
@@ -115,10 +108,9 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
#if defined(_OPENMP)
#pragma omp parallel for default(none) \
- shared(weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
- private(src_add, src_lats, src_lons, wgts, plat, plon, search_result)
+ shared(weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex)
#endif
- for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+ for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
{
#if defined(_OPENMP)
#include "pragma_omp_atomic_update.h"
@@ -130,10 +122,16 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
- plat = tgt_grid->cell_center_lat[tgt_cell_add];
- plon = tgt_grid->cell_center_lon[tgt_cell_add];
+ double plat = tgt_grid->cell_center_lat[tgt_cell_add];
+ double plon = tgt_grid->cell_center_lon[tgt_cell_add];
+
+ size_t src_add[4]; // address for the four source points
+ double src_lats[4]; // latitudes of four bilinear corners
+ double src_lons[4]; // longitudes of four bilinear corners
+ double wgts[4][4]; // bicubic weights for four corners
/* Find nearest square of grid points on source grid */
+ int search_result;
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons,
plat, plon, src_grid->dims,
@@ -147,17 +145,16 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
/* Check to see if points are land points */
if ( search_result > 0 )
{
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
}
/* If point found, find local iw,jw coordinates for weights */
if ( search_result > 0 )
{
- double iw, jw; /* current guess for bilinear coordinate */
-
tgt_grid->cell_frac[tgt_cell_add] = 1.;
+ double iw, jw; /* current guess for bilinear coordinate */
if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
{
/* Successfully found iw,jw - compute weights */
@@ -207,20 +204,13 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
*/
void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double* restrict src_array, double* restrict tgt_array, double missval)
{
- /* Local variables */
- int search_result;
- size_t src_add[4]; /* address for the four source points */
- double src_lats[4]; /* latitudes of four bilinear corners */
- double src_lons[4]; /* longitudes of four bilinear corners */
- double wgts[4][4]; /* bicubic weights for four corners */
- double plat, plon; /* lat/lon coords of destination point */
int remap_grid_type = src_grid->remap_grid_type;
if ( cdoVerbose ) cdoPrint("Called %s()", __func__);
progressInit();
- long tgt_grid_size = tgt_grid->size;
+ size_t tgt_grid_size = tgt_grid->size;
/* Compute mappings from source to target grid */
@@ -239,10 +229,9 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
#if defined(_OPENMP)
#pragma omp parallel for default(none) \
- shared(remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, grad1_lat, grad1_lon, grad1_latlon, findex) \
- private(src_add, src_lats, src_lons, wgts, plat, plon, search_result)
+ shared(remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, grad1_lat, grad1_lon, grad1_latlon, findex)
#endif
- for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+ for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
{
#if defined(_OPENMP)
#include "pragma_omp_atomic_update.h"
@@ -254,10 +243,16 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
- plat = tgt_grid->cell_center_lat[tgt_cell_add];
- plon = tgt_grid->cell_center_lon[tgt_cell_add];
+ double plat = tgt_grid->cell_center_lat[tgt_cell_add];
+ double plon = tgt_grid->cell_center_lon[tgt_cell_add];
+
+ size_t src_add[4]; // address for the four source points
+ double src_lats[4]; // latitudes of four bilinear corners
+ double src_lons[4]; // longitudes of four bilinear corners
+ double wgts[4][4]; // bicubic weights for four corners
/* Find nearest square of grid points on source grid */
+ int search_result;
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons,
plat, plon, src_grid->dims,
@@ -271,17 +266,16 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
/* Check to see if points are land points */
if ( search_result > 0 )
{
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
}
/* If point found, find local iw,jw coordinates for weights */
if ( search_result > 0 )
{
- double iw, jw; /* current guess for bilinear coordinate */
-
tgt_grid->cell_frac[tgt_cell_add] = 1.;
+ double iw, jw; /* current guess for bilinear coordinate */
if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
{
/* Successfully found iw,jw - compute weights */
diff --git a/src/remap_bilinear_scrip.cc b/src/remap_bilinear_scrip.cc
index a87649e..a8cfd9a 100644
--- a/src/remap_bilinear_scrip.cc
+++ b/src/remap_bilinear_scrip.cc
@@ -92,11 +92,11 @@ void set_bilinear_weights(double iw, double jw, double wgts[4])
}
-int num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4])
+unsigned num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4])
{
- int icount = 0;
+ unsigned icount = 0;
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
{
if ( mask[src_add[n]] )
icount++;
@@ -112,8 +112,8 @@ void renormalize_weights(const double src_lats[4], double wgts[4])
{
double sum_wgts = 0.0; /* sum of weights for normalization */
/* 2012-05-08 Uwe Schulzweida: using absolute value of src_lats (bug fix) */
- for ( int n = 0; n < 4; ++n ) sum_wgts += fabs(src_lats[n]);
- for ( int n = 0; n < 4; ++n ) wgts[n] = fabs(src_lats[n])/sum_wgts;
+ for ( unsigned n = 0; n < 4; ++n ) sum_wgts += fabs(src_lats[n]);
+ for ( unsigned n = 0; n < 4; ++n ) wgts[n] = fabs(src_lats[n])/sum_wgts;
}
static
@@ -148,7 +148,7 @@ static
void bilinear_remap(double* restrict tgt_point, const double *restrict src_array, const double wgts[4], const size_t src_add[4])
{
// *tgt_point = 0.;
- // for ( int n = 0; n < 4; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
+ // for ( unsigned n = 0; n < 4; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
*tgt_point = src_array[src_add[0]]*wgts[0] + src_array[src_add[1]]*wgts[1]
+ src_array[src_add[2]]*wgts[2] + src_array[src_add[3]]*wgts[3];
}
@@ -162,12 +162,6 @@ void bilinear_remap(double* restrict tgt_point, const double *restrict src_array
*/
void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
{
- /* Local variables */
- int search_result;
- size_t src_add[4]; /* address for the four source points */
- double src_lats[4]; /* latitudes of four bilinear corners */
- double src_lons[4]; /* longitudes of four bilinear corners */
- double wgts[4]; /* bilinear weights for four corners */
extern int timer_remap_bil;
int remap_grid_type = src_grid->remap_grid_type;
@@ -182,11 +176,11 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
if ( src_grid->rank != 2 )
cdoAbort("Can not do bilinear interpolation when source grid rank != 2");
- long tgt_grid_size = tgt_grid->size;
+ size_t tgt_grid_size = tgt_grid->size;
weightlinks_t *weightlinks = (weightlinks_t *) Malloc(tgt_grid_size*sizeof(weightlinks_t));
weightlinks[0].addweights = (addweight_t *) Malloc(4*tgt_grid_size*sizeof(addweight_t));
- for ( unsigned tgt_cell_add = 1; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+ for ( size_t tgt_cell_add = 1; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
weightlinks[tgt_cell_add].addweights = weightlinks[0].addweights + 4*tgt_cell_add;
double findex = 0;
@@ -194,12 +188,10 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
/* Loop over destination grid */
#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
- shared(weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
- private(src_add, src_lats, src_lons, wgts, search_result) \
- schedule(static)
+#pragma omp parallel for default(none) schedule(static) \
+ shared(weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex)
#endif
- for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+ for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
{
#if defined(_OPENMP)
#include "pragma_omp_atomic_update.h"
@@ -214,7 +206,13 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
double plon = 0, plat = 0;
remapgrid_get_lonlat(tgt_grid, tgt_cell_add, &plon, &plat);
+ size_t src_add[4]; // address for the four source points
+ double src_lats[4]; // latitudes of four bilinear corners
+ double src_lons[4]; // longitudes of four bilinear corners
+ double wgts[4]; // bilinear weights for four corners
+
// Find nearest square of grid points on source grid
+ int search_result;
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons,
plat, plon, src_grid->dims,
@@ -228,17 +226,16 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
// Check to see if points are mask points
if ( search_result > 0 )
{
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
}
// If point found, find local iw,jw coordinates for weights
if ( search_result > 0 )
{
- double iw, jw; // current guess for bilinear coordinate
-
tgt_grid->cell_frac[tgt_cell_add] = 1.;
+ double iw, jw; // current guess for bilinear coordinate
if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
{
// Successfully found iw,jw - compute weights
@@ -287,12 +284,6 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
*/
void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval)
{
- /* Local variables */
- int search_result;
- size_t src_add[4]; /* address for the four source points */
- double src_lats[4]; /* latitudes of four bilinear corners */
- double src_lons[4]; /* longitudes of four bilinear corners */
- double wgts[4]; /* bilinear weights for four corners */
extern int timer_remap_bil;
int remap_grid_type = src_grid->remap_grid_type;
@@ -302,7 +293,7 @@ void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const do
progressInit();
- long tgt_grid_size = tgt_grid->size;
+ size_t tgt_grid_size = tgt_grid->size;
/* Compute mappings from source to target grid */
@@ -314,12 +305,10 @@ void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const do
/* Loop over destination grid */
#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
- shared(cdoSilentMode, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, findex) \
- private(src_add, src_lats, src_lons, wgts, search_result) \
- schedule(static)
+#pragma omp parallel for default(none) schedule(static) \
+ shared(cdoSilentMode, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, findex)
#endif
- for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+ for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
{
#if defined(_OPENMP)
#include "pragma_omp_atomic_update.h"
@@ -334,7 +323,13 @@ void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const do
double plon = 0, plat = 0;
remapgrid_get_lonlat(tgt_grid, tgt_cell_add, &plon, &plat);
+ size_t src_add[4]; // address for the four source points
+ double src_lats[4]; // latitudes of four bilinear corners
+ double src_lons[4]; // longitudes of four bilinear corners
+ double wgts[4]; // bilinear weights for four corners
+
// Find nearest square of grid points on source grid
+ int search_result;
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons,
plat, plon, src_grid->dims,
@@ -348,17 +343,16 @@ void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const do
// Check to see if points are mask points
if ( search_result > 0 )
{
- for ( int n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
}
// If point found, find local iw,jw coordinates for weights
if ( search_result > 0 )
{
- double iw, jw; // current guess for bilinear coordinate
-
tgt_grid->cell_frac[tgt_cell_add] = 1.;
+ double iw, jw; // current guess for bilinear coordinate
if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
{
// Successfully found iw,jw - compute weights
diff --git a/src/remap_conserv.cc b/src/remap_conserv.cc
index d6cd51d..f6822d9 100644
--- a/src/remap_conserv.cc
+++ b/src/remap_conserv.cc
@@ -108,7 +108,7 @@ void search_free(search_t *search)
int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm, const double *restrict xm);
static
-size_t get_srch_cells_reg2d(const int *restrict src_grid_dims,
+size_t get_srch_cells_reg2d(const size_t *restrict src_grid_dims,
const double *restrict src_corner_lat, const double *restrict src_corner_lon,
const double *restrict tgt_cell_bound_box, size_t *srch_add)
{
@@ -219,7 +219,7 @@ void restrict_boundbox(const double *restrict grid_bound_box, double *restrict b
}
static
-void boundbox_from_corners_reg2d(size_t grid_add, const int *restrict grid_dims, const double *restrict corner_lon,
+void boundbox_from_corners_reg2d(size_t grid_add, const size_t *restrict grid_dims, const double *restrict corner_lon,
const double *restrict corner_lat, double *restrict bound_box)
{
size_t nx = grid_dims[0];
diff --git a/src/remap_distwgt.cc b/src/remap_distwgt.cc
index 0a9407a..5d4dcf5 100644
--- a/src/remap_distwgt.cc
+++ b/src/remap_distwgt.cc
@@ -46,7 +46,7 @@ void nbr_check_distance(size_t num_neighbors, const size_t *restrict nbr_add, do
{
// If distance is zero, set to small number
for ( size_t nchk = 0; nchk < num_neighbors; ++nchk )
- if ( nbr_add[nchk] < ULONG_MAX && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
+ if ( nbr_add[nchk] < SIZE_MAX && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
}
@@ -61,7 +61,7 @@ double nbr_compute_weights(size_t num_neighbors, const int *restrict src_grid_ma
for ( size_t n = 0; n < num_neighbors; ++n )
{
nbr_mask[n] = false;
- if ( nbr_add[n] < ULONG_MAX )
+ if ( nbr_add[n] < SIZE_MAX )
if ( src_grid_mask[nbr_add[n]] )
{
nbr_dist[n] = 1./nbr_dist[n];
@@ -75,7 +75,7 @@ double nbr_compute_weights(size_t num_neighbors, const int *restrict src_grid_ma
for ( size_t n = 0; n < num_neighbors; ++n )
{
nbr_mask[n] = false;
- if ( nbr_add[n] < ULONG_MAX )
+ if ( nbr_add[n] < SIZE_MAX )
{
nbr_dist[n] = 1./nbr_dist[n];
dist_tot += nbr_dist[n];
@@ -113,8 +113,8 @@ size_t nbr_normalize_weights(size_t num_neighbors, double dist_tot, const bool *
#define MAX_SEARCH_CELLS 25
static
-void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgrid_t *src_grid, size_t *restrict nbr_add, double *restrict nbr_dist,
- double plon, double plat, const int *restrict src_grid_dims)
+void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist,
+ double plon, double plat)
{
/*
Output variables:
@@ -127,14 +127,13 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
double plat, ! latitude of the search point
double plon, ! longitude of the search point
*/
- size_t n, nadd;
+ size_t n;
size_t ii, jj;
long i, j, ix;
size_t src_add[MAX_SEARCH_CELLS];
size_t *src_add_tmp = NULL;
size_t *psrc_add = src_add;
size_t num_add = 0;
- double distance; // Angular distance
double cos_search_radius = cos(gs->search_radius);
double coslat_dst = cos(plat); // cos(lat) of the search point
double coslon_dst = cos(plon); // cos(lon) of the search point
@@ -147,11 +146,11 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
double *restrict src_center_lon = gs->reg2d_center_lon;
double *restrict src_center_lat = gs->reg2d_center_lat;
- long nx = src_grid_dims[0];
- long ny = src_grid_dims[1];
+ long nx = gs->dims[0];
+ long ny = gs->dims[1];
size_t nxm = nx;
- if ( src_grid->is_cyclic ) nxm++;
+ if ( gs->is_cyclic ) nxm++;
if ( plon < src_center_lon[0] ) plon += PI2;
if ( plon > src_center_lon[nxm-1] ) plon -= PI2;
@@ -160,7 +159,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
if ( lfound )
{
- if ( src_grid->is_cyclic && ii == (nxm-1) ) ii = 0;
+ if ( gs->is_cyclic && ii == (nxm-1) ) ii = 0;
long k;
for ( k = 3; k < 10000; k+=2 )
@@ -183,7 +182,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
{
ix = i;
- if ( src_grid->is_cyclic )
+ if ( gs->is_cyclic )
{
if ( ix < 0 ) ix += nx;
if ( ix >= nx ) ix -= nx;
@@ -197,18 +196,19 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
// Initialize distance and address arrays
for ( n = 0; n < num_neighbors; ++n )
{
- nbr_add[n] = ULONG_MAX;
+ nbr_add[n] = SIZE_MAX;
nbr_dist[n] = BIGNUM;
}
if ( lfound )
{
size_t ix, iy;
+ size_t nadd;
+ double distance; // Angular distance
for ( size_t na = 0; na < num_add; ++na )
{
nadd = psrc_add[na];
-
iy = nadd/nx;
ix = nadd - iy*nx;
@@ -232,7 +232,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
if ( src_add_tmp ) Free(src_add_tmp);
}
- else if ( src_grid->lextrapolate )
+ else if ( gs->extrapolate )
{
int search_result;
@@ -240,7 +240,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
{
size_t nbr_add4[4];
double nbr_dist4[4];
- for ( n = 0; n < num_neighbors; ++n ) nbr_add4[n] = ULONG_MAX;
+ for ( n = 0; n < num_neighbors; ++n ) nbr_add4[n] = SIZE_MAX;
search_result = grid_search_reg2d_nn(nx, ny, nbr_add4, nbr_dist4, plat, plon, src_center_lat, src_center_lon);
if ( search_result < 0 )
{
@@ -254,7 +254,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgri
}
if ( search_result >= 0 )
- for ( n = 0; n < num_neighbors; ++n ) nbr_add[n] = ULONG_MAX;
+ for ( n = 0; n < num_neighbors; ++n ) nbr_add[n] = SIZE_MAX;
}
} // grid_search_nbr_reg2d
@@ -276,7 +276,7 @@ int grid_search_nbr(struct gridsearch *gs, size_t num_neighbors, size_t *restric
double search_radius = gs->search_radius;
// Initialize distance and address arrays
- for ( size_t n = 0; n < num_neighbors; ++n ) nbr_add[n] = ULONG_MAX;
+ for ( size_t n = 0; n < num_neighbors; ++n ) nbr_add[n] = SIZE_MAX;
for ( size_t n = 0; n < num_neighbors; ++n ) nbr_dist[n] = BIGNUM;
size_t ndist = num_neighbors;
@@ -371,9 +371,6 @@ void remap_distwgt_weights(size_t num_neighbors, remapgrid_t *src_grid, remapgri
size_t src_grid_size = src_grid->size;
size_t tgt_grid_size = tgt_grid->size;
- size_t nx = src_grid->dims[0];
- size_t ny = src_grid->dims[1];
- bool lcyclic = src_grid->is_cyclic;
weightlinks_t *weightlinks = (weightlinks_t *) Malloc(tgt_grid_size*sizeof(weightlinks_t));
weightlinks[0].addweights = (addweight_t *) Malloc(num_neighbors*tgt_grid_size*sizeof(addweight_t));
@@ -391,12 +388,14 @@ void remap_distwgt_weights(size_t num_neighbors, remapgrid_t *src_grid, remapgri
struct gridsearch *gs = NULL;
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
- gs = gridsearch_create_reg2d(lcyclic, nx, ny, src_grid->reg2d_center_lon, src_grid->reg2d_center_lat);
+ gs = gridsearch_create_reg2d(src_grid->is_cyclic, src_grid->dims, src_grid->reg2d_center_lon, src_grid->reg2d_center_lat);
else if ( num_neighbors == 1 )
gs = gridsearch_create_nn(src_grid_size, src_grid->cell_center_lon, src_grid->cell_center_lat);
else
gs = gridsearch_create(src_grid_size, src_grid->cell_center_lon, src_grid->cell_center_lat);
+ if ( src_grid->lextrapolate ) gridsearch_extrapolate(gs);
+
#if defined(_OPENMP)
if ( cdoVerbose ) printf("gridsearch created: %.2f seconds\n", omp_get_wtime()-start);
if ( cdoVerbose ) start = omp_get_wtime();
@@ -430,8 +429,7 @@ void remap_distwgt_weights(size_t num_neighbors, remapgrid_t *src_grid, remapgri
// Find nearest grid points on source grid and distances to each point
if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
- grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add[ompthID], nbr_dist[ompthID],
- plon, plat, src_grid->dims);
+ grid_search_nbr_reg2d(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
else
grid_search_nbr(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
@@ -485,9 +483,6 @@ void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt
size_t src_grid_size = src_grid->size;
size_t tgt_grid_size = tgt_grid->size;
- size_t nx = src_grid->dims[0];
- size_t ny = src_grid->dims[1];
- bool lcyclic = src_grid->is_cyclic;
NEW_2D(bool, nbr_mask, ompNumThreads, num_neighbors); // mask at nearest neighbors
NEW_2D(size_t, nbr_add, ompNumThreads, num_neighbors); // source address at nearest neighbors
@@ -500,12 +495,14 @@ void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt
struct gridsearch *gs = NULL;
if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
- gs = gridsearch_create_reg2d(lcyclic, nx, ny, src_grid->reg2d_center_lon, src_grid->reg2d_center_lat);
+ gs = gridsearch_create_reg2d(src_grid->is_cyclic, src_grid->dims, src_grid->reg2d_center_lon, src_grid->reg2d_center_lat);
else if ( num_neighbors == 1 )
gs = gridsearch_create_nn(src_grid_size, src_grid->cell_center_lon, src_grid->cell_center_lat);
else
gs = gridsearch_create(src_grid_size, src_grid->cell_center_lon, src_grid->cell_center_lat);
+ if ( src_grid->lextrapolate ) gridsearch_extrapolate(gs);
+
#if defined(_OPENMP)
if ( cdoVerbose ) printf("gridsearch created: %.2f seconds\n", omp_get_wtime()-start);
if ( cdoVerbose ) start = omp_get_wtime();
@@ -539,8 +536,7 @@ void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt
// Find nearest grid points on source grid and distances to each point
if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
- grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add[ompthID], nbr_dist[ompthID],
- plon, plat, src_grid->dims);
+ grid_search_nbr_reg2d(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
else
grid_search_nbr(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
diff --git a/src/remap_scrip_io.cc b/src/remap_scrip_io.cc
index c38937c..14fd801 100644
--- a/src/remap_scrip_io.cc
+++ b/src/remap_scrip_io.cc
@@ -384,8 +384,11 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
// Write mapping data
- nce(nc_put_var_int(nc_file_id, nc_srcgrddims_id, src_grid.dims));
- nce(nc_put_var_int(nc_file_id, nc_dstgrddims_id, tgt_grid.dims));
+ int dims[2];
+ dims[0] = (int)src_grid.dims[0]; dims[1] = (int)src_grid.dims[1];
+ nce(nc_put_var_int(nc_file_id, nc_srcgrddims_id, dims));
+ dims[0] = (int)tgt_grid.dims[0]; dims[1] = (int)tgt_grid.dims[1];
+ nce(nc_put_var_int(nc_file_id, nc_dstgrddims_id, dims));
nce(nc_put_var_int(nc_file_id, nc_srcgrdimask_id, src_grid.mask));
nce(nc_put_var_int(nc_file_id, nc_dstgrdimask_id, tgt_grid.mask));
@@ -694,7 +697,7 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
rv->max_links = rv->num_links;
- rv->resize_increment = (int) (0.1 * MAX(src_grid->size, tgt_grid->size));
+ rv->resize_increment = (size_t) (0.1 * MAX(src_grid->size, tgt_grid->size));
// Allocate address and weight arrays for mapping 1
@@ -747,7 +750,9 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
// Read all variables
- nce(nc_get_var_int(nc_file_id, nc_srcgrddims_id, src_grid->dims));
+ int dims[2];
+ nce(nc_get_var_int(nc_file_id, nc_srcgrddims_id, dims));
+ src_grid->dims[0] = dims[0]; src_grid->dims[1] = dims[1];
nce(nc_get_var_int(nc_file_id, nc_srcgrdimask_id, src_grid->mask));
@@ -779,7 +784,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
nce(nc_get_var_double(nc_file_id, nc_srcgrdfrac_id, src_grid->cell_frac));
- nce(nc_get_var_int(nc_file_id, nc_dstgrddims_id, tgt_grid->dims));
+ nce(nc_get_var_int(nc_file_id, nc_dstgrddims_id, dims));
+ tgt_grid->dims[0] = dims[0]; tgt_grid->dims[1] = dims[1];
nce(nc_get_var_int(nc_file_id, nc_dstgrdimask_id, tgt_grid->mask));
diff --git a/src/remap_search_latbins.cc b/src/remap_search_latbins.cc
index 8d25ab3..345d0de 100644
--- a/src/remap_search_latbins.cc
+++ b/src/remap_search_latbins.cc
@@ -45,22 +45,17 @@ void calc_bin_addr(size_t gridsize, size_t nbins, const restr_t* restrict bin_la
void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
{
- size_t nbins;
- size_t n; /* Loop counter */
size_t n2;
- double dlat; /* lat/lon intervals for search bins */
- restr_t *bin_lats = NULL;
-
- nbins = src_grid->num_srch_bins;
- dlat = PI/nbins;
+ size_t nbins = src_grid->num_srch_bins;
+ double dlat = PI/nbins; // lat/lon intervals for search bins
if ( cdoVerbose ) cdoPrint("Using %d latitude bins to restrict search.", nbins);
if ( nbins > 0 )
{
- bin_lats = src_grid->bin_lats = (restr_t*) Realloc(src_grid->bin_lats, 2*nbins*sizeof(restr_t));
+ restr_t *bin_lats = src_grid->bin_lats = (restr_t*) Realloc(src_grid->bin_lats, 2*nbins*sizeof(restr_t));
- for ( n = 0; n < nbins; ++n )
+ for ( size_t n = 0; n < nbins; ++n )
{
n2 = n<<1;
bin_lats[n2 ] = RESTR_SCALE((n )*dlat - PIH);
@@ -96,20 +91,15 @@ void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
size_t get_srch_cells(size_t tgt_cell_add, size_t nbins, size_t *bin_addr1, size_t *bin_addr2,
restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, size_t src_grid_size, size_t *srch_add)
{
- size_t num_srch_cells; /* num cells in restricted search arrays */
- size_t min_add; /* addresses for restricting search of */
- size_t max_add; /* destination grid */
- size_t n, n2; /* generic counters */
- size_t src_cell_add; /* current linear address for src cell */
+ size_t n2;
size_t src_cell_addm4;
- restr_t bound_box_lat1, bound_box_lat2, bound_box_lon1, bound_box_lon2;
/* Restrict searches first using search bins */
- min_add = src_grid_size - 1;
- max_add = 0;
+ size_t min_add = src_grid_size - 1;
+ size_t max_add = 0;
- for ( n = 0; n < nbins; ++n )
+ for ( size_t n = 0; n < nbins; ++n )
{
n2 = n<<1;
if ( tgt_cell_add >= bin_addr1[n2] && tgt_cell_add <= bin_addr1[n2+1] )
@@ -121,13 +111,13 @@ size_t get_srch_cells(size_t tgt_cell_add, size_t nbins, size_t *bin_addr1, size
/* Further restrict searches using bounding boxes */
- bound_box_lat1 = tgt_cell_bound_box[0];
- bound_box_lat2 = tgt_cell_bound_box[1];
- bound_box_lon1 = tgt_cell_bound_box[2];
- bound_box_lon2 = tgt_cell_bound_box[3];
+ restr_t bound_box_lat1 = tgt_cell_bound_box[0];
+ restr_t bound_box_lat2 = tgt_cell_bound_box[1];
+ restr_t bound_box_lon1 = tgt_cell_bound_box[2];
+ restr_t bound_box_lon2 = tgt_cell_bound_box[3];
- num_srch_cells = 0;
- for ( src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
+ size_t num_srch_cells = 0;
+ for ( size_t src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
{
src_cell_addm4 = src_cell_add<<2;
if ( (src_cell_bound_box[src_cell_addm4+2] <= bound_box_lon2) &&
@@ -155,7 +145,7 @@ size_t get_srch_cells(size_t tgt_cell_add, size_t nbins, size_t *bin_addr1, size
bound_box_lon2 -= RESTR_SCALE(PI2);
}
- for ( src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
+ for ( size_t src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
{
src_cell_addm4 = src_cell_add<<2;
if ( (src_cell_bound_box[src_cell_addm4+2] <= bound_box_lon2) &&
@@ -187,17 +177,15 @@ int grid_search_nn(size_t min_add, size_t max_add, size_t *restrict nbr_add, dou
const double *restrict src_center_lat, const double *restrict src_center_lon)
{
int search_result = 0;
- size_t n, srch_add;
- size_t i;
- double dist_min, distance; /* For computing dist-weighted avg */
+ double distance; /* For computing dist-weighted avg */
double coslat_dst = cos(plat);
double sinlat_dst = sin(plat);
double coslon_dst = cos(plon);
double sinlon_dst = sin(plon);
- dist_min = BIGNUM;
- for ( n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;
- for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
+ double dist_min = BIGNUM;
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;
+ for ( size_t srch_add = min_add; srch_add <= max_add; ++srch_add )
{
distance = acos(coslat_dst*cos(src_center_lat[srch_add])*
(coslon_dst*cos(src_center_lon[srch_add]) +
@@ -206,11 +194,11 @@ int grid_search_nn(size_t min_add, size_t max_add, size_t *restrict nbr_add, dou
if ( distance < dist_min )
{
- for ( n = 0; n < 4; ++n )
+ for ( unsigned n = 0; n < 4; ++n )
{
if ( distance < nbr_dist[n] )
{
- for ( i = 3; i > n; --i )
+ for ( unsigned i = 3; i > n; --i )
{
nbr_add [i] = nbr_add [i-1];
nbr_dist[i] = nbr_dist[i-1];
@@ -225,17 +213,17 @@ int grid_search_nn(size_t min_add, size_t max_add, size_t *restrict nbr_add, dou
}
}
- for ( n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
distance = 0.0;
- for ( n = 0; n < 4; ++n ) distance += nbr_dist[n];
- for ( n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
+ for ( unsigned n = 0; n < 4; ++n ) distance += nbr_dist[n];
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
return search_result;
}
int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats,
- double *restrict src_lons, double plat, double plon, const int *restrict src_grid_dims,
+ double *restrict src_lons, double plat, double plon, const size_t *restrict src_grid_dims,
const double *restrict src_center_lat, const double *restrict src_center_lon,
const restr_t *restrict src_grid_bound_box, const size_t *restrict src_bin_add)
{
@@ -261,7 +249,7 @@ int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restric
int src_bin_add[][2] ! latitude bins for restricting
*/
/* Local variables */
- size_t n, n2, next_n, srch_add, srch_add4; /* dummy indices */
+ size_t n2, next_n, srch_add, srch_add4; /* dummy indices */
/* Vectors for cross-product check */
double vec1_lat, vec1_lon;
double vec2_lat, vec2_lon;
@@ -276,7 +264,7 @@ int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restric
// restrict search first using bins
- for ( n = 0; n < 4; ++n ) src_add[n] = 0;
+ for ( unsigned n = 0; n < 4; ++n ) src_add[n] = 0;
// addresses for restricting search
size_t min_add = src_grid->size-1;
@@ -307,6 +295,8 @@ int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restric
rlat >= src_grid_bound_box[srch_add4 ] &&
rlat <= src_grid_bound_box[srch_add4+1])
{
+ unsigned n;
+
/* We are within bounding box so get really serious */
/* Determine neighbor addresses */
diff --git a/src/remap_search_reg2d.cc b/src/remap_search_reg2d.cc
index 3aaea0e..da34f58 100644
--- a/src/remap_search_reg2d.cc
+++ b/src/remap_search_reg2d.cc
@@ -6,20 +6,13 @@ int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double
const double *restrict src_center_lat, const double *restrict src_center_lon)
{
int search_result = 0;
- size_t n, srch_add;
- size_t i;
- size_t ii, jj;
- size_t jjskip;
- double coslat, sinlat;
- double dist_min, distance; /* For computing dist-weighted avg */
- double *sincoslon;
double coslat_dst = cos(plat);
double sinlat_dst = sin(plat);
double coslon_dst = cos(plon);
double sinlon_dst = sin(plon);
- dist_min = BIGNUM;
- for ( n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;
+ double dist_min = BIGNUM;
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;
size_t jjf = 0, jjl = ny-1;
if ( plon >= src_center_lon[0] && plon <= src_center_lon[nx-1] )
@@ -40,33 +33,31 @@ int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double
}
}
- sincoslon = (double*) Malloc(nx*sizeof(double));
+ double *sincoslon = (double*) Malloc(nx*sizeof(double));
- for ( ii = 0; ii < nx; ++ii )
+ for ( size_t ii = 0; ii < nx; ++ii )
sincoslon[ii] = coslon_dst*cos(src_center_lon[ii]) + sinlon_dst*sin(src_center_lon[ii]);
- for ( jj = jjf; jj <= jjl; ++jj )
+ for ( size_t jj = jjf; jj <= jjl; ++jj )
{
- coslat = coslat_dst*cos(src_center_lat[jj]);
- sinlat = sinlat_dst*sin(src_center_lat[jj]);
+ double coslat = coslat_dst*cos(src_center_lat[jj]);
+ double sinlat = sinlat_dst*sin(src_center_lat[jj]);
- jjskip = jj > 1 && jj < (ny-2);
+ size_t jjskip = jj > 1 && jj < (ny-2);
- for ( ii = 0; ii < nx; ++ii )
+ for ( size_t ii = 0; ii < nx; ++ii )
{
if ( jjskip && ii > 1 && ii < (nx-2) ) continue;
- srch_add = jj*nx + ii;
-
- distance = acos(coslat*sincoslon[ii] + sinlat);
-
+ double distance = acos(coslat*sincoslon[ii] + sinlat);
if ( distance < dist_min )
{
- for ( n = 0; n < 4; ++n )
+ size_t srch_add = jj*nx + ii;
+ for ( unsigned n = 0; n < 4; ++n )
{
if ( distance < nbr_dist[n] )
{
- for ( i = 3; i > n; --i )
+ for ( unsigned i = 3; i > n; --i )
{
nbr_add [i] = nbr_add [i-1];
nbr_dist[i] = nbr_dist[i-1];
@@ -84,17 +75,17 @@ int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double
Free(sincoslon);
- for ( n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
- distance = 0.0;
- for ( n = 0; n < 4; ++n ) distance += nbr_dist[n];
- for ( n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
+ double distance = 0.0;
+ for ( unsigned n = 0; n < 4; ++n ) distance += nbr_dist[n];
+ for ( unsigned n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
- return (search_result);
+ return search_result;
}
int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats,
- double *restrict src_lons, double plat, double plon, const int *restrict src_grid_dims,
+ double *restrict src_lons, double plat, double plon, const size_t *restrict src_grid_dims,
const double *restrict src_center_lat, const double *restrict src_center_lon)
{
/*
@@ -114,12 +105,9 @@ int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *r
double src_center_lat[] ! latitude of each src grid center
double src_center_lon[] ! longitude of each src grid center
*/
- /* Local variables */
int search_result = 0;
- long n;
- size_t ii, iix, jj;
- for ( n = 0; n < 4; ++n ) src_add[n] = 0;
+ for ( unsigned n = 0; n < 4; ++n ) src_add[n] = 0;
size_t nx = src_grid_dims[0];
size_t ny = src_grid_dims[1];
@@ -130,11 +118,12 @@ int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *r
if ( /*plon < 0 &&*/ plon < src_center_lon[0] ) plon += PI2;
if ( /*plon > PI2 &&*/ plon > src_center_lon[nxm-1] ) plon -= PI2;
+ size_t ii, jj;
int lfound = rect_grid_search(&ii, &jj, plon, plat, nxm, ny, src_center_lon, src_center_lat);
if ( lfound )
{
- iix = ii;
+ size_t iix = ii;
if ( src_grid->is_cyclic && iix == (nxm-1) ) iix = 0;
src_add[0] = (jj-1)*nx+(ii-1);
src_add[1] = (jj-1)*nx+(iix);
@@ -175,5 +164,5 @@ int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *r
*/
search_result = grid_search_reg2d_nn(nx, ny, src_add, src_lats, plat, plon, src_center_lat, src_center_lon);
- return (search_result);
+ return search_result;
} /* grid_search_reg2d */
diff --git a/src/remap_store_link_cnsrv.cc b/src/remap_store_link_cnsrv.cc
index 719425e..ae215d9 100644
--- a/src/remap_store_link_cnsrv.cc
+++ b/src/remap_store_link_cnsrv.cc
@@ -27,7 +27,7 @@ void grid_store_init(grid_store_t* grid_store, long gridsize)
if ( grid_store->max_size%grid_store->blk_size > 0 ) grid_store->nblocks++;
if ( cdoVerbose )
- fprintf(stdout, "blksize = %zu lastblksize = %zu max_size = %zu nblocks = %zu\n",
+ fprintf(stdout, "blksize = %ld lastblksize = %ld max_size = %ld nblocks = %ld\n",
grid_store->blk_size, grid_store->max_size%grid_store->blk_size,
grid_store->max_size, grid_store->nblocks);
diff --git a/src/remaplib.cc b/src/remaplib.cc
index 9410e98..578fd48 100644
--- a/src/remaplib.cc
+++ b/src/remaplib.cc
@@ -413,6 +413,7 @@ void check_lat_boundbox_range(size_t nlats, restr_t *restrict bound_box, double
static
int expand_lonlat_grid(int gridID)
{
+ if ( cdoVerbose ) cdoPrint("expand_lonlat_grid");
size_t nx = gridInqXsize(gridID);
size_t ny = gridInqYsize(gridID);
size_t nxp4 = nx+4;
@@ -459,6 +460,7 @@ int expand_lonlat_grid(int gridID)
static
int expand_curvilinear_grid(int gridID)
{
+ if ( cdoVerbose ) cdoPrint("expand_curvilinear_grid");
size_t gridsize = gridInqSize(gridID);
long nx = (long) gridInqXsize(gridID);
long ny = (long) gridInqYsize(gridID);
@@ -523,7 +525,7 @@ int expand_curvilinear_grid(int gridID)
/*****************************************************************************/
static
-void grid_check_lat_borders_rad(int n, double *ybounds)
+void grid_check_lat_borders_rad(size_t n, double *ybounds)
{
#define YLIM (88*DEG2RAD)
if ( ybounds[0] > ybounds[n-1] )
@@ -726,14 +728,11 @@ void cell_bounding_boxes(remapgrid_t *grid, int remap_grid_basis)
}
else /* full grid search */
{
- size_t gridsize;
- size_t i, i4;
-
- gridsize = grid->size;
-
if ( cdoVerbose ) cdoPrint("Grid: bounds missing -> full grid search!");
- for ( i = 0; i < gridsize; ++i )
+ size_t gridsize = grid->size;
+ size_t i4;
+ for ( size_t i = 0; i < gridsize; ++i )
{
i4 = i<<2;
grid->cell_bound_box[i4 ] = RESTR_SCALE(-PIH);
@@ -794,10 +793,7 @@ void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t
if ( map_type == MAP_TYPE_BILINEAR && src_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D ) tgt_grid->remap_grid_type = REMAP_GRID_TYPE_REG2D;
}
- if ( lextrapolate )
- src_grid->lextrapolate = true;
- else
- src_grid->lextrapolate = false;
+ src_grid->lextrapolate = lextrapolate;
if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSERV_YAC )
{
@@ -869,7 +865,6 @@ void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t
//if ( src_grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
remap_define_grid(map_type, gridID1, src_grid, "Source");
-
remap_define_grid(map_type, gridID2, tgt_grid, "Target");
if ( src_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D && tgt_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -982,7 +977,7 @@ void remap_vars_init(int map_type, size_t src_grid_size, size_t tgt_grid_size, r
/*
This routine resizes remapping arrays by increasing(decreasing) the max_links by increment
*/
-void resize_remap_vars(remapvars_t *rv, int increment)
+void resize_remap_vars(remapvars_t *rv, int64_t increment)
{
/*
Input variables:
@@ -1171,7 +1166,7 @@ size_t get_max_add(size_t num_links, size_t size, const size_t *restrict add)
static
size_t binary_search_int(const size_t *array, size_t len, size_t value)
{
- long low = 0, high = len - 1, midpoint = 0;
+ int64_t low = 0, high = len - 1, midpoint = 0;
while ( low <= high )
{
@@ -1471,7 +1466,7 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
#endif
for ( size_t n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_cell_add[n]]++;
- size_t imin = ULONG_MAX;
+ size_t imin = SIZE_MAX;
size_t imax = 0;
for ( size_t n = 0; n < tgt_grid.size; ++n )
{
diff --git a/src/sellist.cc b/src/sellist.cc
index aab80ae..944979c 100644
--- a/src/sellist.cc
+++ b/src/sellist.cc
@@ -115,7 +115,7 @@ int sellist_add(sellist_t *sellist, const char *txt, const char *name, int type)
if ( first == last )
{
- ((int*)e->cvalues)[j++] = parameter2int(e->values[i]);
+ ((int*)e->cvalues)[j++] = first;
}
else
{
@@ -126,17 +126,20 @@ int sellist_add(sellist_t *sellist, const char *txt, const char *name, int type)
for ( int ival = first; ival >= last; ival += inc ) k++;
e->nvalues += k-1;
- e->cvalues = Realloc(e->cvalues, e->nvalues*sizeof(int));
-
- if ( inc >= 0 )
+ if ( e->nvalues )
{
- for ( int ival = first; ival <= last; ival += inc )
- ((int*)e->cvalues)[j++] = ival;
- }
- else
- {
- for ( int ival = first; ival >= last; ival += inc )
- ((int*)e->cvalues)[j++] = ival;
+ e->cvalues = Realloc(e->cvalues, e->nvalues*sizeof(int));
+
+ if ( inc >= 0 )
+ {
+ for ( int ival = first; ival <= last; ival += inc )
+ ((int*)e->cvalues)[j++] = ival;
+ }
+ else
+ {
+ for ( int ival = first; ival >= last; ival += inc )
+ ((int*)e->cvalues)[j++] = ival;
+ }
}
}
@@ -358,8 +361,11 @@ void sellist_print(sellist_t *sellist)
int nvalues = e->nvalues;
if ( nvalues > 12 ) nvalues = 11;
for ( int i = 0; i < nvalues; ++i ) sellist_print_val(e->type, (cvalues_t *)e->cvalues, i);
- if ( nvalues < e->nvalues ) printf(" ...");
- sellist_print_val(e->type, (cvalues_t *)e->cvalues, e->nvalues-1);
+ if ( nvalues < e->nvalues )
+ {
+ printf(" ...");
+ sellist_print_val(e->type, (cvalues_t *)e->cvalues, e->nvalues-1);
+ }
printf("\n");
}
}
diff --git a/src/util.cc b/src/util.cc
index 790bdde..b51d6f2 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -15,22 +15,23 @@
GNU General Public License for more details.
*/
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#if defined(_OPENMP)
+#ifdef _OPENMP
#include <omp.h>
#endif
-#if defined(HAVE_FNMATCH_H)
+#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#include <stdio.h>
#include <string.h>
-#include <ctype.h> /* tolower */
+#include <ctype.h> /* tolower */
+#include <inttypes.h> /* intmax_t */
#include "cdi.h"
#include "cdo.h"
@@ -39,22 +40,17 @@
#include "util.h"
-#if ! defined(VERSION)
+#ifndef VERSION
#define VERSION "0.0.1"
#endif
-/* refactor: moved here from *.c */
-
-int CDO_opterr = 0; // refactor: moved here from cdo_getopt.cc
-const char *CDO_optarg = NULL; // refactor: moved here from cdo_getopt.cc
-int CDO_optind = 1; // refactor: moved here from cdo_getopt.cc
-
+int CDO_opterr = 0;
+const char *CDO_optarg = NULL;
+int CDO_optind = 1;
-/* refactor: moved here from cdo.cc */
-
-char *Progname;
-const char *CDO_Version = "Climate Data Operators version " VERSION" (http://mpimet.mpg.de/cdo)";
+const char *CDO_progname = NULL;
+const char *CDO_version = "Climate Data Operators version " VERSION" (http://mpimet.mpg.de/cdo)";
int ompNumThreads = 1;
@@ -68,7 +64,7 @@ int cdoDefaultFileType = CDI_UNDEFID;
int cdoDefaultDataType = CDI_UNDEFID;
int cdoDefaultByteorder = CDI_UNDEFID;
int cdoDefaultTableID = CDI_UNDEFID;
-int cdoDefaultInstID = CDI_UNDEFID; // moved here from institution.cc, was UNDEFID
+int cdoDefaultInstID = CDI_UNDEFID;
int cdoDefaultTimeType = CDI_UNDEFID;
int cdoLockIO = FALSE;
@@ -112,7 +108,7 @@ char **cdoVarnames = NULL;
char CDO_File_Suffix[32];
int cdoExpMode = -1;
-const char *cdoExpName = NULL;
+const char *cdoExpName = NULL;
int timer_read, timer_write;
@@ -125,8 +121,8 @@ const char *cdoComment(void)
{
init = true;
- int size = strlen(CDO_Version);
- strncat(comment, CDO_Version, size);
+ int size = strlen(CDO_version);
+ strncat(comment, CDO_version, size);
comment[size] = 0;
}
@@ -184,7 +180,7 @@ void cdo_omp_set_num_threads(int nthreads)
}
-char *getProgname(char *string)
+const char *getProgname(char *string)
{
#if defined(_WIN32)
/* progname = strrchr(string, '\\'); */
@@ -193,8 +189,10 @@ char *getProgname(char *string)
char *progname = strrchr(string, '/');
#endif
- if ( progname == NULL ) progname = string;
- else progname++;
+ if ( progname == NULL )
+ progname = string;
+ else
+ progname++;
return progname;
}
@@ -216,53 +214,50 @@ char *getOperator(const char *argument)
}
-const char *getOperatorName(const char *operatorArg)
+const char *getOperatorName(const char *operatorCommand)
{
char *operatorName = NULL;
- if ( operatorArg )
+ if ( operatorCommand )
{
- if ( operatorArg[0] == '-' )
- {
- operatorArg++;
- }
- char *commapos = (char *)strchr(operatorArg, ',');
- size_t len = (commapos != NULL) ? (size_t)(commapos - operatorArg) : strlen(operatorArg);
+ if ( operatorCommand[0] == '-' ) operatorCommand++;
+ char *commapos = (char *)strchr(operatorCommand, ',');
+ size_t len = (commapos != NULL) ? (size_t)(commapos - operatorCommand) : strlen(operatorCommand);
operatorName = (char*) Malloc(len+1);
- memcpy(operatorName, operatorArg, len);
+ memcpy(operatorName, operatorCommand, len);
operatorName[len] = '\0';
}
/* return operatorName; */
if(is_alias(operatorName))
- {
- operatorName = get_original(operatorName);
- }
- return operatorName;
+ {
+ operatorName = get_original(operatorName);
+ }
+
+ return operatorName;
}
-char *getOperatorArg(const char *xoperator)
+char *getOperatorArg(const char *p_operatorCommand)
{
- char *operatorArg = NULL;
+ char *operatorCommand = NULL;
- if ( xoperator )
+ if ( p_operatorCommand )
{
- char *commapos = (char *)strchr(xoperator, ',');
-
+ char *commapos = (char *)strchr(p_operatorCommand, ',');
if ( commapos )
{
size_t len = strlen(commapos+1);
if ( len )
{
- operatorArg = (char*) Malloc(len+1);
- strcpy(operatorArg, commapos+1);
+ operatorCommand = (char*) Malloc(len+1);
+ strcpy(operatorCommand, commapos+1);
}
}
}
- return operatorArg;
+ return operatorCommand;
}
char *getFileArg(char *argument)
@@ -272,7 +267,6 @@ char *getFileArg(char *argument)
if ( argument )
{
char *blankpos = strchr(argument, ' ');
-
if ( blankpos )
{
char *parg = blankpos + 1;
@@ -327,13 +321,11 @@ void input_int(char *arg, int intarr[], int maxint, int *nintfound)
std::string string2lower(std::string str)
{
- std::string lower_case_string = str;
- for(char c : str)
- {
- c = tolower(c);
- }
- return lower_case_string;
+ std::string lower_case_string = str;
+ for(char c : str) c = tolower(c);
+ return lower_case_string;
}
+
void strtolower(char *str)
{
if ( str )
@@ -408,6 +400,18 @@ int parameter2int(const char *string)
}
+size_t parameter2sizet(const char *string)
+{
+ char *endptr = NULL;
+ size_t ival = (size_t) strtoimax(string, &endptr, 10);
+ if ( *endptr != 0 )
+ cdoAbort("Integer parameter >%s< contains invalid character at position %d!",
+ string, (int)(endptr-string+1));
+
+ return ival;
+}
+
+
int parameter2intlist(const char *string)
{
char *endptr = NULL;
@@ -489,9 +493,7 @@ int month_to_season(int month)
return seas;
}
-//#include <sys/types.h>
#include <sys/stat.h>
-//#include <unistd.h>
bool fileExists(const char *restrict filename)
{
diff --git a/src/util.h b/src/util.h
index 702f07c..9c73b0f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -43,8 +43,12 @@
#define UNCHANGED_RECORD (processSelf().m_ID == 0 && cdoStreamName(0)->argv[0][0] != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
+#define ITSME (strcmp(CDO_username, "\x6d\x32\x31\x34\x30\x30\x33") == 0)
+
#include <string>
-extern char *Progname;
+extern const char *CDO_progname;
+extern const char *CDO_version;
+extern const char *CDO_username;
extern char *cdoGridSearchDir;
extern int CDO_Reduce_Dim;
extern int CDO_Memtype;
@@ -60,7 +64,7 @@ extern int CDO_opterr;
extern int CDO_flt_digits;
extern int CDO_dbl_digits;
-extern int remap_genweights;
+extern bool REMAP_genweights;
extern const char *cdoExpName;
extern int ompNumThreads;
@@ -109,15 +113,12 @@ extern int cdoNumVarnames;
extern char **cdoVarnames;
extern char CDO_File_Suffix[32]; // refactor: added keyword extern
-extern const char *CDO_Version;
-
-
-char *getProgname(char *string);
+const char *getProgname(char *string);
char *GetOperator(const char *argument);
-const char *getOperatorName(const char *xoperator);
-char *getOperatorArg(const char *xoperator);
+const char *getOperatorName(const char *operatorCommand);
+char *getOperatorArg(const char *operatorCommand);
const char *cdoComment(void);
char *getFileArg(char *argument);
@@ -194,7 +195,7 @@ int cdoDefineZaxis(const char *zaxisfile);
int vlistInqNWPV(int vlistID, int varID);
int vlistIsSzipped(int vlistID);
-int vlist_check_gridsize(int vlistID);
+size_t vlist_check_gridsize(int vlistID);
int vlist_get_psvarid(int vlistID, int zaxisID);
double *vlist_read_vct(int vlistID, int *rzaxisIDh, int *rnvct, int *rnhlev, int *rnhlevf, int *rnhlevh);
void vlist_change_hybrid_zaxis(int vlistID1, int vlistID2, int zaxisID1, int zaxisID2);
diff --git a/test/Arithc.test.in b/test/Arithc.test.in
index f036885..e783aa4 100644
--- a/test/Arithc.test.in
+++ b/test/Arithc.test.in
@@ -15,17 +15,20 @@ NTEST=1
for STAT in $STATS; do
RSTAT=0
+ rm Arithc_${STAT}.debug
+ DEBUG_OUT="--seperateDebugFromLog Arithc_${STAT}.debug"
+
OFILE=stat${STAT}_res
for VAR in -777 -1 0 1 777; do
VAL=1
CFILE=constval
- $CDO -f srv -b 64 const,$VAL,$IFILE $CFILE
+ $CDO $DEBUG_OUT -f srv -b 64 const,$VAL,$IFILE $CFILE
# stat var const
CDOTEST="$STAT"
- CDOCOMMAND="$CDO $FORMAT ${STAT} $IFILE $CFILE $OFILE"
+ CDOCOMMAND="$CDO $DEBUG_OUT $FORMAT ${STAT} $IFILE $CFILE $OFILE"
echo "Running test: $NTEST - $CDOTEST"
echo "$CDOCOMMAND"
@@ -36,12 +39,12 @@ for STAT in $STATS; do
# stat,const var
OFILE2=stat${STAT}c_res
- CDOCOMMAND="$CDO $FORMAT ${STAT}c,$VAL $IFILE $OFILE2"
+ CDOCOMMAND="$CDO $DEBUG_OUT $FORMAT ${STAT}c,$VAL $IFILE $OFILE2"
$CDOCOMMAND
test $? -eq 0 || let RSTAT+=1
- $CDO diff $OFILE $OFILE2 > $CDOOUT 2> $CDOERR
+ $CDO $DEBUG_OUT diff $OFILE $OFILE2 > $CDOOUT 2> $CDOERR
test $? -eq 0 || let RSTAT+=1
test -s $CDOOUT && let RSTAT+=1
cat $CDOOUT $CDOERR
@@ -56,12 +59,12 @@ for STAT in $STATS; do
OFILE3=arithc_expr${STAT}_res
INSTR="var130=var130${OP}${VAL};var152=var152${OP}${VAL};var129=var129${OP}${VAL};"
echo $INSTR
- CDOCOMMAND="$CDO $FORMAT expr,$INSTR $IFILE $OFILE3"
+ CDOCOMMAND="$CDO $DEBUG_OUT $FORMAT expr,$INSTR $IFILE $OFILE3"
$CDOCOMMAND
test $? -eq 0 || let RSTAT+=1
- $CDO diff $OFILE $OFILE3 > $CDOOUT 2> $CDOERR
+ $CDO $DEBUG_OUT diff $OFILE $OFILE3 > $CDOOUT 2> $CDOERR
test $? -eq 0 || let RSTAT+=1
test -s $CDOOUT && let RSTAT+=1
cat $CDOOUT $CDOERR
diff --git a/test/Expr.test.in b/test/Expr.test.in
index d03068a..b02d5d3 100644
--- a/test/Expr.test.in
+++ b/test/Expr.test.in
@@ -7,6 +7,7 @@ test -n "$DATAPATH" || DATAPATH=./data
CDOOUT=cout$$
CDOERR=cerr$$
FORMAT="-f srv -b 32"
+ABSLIMMAX=0.001
#
IFILE=$DATAPATH/pl_data
NTEST=1
@@ -38,7 +39,7 @@ function testfunc()
$CDOCOMMAND
test $? -eq 0 || let RSTAT+=1
- $CDO diff $RFILE $OFILE > $CDOOUT 2> $CDOERR
+ $CDO diff,$ABSLIMMAX $RFILE $OFILE > $CDOOUT 2> $CDOERR
test $? -eq 0 || let RSTAT+=1
test -s $CDOOUT && let RSTAT+=1
cat $CDOOUT $CDOERR
diff --git a/test/Makefile.in b/test/Makefile.in
index dcfe021..da19ceb 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -79,31 +89,10 @@ build_triplet = @build@
host_triplet = @host@
XFAIL_TESTS =
subdir = test
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs $(srcdir)/File.test.in \
- $(srcdir)/Read_grib.test.in $(srcdir)/Read_netcdf.test.in \
- $(srcdir)/Copy_netcdf.test.in $(srcdir)/Comp.test.in \
- $(srcdir)/Compc.test.in $(srcdir)/Cat.test.in \
- $(srcdir)/Gridarea.test.in $(srcdir)/Genweights.test.in \
- $(srcdir)/Remap.test.in $(srcdir)/Remap2.test.in \
- $(srcdir)/Remapeta.test.in $(srcdir)/EOF.test.in \
- $(srcdir)/Select.test.in $(srcdir)/Spectral.test.in \
- $(srcdir)/Vertint.test.in $(srcdir)/Timstat.test.in \
- $(srcdir)/Timselstat.test.in $(srcdir)/Seasstat.test.in \
- $(srcdir)/Runstat.test.in $(srcdir)/Multiyearstat.test.in \
- $(srcdir)/Ydrunstat.test.in $(srcdir)/Gridboxstat.test.in \
- $(srcdir)/Vertstat.test.in $(srcdir)/Fldstat.test.in \
- $(srcdir)/Fldpctl.test.in $(srcdir)/Ensstat.test.in \
- $(srcdir)/Enspctl.test.in $(srcdir)/Merstat.test.in \
- $(srcdir)/Zonstat.test.in $(srcdir)/Mergetime.test.in \
- $(srcdir)/Afterburner.test.in $(srcdir)/Detrend.test.in \
- $(srcdir)/Arithc.test.in $(srcdir)/Arith.test.in \
- $(srcdir)/Expr.test.in $(srcdir)/Gradsdes.test.in \
- $(srcdir)/Collgrid.test.in $(srcdir)/threads.test.in \
- $(srcdir)/tsformat.test.in $(srcdir)/wildcard.test.in \
- $(srcdir)/MapReduce.test.in $(srcdir)/Ninfo.test.in README
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -112,6 +101,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES = File.test Read_grib.test Read_netcdf.test \
@@ -347,6 +337,30 @@ am__set_b = \
*) \
b='$*';; \
esac
+am__DIST_COMMON = $(srcdir)/Afterburner.test.in \
+ $(srcdir)/Arith.test.in $(srcdir)/Arithc.test.in \
+ $(srcdir)/Cat.test.in $(srcdir)/Collgrid.test.in \
+ $(srcdir)/Comp.test.in $(srcdir)/Compc.test.in \
+ $(srcdir)/Copy_netcdf.test.in $(srcdir)/Detrend.test.in \
+ $(srcdir)/EOF.test.in $(srcdir)/Enspctl.test.in \
+ $(srcdir)/Ensstat.test.in $(srcdir)/Expr.test.in \
+ $(srcdir)/File.test.in $(srcdir)/Fldpctl.test.in \
+ $(srcdir)/Fldstat.test.in $(srcdir)/Genweights.test.in \
+ $(srcdir)/Gradsdes.test.in $(srcdir)/Gridarea.test.in \
+ $(srcdir)/Gridboxstat.test.in $(srcdir)/Makefile.in \
+ $(srcdir)/MapReduce.test.in $(srcdir)/Mergetime.test.in \
+ $(srcdir)/Merstat.test.in $(srcdir)/Multiyearstat.test.in \
+ $(srcdir)/Ninfo.test.in $(srcdir)/Read_grib.test.in \
+ $(srcdir)/Read_netcdf.test.in $(srcdir)/Remap.test.in \
+ $(srcdir)/Remap2.test.in $(srcdir)/Remapeta.test.in \
+ $(srcdir)/Runstat.test.in $(srcdir)/Seasstat.test.in \
+ $(srcdir)/Select.test.in $(srcdir)/Spectral.test.in \
+ $(srcdir)/Timselstat.test.in $(srcdir)/Timstat.test.in \
+ $(srcdir)/Vertint.test.in $(srcdir)/Vertstat.test.in \
+ $(srcdir)/Ydrunstat.test.in $(srcdir)/Zonstat.test.in \
+ $(srcdir)/threads.test.in $(srcdir)/tsformat.test.in \
+ $(srcdir)/wildcard.test.in $(top_srcdir)/config/mkinstalldirs \
+ README
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -389,18 +403,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -476,6 +494,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -576,7 +595,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign test/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -723,7 +741,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
if test -n "$$am__remaking_logs"; then \
echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
"recursion detected" >&2; \
- else \
+ elif test -n "$$redo_logs"; then \
am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
fi; \
if $(am__make_dryrun); then :; else \
@@ -999,6 +1017,8 @@ uninstall-am:
mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
uninstall uninstall-am
+.PRECIOUS: Makefile
+
export
diff --git a/test/data/Makefile.in b/test/data/Makefile.in
index a08f930..1ff9b69 100644
--- a/test/data/Makefile.in
+++ b/test/data/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
@SET_MAKE@
VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -78,10 +88,10 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/data
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/config/mkinstalldirs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_cfortran_flags.m4 \
+ $(top_srcdir)/m4/acx_check_cfortran.m4 \
+ $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -90,6 +100,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
@@ -114,6 +125,8 @@ am__can_run_installinfo = \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -156,18 +169,22 @@ ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
ENABLE_DATA = @ENABLE_DATA@
ENABLE_EXTRA = @ENABLE_EXTRA@
+ENABLE_FORTRAN = @ENABLE_FORTRAN@
ENABLE_GRIB = @ENABLE_GRIB@
ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
ENABLE_IEG = @ENABLE_IEG@
ENABLE_NC2 = @ENABLE_NC2@
ENABLE_NC4 = @ENABLE_NC4@
ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
+ENABLE_NEARPT3 = @ENABLE_NEARPT3@
ENABLE_NETCDF = @ENABLE_NETCDF@
ENABLE_SERVICE = @ENABLE_SERVICE@
ENABLE_THREADS = @ENABLE_THREADS@
EXEEXT = @EXEEXT@
-FCFLAGS = @FCFLAGS@
+F77 = @F77@
+FFLAGS = @FFLAGS@
FGREP = @FGREP@
+FORTRAN_WORKS = @FORTRAN_WORKS@
GREP = @GREP@
GRIB_API_INCLUDE = @GRIB_API_INCLUDE@
GRIB_API_LIBS = @GRIB_API_LIBS@
@@ -243,6 +260,7 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -354,7 +372,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/data/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign test/data/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -529,6 +546,8 @@ uninstall-am:
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
+.PRECIOUS: Makefile
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/test/data/expr2_ref b/test/data/expr2_ref
index cf28d14..5fa8ee3 100644
Binary files a/test/data/expr2_ref and b/test/data/expr2_ref differ
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/cdo.git
More information about the debian-science-commits
mailing list