Beginning of open source history
authorPhilippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Fri, 29 Apr 2016 14:01:17 +0000 (16:01 +0200)
committerPhilippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Fri, 29 Apr 2016 14:01:17 +0000 (16:01 +0200)
386 files changed:
.gitattributes [new file with mode: 0644]
LIBTOOLS_CVS.TXT [new file with mode: 0644]
README.TXT [new file with mode: 0644]
conf/config.AIX32 [new file with mode: 0644]
conf/config.AIX64 [new file with mode: 0644]
conf/config.HPNAGf95 [new file with mode: 0644]
conf/config.HPf90 [new file with mode: 0644]
conf/config.LXNAGf95 [new file with mode: 0644]
conf/config.LXg95 [new file with mode: 0644]
conf/config.LXgfortran [new file with mode: 0644]
conf/config.LXpgf90 [new file with mode: 0644]
conf/config.SGI32 [new file with mode: 0644]
conf/config.SGI64 [new file with mode: 0644]
conf/config.SP4Idris [new file with mode: 0644]
conf/config.SX5 [new file with mode: 0644]
conf/config.SX8 [new file with mode: 0644]
conf/config.VPP [new file with mode: 0644]
conf/config.gfortranR64 [new file with mode: 0644]
conf/listing [new file with mode: 0755]
lib/COMPRESS/Makefile [new file with mode: 0644]
lib/COMPRESS/Rules.AIX32 [new file with mode: 0644]
lib/COMPRESS/Rules.AIX64 [new file with mode: 0644]
lib/COMPRESS/Rules.HPNAGf95 [new file with mode: 0644]
lib/COMPRESS/Rules.HPf90 [new file with mode: 0644]
lib/COMPRESS/Rules.LXNAGf95 [new file with mode: 0644]
lib/COMPRESS/Rules.LXg95 [new file with mode: 0644]
lib/COMPRESS/Rules.LXgfortran [new file with mode: 0644]
lib/COMPRESS/Rules.LXpgf90 [new file with mode: 0644]
lib/COMPRESS/Rules.SGI32 [new file with mode: 0644]
lib/COMPRESS/Rules.SGI64 [new file with mode: 0644]
lib/COMPRESS/Rules.SX5 [new file with mode: 0644]
lib/COMPRESS/Rules.SX8 [new file with mode: 0644]
lib/COMPRESS/Rules.VPP [new file with mode: 0644]
lib/COMPRESS/src/bitbuff.c [new file with mode: 0644]
lib/COMPRESS/src/comppar.f90 [new file with mode: 0644]
lib/COMPRESS/src/compress.f90 [new file with mode: 0644]
lib/COMPRESS/src/decompress.f90 [new file with mode: 0644]
lib/COMPRESS/src/ieee754.h [new file with mode: 0644]
lib/COMPRESS/src/ieee_is_nan.c [new file with mode: 0644]
lib/COMPRESS/src/nearestpow2.c [new file with mode: 0644]
lib/COMPRESS/src/searchgrp.f90 [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/vis5d/Makefile [new file with mode: 0644]
lib/vis5d/Makefile.v5d [new file with mode: 0644]
lib/vis5d/Rules.HPf90 [new file with mode: 0644]
lib/vis5d/Rules.LXNAGf95 [new file with mode: 0644]
lib/vis5d/Rules.LXg95 [new file with mode: 0644]
lib/vis5d/Rules.LXgfortran [new file with mode: 0644]
lib/vis5d/Rules.SGI32 [new file with mode: 0644]
lib/vis5d/Rules.VPP [new file with mode: 0644]
lib/vis5d/src/binio.c [new file with mode: 0644]
lib/vis5d/src/binio.h [new file with mode: 0644]
lib/vis5d/src/v5d.c [new file with mode: 0644]
lib/vis5d/src/v5d.h [new file with mode: 0644]
lib/vis5d/src/vis5d.h [new file with mode: 0644]
readme/LATEX/Makefile [new file with mode: 0644]
readme/LATEX/conv2dia.tex [new file with mode: 0644]
readme/LATEX/extract.tex [new file with mode: 0644]
readme/LATEX/fic1.eps [new file with mode: 0644]
readme/LATEX/intro.tex [new file with mode: 0644]
readme/LATEX/lfi2cdf.tex [new file with mode: 0644]
readme/LATEX/lfi2grb.tex [new file with mode: 0644]
readme/LATEX/lfiz.tex [new file with mode: 0644]
readme/LATEX/outils_dia.eps [new file with mode: 0644]
readme/LATEX/tools.tex [new file with mode: 0644]
readme/LATEX/toolstab.eps [new file with mode: 0644]
readme/compute_r00.LISEZMOI [new file with mode: 0644]
readme/compute_r00.nam [new file with mode: 0644]
readme/exrwdia.LISEZMOI [new file with mode: 0644]
readme/extractdia.LISEZMOI [new file with mode: 0644]
readme/extractdia.test_cdl.x [new file with mode: 0755]
readme/extractdia.test_diac.x [new file with mode: 0755]
readme/extractdia.test_llhv.x [new file with mode: 0755]
readme/libtools.LISEZMOI [new file with mode: 0644]
readme/mesonh2obs.LISEZMOI [new file with mode: 0644]
readme/obs2mesonh.LISEZMOI [new file with mode: 0644]
readme/tools.ps [new file with mode: 0644]
readme/why.conv2dia [new file with mode: 0644]
readme/why.diaprog [new file with mode: 0644]
tools/Makefile [new file with mode: 0644]
tools/diachro/Makefile [new file with mode: 0644]
tools/diachro/Makefile.conv2dia [new file with mode: 0644]
tools/diachro/Makefile.diaprog [new file with mode: 0644]
tools/diachro/Makefile.exrwdia [new file with mode: 0644]
tools/diachro/Makefile.extractdia [new file with mode: 0644]
tools/diachro/Rules.AIX32 [new file with mode: 0644]
tools/diachro/Rules.AIX64 [new file with mode: 0644]
tools/diachro/Rules.HPNAGf95 [new file with mode: 0644]
tools/diachro/Rules.HPf90 [new file with mode: 0644]
tools/diachro/Rules.LXNAGf95 [new file with mode: 0644]
tools/diachro/Rules.LXg95 [new file with mode: 0644]
tools/diachro/Rules.LXgfortran [new file with mode: 0644]
tools/diachro/Rules.LXpgf90 [new file with mode: 0644]
tools/diachro/Rules.SGI32 [new file with mode: 0644]
tools/diachro/Rules.SGI64 [new file with mode: 0644]
tools/diachro/Rules.SX5 [new file with mode: 0644]
tools/diachro/Rules.SX8 [new file with mode: 0644]
tools/diachro/Rules.VPP [new file with mode: 0644]
tools/diachro/src/DIAPRO/alloc2_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/axelogpres.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/bcgrd_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/caluv_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/careal.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/caresolv.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/carint.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/carmemory.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/closf.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/color_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/colvect.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/compcoord_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/complat.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/conv2xy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/convallij2ll.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/convij2xy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/convlo2up.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/convxy2ij.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/coupe_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/coupeuw_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/datfile_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/defenetre.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/diaprog.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/diff_oper.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/echelleph.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/extract_and_open_files.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/factimp.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/formatxy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/genformat_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/image_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/imagev_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/imcou_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/imcoupv_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/imcouv_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/inidef.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/interp_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/interp_grids.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/interpolw.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/interpxyz.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/kztnp.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/latlongrid.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/load_expr.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/load_fmtaxes.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/load_segments.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/load_tit.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/load_xprdat.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/loadmnmx_ft_pvkt.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/loadmnmxint_iso.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/loadunitit.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/loadxisolevp.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/memcv.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/myheurx.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/oper_process.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/precou_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/prints.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/pro1d_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/pvfct.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_dimgridref.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_filehead.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_sufwind.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_th_pr.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_type.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/read_uvw.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/readcol_ft_pvkt.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/readmnmx_ft_pvkt.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/readmnmxint_iso.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/readrefint_iso.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/readxisolevp.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/realloc_and_load.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/realloc_and_load_records.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/resolv_nijinf_nijsup.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/resolv_times.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/resolv_tit.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/resolv_tity.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/resolvtot.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/rota.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/rotauw.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/subspxy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tabcol_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tit_tra3d.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/traceh_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tracev_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tracexz.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tracircle.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/traflux3d.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/trahtraxy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tramask.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tramask3d.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/trapro_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tratraj3d.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/traxy.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/tsound_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/varfct.f90 [new file with mode: 0644]
tools/diachro/src/DIAPRO/veriflen_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/compute_r00_pc.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/concat_time_diafile.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/dd.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/exrwdia.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/extractdia.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/ff.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/from_computing_units.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/ini2lalo.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/int2lalo.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/mesonh2obs.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/modd_readlh.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/modn_outfile.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/obs2mesonh.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/readvar.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/temporal_dist_for_ext.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/to_computing_units.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/writecdl.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/writegrib.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/writellhv.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/writevar.f90 [new file with mode: 0644]
tools/diachro/src/EXTRACTDIA/zmoy.f90 [new file with mode: 0644]
tools/diachro/src/FM/fm_read.f90 [new file with mode: 0644]
tools/diachro/src/FM/fm_writ.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmattr.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmclos.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmfree.f90 [new file with mode: 0644]
tools/diachro/src/FM/fminit.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmlook.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmopen.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmread.f90 [new file with mode: 0644]
tools/diachro/src/FM/fmwrit.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/alloc_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/conv2dia.elim.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/conv2dia.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/conv2dia.select.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/elim.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/jdlfilaf_fuji.f [new file with mode: 0644]
tools/diachro/src/FM2DIA/lficom0.h [new file with mode: 0644]
tools/diachro/src/FM2DIA/read_and_write_dimgridref.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/read_diachro.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/read_dimgridref_fm2dia.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/resolv_units.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/write_dimgridref.f90 [new file with mode: 0644]
tools/diachro/src/FM2DIA/write_othersfields.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_alloc2_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_alloc_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_allvar.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_convij2xy.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_coord.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_ctl_axes_and_styl.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_cvert.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_defcv.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_diachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_dimgrid_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_emul.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_experim.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_expr.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_field1_cv2d.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_files_diachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_hach.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_mask3d.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_memcv.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_memgriuv.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_nmgrid.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_out.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_out_dia.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_pt_for_ch_fordiachro.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_pvt.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_radar.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_rea_lfi.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_resolvcar.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_rsisocol.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_several_records.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_super.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_tit.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_title.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_traj3d.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_type_allvar.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modd_type_and_lh.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modn_ncar.f90 [new file with mode: 0644]
tools/diachro/src/MOD/modn_para.f90 [new file with mode: 0644]
tools/diachro/src/POS/big.h [new file with mode: 0644]
tools/diachro/src/POS/ccolr.f [new file with mode: 0644]
tools/diachro/src/POS/dewp.f90 [new file with mode: 0644]
tools/diachro/src/POS/echelle.f90 [new file with mode: 0644]
tools/diachro/src/POS/esat.f90 [new file with mode: 0644]
tools/diachro/src/POS/ficstr.f [new file with mode: 0644]
tools/diachro/src/POS/fleche.f90 [new file with mode: 0644]
tools/diachro/src/POS/frame41.f [new file with mode: 0644]
tools/diachro/src/POS/gkscom-5.1.1.h [new file with mode: 0644]
tools/diachro/src/POS/gkscom.h [new file with mode: 0644]
tools/diachro/src/POS/gridal.f [new file with mode: 0644]
tools/diachro/src/POS/os.f90 [new file with mode: 0644]
tools/diachro/src/POS/tracexy.f90 [new file with mode: 0644]
tools/diachro/src/POS/tsa.f90 [new file with mode: 0644]
tools/diachro/src/POS/valmnmx.f90 [new file with mode: 0644]
tools/diachro/src/POS/valngrid.f90 [new file with mode: 0644]
tools/diachro/src/POS/wsous.f90 [new file with mode: 0644]
tools/diachro/src/POS/wtstr.f [new file with mode: 0644]
tools/diachro/src/TOOL/change_a_grid.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/computedir.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/creatlink.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/low2up.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/pinter.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/poub.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/up2low.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/verif_group.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/writedir.f90 [new file with mode: 0644]
tools/diachro/src/TOOL/zinter.f90 [new file with mode: 0644]
tools/diachro/src/listing [new file with mode: 0755]
tools/diachro/src/mesonh/hor_interp_4pts.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/ini_cst.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/init_for_convlfi.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/menu_diachro.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/mode_io.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/set_dim.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/set_grid.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/set_light_grid.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/shuman.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/temporal_dist.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/uv_to_zonal_and_merid.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/vert_coord.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/write_diachro.f90 [new file with mode: 0644]
tools/diachro/src/mesonh/write_lfifm1_fordiachro_cv.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_conf.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_cst.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_dim1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_field1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_fmdeclar.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_fmmulti.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_grid.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_grid1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_lunit1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_nesting.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_param1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_parameters.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_time.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_time1.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/modd_type_date.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/mode_gridcart.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/mode_gridproj.f90 [new file with mode: 0644]
tools/diachro/src/mesonh_MOD/mode_time.f90 [new file with mode: 0644]
tools/fmmore/Makefile [new file with mode: 0644]
tools/fmmore/Rules.AIX [new file with mode: 0644]
tools/fmmore/Rules.HPf90 [new file with mode: 0644]
tools/fmmore/Rules.LXNAGf95 [new file with mode: 0644]
tools/fmmore/Rules.LXg95 [new file with mode: 0644]
tools/fmmore/Rules.LXgfortran [new file with mode: 0644]
tools/fmmore/Rules.LXpgf90 [new file with mode: 0644]
tools/fmmore/Rules.SGI32 [new file with mode: 0644]
tools/fmmore/Rules.SGI64 [new file with mode: 0644]
tools/fmmore/Rules.SX8 [new file with mode: 0644]
tools/fmmore/Rules.VPP [new file with mode: 0644]
tools/fmmore/src/fmmore.f90 [new file with mode: 0644]
tools/fmmore/src/readuntouch.f90 [new file with mode: 0644]
tools/foldown/fold.c [new file with mode: 0644]
tools/lfi2cdf/Makefile [new file with mode: 0644]
tools/lfi2cdf/Rules.HPNAGf95 [new file with mode: 0644]
tools/lfi2cdf/Rules.HPf90 [new file with mode: 0644]
tools/lfi2cdf/Rules.LXNAGf95 [new file with mode: 0644]
tools/lfi2cdf/Rules.LXg95 [new file with mode: 0644]
tools/lfi2cdf/Rules.LXgfortran [new file with mode: 0644]
tools/lfi2cdf/Rules.LXpgf90 [new file with mode: 0644]
tools/lfi2cdf/Rules.SGI32 [new file with mode: 0644]
tools/lfi2cdf/Rules.SGI64 [new file with mode: 0644]
tools/lfi2cdf/Rules.SX5 [new file with mode: 0644]
tools/lfi2cdf/Rules.VPP [new file with mode: 0644]
tools/lfi2cdf/src/fieldtype.f90 [new file with mode: 0644]
tools/lfi2cdf/src/lfi2cdf.f90 [new file with mode: 0644]
tools/lfi2cdf/src/modd_ncparam.f90 [new file with mode: 0644]
tools/lfi2cdf/src/mode_dimlist.f90 [new file with mode: 0644]
tools/lfi2cdf/src/mode_util.f90 [new file with mode: 0644]
tools/lfiz/Makefile [new file with mode: 0644]
tools/lfiz/Rules.AIX32 [new file with mode: 0644]
tools/lfiz/Rules.AIX64 [new file with mode: 0644]
tools/lfiz/Rules.HPNAGf95 [new file with mode: 0644]
tools/lfiz/Rules.HPf90 [new file with mode: 0644]
tools/lfiz/Rules.LXNAGf95 [new file with mode: 0644]
tools/lfiz/Rules.LXg95 [new file with mode: 0644]
tools/lfiz/Rules.LXgfortran [new file with mode: 0644]
tools/lfiz/Rules.LXpgf90 [new file with mode: 0644]
tools/lfiz/Rules.SGI32 [new file with mode: 0644]
tools/lfiz/Rules.SGI64 [new file with mode: 0644]
tools/lfiz/Rules.SX5 [new file with mode: 0644]
tools/lfiz/Rules.SX8 [new file with mode: 0644]
tools/lfiz/Rules.VPP [new file with mode: 0644]
tools/lfiz/src/lfiz.f90 [new file with mode: 0644]
tools/lfiz/src/testlibcomp.f90 [new file with mode: 0644]
tools/lfiz/src/unlfiz.f90 [new file with mode: 0644]
tools/radar/radarascii2llv.c [new file with mode: 0644]
tools/vergrid/Makefile [new file with mode: 0644]
tools/vergrid/src/mode_pos.f90 [new file with mode: 0644]
tools/vergrid/src/vergrid.f90 [new file with mode: 0644]
tools/where.Libs [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..6a18b35
--- /dev/null
@@ -0,0 +1,10 @@
+*.tar  filter=lfs diff=lfs merge=lfs -crlf
+*.tar.gz       filter=lfs diff=lfs merge=lfs -crlf
+*/ecmwf.OD*    filter=lfs diff=lfs merge=lfs -crlf
+*CLEAN4_ops    filter=lfs diff=lfs merge=lfs -crlf
+*arpifs.*      filter=lfs diff=lfs merge=lfs -crlf
+*dasucl4_ops   filter=lfs diff=lfs merge=lfs -crlf
+bin/gmake-3.80 filter=lfs diff=lfs merge=lfs -crlf
+bin_tools/X86/*        filter=lfs diff=lfs merge=lfs -crlf
+bin_tools/X86_64/*     filter=lfs diff=lfs merge=lfs -crlf
+exe/[a-zA-Z]*  filter=lfs diff=lfs merge=lfs -crlf
diff --git a/LIBTOOLS_CVS.TXT b/LIBTOOLS_CVS.TXT
new file mode 100644 (file)
index 0000000..3a48705
--- /dev/null
@@ -0,0 +1,87 @@
+Libtools sources may be retrieved with the following commands.
+Choose a working directory to install the sources, then
+
+- To get the latest stable revision :
+
+         cvs co libtools
+
+- To get the latest development release :
+
+         cvs co -r LIBTOOLS-DEVEL-branch libtools
+
+- To get the latest CNRM development release :
+
+         cvs co -r LIBTOOLS-CNRM-branch libtools
+
+- to get the LIBTOOLS-DEVEL-1-0-2 release :
+   
+         cvs co -r LIBTOOLS-DEVEL-1-0-2 libtools
+
+
+
+
+Tags that may appear in this repository are explained below :
+
+       MAIN
+       ====
+        |               LIBTOOLS-DEVEL-branch              LIBTOOLS-CNRM-branch
+        |               =====================              ====================
+        |                         |                                 |
+        |                         |                                 |
+ LIBTOOLS-1-0-0 ------------------+---------------------------------+
+        |                         |                                 |
+        |                         |                                 |
+        |                         |                                 |
+        |                   DEV-SURC-7-4-1                          |
+        |                         |                                 |
+        |                         |                                 |
+        |                  DEV-SURC-7-4-1-1                         |
+        |                         |                                 |
+        |                         |                                 |
+        |                  DEV-SURC-7-4-1-2                         |
+        |                         |                                 |
+        |                         |                                 |
+        |                LIBTOOLS-DEVEL-1-0-1                       | 
+        |                         |                                 |
+        |                         |                                 |
+        |                         |                                 |
+        |                LIBTOOLS-DEVEL-1-0-2     merge             | 
+        |             merged_from_DEVEL_to_CNRM ---------> LIBTOOLS-CNRM-1-0-2
+        |                         |                                 |
+        .                         .                                 .
+        .                         .                                 .
+        .                         .                                 .
+
+
+
+Branch TAGS
+===========
+
+   MAIN : this branch contains official stable LibTools sources.
+  
+   LIBTOOLS-DEVEL-branch : this branch contains sources currently under 
+                           development that sooner or later are merged to
+                           main branch.
+
+   LIBTOOLS-CNRM-branch : this branch is reserved to CNRM development/tests.
+                          Sources may be merged to MAIN or LIBTOOLS-DEVEL-branch
+                          branch.
+
+
+Release TAGS
+============
+
+LIBTOOLS-x-y-z : this tag is applied to all sources of a stable LIBTOOLS release
+                 on the MAIN branch.
+
+LIBTOOLS-DEVEL-x-y-z : this tag is applied to all sources of a development LIBTOOLS 
+                       release on the LIBTOOLS-DEVEL-branch development branch.
+
+DEV-SURC-x-y... : this tag is only applied to the lib/SURCOUCHE sources on the
+                  LIBTOOLS-DEVEL-branch development branch.
+
+LIBTOOLS-CNRM-x-y... : this tag is applied to all sources of a development/test LIBTOOLS 
+                       release on the LIBTOOLS-CNRM-branch development branch.
+
+Note that all sources from LIBTOOLS-DEVEL-1-0-2 and LIBTOOLS-CNRM-1-0-2 release
+are strictly identical (except maybe for the README.TXT file).
diff --git a/README.TXT b/README.TXT
new file mode 100644 (file)
index 0000000..921fe6e
--- /dev/null
@@ -0,0 +1,54 @@
+Release tag : LIBTOOLS-CNRM-4-8-a  on September 24 2009
+
+Welcome to MESONH Libtools...
+
+Branch : LIBTOOLS-CNRM-branch
+TAG    : $Name$
+
+
+Support for gfortran ver > 4.3 and NCL/NCAR 5.1.1
+with :
+
+export ARCH=LXgfortran
+
+Documentation can be found in 'readme' directory.
+
+LaTeX sources of documentation can be found in 'readme/LATEX'
+directory : type make in the LATEX directory to build the 
+postscript documentation file : tools.ps
+
+
+How to compile ?
+
+ cd lib
+ export ARCH=LXgfortran
+ make COMPRESS
+ make NEWLFI
+ make SURCOUCHE
+ make MPIvide
+ make RAD2
+ make vis5d
+ cd gribex_1302b
+ export ARCH=linux
+ export CNAME=_gfortran
+ export A64=A64
+ make
+ cd ../../tools
+ cd diachro
+ export ARCH=LXgfortran
+ export MNH_LIBTOOLS= absolute path for libtools directory
+ make
+# The executables are in the directory LXgfortran_64 conv2dia and LXgfortran_32 for the others
+
+
+ cd ../fmmore
+ make
+
+# The executable is in the directory LXgfortran_64
+
+ cd ../lfiz
+ make
+
+# The executables ate in the directory LXgfortran
+
diff --git a/conf/config.AIX32 b/conf/config.AIX32
new file mode 100644 (file)
index 0000000..583e436
--- /dev/null
@@ -0,0 +1,8 @@
+CPP = cc -C -E
+AR  = ar 
+F77 = xlf90 -q32 -qextname
+F90 = xlf90 -q32 -qextname
+F77FLAGS = -qfixed -O3 -qstrict
+F90FLAGS = -qfree=f90 -qsuffix=f=f90 -O3 -qstrict
+CPPFLAGS = 
+LDFLAGS = -bloadmap:map_ld
diff --git a/conf/config.AIX64 b/conf/config.AIX64
new file mode 100644 (file)
index 0000000..ba8c8c8
--- /dev/null
@@ -0,0 +1,9 @@
+CPP = cc -C -E
+AR  = ar -X64
+F77 = xlf90_r -qarch=pwr4 -qzerosize -qautodbl=dbl4 -qmaxmem=-1
+F90 = xlf90_r -qarch=pwr4 -qzerosize -qautodbl=dbl4 -qmaxmem=-1
+F77FLAGS = -q64 -qfixed -O3 -qstrict
+F90FLAGS = -q64 -qfree=f90 -qsuffix=f=f90 -O3 -qstrict
+CFLAGS = -q64 
+CPPFLAGS = 
+LDFLAGS = -q64 -bloadmap:map_ld
diff --git a/conf/config.HPNAGf95 b/conf/config.HPNAGf95
new file mode 100644 (file)
index 0000000..ba20c06
--- /dev/null
@@ -0,0 +1,10 @@
+CPP = /usr/lib/cpp -P -C
+AR = ar
+CC = cc
+F77 = f95
+F90 = f95
+
+F90FLAGS = -f77 -kind=byte -w -mismatch_all
+F77FLAGS = -f77 -kind=byte -w -mismatch_all -dusty
+LDFLAGS  = -unsharedf95
+
diff --git a/conf/config.HPf90 b/conf/config.HPf90
new file mode 100644 (file)
index 0000000..24c2342
--- /dev/null
@@ -0,0 +1,10 @@
+CPP = /usr/lib/cpp -P -C
+AR  = ar
+F90 = f90 +DAportable
+F77 = f90 +DAportable
+
+CPPFLAGS = -DHP -DF90HP
+F90FLAGS = -w
+F77FLAGS = -w
+
+
diff --git a/conf/config.LXNAGf95 b/conf/config.LXNAGf95
new file mode 100644 (file)
index 0000000..1352224
--- /dev/null
@@ -0,0 +1,12 @@
+CPP = cpp -P -traditional -Wcomment
+AR = ar
+CC = cc
+F77 = f95
+F90 = f95
+
+CPPFLAGS = -DNAGf95
+#F90FLAGS = -kind=byte -w -C=all -gline
+F90FLAGS = -kind=byte -w -mismatch_all -gline
+F77FLAGS = -kind=byte -w -mismatch_all -dusty
+LDFLAGS = -unsharedf95 
+
diff --git a/conf/config.LXg95 b/conf/config.LXg95
new file mode 100644 (file)
index 0000000..2ab5c7e
--- /dev/null
@@ -0,0 +1,12 @@
+CPP = cpp -P -traditional -Wcomment
+AR = ar
+CC = cc 
+F77 = g95
+F90 = g95
+
+CPPFLAGS = -DG95 
+F90FLAGS = -w -fno-second-underscore
+F77FLAGS = -w -fno-second-underscore
+
+LDFLAGS =  
+
diff --git a/conf/config.LXgfortran b/conf/config.LXgfortran
new file mode 100644 (file)
index 0000000..d2b0fa1
--- /dev/null
@@ -0,0 +1,12 @@
+CPP = cpp -P -traditional -Wcomment
+AR = ar
+CC = cc 
+F77 = gfortran
+F90 = gfortran
+
+CPPFLAGS = -DGFORTRAN
+F90FLAGS = -w -fno-second-underscore
+F77FLAGS = -w -fno-second-underscore
+
+LDFLAGS =  
+
diff --git a/conf/config.LXpgf90 b/conf/config.LXpgf90
new file mode 100644 (file)
index 0000000..cd9029a
--- /dev/null
@@ -0,0 +1,11 @@
+CPP = cpp -P -traditional -Wcomment
+AR = ar
+CC = cc
+F77 = pgf90
+F90 = pgf90
+
+CPPFLAGS = -Dpgf
+F90FLAGS = -w 
+F77FLAGS = -w 
+LDFLAGS = -Wl,-noinhibit-exec -Wl,-warn-once 
+
diff --git a/conf/config.SGI32 b/conf/config.SGI32
new file mode 100644 (file)
index 0000000..fd5dfd0
--- /dev/null
@@ -0,0 +1,12 @@
+CPP = /usr/lib/cpp -P -C
+AR  = ar
+F90 = f90
+F77 = f90
+CC  = cc
+
+F90FLAGS = -n32 -w
+F77FLAGS = -n32 -w
+CFLAGS   = -c -O2
+CPPFLAGS =
+LDFLAGS  = -n32
+
diff --git a/conf/config.SGI64 b/conf/config.SGI64
new file mode 100644 (file)
index 0000000..547bbeb
--- /dev/null
@@ -0,0 +1,11 @@
+CPP = /usr/lib/cpp -P -C
+AR  = ar
+F90 = f90
+F77 = f90
+
+F90FLAGS = -64 -w
+F77FLAGS = -64 -w
+CFLAGS   = -64
+CPPFLAGS =
+LDFLAGS  = -64
+
diff --git a/conf/config.SP4Idris b/conf/config.SP4Idris
new file mode 100644 (file)
index 0000000..53f3de3
--- /dev/null
@@ -0,0 +1,8 @@
+CPP = cc -C -E
+AR  = ar -X64
+F77 = xlf90_r -qarch=pwr4 -qzerosize -qautodbl=dbl4 -qmaxmem=-1
+F90 = xlf90_r -qarch=pwr4 -qzerosize -qautodbl=dbl4 -qmaxmem=-1
+F77FLAGS = -q64 -qfixed -qsave -O3 -qstrict
+F90FLAGS = -q64 -qfree=f90 -qsuffix=f=f90 -qsave -O3 -qstrict
+CPPFLAGS = 
+LDFLAGS = 
diff --git a/conf/config.SX5 b/conf/config.SX5
new file mode 100644 (file)
index 0000000..e972f90
--- /dev/null
@@ -0,0 +1,11 @@
+CPP = /usr/lib/cpp -P -C 
+AR  = sxar
+F90 = sxf90
+F77 = sxf90
+CC  = sxcc
+
+F90FLAGS = -w -Cvsafe
+F77FLAGS = -w -Cvsafe
+
+LDFLAGS = 
+
diff --git a/conf/config.SX8 b/conf/config.SX8
new file mode 100644 (file)
index 0000000..532c235
--- /dev/null
@@ -0,0 +1,11 @@
+CPP = sxcpp -P -C 
+AR  = sxar
+F90 = sxf90
+F77 = sxf90
+CC  = sxcc
+
+F90FLAGS = -w -Cvsafe
+F77FLAGS = -w -Cvsafe
+
+LDFLAGS = 
+
diff --git a/conf/config.VPP b/conf/config.VPP
new file mode 100644 (file)
index 0000000..a0c049c
--- /dev/null
@@ -0,0 +1,9 @@
+CPP = /usr/ccs/lib/cpp -P -C
+AR  = ar
+F90 = frt 
+F77 = frt
+F90FLAGS = -X9 -Am -Sw
+F77FLAGS = -Sw
+CPPFLAGS = -DFUJI
+LDFLAGS = 
+
diff --git a/conf/config.gfortranR64 b/conf/config.gfortranR64
new file mode 100644 (file)
index 0000000..647e0de
--- /dev/null
@@ -0,0 +1,19 @@
+#
+#   Configuration file for PGF (64-bit reals).
+#
+AR      = ar
+ARFLAGS = rv
+#
+CC      = gcc
+CFLAGS  = -O2 -D__hpux -DREAL_8 -DREAL_BIGGER_THAN_INTEGER
+FASTCFLAGS = 
+#
+FC      = gfortran
+VECTFFLAGS =
+CPPFLAGS = -D__hpux -DREAL_8 -DREAL_BIGGER_THAN_INTEGER -Dextend2o -Dg95
+FFLAGS = -w -g -O2 -fdefault-real-8
+#
+LDFLAGS = -L . -l emos$(R64)
+RANLIB  = /bin/true
+CT      = /bin/true
+NPROC   = 1
diff --git a/conf/listing b/conf/listing
new file mode 100755 (executable)
index 0000000..3f69ec7
--- /dev/null
@@ -0,0 +1,8 @@
+>lst.conf
+for i in config.* ; do
+echo $i >>lst.conf
+echo '---------------' >> lst.conf
+cat $i >>lst.conf
+echo '======================================='>> lst.conf
+done
+
diff --git a/lib/COMPRESS/Makefile b/lib/COMPRESS/Makefile
new file mode 100644 (file)
index 0000000..ed63fbb
--- /dev/null
@@ -0,0 +1,38 @@
+LIBCOMP = liblficomp.a
+#######################################
+DIR_OBJ = ./$(ARCH)
+
+VPATH = src:$(DIR_OBJ)
+INC = -I$(DIR_OBJ)
+
+DIR_CONF:=$(shell pwd|sed -e 's/lib\/.*/conf/')
+
+include $(DIR_CONF)/config.$(ARCH)
+include Rules.$(ARCH)
+
+
+%.o:%.f90
+       $(CPP) $(INC) $(CPPFLAGS) $< >  $(DIR_OBJ)/cpp_$(*F).f90
+       $(F90) $(INC) -c $(F90FLAGS) $(DIR_OBJ)/cpp_$(*F).f90 -o $(DIR_OBJ)/$(*F).o
+       -@mv  *.mod $(DIR_OBJ)/. 2> /dev/null || echo pas de module dans $*.f90
+
+%.o:%.c
+       $(CC) $(INC) $(CFLAGS) $(CPPFLAGS) -c $< -o $(DIR_OBJ)/$(*F).o
+
+$(LIBCOMP) : $(DIR_OBJ)/.dummy $(OBJS)
+       cd $(DIR_OBJ);$(AR) crv $@ $(OBJS)
+
+$(DIR_OBJ)/.dummy :
+       mkdir -p $(DIR_OBJ)
+       @touch $(DIR_OBJ)/.dummy
+
+compress.o : searchgrp.o comppar.o
+decompress.o : searchgrp.o comppar.o
+
+clean:
+       (if [ -d $(DIR_OBJ) ] ; then cd $(DIR_OBJ); rm -f cpp_*.f90 *.o ; fi)
+
+distclean:
+       rm -rf $(DIR_OBJ)
+
+
diff --git a/lib/COMPRESS/Rules.AIX32 b/lib/COMPRESS/Rules.AIX32
new file mode 100644 (file)
index 0000000..2c1ea28
--- /dev/null
@@ -0,0 +1,3 @@
+CPPFLAGS += -DBIG_endian
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.AIX64 b/lib/COMPRESS/Rules.AIX64
new file mode 100644 (file)
index 0000000..2c1ea28
--- /dev/null
@@ -0,0 +1,3 @@
+CPPFLAGS += -DBIG_endian
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.HPNAGf95 b/lib/COMPRESS/Rules.HPNAGf95
new file mode 100644 (file)
index 0000000..f8db394
--- /dev/null
@@ -0,0 +1,4 @@
+F90FLAGS += -O2
+CPPFLAGS += -DNAGf95 -DBIG_endian -DNO_UNDERSCORE
+
+OBJS=comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.HPf90 b/lib/COMPRESS/Rules.HPf90
new file mode 100644 (file)
index 0000000..94847a5
--- /dev/null
@@ -0,0 +1,5 @@
+CFLAGS   += -Ae
+F90FLAGS += -O3
+CPPFLAGS += -DNO_UNDERSCORE -DBIG_endian
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.LXNAGf95 b/lib/COMPRESS/Rules.LXNAGf95
new file mode 100644 (file)
index 0000000..ec73483
--- /dev/null
@@ -0,0 +1,5 @@
+F77FLAGS +=
+F90FLAGS += -O2
+CPPFLAGS = -DNAGf95 -DLITTLE_endian
+
+OBJS=comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.LXg95 b/lib/COMPRESS/Rules.LXg95
new file mode 100644 (file)
index 0000000..c292560
--- /dev/null
@@ -0,0 +1,5 @@
+F77FLAGS +=
+F90FLAGS += -O2
+CPPFLAGS = -DLITTLE_endian
+
+OBJS=comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o ieee_is_nan.o
diff --git a/lib/COMPRESS/Rules.LXgfortran b/lib/COMPRESS/Rules.LXgfortran
new file mode 100644 (file)
index 0000000..c292560
--- /dev/null
@@ -0,0 +1,5 @@
+F77FLAGS +=
+F90FLAGS += -O2
+CPPFLAGS = -DLITTLE_endian
+
+OBJS=comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o ieee_is_nan.o
diff --git a/lib/COMPRESS/Rules.LXpgf90 b/lib/COMPRESS/Rules.LXpgf90
new file mode 100644 (file)
index 0000000..2e9dcee
--- /dev/null
@@ -0,0 +1,3 @@
+CPPFLAGS = -DLITTLE_endian
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.SGI32 b/lib/COMPRESS/Rules.SGI32
new file mode 100644 (file)
index 0000000..b6f8825
--- /dev/null
@@ -0,0 +1,6 @@
+F77LAGS  +=
+F90FLAGS += -O2
+CFLAGS   +=
+CPPFLAGS += -DBIG_endian
+
+OBJS = ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.SGI64 b/lib/COMPRESS/Rules.SGI64
new file mode 100644 (file)
index 0000000..b7a01ad
--- /dev/null
@@ -0,0 +1,5 @@
+F77FLAGS +=
+F90FLAGS += -O2
+CPPFLAGS += -DBIG_endian
+
+OBJS = ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.SX5 b/lib/COMPRESS/Rules.SX5
new file mode 100644 (file)
index 0000000..3682a96
--- /dev/null
@@ -0,0 +1,4 @@
+F90FLAGS +=
+CPPFLAGS += -DBIG_endian -DSX5
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.SX8 b/lib/COMPRESS/Rules.SX8
new file mode 100644 (file)
index 0000000..3682a96
--- /dev/null
@@ -0,0 +1,4 @@
+F90FLAGS +=
+CPPFLAGS += -DBIG_endian -DSX5
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/Rules.VPP b/lib/COMPRESS/Rules.VPP
new file mode 100644 (file)
index 0000000..43ffdda
--- /dev/null
@@ -0,0 +1,5 @@
+F77FLAGS +=
+F90FLAGS += 
+CPPFLAGS += -DVPP -DBIG_endian
+
+OBJS=ieee_is_nan.o comppar.o compress.o decompress.o nearestpow2.o searchgrp.o bitbuff.o
diff --git a/lib/COMPRESS/src/bitbuff.c b/lib/COMPRESS/src/bitbuff.c
new file mode 100644 (file)
index 0000000..48e5ed4
--- /dev/null
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef VPP
+# include <sys/types.h>
+typedef __uint64_t WORD;
+#else
+#ifdef SX5
+typedef unsigned long uint64_t;
+#else
+# include <inttypes.h>
+#endif
+typedef uint64_t WORD;
+#endif
+
+#define WORDSIZE 64
+
+#ifdef NO_UNDERSCORE
+# define SET_FILLIDX set_fillidx
+# define GET_FILLIDX get_fillidx
+# define FILL_BBUFF  fill_bbuff
+# define SET_EXTRACTIDX set_extractidx
+# define GET_EXTRACTIDX get_extractidx
+# define EXTRACT_BBUFF  extract_bbuff
+#else
+# define SET_FILLIDX set_fillidx_
+# define GET_FILLIDX get_fillidx_
+# define FILL_BBUFF  fill_bbuff_
+# define SET_EXTRACTIDX set_extractidx_
+# define GET_EXTRACTIDX get_extractidx_
+# define EXTRACT_BBUFF  extract_bbuff_
+#endif
+
+int outidx = 0;
+int outbrem = WORDSIZE ;
+
+int inidx = 0;
+int inbrem = WORDSIZE;
+
+void SET_FILLIDX(unsigned *idx, unsigned *bitoffset){
+    inidx  = *idx;
+    inidx += (*bitoffset/WORDSIZE);
+    inbrem = WORDSIZE - (*bitoffset%WORDSIZE);
+}
+
+void GET_FILLIDX(unsigned *idx, unsigned *bitoffset){
+    *idx    = inidx;
+    *bitoffset = WORDSIZE - inbrem;
+}
+
+void FILL_BBUFF(WORD *out, int *n, unsigned *val){
+    /* inidx = index of the current buffer elt to fill */
+    /* inbrem = number of bits remaining on buffer elt out[idx] */
+
+    /* fill buffer out with n low bits of val */
+
+    if (inbrem >= *n){
+       inbrem = inbrem - *n;
+       /* turn to 0 the n bits of out */
+       out[inidx] &= ~(~(~(WORD)0 << *n) << inbrem);
+       /* now set the n bits of out to val */
+       out[inidx] |= (*val & ~(~(WORD)0 << *n)) << inbrem;
+       return;
+    } else {
+       int nex = *n - inbrem; /* number of bits that will be filled later */
+       if (inbrem != 0){
+           /* turn to 0 the inbrem lower bits of out */
+           out[inidx] &= (~(WORD)0 << inbrem) ;
+           /* now set the inbrem lower bits of out with val */
+           out[inidx] |= ((*val >> nex) & ~(~(WORD)0 << inbrem));
+       }
+       inidx++;
+       inbrem = WORDSIZE;
+       FILL_BBUFF(out, &nex, val);
+    }
+
+}
+
+void SET_EXTRACTIDX(unsigned *idx, unsigned *bitoffset) {
+    outidx = *idx;
+    outidx += (*bitoffset/WORDSIZE);
+    outbrem = WORDSIZE-(*bitoffset%WORDSIZE);
+}
+
+void GET_EXTRACTIDX(unsigned *idx, unsigned *bitoffset){
+    *idx = outidx;
+    *bitoffset = WORDSIZE - outbrem;
+}
+
+    
+void extract_bbuff_rec(WORD *buff, int *n, unsigned *val) {
+    
+    if (outbrem >= *n){
+       outbrem = outbrem - *n;
+       *val = (*val << *n) | (unsigned)((buff[outidx]>>outbrem) & ~(~(WORD)0 << *n));
+       return;
+    } else {
+       int nex = *n - outbrem;
+       if (outbrem != 0){
+           *val = (*val << outbrem)| (unsigned)(buff[outidx] & ~(~(WORD)0 << outbrem));
+
+       }
+       outidx++;
+       outbrem=WORDSIZE;
+       extract_bbuff_rec(buff,&nex,val);
+    }
+}
+
+void EXTRACT_BBUFF(WORD *buff, int *n, unsigned *val) {
+    
+    unsigned tmpval;
+
+    tmpval=0;
+    extract_bbuff_rec(buff,n,&tmpval);
+    *val = tmpval;
+}
+
diff --git a/lib/COMPRESS/src/comppar.f90 b/lib/COMPRESS/src/comppar.f90
new file mode 100644 (file)
index 0000000..c2712ba
--- /dev/null
@@ -0,0 +1,32 @@
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$ $Date$
+!-----------------------------------------------------------------
+!-----------------------------------------------------------------
+!-----------------------------------------------------------------
+MODULE MODD_COMPPAR
+IMPLICIT NONE 
+! Debug mode : set LPDEBUG to .TRUE.
+LOGICAL,PARAMETER :: LPDEBUG = .FALSE.
+
+
+! contains coding parameters for (de)compress routines
+
+INTEGER,PARAMETER :: JPCSTENCOD = 1 ! constant array 
+INTEGER,PARAMETER :: JPSOPENCOD = 2 ! second order packing 
+INTEGER,PARAMETER :: JPEXTENCOD = 3 ! second order packing with min/max values excluded
+
+! Extended code when JPEXTENCOD enabled
+!
+! BE CAREFUL : 3 bits are reserved for coding this code => max value is 7
+INTEGER,PARAMETER :: JPCONST   = 0 ! constant value array
+INTEGER,PARAMETER :: JPNORM    = 1 ! same as JPSOPENCOD
+INTEGER,PARAMETER :: JPMINEXCL = 2 ! Min value is isolated
+INTEGER,PARAMETER :: JPMAXEXCL = 3 ! Max value is isolated
+INTEGER,PARAMETER :: JPMINMAXEXCL = 4 ! Min&Max values are isolated
+INTEGER,PARAMETER :: JP2VAL       = 5 ! 2 different values in array
+INTEGER,PARAMETER :: JP3VAL       = 6 ! 3 different values in array
+INTEGER,PARAMETER :: JPOTHER      = 7 ! for future use
+INTEGER,PARAMETER :: JPLOG        = 8
+END MODULE MODD_COMPPAR
diff --git a/lib/COMPRESS/src/compress.f90 b/lib/COMPRESS/src/compress.f90
new file mode 100644 (file)
index 0000000..2bc2dfa
--- /dev/null
@@ -0,0 +1,380 @@
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$ $Date$
+!-----------------------------------------------------------------
+SUBROUTINE COMPRESS_FIELD(XTAB,KX,KY,KNBTOT,KNBUSE)
+USE MODD_COMPPAR
+USE MODE_SEARCHGRP
+
+#ifdef NAGf95
+USE,INTRINSIC :: IEEE_ARITHMETIC
+#endif
+
+IMPLICIT NONE 
+
+REAL,PARAMETER :: PPFLOATMIN = 2.0**(-126)
+
+INTEGER, INTENT(IN) :: KX,KY
+!INTEGER, INTENT(IN) :: KNBLEV
+INTEGER, INTENT(IN) :: KNBTOT
+REAL(KIND=8),DIMENSION(KNBTOT),INTENT(INOUT) :: XTAB
+
+INTEGER, INTENT(OUT) :: KNBUSE
+
+INTEGER :: INBLEV
+INTEGER,DIMENSION(:), ALLOCATABLE :: ITAB
+REAL :: XMIN,XMAX
+TYPE(SOP_t) :: SOPRES
+INTEGER :: IND1, IND2
+INTEGER :: GELT,IBE
+INTEGER :: ILEVNBELT
+INTEGER :: NBITCOD
+INTEGER :: II, JI, JJ
+INTEGER :: BITOFFSET
+INTEGER :: GRPIDX,GRPOFF,IDXSAVE,OFFSAVE
+INTEGER :: nbgroupmod
+INTEGER :: IEXTCOD
+CHARACTER(LEN=8),PARAMETER :: KEYWORD='COMPRESS'
+REAL,DIMENSION(KNBTOT) :: XWORKTAB
+LOGICAL :: LUPREAL,LNAN
+#ifndef NAGf95
+LOGICAL, EXTERNAL :: IEEE_IS_NAN
+#endif
+
+ILEVNBELT = KX*KY
+LUPREAL = .FALSE.
+LNAN    = .FALSE.
+
+! Check for NAN and change Upper and Lower bound according to 32bits real limits.
+DO JI=1,KNBTOT
+  IF (IEEE_IS_NAN(XTAB(JI))) THEN 
+    XTAB(JI)=0.
+    LNAN = .TRUE.
+  ELSE IF (ABS(XTAB(JI)) > HUGE(1.0_4)) THEN
+    XTAB(JI) = SIGN(REAL(HUGE(1.0_4)/1.1,8),XTAB(JI))
+    LUPREAL = .TRUE.
+  ELSEIF (ABS(XTAB(JI)) < TINY(1.0_4)) THEN
+    XTAB(JI) = 0.
+  END IF
+END DO
+
+XMIN=MINVAL(XTAB)
+XMAX=MAXVAL(XTAB)
+PRINT *,'MINVAL,MAXVAL= ',XMIN,XMAX
+IF (LNAN) PRINT *,"==================> NAN values DETECTED : set to 0.0"
+IF (LUPREAL) PRINT *,"==================> OVERFLOW values DETECTED : set to ",HUGE(1.0_4)/1.1
+
+! Convert 64 bits real to 32 bits real
+XWORKTAB(:) = XTAB(:)
+!
+! BEWARE : Now XTAB is overwritten. 
+!          XWORKTAB contains the 32 bits floating point data.
+!
+CALL SET_FILLIDX(0,0)
+! store 8 characters header string in buffer
+DO II=1,LEN(KEYWORD)
+  CALL FILL_BBUFF(XTAB,8,ICHAR(KEYWORD(II:II)))
+END DO
+
+! is whole array XTAB64 a constant field ?
+
+IF (xmin == xmax) THEN
+  PRINT *,"--------> CONSTANT ARRAY !"
+  CALL FILL_BBUFF(XTAB,32,JPCSTENCOD)
+  CALL FILL_BBUFF(XTAB,32,KNBTOT)
+  CALL FILL_BBUFF(XTAB,32,xmin)
+  CALL GET_FILLIDX(KNBUSE,BITOFFSET)
+  KNBUSE=KNBUSE+1
+  RETURN
+END IF
+
+
+INBLEV = KNBTOT/(ILEVNBELT)
+IF (KNBTOT /= (INBLEV*ILEVNBELT)) THEN
+  PRINT *,'Pb in COMPRESS_FIELD : KNBTOT must be a multiple of KX*KY'
+  STOP
+END IF
+
+
+
+ALLOCATE(ITAB(ILEVNBELT))
+CALL INI_SOPDATA(SOPRES)
+
+CALL FILL_BBUFF(XTAB,32,JPEXTENCOD)
+CALL FILL_BBUFF(XTAB,32,KNBTOT)
+CALL FILL_BBUFF(XTAB,32,KX)
+CALL FILL_BBUFF(XTAB,32,KY)
+
+DO JI=1,INBLEV
+  IND1=(JI-1)*ILEVNBELT+1
+  IND2=JI*ILEVNBELT
+  IF (LPDEBUG) PRINT *,"---- Compressing Level ",JI," ----"
+  CALL COMP_FOPEXT(XWORKTAB(IND1:IND2),ITAB,IEXTCOD)
+  IF (IEXTCOD /= JPCONST) THEN
+    CALL INVERTCOL(ITAB,KX,KY)
+    CALL RECSEARCH(ITAB,SOPRES)
+    GELT = MAXVAL(SOPRES%IEND(1:SOPRES%NBGRP)-SOPRES%IBEG(1:SOPRES%NBGRP)+1)
+    IBE = FMINBITS_IN_WORD(GELT)
+    CALL GET_FILLIDX(GRPIDX,GRPOFF) ! save the idx/offset for future NBGRP modification
+    CALL FILL_BBUFF(XTAB,32,SOPRES%NBGRP)
+    CALL FILL_BBUFF(XTAB,5,IBE)
+  
+    NBGROUPMOD = SOPRES%NBGRP
+    DO II=1,SOPRES%NBGRP
+      GELT = SOPRES%IEND(II)-SOPRES%IBEG(II)+1
+      nbitcod  = FMINBITS_IN_WORD(SOPRES%VALMAX(II)-SOPRES%VALMIN(II))
+      !    PRINT *, 'Groupe',II,'(',GELT,')',':',SOPRES%IBEG(II),SOPRES%IEND(II),&
+      !         &'MIN,MAX=',SOPRES%VALMIN(II),SOPRES%VALMAX(II),&
+      !         &'(',SOPRES%VALMAX(II)-SOPRES%VALMIN(II),'/',&
+      !         &nbitcod,')'
+      IF (nbitcod >= 16) THEN
+        PRINT *,'-----> ERREUR FATALE : Groupe',II,'codage sur ',nbitcod,'bits'
+      END IF
+      IF (GELT > 1) THEN
+        ! Plus d'un element dans le groupe
+        IF ((17*GELT) < (17+4+IBE+nbitcod*GELT)) THEN
+          ! on prefere GELT groupes de 1 elt
+          DO JJ=SOPRES%IBEG(II),SOPRES%IEND(II)
+            ! 1 seul elt par groupe
+            CALL FILL_BBUFF(XTAB,1,1)
+            CALL FILL_BBUFF(XTAB,16,ITAB(JJ))
+          END DO
+          NBGROUPMOD = NBGROUPMOD+GELT-1
+        ELSE
+          CALL FILL_BBUFF(XTAB,1,0)
+          CALL FILL_BBUFF(XTAB,16,SOPRES%VALMIN(II))
+          CALL FILL_BBUFF(XTAB,4,nbitcod)
+          CALL FILL_BBUFF(XTAB,IBE,GELT)
+          IF (nbitcod > 0) THEN
+            DO JJ=SOPRES%IBEG(II),SOPRES%IEND(II)
+              ! stockage des GELT écarts/VALMIN
+              CALL FILL_BBUFF(XTAB,nbitcod,ITAB(JJ)-SOPRES%VALMIN(II))
+            END DO
+          END IF
+        END IF
+      ELSE
+        ! 1 seul elt dans groupe
+        CALL FILL_BBUFF(XTAB,1,1)
+        CALL FILL_BBUFF(XTAB,16,SOPRES%VALMIN(II))
+      END IF
+    END DO
+    IF (NBGROUPMOD > SOPRES%NBGRP) THEN
+      ! we must change the number of elements 
+      CALL GET_FILLIDX(IDXSAVE,OFFSAVE) ! save the current idx/offset
+      CALL SET_FILLIDX(GRPIDX,GRPOFF)   
+      CALL FILL_BBUFF(XTAB,32,NBGROUPMOD)
+      CALL SET_FILLIDX(IDXSAVE,OFFSAVE) ! restore the current idx/offset
+    END IF
+  END IF
+END DO
+
+CALL GET_FILLIDX(IDXSAVE,OFFSAVE)
+KNBUSE=IDXSAVE+1
+
+DEALLOCATE(ITAB)
+
+CONTAINS 
+
+SUBROUTINE COMP_FOPEXT(PTAB,KTAB,KEXTCOD)
+REAL,    DIMENSION(:), INTENT(IN) :: PTAB
+INTEGER, DIMENSION(:), INTENT(OUT):: KTAB 
+INTEGER,               INTENT(OUT):: KEXTCOD
+
+LOGICAL,DIMENSION(SIZE(PTAB)) :: GMASK
+REAL,DIMENSION(SIZE(PTAB)) :: PTABWORK
+REAL :: XMIN1,XMAX1,XRANGE1
+REAL :: XMIN2,XMAX2,XRANGE2
+REAL :: XREF,XMAX,XCOEFF
+INTEGER :: INTRANGE
+INTEGER :: INDCOR   ! correction d'index pour la supression du min
+LOGICAL :: GMINEXCL,GMAXEXCL,GLOG
+INTEGER :: IEXTCOD2
+REAL, PARAMETER :: XUNDEF = 999.
+REAL, PARAMETER :: XUNDEFSURF =  1.E+20
+
+
+!! G. TANGUY avril 2010 : on change la valeur indéfinie 999. a une valeur
+!indéfinie plus grande que sera de façon certaine le max du champ s'il est
+!present. POur ça on travaille dans le tableau de travail PTABWORK
+PTABWORK=PTAB
+WHERE(PTABWORK == XUNDEF)
+        PTABWORK=XUNDEFSURF
+END WHERE
+
+XMIN1=MINVAL(PTABWORK(:))
+XMAX1=MAXVAL(PTABWORK(:))
+XRANGE1=XMAX1-XMIN1
+IF (LPDEBUG) PRINT *,"XMIN1,XMAX1,XRANGE1 = ",XMIN1,XMAX1,XRANGE1
+
+IF (XRANGE1 > 0.) THEN
+  XMIN2=MINVAL(PTABWORK,MASK=PTABWORK>XMIN1)
+  XMAX2=MAXVAL(PTABWORK,MASK=PTABWORK<XMAX1)
+  XRANGE2 = XMAX2-XMIN2
+  IF (LPDEBUG) PRINT *,"XMIN2,XMAX2,XRANGE2 = ",XMIN2,XMAX2,XRANGE2
+  IF (XRANGE2 > 0.) THEN
+    GLOG     = .FALSE.
+    GMINEXCL = .FALSE.
+    GMAXEXCL = .FALSE.
+    GMASK(:) = .TRUE.
+    INDCOR = 0
+    KEXTCOD = JPNORM
+    INTRANGE=65535
+    XREF = XMIN1
+    XMAX = XMAX1
+
+    ! Check for range between 0 and 1 to convert to LOG values
+    IF (XMIN1 >= 0. .AND. XMAX1 < 1.) THEN
+      IF ((XMAX2/XMIN2)>10.) THEN 
+        GLOG = .TRUE.
+        KEXTCOD = JPOTHER
+        IEXTCOD2 = JPLOG
+        INTRANGE=INTRANGE-1
+        INDCOR = 1           ! On reserve la valeur 0 dans tous les cas
+        IF (XMIN1 == 0.0) THEN
+          XREF = LOG(XMIN2)
+          WHERE (PTABWORK < XMIN2)
+            KTAB  = 0
+            GMASK = .FALSE.
+          END WHERE
+        ELSE
+          XREF = LOG(XMIN1)
+        END IF
+        XMAX1 = LOG(XMAX1)
+        XMAX  = XMAX1
+        XMAX2 = LOG(XMAX2)
+        XRANGE2 = XMAX2 - XREF
+        IF (LPDEBUG) PRINT *,"EXTENCOD,  LOG conversion enabled : XMIN1, XREF, XMAX1, XMAX2 =",&
+             &XMIN1,XREF,XMAX1,XMAX2
+      END IF
+    ELSE
+      ! Check for MIN value exclusion
+      IF (XMIN1 == XUNDEFSURF .OR. (XMIN2-XMIN1) > XRANGE2) THEN
+        ! Min value excluded 
+        GMINEXCL = .TRUE.
+        XREF=XMIN2
+        INTRANGE=INTRANGE-1
+        INDCOR = 1
+        WHERE (PTABWORK < XMIN2)
+          KTAB = 0
+          GMASK = .FALSE.
+        END WHERE
+        IF (LPDEBUG) PRINT *,"EXTENCOD,     Min value isolated :",XMIN1
+        KEXTCOD = JPMINEXCL
+        IF (XMIN1 == XUNDEFSURF) THEN 
+                XMIN1=XUNDEF
+        END IF
+      END IF
+      ! Check for MAX value exclusion
+      IF (XMAX1 == XUNDEFSURF .OR. (XMAX1-XMAX2) > XRANGE2) THEN
+        ! Max value excluded
+        GMAXEXCL = .TRUE.
+        XMAX=XMAX2
+        INTRANGE=INTRANGE-1
+        WHERE (PTABWORK > XMAX2)
+          KTAB = 65535
+          GMASK = .FALSE.
+        END WHERE
+        
+        IF (GMINEXCL) THEN
+          KEXTCOD = JPMINMAXEXCL ! Min et Max exclus
+          IF (LPDEBUG) PRINT *,"EXTENCOD, and Max value isolated :",XMAX1
+        ELSE
+          KEXTCOD = JPMAXEXCL ! Max exclus
+          IF (LPDEBUG) PRINT *,"EXTENCOD, Max value isolated :",XMAX1
+        END IF
+        ! avril 2010 : on remet la valeur indefine de mesonh 999.
+        IF (XMAX1 == XUNDEFSURF) THEN 
+                XMAX1=XUNDEF
+        END IF
+      END IF
+    END IF
+    !
+    XCOEFF=(XMAX-XREF)/INTRANGE
+    IF (XCOEFF < PPFLOATMIN) THEN
+      XCOEFF = PPFLOATMIN
+      PRINT *, "very low range DATA : XCOEFF set to",XCOEFF
+    END IF
+    IF (LPDEBUG) PRINT *,"XCOEFF = ",XCOEFF
+    IF (GLOG) THEN
+      WHERE(GMASK)
+        KTAB = INDCOR + NINT((LOG(PTABWORK)-XREF)/XCOEFF)
+      END WHERE
+    ELSE
+      WHERE(GMASK)
+        KTAB = INDCOR + NINT((PTABWORK(:)-XREF)/XCOEFF)
+      END WHERE
+    END IF
+    IF (LPDEBUG) PRINT *,"KEXTCOD = ",KEXTCOD
+    CALL FILL_BBUFF(XTAB,3,KEXTCOD)
+    IF (GLOG)     CALL FILL_BBUFF(XTAB,3,IEXTCOD2)
+    IF (GMINEXCL) CALL FILL_BBUFF(XTAB,32,XMIN1)
+    IF (GMAXEXCL) CALL FILL_BBUFF(XTAB,32,XMAX1)
+    CALL FILL_BBUFF(XTAB,32,XREF)
+    CALL FILL_BBUFF(XTAB,32,XCOEFF)
+  ELSE
+    IF (XRANGE2 < 0.) THEN
+      ! only 2 values in PTAB array
+      !
+      ! KTAB(i)= 0 if PTAB(i)==XMIN1
+      !          1 if PTAB(i)==XMAX1
+      !
+      IF (LPDEBUG) PRINT *,"EXTENCOD, 2 values in array :",XMIN1,XMAX1
+        IF (XMAX1 == XUNDEFSURF) THEN 
+                XMAX1=XUNDEF
+        END IF
+        IF (XMIN1 == XUNDEFSURF) THEN 
+                XMIN1=XUNDEF
+        END IF
+      KEXTCOD = JP2VAL
+      CALL FILL_BBUFF(XTAB,3,KEXTCOD)
+      CALL FILL_BBUFF(XTAB,32,XMIN1)
+      CALL FILL_BBUFF(XTAB,32,XMAX1)
+      WHERE (PTABWORK < XMAX1)
+        KTAB = 0
+      ELSEWHERE
+        KTAB = 1
+      END WHERE
+    ELSE
+      ! XRANGE2 == 0. <==> XMIN2=XMAX2 
+      ! 3 values in PTAB array :
+      !
+      !          0 if PTAB(i)==XMIN1      ! KTAB(i)= 1 if PTAB(i)==XMIN2(=XMAX2)
+      !          2 if PTAB(i)==XMAX1
+      !
+      IF (LPDEBUG) PRINT *,"EXTENCOD, 3 values in array :",XMIN1,XMIN2,XMAX1
+        IF (XMAX1 == XUNDEFSURF) THEN 
+                XMAX1=XUNDEF
+        END IF
+        IF (XMIN1 == XUNDEFSURF) THEN 
+                XMIN1=XUNDEF
+        END IF
+
+      KEXTCOD = JP3VAL
+      CALL FILL_BBUFF(XTAB,3,KEXTCOD)
+      CALL FILL_BBUFF(XTAB,32,XMIN1)
+      CALL FILL_BBUFF(XTAB,32,XMIN2)
+      CALL FILL_BBUFF(XTAB,32,XMAX1)
+      WHERE (PTABWORK < XMIN2)
+        KTAB = 0
+      ELSEWHERE
+        KTAB = 1
+      END WHERE
+      WHERE (PTABWORK > XMIN2) KTAB = 2
+    END IF
+    
+  END IF
+ELSE
+        IF (XMIN1 == XUNDEFSURF) THEN 
+                XMIN1=XUNDEF
+        END IF
+
+  ! Constant array found : save its 32 bits real value.
+  KEXTCOD=JPCONST
+  CALL FILL_BBUFF(XTAB,3,KEXTCOD)
+  CALL FILL_BBUFF(XTAB,32,XMIN1)
+  IF (LPDEBUG) PRINT *,"EXTENCOD, constant array : ",XMIN1
+END IF
+END SUBROUTINE COMP_FOPEXT
+
+END SUBROUTINE COMPRESS_FIELD
diff --git a/lib/COMPRESS/src/decompress.f90 b/lib/COMPRESS/src/decompress.f90
new file mode 100644 (file)
index 0000000..095f7dc
--- /dev/null
@@ -0,0 +1,303 @@
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$ $Date$
+!-----------------------------------------------------------------
+SUBROUTINE GET_COMPHEADER(KTAB,SIZEKTAB,KNBELT,KTYPECOD)
+
+INTEGER, INTENT(IN) :: SIZEKTAB
+INTEGER(KIND=8), DIMENSION(SIZEKTAB), INTENT(IN) :: KTAB
+INTEGER, INTENT(OUT) :: KNBELT    ! size of decompressed array
+INTEGER, INTENT(OUT) :: KTYPECOD  ! code for compression type
+
+CHARACTER(LEN=8) :: STRKEY
+
+INTEGER :: INTCHAR
+INTEGER :: JI
+
+CALL SET_EXTRACTIDX(0,0)
+! extract string header 
+DO JI=1,8
+  CALL EXTRACT_BBUFF(KTAB,8,INTCHAR)
+  STRKEY(JI:JI) = CHAR(INTCHAR)
+END DO
+
+! Treat array if it is compressed
+IF (STRKEY == 'COMPRESS') THEN
+  CALL EXTRACT_BBUFF(KTAB,32,KTYPECOD)
+  CALL EXTRACT_BBUFF(KTAB,32,KNBELT)
+ELSE
+  KNBELT    =-1
+  KTYPECOD = 0
+END IF
+
+END SUBROUTINE GET_COMPHEADER
+
+SUBROUTINE DECOMPRESS_FIELD(XTAB,NBELT,COMPTAB,NBCOMPELT,CODINGTYPE)
+USE MODD_COMPPAR
+USE MODE_SEARCHGRP
+
+IMPLICIT NONE 
+INTEGER,                                INTENT(IN)  :: NBELT 
+INTEGER,                                INTENT(IN)  :: NBCOMPELT 
+REAL   (KIND=8),DIMENSION(NBELT),TARGET,INTENT(OUT) :: XTAB
+INTEGER(KIND=8),DIMENSION(NBCOMPELT),   INTENT(IN)  :: COMPTAB
+INTEGER,                                INTENT(IN)  :: CODINGTYPE
+
+INTEGER,DIMENSION(:), ALLOCATABLE  :: ITAB
+LOGICAL,DIMENSION(:), ALLOCATABLE  :: GMASK
+
+REAL :: XREF, XCOEFF
+INTEGER :: INBLEV
+INTEGER :: ILEVNBELT
+INTEGER :: JI
+INTEGER :: IND1, IND2
+INTEGER :: IDIMX,IDIMY
+INTEGER :: IEXTCOD
+REAL(KIND=8),DIMENSION(:),POINTER  :: XPTRTAB
+REAL :: XMIN,XMAX
+
+SELECT CASE (CODINGTYPE)
+CASE (JPCSTENCOD)
+  CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+  XTAB(:) = XREF
+
+CASE (JPSOPENCOD)
+  CALL EXTRACT_BBUFF(COMPTAB,32,IDIMX)
+  CALL EXTRACT_BBUFF(COMPTAB,32,IDIMY)
+  ILEVNBELT = IDIMX * IDIMY
+  INBLEV = NBELT/(ILEVNBELT)
+  ALLOCATE(ITAB(ILEVNBELT))
+  DO JI=1,INBLEV
+    IND1=(JI-1)*ILEVNBELT+1
+    IND2=JI*ILEVNBELT
+    XPTRTAB=>XTAB(IND1:IND2)
+    IF (LPDEBUG) PRINT *,'######   Decompress(SOPENCOD) LEVEL ',JI,'######'
+    CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+    CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+    CALL EXTRACTINTARRAY(ITAB)
+    CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF)
+  END DO
+  
+CASE (JPEXTENCOD)
+  CALL EXTRACT_BBUFF(COMPTAB,32,IDIMX)
+  CALL EXTRACT_BBUFF(COMPTAB,32,IDIMY)
+  ILEVNBELT = IDIMX * IDIMY
+  INBLEV = NBELT/(ILEVNBELT)
+  ALLOCATE(ITAB(ILEVNBELT))
+  ALLOCATE(GMASK(ILEVNBELT))
+  DO JI=1,INBLEV
+
+    IF (LPDEBUG) PRINT *,'###### Decompress(EXTENCOD) LEVEL ',JI,'######'
+    IND1=(JI-1)*ILEVNBELT+1
+    IND2=JI*ILEVNBELT
+    XPTRTAB=>XTAB(IND1:IND2)
+    !
+    CALL EXTRACT_BBUFF(COMPTAB,3,IEXTCOD)
+    IF (IEXTCOD == JPOTHER) THEN
+      CALL EXTRACT_BBUFF(COMPTAB,3,IEXTCOD)
+      IEXTCOD = IEXTCOD + 8
+    END IF
+    IF (LPDEBUG) PRINT *, "IEXTCOD = ",IEXTCOD
+    SELECT CASE(IEXTCOD)
+    CASE(JPLOG)
+      ! Conversion to log values of original data 0<=x<1
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+      CALL EXTRACTINTARRAY(ITAB)
+      GMASK(:) = .TRUE.
+      WHERE (ITAB == 0)
+        GMASK = .FALSE.
+        XPTRTAB = 0.0
+      END WHERE
+      CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1)
+      WHERE(GMASK)
+        XPTRTAB = EXP(XPTRTAB)
+      END WHERE
+      
+    CASE(JPCONST)
+      ! constant value array
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      XPTRTAB(:) = XREF
+      IF (LPDEBUG) PRINT *,"  CONST value=",XREF
+
+    CASE(JP2VAL)
+      ! 2 different values in array
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMIN)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMAX)
+      CALL EXTRACTINTARRAY(ITAB)
+      WHERE (ITAB == 0)
+        XPTRTAB = XMIN
+      ELSEWHERE
+        XPTRTAB = XMAX
+      END WHERE
+      IF (LPDEBUG) PRINT *,"  2 values:",XMIN,XMAX
+      
+    CASE(JP3VAL)
+      ! 3 different values in array
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMIN)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMAX)
+      CALL EXTRACTINTARRAY(ITAB)
+      WHERE (ITAB == 0)
+        XPTRTAB = XMIN
+      ELSEWHERE
+        XPTRTAB = XREF
+      END WHERE
+      WHERE (ITAB == 2) XPTRTAB = XMAX
+      IF (LPDEBUG) PRINT *,"  3 values:",XMIN,XREF,XMAX
+
+    CASE(JPNORM)
+      ! same as JPSOPENCOD
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+      CALL EXTRACTINTARRAY(ITAB)
+      CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF)
+      IF (LPDEBUG) PRINT *,"  normal, XREF/XCOEFF = ",XREF,XCOEFF 
+
+    CASE(JPMINEXCL)
+      ! Min value is isolated
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMIN)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+      CALL EXTRACTINTARRAY(ITAB)
+      GMASK(:) = .TRUE.
+      WHERE (ITAB == 0)
+        GMASK = .FALSE.
+        XPTRTAB = XMIN
+      END WHERE
+      CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1)
+      IF (LPDEBUG) PRINT *,"  Min exclus, MIN/XREF/XCOEFF = ",XMIN,XREF,XCOEFF
+
+    CASE(JPMAXEXCL)
+      ! Max value is isolated
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMAX)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+      CALL EXTRACTINTARRAY(ITAB)
+      GMASK(:) = .TRUE.
+      WHERE (ITAB == 65535)
+        GMASK = .FALSE.
+        XPTRTAB = XMAX
+      END WHERE
+      CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,0)   
+      IF (LPDEBUG) PRINT *,"  Max exclus, MAX/XREF/XCOEFF = ",XMAX,XREF,XCOEFF
+
+    CASE(JPMINMAXEXCL)
+      ! Min&Max value are isolated
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMIN)        
+      CALL EXTRACT_BBUFF(COMPTAB,32,XMAX)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XREF)
+      CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF)
+      CALL EXTRACTINTARRAY(ITAB)
+      GMASK(:) = .TRUE.
+      WHERE (ITAB == 0)
+        GMASK = .FALSE.
+        XPTRTAB = XMIN
+      END WHERE
+      WHERE (ITAB == 65535)
+        GMASK = .FALSE.
+        XPTRTAB = XMAX
+      END WHERE
+      CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1)
+      IF (LPDEBUG) PRINT *,"  Min et Max exclus, MIN/MAX/XREF/XCOEFF = ",&
+           &XMIN,XMAX,XREF,XCOEFF
+    END SELECT
+  END DO
+  
+CASE DEFAULT
+  PRINT *,'Error in CODINGTYPE : program aborted'
+  STOP
+END SELECT
+
+CONTAINS 
+
+SUBROUTINE DECOMP_FOP(PTAB,KTAB,PREF,PCOEFF,OMASK,KINDCOR)
+REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: PTAB 
+! Attention: avec le compilateur PGF, utiliser INTENT(OUT) provoque une recopie
+! complete du tableau dans PTAB (avec ecrasement possible des valeurs 
+! presentes a l'appel de la procedure). Le phenomene est genant lorsque
+! DECOMP_FOP ne calcule que sur une portion de PTAB (valeurs min et/ou max 
+! sont presentes). En declarant PTAB en INOUT, les valeurs en entree de la routine
+! sont conservees si elles n'ont pas ete modifiees.
+
+INTEGER,      DIMENSION(:), INTENT(IN) :: KTAB 
+REAL, INTENT(IN) :: PREF
+REAL, INTENT(IN) :: PCOEFF
+LOGICAL, DIMENSION(:),INTENT(IN),OPTIONAL :: OMASK
+INTEGER,INTENT(IN),OPTIONAL  :: KINDCOR ! 1 if Min value is isolated, 0 otherwise
+
+INTEGER :: INDCOR
+
+IF (.NOT. PRESENT(KINDCOR)) THEN
+  INDCOR = 0
+ELSE
+  INDCOR = KINDCOR
+END IF
+  
+IF (PRESENT(OMASK)) THEN
+  WHERE (OMASK)
+    PTAB(:) = PCOEFF*(KTAB(:)-INDCOR)+PREF
+  END WHERE
+ELSE
+  IF (PCOEFF == 0.0) THEN
+    PTAB(:) = PREF
+  ELSE
+    PTAB(:) = PCOEFF*KTAB(:)+PREF
+  END IF
+END IF
+
+END SUBROUTINE DECOMP_FOP
+
+SUBROUTINE EXTRACTINTARRAY(KTAB)
+INTEGER,DIMENSION(:),INTENT(OUT) :: KTAB
+!
+! COMPTAB, IDIMX and IDIMY  are defined in the calling routine
+!
+INTEGER :: NBGRP
+INTEGER :: IBE
+INTEGER :: CPT
+INTEGER :: JJ
+INTEGER :: ALONE
+INTEGER :: NBITCOD,IMIN
+INTEGER :: GELT
+INTEGER :: JELT
+INTEGER :: IEPS
+
+CALL EXTRACT_BBUFF(COMPTAB,32,NBGRP)
+!      PRINT *,'Nbre de groupes =',NBGRP
+CALL EXTRACT_BBUFF(COMPTAB,5,IBE)
+!      PRINT *,'Nbre de bits pour coder le nombre d''elements:',IBE
+CPT = 1
+DO JJ=1,NBGRP
+  !      PRINT *,'Groupe ',JJ,' : '
+  CALL EXTRACT_BBUFF(COMPTAB,1,ALONE)
+  CALL EXTRACT_BBUFF(COMPTAB,16,IMIN)
+  !      PRINT *,'IREF=',IMIN
+  
+  IF (ALONE == 1) THEN
+    ! 1 seul elt dans le groupe
+    !        PRINT *,'--> un seul element dans le groupe'
+    KTAB(CPT)=IMIN
+    CPT=CPT+1
+  ELSE
+    CALL EXTRACT_BBUFF(COMPTAB,4,NBITCOD)
+    CALL EXTRACT_BBUFF(COMPTAB,IBE,GELT)
+    !        PRINT *,'--> ',GELT,' elts, codage ecart sur ',nbitcod,'bits'
+    IF (NBITCOD > 0) THEN
+      DO JELT=1,GELT
+        CALL EXTRACT_BBUFF(COMPTAB,NBITCOD,IEPS)
+        KTAB(CPT) = IMIN+IEPS
+        CPT=CPT+1
+      END DO
+    ELSE
+      KTAB(CPT:CPT+GELT-1) = IMIN
+      CPT = CPT+GELT
+    END IF
+  END IF
+END DO
+CALL INVERTCOL(KTAB,IDIMX,IDIMY)        
+END SUBROUTINE EXTRACTINTARRAY
+
+END SUBROUTINE DECOMPRESS_FIELD
+
diff --git a/lib/COMPRESS/src/ieee754.h b/lib/COMPRESS/src/ieee754.h
new file mode 100644 (file)
index 0000000..0f5802b
--- /dev/null
@@ -0,0 +1,63 @@
+#undef __BYTE_ORDER
+
+#ifdef BIG_endian
+# define __BYTE_ORDER 1234
+#endif
+#ifdef LITTLE_endian
+# define __BYTE_ORDER 4321
+#endif
+#if !(defined(__BYTE_ORDER))
+ #error "ieee754.h : you MUST specify \
+-DBIG_endian or -DLITTLE_endian \
+in CPPFLAGS of your Makefile."
+/* Compiler must throw us out at this point! */
+#endif
+
+#define __BIG_ENDIAN    1234
+#define __LITTLE_ENDIAN 4321
+
+union ieee754_double
+  {
+    double d;
+
+    /* This is the IEEE 754 double-precision format.  */
+    struct
+      {
+#if     __BYTE_ORDER == __BIG_ENDIAN
+        unsigned int negative:1;
+        unsigned int exponent:11;
+        /* Together these comprise the mantissa.  */
+        unsigned int mantissa0:20;
+        unsigned int mantissa1:32;
+#endif                          /* Big endian.  */
+#if     __BYTE_ORDER == __LITTLE_ENDIAN
+        /* Together these comprise the mantissa.  */
+        unsigned int mantissa1:32;
+        unsigned int mantissa0:20;
+        unsigned int exponent:11;
+        unsigned int negative:1;
+#endif                          /* Little endian.  */
+      } ieee;
+
+    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+    struct
+      {
+#if     __BYTE_ORDER == __BIG_ENDIAN
+        unsigned int negative:1;
+        unsigned int exponent:11;
+        unsigned int quiet_nan:1;
+        /* Together these comprise the mantissa.  */
+        unsigned int mantissa0:19;
+        unsigned int mantissa1:32;
+#else
+        /* Together these comprise the mantissa.  */
+        unsigned int mantissa1:32;
+        unsigned int mantissa0:19;
+        unsigned int quiet_nan:1;
+        unsigned int exponent:11;
+        unsigned int negative:1;
+#endif
+      } ieee_nan;
+  };
+
+#define IEEE754_DOUBLE_BIAS     0x3ff /* Added to exponent.  */
diff --git a/lib/COMPRESS/src/ieee_is_nan.c b/lib/COMPRESS/src/ieee_is_nan.c
new file mode 100644 (file)
index 0000000..f8682fb
--- /dev/null
@@ -0,0 +1,11 @@
+#include <math.h>
+
+#ifdef NO_UNDERSCORE
+# define IEEE_IS_NAN ieee_is_nan
+#else
+# define IEEE_IS_NAN ieee_is_nan_
+#endif
+
+int IEEE_IS_NAN(double *x){
+    return isnan(*x);
+}
diff --git a/lib/COMPRESS/src/nearestpow2.c b/lib/COMPRESS/src/nearestpow2.c
new file mode 100644 (file)
index 0000000..e07a0ec
--- /dev/null
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include "ieee754.h"
+#include <math.h>
+
+#ifdef NO_UNDERSCORE
+# define NEAREST_POW2 nearest_pow2
+# define MINBITS_IN_WORD minbits_in_word
+# define FMINBITS_IN_WORD fminbits_in_word
+#else
+# define NEAREST_POW2 nearest_pow2_
+# define MINBITS_IN_WORD minbits_in_word_
+# define FMINBITS_IN_WORD fminbits_in_word_
+#endif
+
+void NEAREST_POW2(union ieee754_double *xval, unsigned int *pow)
+{
+
+  if (xval->d != 0.0)
+    *pow = xval->ieee.exponent - IEEE754_DOUBLE_BIAS;
+  else {
+      printf("Warning : NEAREST_POW2 ne traite que des reels > 0.0\n");
+      *pow = 0;
+  }
+
+}
+
+void MINBITS_IN_WORD(int *nval, unsigned int *nbit)
+{
+  union ieee754_double xval;
+  int ival = *nval;
+
+  /* ne fonctionne qu'avec des entiers non signés */
+  if (ival-- < 0){
+    printf("Warning : MINBITS_IN_WORD ne traite que des entiers POSITIFS.\n");
+    *nbit = -1;
+    return;
+  } else
+    if (ival > 0){
+      xval.d = (double)ival;
+      NEAREST_POW2(&xval,nbit);
+      (*nbit)++;
+    } else 
+      *nbit = 0 ;
+    
+}
+
+int FMINBITS_IN_WORD(int *nval)
+{
+  union ieee754_double xval;
+  int ival = *nval;
+  unsigned int nbit;
+
+  /* ne fonctionne qu'avec des entiers non signés */
+  if (ival < 0){
+    printf("Warning : MINBITS_IN_WORD ne traite que des entiers POSITIFS.\n");
+    return -1;
+  } else {
+    if (ival > 0){
+      xval.d = (double)ival;
+      NEAREST_POW2(&xval,&nbit);
+      nbit++;
+    } else 
+      nbit = 0 ;
+    return nbit;
+  }
+}
+
+/* int main(){ */
+
+/*   double x; */
+/*   int i,nbit; */
+/*   int exp2; */
+
+/*   printf("Reel : "); */
+/*   scanf("%lf",&x); */
+  
+/*   nearest_pow2_((union ieee754_double*)&x,&exp2); */
+
+/*   printf("2**%d = %lf est la puissance de 2 la plus proche et inferieure à %lf\n", */
+/*      exp2,pow(2.,exp2),x); */
+/*   printf("%lf <= %lf <= %lf\n",pow(2.,(double)exp2),x,pow(2.,(double)exp2+1.)); */
+  
+/*   printf("Entier positif : "); */
+/*   scanf("%d",&i); */
+/*   minbits_in_word_(&i,&nbit); */
+/*   printf("%d valeurs : %d bits (2**%d = %d).\n",i,nbit,nbit,(1<<nbit)); */
+/* } */
diff --git a/lib/COMPRESS/src/searchgrp.f90 b/lib/COMPRESS/src/searchgrp.f90
new file mode 100644 (file)
index 0000000..5b7aed9
--- /dev/null
@@ -0,0 +1,197 @@
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$ $Date$
+!-----------------------------------------------------------------
+!-----------------------------------------------------------------
+MODULE MODE_SEARCHGRP
+IMPLICIT NONE 
+TYPE SOP_t
+  INTEGER :: NBGRP
+  INTEGER,DIMENSION(:),POINTER :: IBEG
+  INTEGER,DIMENSION(:),POINTER :: IEND
+  INTEGER,DIMENSION(:),POINTER :: VALMIN
+  INTEGER,DIMENSION(:),POINTER :: VALMAX
+END TYPE SOP_t
+
+INTEGER,EXTERNAL :: FMINBITS_IN_WORD
+
+! Private variables
+INTEGER,SAVE,                           PRIVATE :: IGRP
+INTEGER,DIMENSION(:),ALLOCATABLE,TARGET,PRIVATE :: IBEG,IEND,VALMAX,VALMIN
+INTEGER,PARAMETER,                      PRIVATE :: MAINSEUIL=8
+INTEGER,SAVE,                           PRIVATE :: IGRPMAX
+INTEGER,SAVE,                           PRIVATE :: ICOUNT
+INTEGER,DIMENSION(16),PARAMETER,      PRIVATE :: MINELT=(/4,4,4,4,5,5,6,6,7,8,9,11,13,17,26,51/)
+
+! Private routines
+PRIVATE :: RECSEARCH_GRP
+
+CONTAINS 
+SUBROUTINE INI_SOPDATA(SOPDATA)
+TYPE(SOP_t), INTENT(OUT) :: SOPDATA
+
+SOPDATA%NBGRP = 0
+NULLIFY(SOPDATA%IBEG)
+NULLIFY(SOPDATA%IEND)
+NULLIFY(SOPDATA%VALMIN)
+NULLIFY(SOPDATA%VALMAX)
+
+END SUBROUTINE INI_SOPDATA
+
+SUBROUTINE RECSEARCH(KTAB,SOPDATA)
+INTEGER,DIMENSION(:) :: KTAB
+TYPE(SOP_t), INTENT(OUT) :: SOPDATA
+
+INTEGER :: NELT
+INTEGER :: GELT,BGELT
+
+IF (ALLOCATED(IBEG)) THEN
+  DEALLOCATE(IBEG,IEND,VALMAX,VALMIN)
+END IF
+
+NELT=SIZE(KTAB)
+ALLOCATE(IBEG(NELT),IEND(NELT),VALMAX(NELT),VALMIN(NELT))
+ICOUNT = 0
+IGRP   = 0
+IGRPMAX = NELT
+CALL RECSEARCH_GRP(1,NELT,KTAB,MAINSEUIL)
+GELT = MAXVAL(IEND(1:IGRP)-IBEG(1:IGRP)+1)
+BGELT = FMINBITS_IN_WORD(GELT)
+
+#ifdef DEBUG
+PRINT *,'Routine RECSEARCH_GRP appelee',ICOUNT,'fois.'
+PRINT *,'Nbre de groupes =',IGRP
+PRINT *,'Nbre maxi d''elements dans groupes',GELT
+PRINT *,'Nbre de bits pour coder le nombre d''elements:',BGELT
+#endif
+
+SOPDATA%NBGRP=IGRP
+SOPDATA%IBEG=>IBEG
+SOPDATA%IEND=>IEND
+SOPDATA%VALMIN=>VALMIN
+SOPDATA%VALMAX=>VALMAX
+
+END SUBROUTINE RECSEARCH
+
+RECURSIVE SUBROUTINE RECSEARCH_GRP(IND1,IND2,ITAB,ISEUIL)
+INTEGER,             INTENT(IN) :: IND1,IND2,ISEUIL
+INTEGER,DIMENSION(:),INTENT(IN) :: ITAB
+
+INTEGER :: II
+INTEGER :: IMAX,IMIN
+INTEGER :: IVAL
+INTEGER :: nbitcod
+INTEGER :: tmpidx1,tmpidx2
+
+ICOUNT=ICOUNT+1
+
+IF (IGRP == 0) THEN
+  IMIN = MINVAL(ITAB(IND1:IND2))
+  IMAX = MAXVAL(ITAB(IND1:IND2))
+  IGRP = 1
+  VALMIN(IGRP) = IMIN
+  VALMAX(IGRP) = IMAX
+  IBEG(IGRP) = IND1
+  IEND(IGRP) = IND2
+ELSE
+  IMIN = VALMIN(IGRP)
+  IMAX = VALMAX(IGRP)
+END IF
+
+IF (IMAX > IMIN) THEN
+
+  IBEG(IGRP) = IND1
+  IEND(IGRP) = IND1
+  VALMIN(IGRP) = ITAB(IND1)
+  VALMAX(IGRP) = ITAB(IND1)
+  
+  DO II=IND1,IND2-1
+    IVAL = ITAB(II+1)
+    IMAX=MAX(VALMAX(IGRP),IVAL)
+    IMIN=MIN(VALMIN(IGRP),IVAL)
+    IF ((IMAX-IMIN)<(2**ISEUIL)) THEN
+      ! II+1 belong to group IGRP
+      IEND(IGRP) = II+1
+      VALMIN(IGRP) = IMIN
+      VALMAX(IGRP) = IMAX
+    ELSE
+      ! Search the created group
+      nbitcod=FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP))
+#ifdef DEBUG
+      PRINT *,'F:(IGRP,IBEG,IEND,MAX,MIN,nbitcod)=',IGRP,',',IBEG(IGRP),',',IEND(IGRP),',',VALMAX(IGRP),',',VALMIN(IGRP),',',nbitcod
+#endif      
+      IF (IEND(IGRP)-IBEG(IGRP)>MINELT(nbitcod+1)) THEN
+        IF (nbitcod > 0) THEN
+          tmpidx1=IBEG(IGRP)
+          tmpidx2=IEND(IGRP)
+#ifdef DEBUG
+          PRINT *,'Appel 1 RECSEARCH_GRP (first,last,seuil):',tmpidx1,tmpidx2,nbitcod/2
+#endif
+          CALL RECSEARCH_GRP(tmpidx1,tmpidx2,ITAB,nbitcod/2)
+        END IF
+      ELSE
+        IF (IGRP > 1) THEN
+          nbitcod=FMINBITS_IN_WORD(VALMAX(IGRP-1)-VALMIN(IGRP-1))
+          IMIN=MIN(VALMIN(IGRP-1),VALMIN(IGRP))
+          IMAX=MAX(VALMAX(IGRP-1),VALMAX(IGRP))
+          IF (IEND(IGRP-1)-IBEG(IGRP-1)<=MINELT(nbitcod+1)) THEN
+            IF ((IMAX-IMIN) < 2**15) THEN 
+            ! concat IGRP-1 and IGRP
+              IEND(IGRP-1) = IEND(IGRP)
+              VALMIN(IGRP-1) = IMIN
+              VALMAX(IGRP-1) = IMAX
+              IGRP = IGRP-1
+            END IF
+          ELSE
+            IF (FMINBITS_IN_WORD(IMAX-IMIN) <= nbitcod) THEN
+              ! concat IGRP-1 and IGRP
+              IEND(IGRP-1) = IEND(IGRP)
+              VALMIN(IGRP-1) = IMIN
+              VALMAX(IGRP-1) = IMAX
+              IGRP = IGRP-1
+            END IF
+          END IF
+        END IF
+      END IF
+      ! New group is created
+      IGRP = IGRP+1
+      IF (IGRP>IGRPMAX) THEN
+        PRINT *,'ERROR max number of group exceeded !'
+        STOP
+      END IF
+      IBEG(IGRP) = II+1
+      IEND(IGRP) = II+1
+      VALMIN(IGRP) = IVAL
+      VALMAX(IGRP) = IVAL
+    END IF
+  END DO
+#ifdef DEBUG
+  PRINT *,'L:',IGRP,':',VALMAX(IGRP)-VALMIN(IGRP),FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP))
+#endif
+  nbitcod = FMINBITS_IN_WORD(VALMAX(IGRP)-VALMIN(IGRP))
+  IF (IEND(IGRP)-IBEG(IGRP)>= MINELT(nbitcod+1)) THEN
+    IF (nbitcod > 0) THEN
+      tmpidx1=IBEG(IGRP)
+      tmpidx2=IEND(IGRP)
+#ifdef DEBUG
+      PRINT *,'Appel 2 RECSEARCH_GRP (first,last,seuil):',tmpidx1,tmpidx2,nbitcod/2
+#endif
+      CALL RECSEARCH_GRP(tmpidx1,tmpidx2,ITAB,nbitcod/2)
+    END IF
+  END IF
+END IF
+    
+END SUBROUTINE RECSEARCH_GRP
+
+END MODULE MODE_SEARCHGRP
+
+SUBROUTINE INVERTCOL(ITAB,KX,KY)
+IMPLICIT NONE 
+INTEGER,                  INTENT(IN)   :: KX,KY
+INTEGER,DIMENSION(KX,KY), INTENT(INOUT)::ITAB
+
+ITAB(:,2:KY:2) = ITAB(KX:1:-1,2:KY:2)
+
+END SUBROUTINE INVERTCOL
+
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..8223eb6
--- /dev/null
@@ -0,0 +1,32 @@
+GRIB_DIR=$(wildcard gribex*)
+SUBDIRS = NEWLFI COMPRESS MPIvide RAD2 SURCOUCHE vis5d
+.PHONY: subdirs $(SUBDIRS) $(GRIB_DIR)
+
+ifndef ARCH
+VALID_ARCH=$(subst ../conf/config.,,$(wildcard ../conf/config.*))
+dummy %:
+       @echo "ERROR : ARCH variable is not set !";echo
+       @echo "Please, choose one of these statements then try again :";echo " "
+       @for i in $(VALID_ARCH); do echo export ARCH=$$i; done
+
+else   
+subdirs: $(SUBDIRS) $(GRIB_DIR)
+
+$(SUBDIRS):
+       $(MAKE) -C $@
+
+$(GRIB_DIR):
+       @echo "==========================================================================="
+       @echo "GRIB library : please go into $@ directory and see README files"
+       @echo "               in order to generate manually the GRIB library."
+       @echo "==========================================================================="
+
+clean distclean:
+       @for dir in $(SUBDIRS) $(GRIB_DIR); do \
+       $(MAKE) -C $$dir $@; \
+       done
+
+endif
+
+
+
diff --git a/lib/vis5d/Makefile b/lib/vis5d/Makefile
new file mode 100644 (file)
index 0000000..15f4d22
--- /dev/null
@@ -0,0 +1,33 @@
+DIR_OBJ = ./$(ARCH)
+
+VPATH = src:$(DIR_OBJ)
+DIR_CONF:=$(shell pwd|sed -e 's/lib\/.*/conf/')
+
+include $(DIR_CONF)/config.$(ARCH)
+include Rules.$(ARCH)
+
+
+OBJS = binio.o v5d.o
+
+# The following are dependencies generated by running makedepend:
+
+all : libv5d.a
+
+libv5d.a : $(DIR_OBJ)/.dummy $(OBJS)
+       cd $(DIR_OBJ) ; $(AR) crv $@ $(OBJS)
+
+binio.o: binio.c binio.h
+       $(CC) -c $(CFLAGS) $< -o $(DIR_OBJ)/$@
+v5d.o: v5d.c binio.h v5d.h vis5d.h
+       $(CC) -c $(CFLAGS) $< -o $(DIR_OBJ)/$@
+
+$(DIR_OBJ)/.dummy :
+       mkdir -p $(DIR_OBJ)
+       @touch $(DIR_OBJ)/.dummy
+tar :
+       tar cvf vis5d.tar Makefile Rules* binio.c binio.h v5d.c v5d.h vis5d.h
+clean :
+       (if [ -d $(DIR_OBJ) ] ; then cd $(DIR_OBJ) ; rm -f $(OBJS); fi)
+
+distclean:
+       rm -rf $(DIR_OBJ)
diff --git a/lib/vis5d/Makefile.v5d b/lib/vis5d/Makefile.v5d
new file mode 100644 (file)
index 0000000..f32bae7
--- /dev/null
@@ -0,0 +1,23 @@
+CC = cc
+#CFLAGS = -c -O2 -DUNDERSCORE -DLITTLE
+CFLAGS = -c -O2 -DUNDERSCORE -DVPP
+
+OBJETS = binio.o v5d.o
+
+# The following are dependencies generated by running makedepend:
+
+all : libv5d.a
+
+libv5d.a : $(OBJETS)
+       ar crv $@ $?
+
+binio.o: binio.c binio.h
+       $(CC) $(CFLAGS) binio.c
+v5d.o: binio.h v5d.h vis5d.h v5d.c
+       $(CC) $(CFLAGS) v5d.c
+
+tar :
+        tar cvf libvis5d.tar Makefile binio.c binio.h v5d.c v5d.h vis5d.h
+clean :
+       rm -rf libv5d.a $(OBJETS)
+
diff --git a/lib/vis5d/Rules.HPf90 b/lib/vis5d/Rules.HPf90
new file mode 100644 (file)
index 0000000..b13568d
--- /dev/null
@@ -0,0 +1,3 @@
+#CFLAGS += -DUNDERSCORE -DVPP
+#CFLAGS += -DUNDERSCORE -DLITTLE
+CFLAGS += -DUNDERSCORE
diff --git a/lib/vis5d/Rules.LXNAGf95 b/lib/vis5d/Rules.LXNAGf95
new file mode 100644 (file)
index 0000000..b13568d
--- /dev/null
@@ -0,0 +1,3 @@
+#CFLAGS += -DUNDERSCORE -DVPP
+#CFLAGS += -DUNDERSCORE -DLITTLE
+CFLAGS += -DUNDERSCORE
diff --git a/lib/vis5d/Rules.LXg95 b/lib/vis5d/Rules.LXg95
new file mode 100644 (file)
index 0000000..ef46668
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Don't forget -DLITTLE flag for little-endian architecture
+#
+
+#CFLAGS += -DUNDERSCORE -DVPP
+CFLAGS += -DUNDERSCORE -DLITTLE
+
diff --git a/lib/vis5d/Rules.LXgfortran b/lib/vis5d/Rules.LXgfortran
new file mode 100644 (file)
index 0000000..b13568d
--- /dev/null
@@ -0,0 +1,3 @@
+#CFLAGS += -DUNDERSCORE -DVPP
+#CFLAGS += -DUNDERSCORE -DLITTLE
+CFLAGS += -DUNDERSCORE
diff --git a/lib/vis5d/Rules.SGI32 b/lib/vis5d/Rules.SGI32
new file mode 100644 (file)
index 0000000..0efee43
--- /dev/null
@@ -0,0 +1 @@
+CFLAGS += -DUNDERSCORE
diff --git a/lib/vis5d/Rules.VPP b/lib/vis5d/Rules.VPP
new file mode 100644 (file)
index 0000000..a06bddb
--- /dev/null
@@ -0,0 +1 @@
+CFLAGS += -DUNDERSCORE -DVPP
diff --git a/lib/vis5d/src/binio.c b/lib/vis5d/src/binio.c
new file mode 100644 (file)
index 0000000..ee48400
--- /dev/null
@@ -0,0 +1,804 @@
+/* Vis5D version 5.1 */
+
+/*
+Vis5D system for visualizing five dimensional gridded data sets
+Copyright (C) 1990 - 1997 Bill Hibbard, Johan Kellum, Brian Paul,
+Dave Santek, and Andre Battaiola.
+
+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; either version 1, or (at your option)
+any later version.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * Functions to do binary I/O of floats, ints.
+ *
+ * >>>> These functions are built on top of Unix I/O functions, not stdio! <<<<
+ *
+ * The file format is assumed to be BIG-ENDIAN.
+ * If this code is compiled with -DLITTLE and executes on a little endian
+ * CPU then byte-swapping will be done.
+ *
+ * If an ANSI compiler is used prototypes and ANSI function declarations
+ * are used.  Otherwise use K&R conventions.
+ *
+ * If we're running on a CRAY (8-byte ints and floats), conversions will
+ * be done as needed.
+ */
+
+
+/*
+ * Updates:
+ *
+ * April 13, 1995, brianp
+ *   added cray_to_ieee and iee_to_cray array conversion functions.
+ *   fixed potential cray bug in write_float4_array function.
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef _CRAY
+#  include <string.h>
+#endif
+#include "binio.h"
+
+
+
+
+/**********************************************************************/
+/******                     Byte Flipping                         *****/
+/**********************************************************************/
+
+
+#define FLIP4( n )  (  (n & 0xff000000) >> 24     \
+                     | (n & 0x00ff0000) >> 8      \
+                     | (n & 0x0000ff00) << 8      \
+                     | (n & 0x000000ff) << 24  )
+
+
+#define FLIP2( n )  (((unsigned short) (n & 0xff00)) >> 8  |  (n & 0x00ff) << 8)
+
+
+
+/*
+ * Flip the order of the 4 bytes in an array of 4-byte words.
+ */
+void flip4( const unsigned int *src, unsigned int *dest, int n )
+{
+   int i;
+
+   for (i=0;i<n;i++) {
+      unsigned int tmp = src[i];
+      dest[i] = FLIP4( tmp );
+   }
+}
+
+
+
+/*
+ * Flip the order of the 2 bytes in an array of 2-byte words.
+ */
+void flip2( const unsigned short *src, unsigned short *dest, int n )
+{
+   int i;
+
+   for (i=0;i<n;i++) {
+      unsigned short tmp = src[i];
+      dest[i] = FLIP2( tmp );
+   }
+}
+
+
+#ifdef _CRAY
+/*****************************************************************************
+*
+* The following source code is in the public domain.
+* Specifically, we give to the public domain all rights for future licensing
+* of the source code, all resale rights, and all publishing rights.
+*
+* We ask, but do not require, that the following message be included in all
+* derived works:
+*
+* Portions developed at the National Center for Supercomputing Applications at
+* the University of Illinois at Urbana-Champaign.
+*
+* THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
+* SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
+* WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
+*
+****************************************************************************/
+
+/** THESE ROUTINES MUST BE COMPILED ON THE CRAY ONLY SINCE THEY **/
+/** REQUIRE 8-BYTES PER C-TYPE LONG                             **/
+
+/* Cray to IEEE single precision */
+static void c_to_if( long *t, const long *f)
+{
+    if (*f != 0){
+        *t = (((*f & 0x8000000000000000) |      /* sign bit */
+                 ((((*f & 0x7fff000000000000) >> 48)-16258) << 55)) + /* exp */
+                 (((*f & 0x00007fffff000000) +
+                    ((*f & 0x0000000000800000) << 1)) << 8));  /* mantissa */
+    }
+    else *t = *f;
+}
+
+
+#define C_TO_IF( T, F )                                                        \
+       if (F != 0) {                                                   \
+               T = (((F & 0x8000000000000000) |                        \
+               ((((F & 0x7fff000000000000) >> 48)-16258) << 55)) +     \
+               (((F & 0x00007fffff000000) +                            \
+               ((F & 0x0000000000800000) << 1)) << 8));                \
+       }                                                               \
+       else {                                                          \
+               T = F;                                                  \
+       }
+
+
+
+/* IEEE single precison to Cray */
+static void if_to_c( long *t, const long *f)
+{
+    if (*f != 0) {
+        *t = (((*f & 0x8000000000000000) |
+                ((*f & 0x7f80000000000000) >> 7) +
+                (16258 << 48)) |
+                (((*f & 0x007fffff00000000) >> 8) | (0x0000800000000000)));
+        if ((*f << 1) == 0) *t = 0;
+    }
+    else *t = *f;
+}
+
+/* T and F must be longs! */
+#define IF_TO_C( T, F )                                                        \
+       if (F != 0) {                                                   \
+               T = (((F & 0x8000000000000000) |                        \
+               ((F & 0x7f80000000000000) >> 7) +                       \
+               (16258 << 48)) |                                        \
+               (((F & 0x007fffff00000000) >> 8) | (0x0000800000000000)));  \
+               if ((F << 1) == 0) T = 0;                               \
+       }                                                               \
+       else {                                                          \
+               T = F;                                                  \
+       }
+
+
+
+
+/*
+ * Convert an array of Cray 8-byte floats to an array of IEEE 4-byte floats.
+ */
+void cray_to_ieee_array( long *dest, const float *source, int n )
+{
+   long *dst;
+   const long *src;
+   long tmp1, tmp2;
+   int i;
+
+   dst = dest;
+   src = (const long *) source;
+
+   for (i=0;i<n;i+=2) {       /* add 1 in case n is odd */
+      c_to_if( &tmp1, &src[i] );
+      c_to_if( &tmp2, &src[i+1] );
+      *dst = (tmp1 & 0xffffffff00000000) | (tmp2 >> 32);
+      dst++;
+   }
+}
+
+
+
+/*
+ * Convert an array of IEEE 4-byte floats to an array of 8-byte Cray floats.
+ */
+void ieee_to_cray_array( float *dest, const long *source, int n )
+{
+   long *dst;
+   const long *src;
+   int i;
+   long ieee;
+
+   src = source;
+   dst = (long *) dest;
+
+   for (i=0;i<n;i++) {
+      /* most significant 4-bytes of ieee contain bit pattern to convert */
+      if ((i&1)==0) {
+         /* get upper half */
+         ieee = src[i/2] & 0xffffffff00000000;
+      }
+      else {
+         /* get lower half */
+         ieee = src[i/2] << 32;
+      }
+      if_to_c( dst, &ieee );
+      dst++;
+   }
+}
+
+
+#endif /*_CRAY*/
+
+
+
+/**********************************************************************/
+/*****                     Read Functions                         *****/
+/**********************************************************************/
+
+
+/*
+ * Read a block of bytes.
+ *  Input:  f - the file descriptor to read from.
+ *         b - address of buffer to read into.
+ *         n - number of bytes to read.
+ * Return:  number of bytes read, 0 if error.
+ */
+int read_bytes( int f, void *b, int n )
+{
+   return read( f, b, n );
+}
+
+
+
+/*
+ * Read an array of 2-byte integers.
+ * Input:  f - file descriptor
+ *         iarray - address to put integers
+ *         n - number of integers to read.
+ * Return:  number of integers read.
+ */
+int read_int2_array( int f, short *iarray, int n )
+{
+#ifdef _CRAY
+   int i;
+   signed char *buffer;
+   int nread;
+   buffer = (signed char *) malloc( n * 2 );
+   if (!buffer)  return 0;
+   nread = read( f, buffer, n*2 );
+   if (nread<=0)  return 0;
+   nread /= 2;
+   for (i=0;i<nread;i++) {
+      /* don't forget about sign extension! */
+      iarray[i] = (buffer[i*2] * 256) | buffer[i*2+1];
+   }
+   free( buffer );
+   return nread;
+#else
+   int nread = read( f, iarray, n*2 );
+   if (nread<=0)
+      return 0;
+#ifdef LITTLE
+   flip2( (const unsigned short *) iarray, (unsigned short *) iarray, nread/2);
+#endif
+   return nread/2;
+#endif
+}
+
+
+
+/*
+ * Read an array of unsigned 2-byte integers.
+ * Input:  f - file descriptor
+ *         iarray - address to put integers
+ *         n - number of integers to read.
+ * Return:  number of integers read.
+ */
+int read_uint2_array( int f, unsigned short *iarray, int n )
+{
+#ifdef _CRAY
+   int i;
+   unsigned char *buffer;
+   int nread;
+   buffer = (unsigned char *) malloc( n * 2 );
+   if (!buffer)  return 0;
+   nread = read( f, buffer, n*2 );
+   if (nread<=0)  return 0;
+   nread /= 2;
+   for (i=0;i<nread;i++) {
+      iarray[i] = (buffer[i*2] << 8) | buffer[i*2+1];
+   }
+   free( buffer );
+   return nread;
+#else
+   int nread = read( f, iarray, n*2 );
+   if (nread<=0)
+      return 0;
+#ifdef LITTLE
+   flip2( iarray, iarray, nread/2 );
+#endif
+   return nread/2;
+#endif
+}
+
+
+
+/*
+ * Read a 4-byte integer.
+ * Input:  f - the file descriptor to read from
+ *         i - pointer to integer to put result into.
+ * Return:  1 = ok, 0 = error
+ */
+int read_int4( int f, int *i )
+{
+#ifdef LITTLE
+   /* read big endian and convert to little endian */
+   unsigned int n;
+   if (read( f, &n, 4 )==4) {
+      *i = FLIP4( n );
+      return 1;
+   }
+   else {
+      return 0;
+   }
+#else
+   if (read( f, i, 4 )==4) {
+#  ifdef _CRAY
+      *i = *i >> 32;
+#  endif
+      return 1;
+   }
+   else {
+      return 0;
+   }
+#endif
+}
+
+
+
+/*
+ * Read an array of 4-byte integers.
+ * Input:  f - file descriptor
+ *         iarray - address to put integers
+ *         n - number of integers to read.
+ * Return:  number of integers read.
+ */
+int read_int4_array( int f, int *iarray, int n )
+{
+#ifdef _CRAY
+   int j, nread;
+   int *buffer;
+
+   buffer = (int *) malloc( (n+1)*4 );
+   if (!buffer)
+      return 0;
+   nread = read( f, buffer, 4*n );
+   if (nread<=0) {
+      return 0;
+   }
+   nread /= 4;
+
+   for (j=0;j<nread;j++) {
+      if ((j&1)==0) {
+         iarray[j] = buffer[j/2] >> 32;
+      }
+      else {
+         iarray[j] = buffer[j/2] & 0xffffffff;
+      }
+   }
+   free( buffer );
+   return nread;
+#else
+   int nread = read( f, iarray, 4*n );
+   if (nread<=0)
+     return 0;
+#  ifdef LITTLE
+      flip4( (const unsigned int *) iarray, (unsigned int *) iarray, nread/4 );
+#  endif
+   return nread/4;
+#endif
+}
+
+
+
+/*
+ * Read a 4-byte IEEE float.
+ * Input:  f - the file descriptor to read from.
+ *         x - pointer to float to put result into.
+ * Return:  1 = ok, 0 = error
+ */
+int read_float4( int f, float *x )
+{
+#ifdef _CRAY
+   long buffer = 0;
+
+   if ( read( f, &buffer, 4 )==4 ) {
+      /* convert IEEE float (buffer) to Cray float (x) */
+      if_to_c( (long *) x, &buffer );
+      return 1;
+    }
+    return 0;
+#else
+#  ifdef LITTLE
+      unsigned int n, *iptr;
+      if (read( f, &n, 4 )==4) {
+         iptr = (unsigned int *) x;
+         *iptr = FLIP4( n );
+         return 1;
+      }
+      else {
+         return 0;
+      }
+#  else
+      if (read( f, x, 4 )==4) {
+         return 1;
+      }
+      else {
+         return 0;
+      }
+#  endif
+#endif
+}
+
+
+
+/*
+ * Read an array of 4-byte IEEE floats.
+ * Input:  f - file descriptor
+ *         x - address to put floats
+ *         n - number of floats to read.
+ * Return:  number of floats read.
+ */
+int read_float4_array( int f, float *x, int n )
+{
+#ifdef _CRAY
+   /* read IEEE floats into buffer, then convert to Cray format */
+   long *buffer;
+   int i, nread;
+
+   buffer = (long *) malloc( (n+1) * 4 );
+   if (!buffer) return 0;
+   nread = read( f, buffer, n*4 );
+   if (nread<=0)  return 0;
+   nread /= 4;
+   ieee_to_cray_array( x, buffer, nread );
+   free( buffer );
+   return nread;
+#else
+   int nread = read( f, x, 4*n );
+   if (nread<=0)
+      return 0;
+#ifdef LITTLE
+   flip4( (const unsigned int *) x, (unsigned int*) x, nread/4 );
+#endif
+   return nread/4;
+#endif
+}
+
+
+
+/*
+ * Read a block of memory.
+ * Input:  f - file descriptor
+ *         data - address of first byte
+ *         elements - number of elements to read
+ *         elsize - size of each element to read (1, 2 or 4)
+ * Return: number of elements written
+ */
+int read_block( int f, void *data, int elements, int elsize )
+{
+   if (elsize==1) {
+      return read( f, data, elements );
+   }
+   else if (elsize==2) {
+#ifdef LITTLE
+      int n;
+      n = read( f, data, elements*2 ) / 2;
+      if (n==elements) {
+         flip2( (const unsigned short *) data, (unsigned short *) data,
+                elements );
+      }
+      return n;
+#else
+      return read( f, data, elements*2 ) / 2;
+#endif
+   }
+   else if (elsize==4) {
+#ifdef LITTLE
+      int n;
+      n = read( f, data, elements*4 ) / 4;
+      if (n==elements) {
+         flip4( (const unsigned int *) data, (unsigned int *) data, elements );
+      }
+      return n;
+#else
+      return read( f, data, elements*4 ) / 4;
+#endif
+   }
+   else {
+      printf("Fatal error in read_block(): bad elsize (%d)\n", elsize );
+      abort();
+   }
+   return 0;
+}
+
+
+
+
+/**********************************************************************/
+/*****                         Write Functions                    *****/
+/**********************************************************************/
+
+
+
+/*
+ * Write a block of bytes.
+ * Input:  f - the file descriptor to write to.
+ *         b - address of buffer to write.
+ *         n - number of bytes to write.
+ * Return:  number of bytes written, 0 if error.
+ */
+int write_bytes( int f, const void *b, int n )
+{
+   return write( f, b, n );
+}
+
+
+
+
+/*
+ * Write an array of 2-byte integers.
+ * Input:  f - file descriptor
+ *         iarray - address to put integers
+ *         n - number of integers to write.
+ * Return:  number of integers written
+ */
+int write_int2_array( int f, const short *iarray, int n )
+{
+#ifdef _CRAY
+   printf("write_int2_array not implemented!\n");
+   exit(1);
+#else
+   int nwritten;
+#ifdef LITTLE
+   flip2( (const unsigned short *) iarray, (unsigned short *) iarray, n );
+#endif
+   nwritten = write( f, iarray, 2*n );
+#ifdef LITTLE
+   flip2( (const unsigned short *) iarray, (unsigned short *) iarray, n );
+#endif
+   if (nwritten<=0)
+      return 0;
+   return nwritten/2;
+#endif
+}
+
+
+
+/*
+ * Write an array of 2-byte unsigned integers.
+ * Input:  f - file descriptor
+ *         iarray - address to put integers
+ *         n - number of integers to write.
+ * Return:  number of integers written
+ */
+int write_uint2_array( int f, const unsigned short *iarray, int n )
+{
+#ifdef _CRAY
+   int i, nwritten;
+   unsigned char *buffer;
+   buffer = (unsigned char *) malloc( 2*n );
+   if (!buffer)  return 0;
+   for (i=0;i<n;i++) {
+      buffer[i*2] = (iarray[i] >> 8) & 0xff;
+      buffer[i*2+1] = iarray[i] & 0xff;
+   }
+   nwritten = write( f, buffer, 2*n );
+   free( buffer );
+   if (nwritten<=0)
+      return 0;
+   else
+      return nwritten/2;
+#else
+   int nwritten;
+#ifdef LITTLE
+   flip2( iarray, (unsigned short *) iarray, n );
+#endif
+   nwritten = write( f, iarray, 2*n );
+#ifdef LITTLE
+   flip2( iarray, (unsigned short *) iarray, n );
+#endif
+   if (nwritten<=0)
+      return 0;
+   else
+      return nwritten/2;
+#endif
+}
+
+
+
+/*
+ * Write a 4-byte integer.
+ *Input:  f - the file descriptor
+ *         i - the integer
+ * Return:  1 = ok, 0 = error
+ */
+int write_int4( int f, int i )
+{
+#ifdef _CRAY
+   i = i << 32;
+   return write( f, &i, 4 ) > 0;
+#else
+#  ifdef LITTLE
+     i = FLIP4( i );
+#  endif
+   return write( f, &i, 4 ) > 0;
+#endif
+}
+
+
+
+/*
+ * Write an array of 4-byte integers.
+ * Input:  f - the file descriptor
+ *         i - the array of ints
+ *           n - the number of ints in array
+ *  Return:  number of integers written.
+ */
+int write_int4_array( int f, const int *i, int n )
+{
+#ifdef _CRAY
+   int j, nwritten;
+   char *buf, *b, *ptr;
+
+   b = buf = (char *) malloc( n*4 + 8 );
+   if (!b)
+      return 0;
+   ptr = (char *) i;
+   for (j=0;j<n;j++) {
+      ptr += 4;      /* skip upper 4 bytes */
+      *b++ = *ptr++;
+      *b++ = *ptr++;
+      *b++ = *ptr++;
+      *b++ = *ptr++;
+   }
+   nwritten = write( f, buf, 4*n );
+   free( buf );
+   if (nwritten<=0)
+      return 0;
+   else
+      return nwritten / 4;
+#else
+#  ifdef LITTLE
+      int nwritten;
+      flip4( (const unsigned int *) i, (unsigned int *) i, n );
+      nwritten = write( f, i, 4*n );
+      flip4( (const unsigned int *) i, (unsigned int *) i, n );
+      if (nwritten<=0)
+         return 0;
+      else
+        return nwritten / 4;
+#  else
+      return write( f, i, 4*n ) / 4;
+#  endif
+#endif
+}
+
+
+
+/*
+ * Write a 4-byte IEEE float.
+ * Input:  f - the file descriptor
+ *         x - the float
+ * Return:  1 = ok, 0 = error
+ */
+int write_float4( int f, float x )
+{
+#ifdef _CRAY
+   char buffer[8];
+   c_to_if( (long *) buffer, (const long *) &x );
+   return write( f, buffer, 4 ) > 0;
+#else
+#  ifdef LITTLE
+      float y;
+      unsigned int *iptr = (unsigned int *) &y, temp;
+      y = (float) x;
+      temp = FLIP4( *iptr );
+      return write( f, &temp, 4 ) > 0;
+#  else
+      float y;
+      y = (float) x;
+      return write( f, &y, 4 ) > 0;
+#  endif
+#endif
+}
+
+
+
+/*
+ * Write an array of 4-byte IEEE floating point numbers.
+ * Input:  f - the file descriptor
+ *         x - the array of floats
+ *         n - number of floats in array
+ * Return:  number of float written.
+ */
+int write_float4_array( int f, const float *x, int n )
+{
+#ifdef _CRAY
+   /* convert cray floats to IEEE and put into buffer */
+   int nwritten;
+   long *buffer;
+   buffer = (long *) malloc( n*4 + 8 );
+   if (!buffer)
+      return 0;
+   cray_to_ieee_array( buffer, x, n );
+   nwritten = write( f, buffer, 4*n );
+   free( buffer );
+   if (nwritten<=0)
+      return 0;
+   else
+      return nwritten / 4;
+#else
+#  ifdef LITTLE
+      int nwritten;
+      flip4( (const unsigned int *) x, (unsigned int *) x, n );
+      nwritten = write( f, x, 4*n );
+      flip4( (const unsigned int *) x, (unsigned int *) x, n );
+      if (nwritten<=0)
+         return 0;
+      else 
+         return nwritten / 4;
+#  else
+      return write( f, x, 4*n ) / 4;
+#  endif
+#endif
+}
+
+
+
+/*
+ * Write a block of memory.
+ * Input:  f - file descriptor
+ *         data - address of first byte
+ *         elements - number of elements to write
+ *         elsize - size of each element to write (1, 2 or 4)
+ * Return: number of elements written
+ */
+int write_block( int f, const void *data, int elements, int elsize )
+{
+   if (elsize==1) {
+      return write( f, data, elements );
+   }
+   else if (elsize==2) {
+#ifdef LITTLE
+      int n;
+      flip2( (const unsigned short *) data, (unsigned short *) data, elements);
+      n = write( f, data, elements*2 ) / 2;
+      flip2( (const unsigned short *) data, (unsigned short *) data, elements);
+      return n;
+#else
+      return write( f, data, elements*2 ) / 2;
+#endif
+   }
+   else if (elsize==4) {
+#ifdef LITTLE
+      int n;
+      flip4( (const unsigned int *) data, (unsigned int *) data, elements );
+      n = write( f, data, elements*4 ) / 4;
+      flip4( (const unsigned int *) data, (unsigned int *) data, elements );
+      return n;
+#else
+      return write( f, data, elements*4 ) / 4;
+#endif
+   }
+   else {
+      printf("Fatal error in write_block(): bad elsize (%d)\n", elsize );
+      abort();
+   }
+   return 0;
+}
diff --git a/lib/vis5d/src/binio.h b/lib/vis5d/src/binio.h
new file mode 100644 (file)
index 0000000..ce74f7c
--- /dev/null
@@ -0,0 +1,107 @@
+/* Vis5D version 5.1 */
+
+/*
+Vis5D system for visualizing five dimensional gridded data sets
+Copyright (C) 1990 - 1997  Bill Hibbard, Brian Paul, Dave Santek,
+and Andre Battaiola.
+
+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; either version 1, or (at your option)
+any later version.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/*
+ * Functions to do binary I/O of floats, ints, etc. with byte swapping
+ * as needed.
+ */
+
+
+#ifndef BINIO_H
+#define BINIO_H
+
+
+/* Include files which define SEEK_SET, O_RD_ONLY, etc. */
+/* and prototype open(), close(), lseek(), etc. */
+#include <unistd.h>
+#include <fcntl.h>
+
+
+
+extern void flip4( const unsigned int *src, unsigned int *dest, int n );
+
+extern void flip2( const unsigned short *src, unsigned short *dest, int n );
+
+
+/* Modif pour prendre en compte la FUJI avec des entiers 32 bits
+   et des reels 64 bits. Or on a :
+
+   sizeof(int)       = 4
+   sizeof(long)      = 4
+   sizeof(long long) = 8
+   sizeof(float)     = 4
+   sizeof(double)    = 8
+*/
+
+
+#ifdef _CRAY
+  extern void cray_to_ieee_array( long *dest, const float *source, int n );
+  extern void ieee_to_cray_array( float *dest, const long *source, int n );
+#endif
+
+
+/**********************************************************************/
+/*****                     Read Functions                         *****/
+/**********************************************************************/
+
+
+extern int read_bytes( int f, void *b, int n );
+
+extern int read_int2_array( int f, short *iarray, int n );
+
+extern int read_uint2_array( int f, unsigned short *iarray, int n );
+
+extern int read_int4( int f, int *i );
+
+extern int read_int4_array( int f, int *iarray, int n );
+
+extern int read_float4( int f, float *x );
+
+extern int read_float4_array( int f, float *x, int n );
+
+extern int read_block( int f, void *data, int elements, int elsize );
+
+
+
+/**********************************************************************/
+/*****                         Write Functions                    *****/
+/**********************************************************************/
+
+
+extern int write_bytes( int f, const void *b, int n );
+
+extern int write_int2_array( int f, const short *iarray, int n );
+
+extern int write_uint2_array( int f, const unsigned short *iarray, int n );
+
+extern int write_int4( int f, int i );
+
+extern int write_int4_array( int f, const int *iarray, int n );
+
+extern int write_float4( int f, float x );
+
+extern int write_float4_array( int f, const float *x, int n );
+
+extern int write_block( int f, const void *data, int elements, int elsize );
+
+#endif
diff --git a/lib/vis5d/src/v5d.c b/lib/vis5d/src/v5d.c
new file mode 100644 (file)
index 0000000..814a680
--- /dev/null
@@ -0,0 +1,3150 @@
+/* v5d.c */
+
+/* Vis5D version 5.1 */
+
+/*
+Vis5D system for visualizing five dimensional gridded data sets
+Copyright (C) 1990 - 1997 Bill Hibbard, Johan Kellum, Brian Paul,
+Dave Santek, and Andre Battaiola.
+
+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; either version 1, or (at your option)
+any later version.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* this should be updated when the file version changes */
+#define FILE_VERSION "4.3"
+
+
+
+/*
+ * New grid file format for VIS-5D:
+ *
+ * The header is a list of tagged items.  Each item has 3 parts:
+ *    1. A tag which is a 4-byte integer identifying the type of item.
+ *    2. A 4-byte integer indicating how many bytes of data follow.
+ *    3. The binary data.
+ *
+ * If we need to add new information to a file header we just create a
+ * new tag and add the code to read/write the information.
+ *
+ * If we're reading a header and find an unknown tag, we can use the
+ * length field to skip ahead to the next tag.  Therefore, the file
+ * format is forward (and backward) compatible.
+ *
+ * Grid data is stored as either:
+ *     1-byte unsigned integers  (255=missing)
+ *     2-byte unsigned integers  (65535=missing)
+ *     4-byte IEEE floats        ( >1.0e30 = missing) 
+ *
+ * All numeric values are stored in big endian order.  All floating point
+ * values are in IEEE format.
+ */
+
+
+
+/*
+ * Updates:
+ *
+ * April 13, 1995, brianp
+ *   finished Cray support for 2-byte and 4-byte compress modes
+ */
+
+
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "binio.h"
+#include "v5d.h"
+#include "vis5d.h"
+#ifndef SEEK_SET
+#  define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#  define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#  define SEEK_END 2
+#endif
+
+
+
+/*
+ * Currently defined tags:
+ * Note:  the notation a[i] doesn't mean a is an array of i elements,
+ * rather it just refers to the ith element of a[].
+ *
+ * Tags marked as PHASED OUT should be readable but are no longer written.
+ * Old tag numbers can't be reused!
+ * 
+ */
+
+
+/*      TAG NAME        VALUE       DATA (comments)                     */
+/*----------------------------------------------------------------------*/
+#define TAG_ID          0x5635440a  /* hex encoding of "V5D\n"          */
+
+/* general stuff 1000+ */
+#define TAG_VERSION     1000        /* char*10 FileVersion              */
+#define TAG_NUMTIMES    1001        /* int*4 NumTimes                   */
+#define TAG_NUMVARS     1002        /* int*4 NumVars                    */
+#define TAG_VARNAME     1003        /* int*4 var; char*10 VarName[var]  */
+
+#define TAG_NR          1004        /* int*4 Nr                         */ 
+#define TAG_NC          1005        /* int*4 Nc                         */
+#define TAG_NL          1006        /* int*4 Nl  (Nl for all vars)      */
+#define TAG_NL_VAR      1007        /* int*4 var; int*4 Nl[var]         */
+#define TAG_LOWLEV_VAR  1008        /* int*4 var; int*4 LowLev[var]     */
+
+#define TAG_TIME        1010        /* int*4 t;  int*4 TimeStamp[t]     */
+#define TAG_DATE        1011        /* int*4 t;  int*4 DateStamp[t]     */
+
+#define TAG_MINVAL      1012        /* int*4 var;  real*4 MinVal[var]   */
+#define TAG_MAXVAL      1013        /* int*4 var;  real*4 MaxVal[var]   */
+
+#define TAG_COMPRESS    1014        /* int*4 CompressMode; (#bytes/grid)*/
+
+#define TAG_UNITS       1015        /* int *4 var; char*20 Units[var]   */
+
+/* vertical coordinate system 2000+ */
+#define TAG_VERTICAL_SYSTEM 2000    /* int*4 VerticalSystem             */
+#define TAG_VERT_ARGS    2100       /* int*4 n;  real*4 VertArgs[0..n-1]*/
+
+#define TAG_BOTTOMBOUND  2001       /* real*4 BottomBound     (PHASED OUT)  */
+#define TAG_LEVINC       2002       /* real*4 LevInc      (PHASED OUT)      */
+#define TAG_HEIGHT       2003    /* int*4 l;  real*4 Height[l] (PHASED OUT) */
+
+
+/* projection 3000+ */
+#define TAG_PROJECTION   3000       /* int*4 projection:                    */
+                                    /*   0 = generic linear                 */
+                                    /*   1 = cylindrical equidistant        */
+                                    /*   2 = Lambert conformal/Polar Stereo */
+                                    /*   3 = rotated equidistant            */
+#define TAG_PROJ_ARGS    3100       /* int *4 n;  real*4 ProjArgs[0..n-1]   */
+
+#define TAG_NORTHBOUND   3001       /* real*4 NorthBound       (PHASED OUT) */
+#define TAG_WESTBOUND    3002       /* real*4 WestBound        (PHASED OUT) */
+#define TAG_ROWINC       3003       /* real*4 RowInc           (PHASED OUT) */
+#define TAG_COLINC       3004       /* real*4 ColInc           (PHASED OUT) */
+#define TAG_LAT1         3005       /* real*4 Lat1             (PHASED OUT) */
+#define TAG_LAT2         3006       /* real*4 Lat2             (PHASED OUT) */
+#define TAG_POLE_ROW     3007       /* real*4 PoleRow          (PHASED OUT) */
+#define TAG_POLE_COL     3008       /* real*4 PoleCol          (PHASED OUT) */
+#define TAG_CENTLON      3009       /* real*4 CentralLon       (PHASED OUT) */
+#define TAG_CENTLAT      3010       /* real*4 CentralLat       (PHASED OUT) */
+#define TAG_CENTROW      3011       /* real*4 CentralRow       (PHASED OUT) */
+#define TAG_CENTCOL      3012       /* real*4 CentralCol       (PHASED OUT) */
+#define TAG_ROTATION     3013       /* real*4 Rotation         (PHASED OUT) */
+
+
+#define TAG_END                9999
+
+
+
+
+
+
+/**********************************************************************/
+/*****                  Miscellaneous Functions                   *****/
+/**********************************************************************/
+
+
+float pressure_to_height(float pressure)
+{
+  return (float) DEFAULT_LOG_EXP * log((double) pressure / DEFAULT_LOG_SCALE);
+}
+
+float height_to_pressure(float height)
+{
+  return (float) DEFAULT_LOG_SCALE * exp((double) height / DEFAULT_LOG_EXP);
+}
+
+
+/*
+ * Return current file position.
+ * Input:  f - file descriptor
+ */
+static off_t ltell( int f )
+{
+   return lseek( f, 0, SEEK_CUR );
+}
+
+
+/*
+ * Copy up to maxlen characters from src to dst stopping upon whitespace
+ * in src.  Terminate dst with null character.
+ * Return:  length of dst.
+ */
+static int copy_string2( char *dst, const char *src, int maxlen )
+{
+   int i;
+
+   for (i=0;i<maxlen;i++) dst[i] = src[i];
+   for (i=maxlen-1; i>=0; i--) {
+     if (dst[i]==' ' || i==maxlen-1) dst[i] = 0;
+     else break;
+   }
+   return strlen(dst);
+}
+
+
+
+/*
+ * Copy up to maxlen characters from src to dst stopping upon whitespace
+ * in src.  Terminate dst with null character.
+ * Return:  length of dst.
+ */
+static int copy_string( char *dst, const char *src, int maxlen )
+{
+   int i;
+
+   for (i=0;i<maxlen;i++) {
+      if (src[i]==' ' || i==maxlen-1) {
+         dst[i] = 0;
+         break;
+      }
+      else {
+         dst[i] = src[i];
+      }
+   }
+   return i;
+}
+
+
+
+/*
+ * Convert a date from YYDDD format to days since Jan 1, 1900.
+ */
+int v5dYYDDDtoDays( int yyddd )
+{
+   int iy, id, idays;
+
+   iy = yyddd / 1000;
+   id = yyddd - 1000*iy;
+   if (iy < 50) iy += 100; /* WLH 31 July 96 << 31 Dec 99 */
+   idays = 365*iy + (iy-1)/4 + id;
+
+   return idays;
+}
+
+
+/*
+ * Convert a time from HHMMSS format to seconds since midnight.
+ */
+int v5dHHMMSStoSeconds( int hhmmss )
+{
+   int h, m, s;
+
+   h = hhmmss / 10000;
+   m = (hhmmss / 100) % 100;
+   s = hhmmss % 100;
+
+   return s + m*60 + h*60*60;
+}
+
+
+
+/*
+ * Convert a day since Jan 1, 1900 to YYDDD format.
+ */
+int v5dDaysToYYDDD( int days )
+{
+   int iy, id, iyyddd;
+
+   iy = (4*days)/1461;
+   id = days-(365*iy+(iy-1)/4);
+   if (iy > 99) iy = iy - 100; /* WLH 31 July 96 << 31 Dec 99 */
+   /* iy = iy + 1900; is the right way to fix this, but requires
+      changing all places where dates are printed - procrastinate */
+   iyyddd = iy*1000+id;
+
+   return iyyddd;
+}
+
+
+/*
+ * Convert a time in seconds since midnight to HHMMSS format.
+ */
+int v5dSecondsToHHMMSS( int seconds )
+{
+   int hh, mm, ss;
+
+   hh = seconds / (60*60);
+   mm = (seconds / 60) % 60;
+   ss = seconds % 60;
+   return hh*10000 + mm * 100 + ss;
+}
+
+
+
+
+void v5dPrintStruct( const v5dstruct *v )
+{
+   static char day[7][10] = { "Sunday", "Monday", "Tuesday", "Wednesday",
+                              "Thursday", "Friday", "Saturday" };
+   int time, var, i;
+   int maxnl;
+
+   maxnl = 0;
+   for (var=0;var<v->NumVars;var++) {
+      if (v->Nl[var]+v->LowLev[var]>maxnl) {
+         maxnl = v->Nl[var]+v->LowLev[var];
+      }
+   }
+
+   if (v->FileFormat==0) {
+      if (v->FileVersion[0] == 0) {
+        printf("File format: v5d  version: (4.0 or 4.1)\n");
+      }
+      else {
+        printf("File format: v5d  version: %s\n", v->FileVersion);
+      }
+   }
+   else {
+      printf("File format: comp5d  (VIS-5D 3.3 or older)\n");
+   }
+
+   if (v->CompressMode==1) {
+      printf("Compression:  1 byte per gridpoint.\n");
+   }
+   else {
+      printf("Compression:  %d bytes per gridpoint.\n", v->CompressMode);
+   }
+   printf("header size=%d\n", v->FirstGridPos);
+   printf("sizeof(v5dstruct)=%d\n", sizeof(v5dstruct) );
+   printf("\n");
+
+   printf("NumVars = %d\n", v->NumVars );
+
+   printf("Var  Name       Units      Rows  Cols  Levels LowLev  MinVal       MaxVal\n");
+   for (var=0;var<v->NumVars;var++) {
+      printf("%3d  %-10s %-10s %3d   %3d   %3d    %3d",
+             var+1, v->VarName[var], v->Units[var],
+             v->Nr, v->Nc, v->Nl[var], v->LowLev[var] );
+      if (v->MinVal[var] > v->MaxVal[var]) {
+         printf("     MISSING      MISSING\n");
+      }
+      else {
+         printf("     %-12g %-12g\n", v->MinVal[var], v->MaxVal[var] );
+      }
+   }
+
+   printf("\n");
+
+   printf("NumTimes = %d\n", v->NumTimes );
+   printf("Step    Date(YYDDD)    Time(HH:MM:SS)   Day\n");
+   for (time=0;time<v->NumTimes;time++) {
+      int i = v->TimeStamp[time];
+      printf("%3d        %05d       %5d:%02d:%02d     %s\n",
+             time+1,
+             v->DateStamp[time],
+             i/10000, (i/100)%100, i%100,
+             day[ v5dYYDDDtoDays(v->DateStamp[time]) % 7 ]);
+   }
+   printf("\n");
+
+   switch (v->VerticalSystem) {
+      case 0:
+         printf("Generic linear vertical coordinate system:\n");
+         printf("\tBottom Bound: %f\n", v->VertArgs[0] );
+         printf("\tIncrement between levels:  %f\n", v->VertArgs[1] );
+         break;
+      case 1:
+         printf("Equally spaced levels in km:\n");
+         printf("\tBottom Bound: %f\n", v->VertArgs[0] );
+         printf("\tIncrement: %f\n", v->VertArgs[1] );
+         break;
+      case 2:
+         printf("Unequally spaced levels in km:\n");
+         printf("Level\tHeight(km)\n");
+         for (i=0;i<maxnl;i++) {
+            printf("%3d     %10.3f\n", i+1, v->VertArgs[i] );
+         }
+         break;
+      case 3:
+         printf("Unequally spaced levels in mb:\n");
+         printf("Level\tPressure(mb)\n");
+         for (i=0;i<maxnl;i++) {
+            printf("%3d     %10.3f\n", i+1, height_to_pressure(v->VertArgs[i]) );
+         }
+         break;
+      default:
+         printf("Bad VerticalSystem value: %d\n", v->VerticalSystem );
+   }
+   printf("\n");
+
+   switch (v->Projection) {
+      case 0:
+         printf("Generic linear projection:\n");
+         printf("\tNorth Boundary: %f\n", v->ProjArgs[0] );
+         printf("\tWest Boundary: %f\n", v->ProjArgs[1] );
+         printf("\tRow Increment: %f\n", v->ProjArgs[2] );
+         printf("\tColumn Increment: %f\n", v->ProjArgs[3] );
+         break;
+      case 1:
+         printf("Cylindrical Equidistant projection:\n");
+         printf("\tNorth Boundary: %f degrees\n", v->ProjArgs[0] );
+         printf("\tWest Boundary: %f degrees\n", v->ProjArgs[1] );
+         printf("\tRow Increment: %f degrees\n", v->ProjArgs[2] );
+         printf("\tColumn Increment: %f degrees\n", v->ProjArgs[3] );
+/*
+         printf("\tSouth Boundary: %f degrees\n",
+                v->NorthBound - v->RowInc * (v->Nr-1) );
+         printf("\tEast Boundary: %f degrees\n",
+                v->WestBound - v->ColInc * (v->Nc-1) );
+*/
+         break;
+      case 2:
+         printf("Lambert Conformal projection:\n");
+         printf("\tStandard Latitude 1: %f\n", v->ProjArgs[0] );
+         printf("\tStandard Latitude 2: %f\n", v->ProjArgs[1] );
+         printf("\tNorth/South Pole Row: %f\n", v->ProjArgs[2] );
+         printf("\tNorth/South Pole Column: %f\n", v->ProjArgs[3] );
+         printf("\tCentral Longitude: %f\n", v->ProjArgs[4] );
+         printf("\tColumn Increment: %f km\n", v->ProjArgs[5] );
+         break;
+      case 3:
+         printf("Stereographic:\n");
+         printf("\tCenter Latitude: %f\n", v->ProjArgs[0] );
+         printf("\tCenter Longitude: %f\n", v->ProjArgs[1] );
+         printf("\tCenter Row: %f\n", v->ProjArgs[2] );
+         printf("\tCenter Column: %f\n", v->ProjArgs[3] );
+         printf("\tColumn Spacing: %f\n", v->ProjArgs[4] );
+         break;
+      case 4:
+         /* WLH 4-21-95 */
+         printf("Rotated equidistant projection:\n");
+         printf("\tLatitude of grid(0,0): %f\n", v->ProjArgs[0] );
+         printf("\tLongitude of grid(0,0): %f\n", v->ProjArgs[1] );
+         printf("\tRow Increment: %f degress\n", v->ProjArgs[2] );
+         printf("\tColumn Increment: %f degrees\n", v->ProjArgs[3] );
+         printf("\tCenter Latitude: %f\n", v->ProjArgs[4] );
+         printf("\tCenter Longitude: %f\n", v->ProjArgs[5] );
+         printf("\tRotation: %f degrees\n", v->ProjArgs[6] );
+         break;
+      default:
+         printf("Bad projection number: %d\n", v->Projection );
+   }
+}
+
+
+
+/*
+ * Compute the location of a compressed grid within a file.
+ * Input:  v - pointer to v5dstruct describing the file header.
+ *         time, var - which timestep and variable.
+ * Return:  file offset in bytes
+ */
+static int grid_position( const v5dstruct *v, int time, int var )
+{
+   int pos, i;
+
+   assert( time >= 0 );
+   assert( var >= 0 );
+   assert( time < v->NumTimes );
+   assert( var < v->NumVars );
+
+   pos = v->FirstGridPos + time * v->SumGridSizes;
+   for (i=0;i<var;i++) {
+      pos += v->GridSize[i];
+   }
+
+   return pos;
+}
+
+
+
+/*
+ * Compute the ga and gb (de)compression values for a grid.
+ * Input:  nr, nc, nl - size of grid
+ *         data - the grid data
+ *         ga, gb - arrays to store results.
+ *         minval, maxval - pointer to floats to return min, max values
+ *         compressmode - 1, 2 or 4 bytes per grid point
+ * Output:  ga, gb - the (de)compression values
+ *          minval, maxval - the min and max grid values
+ * Side effect:  the MinVal[var] and MaxVal[var] fields in g may be
+ *               updated with new values.
+ */
+static void compute_ga_gb( int nr, int nc, int nl, 
+                           const float data[], int compressmode,
+                           float ga[], float gb[],
+                           float *minval, float *maxval )
+{
+#ifdef SIMPLE_COMPRESSION
+   /*
+    * Compute ga, gb values for whole grid.
+    */
+   int i, lev, allmissing, num;
+   float min, max, a, b;
+
+   min = 1.0e30;
+   max = -1.0e30;
+   num = nr * nc * nl;
+   allmissing = 1;
+   for (i=0;i<num;i++) {
+      if (!IS_MISSING(data[i])) {
+         if (data[i]<min)  min = data[i];
+         if (data[i]>max)  max = data[i];
+         allmissing = 0;
+      }
+   }
+   if (allmissing) {
+      a = 1.0;
+      b = 0.0;
+   }
+   else {
+      a = (max-min) / 254.0;
+      b = min;
+   }
+
+   /* return results */
+   for (i=0;i<nl;i++) {
+      ga[i] = a;
+      gb[i] = b;
+   }
+
+   *minval = min;
+   *maxval = max;
+#else
+   /*
+    * Compress grid on level-by-level basis.
+    */
+#  define SMALLVALUE -1.0e30
+#  define BIGVALUE 1.0e30
+#  define ABS(x)   ( ((x) < 0.0) ? -(x) : (x) )
+   float gridmin, gridmax;
+   float levmin[MAXLEVELS], levmax[MAXLEVELS];
+   float d[MAXLEVELS], dmax;
+   float ival, mval;
+   int j, k, lev, nrnc;
+
+   nrnc = nr * nc;
+
+   /* find min and max for each layer and the whole grid */
+   gridmin = BIGVALUE;
+   gridmax = SMALLVALUE;
+   j = 0;
+
+
+   for (lev=0;lev<nl;lev++) {
+      float ave, var;
+      float min, max;
+      min = BIGVALUE;
+      max = SMALLVALUE;
+      ave = 0.0;
+      var = 0.0;
+      for (k=0;k<nrnc;k++) {
+         if (!IS_MISSING(data[j]) && data[j]<min)
+            min = data[j];
+         if (!IS_MISSING(data[j]) && data[j]>max)
+            max = data[j];
+         j++;
+      }
+
+      if (min<gridmin)
+        gridmin = min;
+      if (max>gridmax)
+        gridmax = max;
+      levmin[lev] = min;
+      levmax[lev] = max;
+   }
+
+/* WLH 2-2-95 */
+#ifdef KLUDGE
+   /* if the grid minimum is within delt of 0.0, fudge all values */
+   /* within delt of 0.0 to delt, and recalculate mins and maxes */
+   {
+      float delt;
+      int nrncnl = nrnc * nl;
+
+      delt = (gridmax - gridmin)/100000.0;
+      if ( ABS(gridmin) < delt && gridmin!=0.0 && compressmode != 4 ) {
+         float min, max;
+         for (j=0; j<nrncnl; j++) {
+            if (!IS_MISSING(data[j]) && data[j]<delt)
+              data[j] = delt;
+         }
+         /* re-calculate min and max for each layer and the whole grid */
+         gridmin = delt;
+         for (lev=0;lev<nl;lev++) {
+            if (ABS(levmin[lev]) < delt)
+              levmin[lev] = delt;
+            if (ABS(levmax[lev]) < delt)
+              levmax[lev] = delt;
+         }
+      }
+   }
+#endif
+
+   /* find d[lev] and dmax = MAX( d[0], d[1], ... d[nl-1] ) */
+   dmax = 0.0;
+   for (lev=0;lev<nl;lev++) {
+      if (levmin[lev]>=BIGVALUE && levmax[lev]<=SMALLVALUE) {
+         /* all values in the layer are MISSING */
+         d[lev] = 0.0;
+      }
+      else {
+         d[lev] = levmax[lev]-levmin[lev];
+      }
+      if (d[lev]>dmax)
+         dmax = d[lev];
+   }
+
+   /*** Compute ga (scale) and gb (bias) for each grid level */
+   if (dmax==0.0) {
+      /*** Special cases ***/
+      if (gridmin==gridmax) {
+         /*** whole grid is of same value ***/
+         for (lev=0; lev<nl; lev++) {
+            ga[lev] = gridmin;
+            gb[lev] = 0.0;
+         }
+      }
+      else {
+         /*** every layer is of a single value ***/
+         for (lev=0; lev<nl; lev++) {
+            ga[lev] = levmin[lev];
+            gb[lev] = 0.0;
+         }
+      }
+   }
+   else {
+      /*** Normal cases ***/
+      if (compressmode == 1) {
+#define ORIGINAL
+#ifdef ORIGINAL
+         ival = dmax / 254.0;
+         mval = gridmin;
+
+         for (lev=0; lev<nl; lev++) {
+            ga[lev] = ival;
+            gb[lev] = mval + ival * (int) ( (levmin[lev]-mval) / ival ); 
+         }
+#else
+         for (lev=0; lev<nl; lev++) {
+            if (d[lev]==0.0) {
+               ival = 1.0;
+            }
+            else {
+               ival = d[lev] / 254.0;
+            }
+            ga[lev] = ival;
+            gb[lev] = levmin[lev];
+         }
+#endif
+      }
+      else if (compressmode == 2) {
+         ival = dmax / 65534.0;
+         mval = gridmin;
+
+         for (lev=0; lev<nl; lev++) {
+            ga[lev] = ival;
+            gb[lev] = mval + ival * (int) ( (levmin[lev]-mval) / ival );
+         }
+      }
+      else {
+         assert( compressmode==4 );
+         for (lev=0; lev<nl; lev++) {
+            ga[lev] = 1.0;
+            gb[lev] = 0.0;
+         }
+      }
+   }
+
+   /* update min, max values */
+   *minval = gridmin;
+   *maxval = gridmax;
+#endif
+}
+
+
+
+
+/*
+ * Compress a 3-D grid from floats to 1-byte unsigned integers.
+ * Input: nr, nc, nl - size of grid
+ *        compressmode - 1, 2 or 4 bytes per grid point
+ *        data - array of [nr*nc*nl] floats
+ *        compdata - pointer to array of [nr*nc*nl*compressmode] bytes
+ *                   to put results into.
+ *        ga, gb - pointer to arrays to put ga and gb decompression values
+ *        minval, maxval - pointers to float to return min & max values
+ * Output:  compdata - the compressed grid data
+ *          ga, gb - the decompression values
+ *          minval, maxval - the min and max grid values
+ */
+void v5dCompressGrid( int nr, int nc, int nl, int compressmode,
+                      const float data[],
+                      void *compdata, float ga[], float gb[],
+                      float *minval, float *maxval )
+{
+   int nrnc = nr * nc;
+   int nrncnl = nr * nc * nl;
+   V5Dubyte *compdata1 = (V5Dubyte *) compdata;
+   V5Dushort *compdata2 = (V5Dushort *) compdata;
+
+   /* compute ga, gb values */
+   compute_ga_gb( nr, nc, nl, data, compressmode, ga, gb, minval, maxval );
+
+   /* compress the data */
+   if (compressmode==1) {
+      int i, lev, p;
+      p = 0;
+      for (lev=0;lev<nl;lev++) {
+         float one_over_a, b;
+/* WLH 5 Nov 98
+         b = gb[lev] - 0.0001;
+*/
+         /* WLH 5 Nov 98 */
+         b = gb[lev];
+                                /* subtract an epsilon so the int((d-b)/a) */
+                                /* expr below doesn't get mis-truncated. */
+         if (ga[lev]==0.0) {
+            one_over_a = 1.0;
+         }
+         else {
+            one_over_a = 1.0 / ga[lev];
+         }
+         for (i=0;i<nrnc;i++,p++) {
+            if (IS_MISSING(data[p])) {
+               compdata1[p] = 255;
+            }
+            else {
+/* MJK 1.19.99
+               compdata1[p] = (V5Dubyte) (int) ((data[p]-b) * one_over_a);
+*/
+               compdata1[p] = (V5Dubyte) rint((data[p]-b) * one_over_a);
+               if (compdata1[p] >= 255){
+                  compdata1[p] = (V5Dubyte) (int) (255.0 - .0001);
+               }
+            }
+         }
+      }
+   }
+
+   else if (compressmode == 2) {
+      int i, lev, p;
+      p = 0;
+      for (lev=0;lev<nl;lev++) {
+         float one_over_a, b;
+/* WLH 5 Nov 98
+         b = gb[lev] - 0.0001;
+*/
+         /* WLH 5 Nov 98 */
+         b = gb[lev];
+
+         if (ga[lev]==0.0) {
+            one_over_a = 1.0;
+         }
+         else {
+            one_over_a = 1.0 / ga[lev];
+         }
+#ifdef _CRAY
+         /* this is tricky because sizeof(V5Dushort)==8, not 2 */
+         for (i=0;i<nrnc;i++,p++) {
+            V5Dushort compvalue;
+            if (IS_MISSING(data[p])) {
+               compvalue = 65535;
+            }
+            else {
+/* MJK 3.2.99
+               compvalue = (V5Dushort) (int) ((data[p]-b) * one_over_a);
+*/
+               compvalue = (V5Dushort) rint((data[p]-b) * one_over_a);
+            }
+            compdata1[p*2+0] = compvalue >> 8;     /* upper byte */
+            compdata1[p*2+1] = compvalue & 0xffu;  /* lower byte */
+         }
+#else
+         for (i=0;i<nrnc;i++,p++) {
+            if (IS_MISSING(data[p])) {
+               compdata2[p] = 65535;
+            }
+            else {
+               compdata2[p] = (V5Dushort) rint((data[p]-b) * one_over_a);
+
+/*
+               compdata2[p] = (V5Dushort) (int) ((data[p]-b) * one_over_a);
+*/
+/* MJK 3.24.99 I put this here so if the value is close
+   to the missing value and get's rounded up it won't come out
+   as missing data */
+               if (compdata2[p] == 65535){
+                  compdata2[p] = 65534;
+               }
+            }
+         }
+         /* TODO: byte-swapping on little endian??? */
+#endif
+      }
+   }
+
+   else {
+      /* compressmode==4 */
+#ifdef _CRAY
+      cray_to_ieee_array( compdata, data, nrncnl );
+#else
+      /* other machines: just copy 4-byte IEEE floats */
+      assert( sizeof(float)==4 );
+      memcpy( compdata, data, nrncnl*4 );
+      /* TODO: byte-swapping on little endian??? */
+#endif
+   }
+}
+
+
+
+/*
+ * Decompress a 3-D grid from 1-byte integers to 4-byte floats.
+ * Input:  nr, nc, nl - size of grid
+ *         compdata - array of [nr*nr*nl*compressmode] bytes
+ *         ga, gb - arrays of decompression factors
+ *         compressmode - 1, 2 or 4 bytes per grid point
+ *         data - address to put decompressed values
+ * Output:  data - uncompressed floating point data values
+ */
+void v5dDecompressGrid( int nr, int nc, int nl, int compressmode,
+                        void *compdata, float ga[], float gb[],
+                        float data[] )
+{
+   int nrnc = nr * nc;
+   int nrncnl = nr * nc * nl;
+   V5Dubyte *compdata1 = (V5Dubyte *) compdata;
+   V5Dushort *compdata2 = (V5Dushort *) compdata;
+
+   if (compressmode == 1) {
+      int p, i, lev;
+      p = 0;
+      for (lev=0;lev<nl;lev++) {
+         float a = ga[lev];
+         float b = gb[lev];
+
+         /* WLH 2-2-95 */
+         float d, aa;
+         int id;
+         if (a > 0.0000000001) {
+           d = b / a;
+           id = floor(d);
+           d = d - id;
+           aa = a * 0.000001;
+         }
+         else {
+           id = 1;
+         }
+         if (-254 <= id && id <= 0 && d < aa) {
+           for (i=0;i<nrnc;i++,p++) {
+              if (compdata1[p]==255) {
+                 data[p] = MISSING;
+              }
+              else {
+                 data[p] = (float) (int) compdata1[p] * a + b;
+                 if (fabs(data[p]) < aa) data[p] = aa;
+              }
+           }
+         }
+         else {
+           for (i=0;i<nrnc;i++,p++) {
+              if (compdata1[p]==255) {
+                 data[p] = MISSING;
+              }
+              else {
+                 data[p] = (float) (int) compdata1[p] * a + b;
+              }
+           }
+         }
+         /* end of WLH 2-2-95 */
+      }
+   }
+
+   else if (compressmode == 2) {
+      int p, i, lev;
+      p = 0;
+      for (lev=0;lev<nl;lev++) {
+         float a = ga[lev];
+         float b = gb[lev];
+#ifdef _CRAY
+         /* this is tricky because sizeof(V5Dushort)==8, not 2 */
+         for (i=0;i<nrnc;i++,p++) {
+            int compvalue;
+            compvalue = (compdata1[p*2] << 8) | compdata1[p*2+1];
+            if (compvalue==65535) {
+               data[p] = MISSING;
+            }
+            else {
+               data[p] = (float) compvalue * a + b;
+            }
+         }
+#else
+         /* sizeof(V5Dushort)==2! */
+         for (i=0;i<nrnc;i++,p++) {
+            if (compdata2[p]==65535) {
+               data[p] = MISSING;
+            }
+            else {
+               data[p] = (float) (int) compdata2[p] * a + b;
+            }
+         }
+#endif
+      }
+   }
+
+   else {
+      /* compressmode==4 */
+#ifdef _CRAY
+      ieee_to_cray_array( data, compdata, nrncnl );
+#else
+      /* other machines: just copy 4-byte IEEE floats */
+      assert( sizeof(float)==4 );
+      memcpy( data, compdata, nrncnl*4 );
+#endif
+   }
+}
+
+
+
+
+/*
+ * Return the size (in bytes) of the 3-D grid specified by time and var.
+ * Input:  v - pointer to v5dstruct describing the file
+ *         time, var - which timestep and variable
+ * Return:  number of data points.
+ */
+int v5dSizeofGrid( const v5dstruct *v, int time, int var )
+{
+   return v->Nr * v->Nc * v->Nl[var] * v->CompressMode;
+}
+
+
+
+/*
+ * Initialize a v5dstructure to reasonable initial values.
+ * Input:  v - pointer to v5dstruct.
+ */
+void v5dInitStruct( v5dstruct *v )
+{
+   int i;
+
+   /* set everything to zero */
+   memset( v, 0, sizeof(v5dstruct) );
+
+   /* special cases */
+   v->Projection = -1;
+   v->VerticalSystem = -1;
+
+   for (i=0;i<MAXVARS;i++) {
+      v->MinVal[i] = MISSING;
+      v->MaxVal[i] = -MISSING;
+      v->LowLev[i] = 0;
+   }
+
+   /* set file version */
+   strcpy(v->FileVersion, FILE_VERSION);
+
+   v->CompressMode = 1;
+   v->FileDesc = -1;
+}
+
+
+
+/*
+ * Return a pointer to a new, initialized v5dstruct.
+ */
+v5dstruct *v5dNewStruct( void )
+{
+   v5dstruct *v;
+
+   v = (v5dstruct *) malloc( sizeof(v5dstruct) );
+   if (v) {
+      v5dInitStruct(v);
+   }
+   return v;
+}
+
+
+
+/*
+ * Free an initialized v5dstruct. (Todd Plessel)
+ */
+void v5dFreeStruct( v5dstruct* v )
+{
+   /*assert( v5dVerifyStruct( v ) );*/
+   free( v );
+   v = 0;
+}
+
+
+
+/*
+ * Do some checking that the information in a v5dstruct is valid.
+ * Input:  v - pointer to v5dstruct
+ * Return:  1 = g is ok, 0 = g is invalid
+ */
+int v5dVerifyStruct( const v5dstruct *v )
+{
+   int var, i, invalid, maxnl;
+
+   invalid = 0;
+
+   if (!v)
+      return 0;
+
+   /* Number of variables */
+   if (v->NumVars<0) {
+      printf("Invalid number of variables: %d\n", v->NumVars );
+      invalid = 1;
+   }
+   else if (v->NumVars>MAXVARS) {
+      printf("Too many variables: %d  (Maximum is %d)\n",
+             v->NumVars, MAXVARS);
+      invalid = 1;
+   }
+
+   /* Variable Names */
+   for (i=0;i<v->NumVars;i++) {
+      if (v->VarName[i][0]==0) {
+         printf("Missing variable name: VarName[%d]=\"\"\n", i );
+         invalid = 1;
+      }
+   }
+
+   /* Number of timesteps */
+   if (v->NumTimes<0) {
+      printf("Invalid number of timesteps: %d\n", v->NumTimes );
+      invalid = 1;
+   }
+   else if (v->NumTimes>MAXTIMES) {
+      printf("Too many timesteps: %d  (Maximum is %d)\n",
+             v->NumTimes, MAXTIMES );
+      invalid = 1;
+   }
+
+   /* Make sure timestamps are increasing */
+   for (i=1;i<v->NumTimes;i++) {
+      int date0 = v5dYYDDDtoDays( v->DateStamp[i-1] );
+      int date1 = v5dYYDDDtoDays( v->DateStamp[i] );
+      int time0 = v5dHHMMSStoSeconds( v->TimeStamp[i-1] );
+      int time1 = v5dHHMMSStoSeconds( v->TimeStamp[i] );
+      if (time1<=time0 && date1<=date0) {
+         printf("Timestamp for step %d must be later than step %d\n", i, i-1);
+         invalid = 1;
+      }
+   }
+
+   /* Rows */
+   if (v->Nr<2) {
+      printf("Too few rows: %d (2 is minimum)\n", v->Nr );
+      invalid = 1;
+   }
+   else if (v->Nr>MAXROWS) {
+      printf("Too many rows: %d (%d is maximum)\n", v->Nr, MAXROWS );
+      invalid = 1;
+   }
+
+   /* Columns */
+   if (v->Nc<2) {
+      printf("Too few columns: %d (2 is minimum)\n", v->Nc );
+      invalid = 1;
+   }
+   else if (v->Nc>MAXCOLUMNS) {
+      printf("Too many columns: %d (%d is maximum)\n", v->Nc, MAXCOLUMNS );
+      invalid = 1;
+   }
+
+   /* Levels */
+   maxnl = 0;
+   for (var=0;var<v->NumVars;var++) {
+      if (v->LowLev[var] < 0) {
+         printf("Low level cannot be negative for var %s: %d\n",
+                 v->VarName[var], v->LowLev[var] );
+         invalid = 1;
+      }
+      if (v->Nl[var]<1) {
+         printf("Too few levels for var %s: %d (1 is minimum)\n",
+                 v->VarName[var], v->Nl[var] );
+         invalid = 1;
+      }
+      if (v->Nl[var]+v->LowLev[var]>MAXLEVELS) {
+         printf("Too many levels for var %s: %d (%d is maximum)\n",
+                 v->VarName[var], v->Nl[var]+v->LowLev[var], MAXLEVELS );
+         invalid = 1;
+      }
+      if (v->Nl[var]+v->LowLev[var]>maxnl) {
+         maxnl = v->Nl[var]+v->LowLev[var];
+      }
+   }
+
+   if (v->CompressMode != 1 && v->CompressMode != 2 && v->CompressMode != 4) {
+      printf("Bad CompressMode: %d (must be 1, 2 or 4)\n", v->CompressMode );
+      invalid = 1;
+   }
+
+   switch (v->VerticalSystem) {
+      case 0:
+      case 1:
+         if (v->VertArgs[1]==0.0) {
+            printf("Vertical level increment is zero, must be non-zero\n");
+            invalid = 1;
+         }
+         break;
+      case 2:
+         /* Check that Height values increase upward */
+         for (i=1;i<maxnl;i++) {
+            if (v->VertArgs[i] <= v->VertArgs[i-1]) {
+               printf("Height[%d]=%f <= Height[%d]=%f, level heights must increase\n",
+                      i, v->VertArgs[i], i-1, v->VertArgs[i-1] );
+               invalid = 1;
+               break;
+            }
+         }
+         break;
+      case 3:
+         /* Check that Pressure values decrease upward */
+         for (i=1;i<maxnl;i++) {
+            if (v->VertArgs[i] <= v->VertArgs[i-1]) {
+               printf("Pressure[%d]=%f >= Pressure[%d]=%f, level pressures must decrease\n",
+                      i, height_to_pressure(v->VertArgs[i]),
+                      i-1, height_to_pressure(v->VertArgs[i-1]) );
+               invalid = 1;
+               break;
+            }
+         }
+         break;
+      default:
+         printf("VerticalSystem = %d, must be in 0..3\n", v->VerticalSystem );
+         invalid = 1;
+   }
+
+
+   switch (v->Projection) {
+      case 0:  /* Generic */
+         if (v->ProjArgs[2]==0.0) {
+            printf("Row Increment (ProjArgs[2]) can't be zero\n");
+            invalid = 1;
+         }
+         if (v->ProjArgs[3]==0.0) {
+            printf("Column increment (ProjArgs[3]) can't be zero\n");
+            invalid = 1;
+         }
+         break;
+      case 1:  /* Cylindrical equidistant */
+         if (v->ProjArgs[2]<0.0) {
+            printf("Row Increment (ProjArgs[2]) = %g  (must be >=0.0)\n",
+                   v->ProjArgs[2] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[3]<=0.0) {
+            printf("Column Increment (ProjArgs[3]) = %g  (must be >=0.0)\n",
+                   v->ProjArgs[3] );
+            invalid = 1;
+         }
+         break;
+      case 2:  /* Lambert Conformal */
+         if (v->ProjArgs[0]<-90.0 || v->ProjArgs[0]>90.0) {
+            printf("Lat1 (ProjArgs[0]) out of range: %g\n", v->ProjArgs[0] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[1]<-90.0 || v->ProjArgs[1]>90.0) {
+            printf("Lat2 (ProjArgs[1] out of range: %g\n", v->ProjArgs[1] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[5]<=0.0) {
+            printf("ColInc (ProjArgs[5]) = %g  (must be >=0.0)\n",
+                   v->ProjArgs[5] );
+            invalid = 1;
+         }
+         break;
+      case 3:  /* Stereographic */
+         if (v->ProjArgs[0]<-90.0 || v->ProjArgs[0]>90.0) {
+            printf("Central Latitude (ProjArgs[0]) out of range: ");
+            printf("%g  (must be in +/-90)\n", v->ProjArgs[0] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[1]<-180.0 || v->ProjArgs[1]>180.0) {
+            printf("Central Longitude (ProjArgs[1]) out of range: ");
+            printf("%g  (must be in +/-180)\n", v->ProjArgs[1] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[4]<0) {
+            printf("Column spacing (ProjArgs[4]) = %g  (must be positive)\n",
+                   v->ProjArgs[4]);
+            invalid = 1;
+         }
+         break;
+      case 4:  /* Rotated */
+         /* WLH 4-21-95 */
+         if (v->ProjArgs[2]<=0.0) {
+            printf("Row Increment (ProjArgs[2]) = %g  (must be >=0.0)\n",
+                   v->ProjArgs[2] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[3]<=0.0) {
+            printf("Column Increment = (ProjArgs[3]) %g  (must be >=0.0)\n",
+                   v->ProjArgs[3] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[4]<-90.0 || v->ProjArgs[4]>90.0) {
+            printf("Central Latitude (ProjArgs[4]) out of range: ");
+            printf("%g  (must be in +/-90)\n", v->ProjArgs[4] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[5]<-180.0 || v->ProjArgs[5]>180.0) {
+            printf("Central Longitude (ProjArgs[5]) out of range: ");
+            printf("%g  (must be in +/-180)\n", v->ProjArgs[5] );
+            invalid = 1;
+         }
+         if (v->ProjArgs[6]<-180.0 || v->ProjArgs[6]>180.0) {
+            printf("Central Longitude (ProjArgs[6]) out of range: ");
+            printf("%g  (must be in +/-180)\n", v->ProjArgs[6] );
+            invalid = 1;
+         }
+         break;
+      default:
+         printf("Projection = %d, must be in 0..4\n", v->Projection );
+         invalid = 1;
+   }
+
+   return !invalid;
+}
+
+
+
+/*
+ * Get the McIDAS file number and grid number associated with the grid
+ * identified by time and var.
+ * Input:  v - v5d grid struct
+ *         time, var - timestep and variable of grid
+ * Output:  mcfile, mcgrid - McIDAS grid file number and grid number
+ */
+int v5dGetMcIDASgrid( v5dstruct *v, int time, int var,
+                      int *mcfile, int *mcgrid )
+{
+   if (time<0 || time>=v->NumTimes) {
+      printf("Bad time argument to v5dGetMcIDASgrid: %d\n", time );
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Bad var argument to v5dGetMcIDASgrid: %d\n", var );
+      return 0;
+   }
+
+   *mcfile = (int) v->McFile[time][var];
+   *mcgrid = (int) v->McGrid[time][var];
+   return 1;
+}
+
+
+
+/*
+ * Set the McIDAS file number and grid number associated with the grid
+ * identified by time and var.
+ * Input:  v - v5d grid struct
+ *         time, var - timestep and variable of grid
+ *         mcfile, mcgrid - McIDAS grid file number and grid number
+ * Return:  1 = ok, 0 = error (bad time or var)
+ */
+int v5dSetMcIDASgrid( v5dstruct *v, int time, int var,
+                      int mcfile, int mcgrid )
+{
+   if (time<0 || time>=v->NumTimes) {
+      printf("Bad time argument to v5dSetMcIDASgrid: %d\n", time );
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Bad var argument to v5dSetMcIDASgrid: %d\n", var );
+      return 0;
+   }
+
+   v->McFile[time][var] = (short) mcfile;
+   v->McGrid[time][var] = (short) mcgrid;
+   return 1;
+}
+
+
+
+/**********************************************************************/
+/*****                    Input Functions                         *****/
+/**********************************************************************/
+
+
+
+/*
+ * Read the header from a COMP* file and return results in the v5dstruct.
+ * Input:  f - the file descriptor
+ *         v - pointer to a v5dstruct.
+ * Return:  1 = ok, 0 = error.
+ */
+static int read_comp_header( int f, v5dstruct *v )
+{
+   unsigned int id;
+
+   /* reset file position to start of file */
+   lseek( f, 0, SEEK_SET );
+
+   /* read file ID */
+   read_int4( f, (int *) &id );
+
+   if (id==0x80808080 || id==0x80808081) {
+      /* Older COMP5D format */
+      int gridtimes, gridparms;
+      int i, j, it, iv, nl;
+      int gridsize;
+      float hgttop, hgtinc;
+      /*char *compgrid;*/
+
+      if (id==0x80808080) {
+         /* 20 vars, 300 times */
+         gridtimes = 300;
+         gridparms = 20;
+      }
+      else {
+         /* 30 vars, 400 times */
+         gridtimes = 400;
+         gridparms = 30;
+      }
+
+      v->FirstGridPos = 12*4 + 8*gridtimes + 4*gridparms;
+
+      read_int4( f, &v->NumTimes );
+      read_int4( f, &v->NumVars );
+      read_int4( f, &v->Nr );
+      read_int4( f, &v->Nc );
+      read_int4( f, &nl );
+      for (i=0;i<v->NumVars;i++) {
+         v->Nl[i] = nl;
+         v->LowLev[i] = 0;
+      }
+      read_float4( f, &v->ProjArgs[0] );
+      read_float4( f, &v->ProjArgs[1] );
+      read_float4( f, &hgttop );
+      read_float4( f, &v->ProjArgs[2] );
+      read_float4( f, &v->ProjArgs[3] );
+      read_float4( f, &hgtinc );
+/*
+      for (i=0;i<nl;i++) {
+         v->Height[nl-i-1] = hgttop - i * hgtinc;
+      }
+*/
+      v->VerticalSystem = 1;
+      v->VertArgs[0] = hgttop - hgtinc * (nl-1);
+      v->VertArgs[1] = hgtinc;
+
+      /* read dates and times */
+      for (i=0;i<gridtimes;i++) {
+         read_int4( f, &j );
+         v->DateStamp[i] = v5dDaysToYYDDD( j );
+      }
+      for (i=0;i<gridtimes;i++) {
+         read_int4( f, &j );
+         v->TimeStamp[i] = v5dSecondsToHHMMSS( j );
+      }
+
+      /* read variable names */
+      for (i=0;i<gridparms;i++) {
+         char name[4];
+         read_bytes( f, name, 4 );
+         /* remove trailing spaces, if any */
+         for (j=3;j>0;j--) {
+            if (name[j]==' ' || name[j]==0)
+              name[j] = 0;
+            else
+              break;
+         }
+         strncpy( v->VarName[i], name, 4 );
+         v->VarName[i][4] = 0;
+      }
+
+      gridsize = ( (v->Nr * v->Nc * nl + 3) / 4) * 4;
+      for (i=0;i<v->NumVars;i++) {
+         v->GridSize[i] = 8 + gridsize;
+      }
+      v->SumGridSizes = (8+gridsize) * v->NumVars;
+
+      /* read the grids and their ga,gb values to find min and max values */
+
+      for (i=0;i<v->NumVars;i++) {
+         v->MinVal[i] = 999999.9;
+         v->MaxVal[i] = -999999.9;
+      }
+
+      /*compgrid = (char *) malloc( gridsize );*/
+
+      for (it=0; it<v->NumTimes; it++) {
+         for (iv=0; iv<v->NumVars; iv++) {
+            float ga, gb;
+            float min, max;
+
+            read_float4( f, &ga );
+            read_float4( f, &gb );
+
+            /* skip ahead by 'gridsize' bytes */
+            if (lseek( f, gridsize, SEEK_CUR )==-1) {
+               printf("Error:  Unexpected end of file, ");
+               printf("file may be corrupted.\n");
+               return 0;
+            }
+            min = -(125.0+gb)/ga;
+            max = (125.0-gb)/ga;
+            if (min<v->MinVal[iv])  v->MinVal[iv] = min;
+            if (max>v->MaxVal[iv])  v->MaxVal[iv] = max;
+         }
+      }
+
+      /*free( compgrid );*/
+
+      /* done */
+   }
+   else if (id==0x80808082 || id==0x80808083) {
+      /* Newer COMP5D format */
+      int gridtimes, gridsize;
+      int it, iv, nl, i, j;
+      float delta;
+
+      read_int4( f, &gridtimes );
+      read_int4( f, &v->NumVars );
+      read_int4( f, &v->NumTimes );
+      read_int4( f, &v->Nr );
+      read_int4( f, &v->Nc );
+      read_int4( f, &nl );
+      for (i=0;i<v->NumVars;i++) {
+         v->Nl[i] = nl;
+      }
+
+      read_float4( f, &v->ProjArgs[2] );
+      read_float4( f, &v->ProjArgs[3] );
+
+      /* Read height and determine if equal spacing */
+      v->VerticalSystem = 1;
+      for (i=0;i<nl;i++) {
+         read_float4( f, &v->VertArgs[i] );
+         if (i==1) {
+            delta = v->VertArgs[1] - v->VertArgs[0];
+         }
+         else if (i>1) {
+            if (delta != (v->VertArgs[i] - v->VertArgs[i-1])) {
+               v->VerticalSystem = 2;
+            }
+         }
+      }
+      if (v->VerticalSystem==1) {
+         v->VertArgs[1] = delta;
+      }
+
+      /* read variable names */
+      for (iv=0; iv<v->NumVars; iv++) {
+         char name[8];
+
+         read_bytes( f, name, 8 );
+
+         /* remove trailing spaces, if any */
+         for (j=7;j>0;j--) {
+            if (name[j]==' ' || name[j]==0)
+              name[j] = 0;
+            else
+              break;
+         }
+         strncpy( v->VarName[iv], name, 8 );
+         v->VarName[iv][8] = 0;
+      }
+
+      for (iv=0;iv<v->NumVars;iv++) {
+         read_float4( f, &v->MinVal[iv] );
+      }
+      for (iv=0;iv<v->NumVars;iv++) {
+         read_float4( f, &v->MaxVal[iv] );
+      }
+      for (it=0;it<gridtimes;it++) {
+         read_int4( f, &j );
+         v->TimeStamp[it] = v5dSecondsToHHMMSS( j );
+      }
+      for (it=0;it<gridtimes;it++) {
+         read_int4( f, &j );
+         v->DateStamp[it] = v5dDaysToYYDDD( j );
+      }
+      for (it=0;it<gridtimes;it++) {
+         float nlat;
+         read_float4( f, &nlat );
+         if (it==0)  v->ProjArgs[0] = nlat;
+      }
+      for (it=0;it<gridtimes;it++) {
+         float wlon;
+         read_float4( f, &wlon );
+         if (it==0)  v->ProjArgs[1] = wlon;
+      }
+
+      /* calculate grid storage sizes */
+      if (id==0x80808082) {
+         gridsize = nl*2*4 + ( (v->Nr * v->Nc * nl + 3) / 4) * 4;
+      }
+      else {
+         /* McIDAS grid and file numbers present */
+         gridsize = 8 + nl*2*4 + ( (v->Nr * v->Nc * nl + 3) / 4) * 4;
+      }
+      for (i=0;i<v->NumVars;i++) {
+         v->GridSize[i] = gridsize;
+      }
+      v->SumGridSizes = gridsize * v->NumVars;
+
+      /* read McIDAS numbers??? */
+
+      /* size (in bytes) of all header info */
+      v->FirstGridPos = 9*4 + v->Nl[0]*4 + v->NumVars*16 + gridtimes*16;
+
+   }
+
+   v->CompressMode = 1; /* one byte per grid point */
+   v->Projection = 1;  /* Cylindrical equidistant */
+   v->FileVersion[0] = 0;
+
+   return 1;
+}
+
+
+
+/*
+ * Read a compressed grid from a COMP* file.
+ * Return:  1 = ok, 0 = error.
+ */
+static int read_comp_grid( v5dstruct *v, int time, int var,
+                           float *ga, float *gb, void *compdata )
+{
+   unsigned int pos;
+   V5Dubyte bias;
+   int i, n, nl;
+   int f;
+   V5Dubyte *compdata1 = (V5Dubyte *) compdata;
+
+   f = v->FileDesc;
+
+   /* move to position in file */
+   pos = grid_position( v, time, var );
+   lseek( f, pos, SEEK_SET );
+
+   if (v->FileFormat==0x80808083) {
+      /* read McIDAS grid and file numbers */
+      int mcfile, mcgrid;
+      read_int4( f, &mcfile );
+      read_int4( f, &mcgrid );
+      v->McFile[time][var] = (short) mcfile;
+      v->McGrid[time][var] = (short) mcgrid;
+   }
+
+   nl = v->Nl[var];
+
+   if (v->FileFormat==0x80808080 || v->FileFormat==0x80808081) {
+      /* single ga,gb pair for whole grid */
+      float a, b;
+      read_float4( f, &a );
+      read_float4( f, &b );
+      /* convert a, b to new v5d ga, gb values */
+      for (i=0;i<nl;i++) {
+         if (a==0.0) {
+            ga[i] = gb[i] = 0.0;
+         }
+         else {
+            gb[i] = (b+128.0) / -a;
+            ga[i] = 1.0 / a;
+         }
+      }
+      bias = 128;
+   }
+   else {
+      /* read ga, gb arrays */
+      read_float4_array( f, ga, v->Nl[var] );
+      read_float4_array( f, gb, v->Nl[var] );
+
+      /* convert ga, gb values to v5d system */
+      for (i=0;i<nl;i++) {
+         if (ga[i]==0.0) {
+            ga[i] = gb[i] = 0.0;
+         }
+         else {
+            /*gb[i] = (gb[i]+125.0) / -ga[i];*/
+            gb[i] = (gb[i]+128.0) / -ga[i];
+            ga[i] = 1.0 / ga[i];
+         }
+      }
+      bias = 128;  /* 125 ??? */
+   }
+
+   /* read compressed grid data */
+   n = v->Nr * v->Nc * v->Nl[var];
+   if (read_bytes( f, compdata1, n )!=n)
+      return 0;
+
+   /* convert data values to v5d system */
+   n = v->Nr * v->Nc * v->Nl[var];
+   for (i=0;i<n;i++) {
+      compdata1[i] += bias;
+   }
+
+   return 1;
+}
+
+
+
+/*
+ * Read a v5d file header.
+ * Input:  f - file opened for reading.
+ *         v - pointer to v5dstruct to store header info into.
+ * Return:  1 = ok, 0 = error.
+ */
+static int read_v5d_header( v5dstruct *v )
+{
+#define SKIP(N)   lseek( f, N, SEEK_CUR )
+   int end_of_header = 0;
+   unsigned int id;
+   int idlen, var, numargs;
+   int f;
+
+   f = v->FileDesc;
+
+   /* first try to read the header id */
+   read_int4( f, (int*) &id );
+   read_int4( f, &idlen );
+   if (id==TAG_ID && idlen==0) {
+      /* this is a v5d file */
+      v->FileFormat = 0;
+   }
+   else if (id>=0x80808080 && id<=0x80808083) {
+      /* this is an old COMP* file */
+      v->FileFormat = id;
+      return read_comp_header( f, v );
+   }
+   else {
+      /* unknown file type */
+      printf("Error: not a v5d file\n");
+      return 0;
+   }
+
+   v->CompressMode = 1; /* default */
+
+   while (!end_of_header) {
+      int tag, length;
+      int i, var, time, nl, lev;
+
+      if (read_int4(f,&tag)<1 || read_int4(f,&length)<1) {
+         printf("Error while reading header, premature EOF\n");
+         return 0;
+      }
+
+      switch (tag) {
+         case TAG_VERSION:
+            assert( length==10 );
+            read_bytes( f, v->FileVersion, 10 );
+            /* Check if reading a file made by a future version of Vis5D */
+            if (strcmp(v->FileVersion, FILE_VERSION)>0) {
+               /* WLH 6 Oct 98 */
+               printf("Warning: Trying to read a version %s file,", v->FileVersion);
+               printf(" you should upgrade Vis5D.\n");
+            }
+            break;
+         case TAG_NUMTIMES:
+            assert( length==4 );
+            read_int4( f, &v->NumTimes );
+            break;
+         case TAG_NUMVARS:
+            assert( length==4 );
+            read_int4( f, &v->NumVars );
+            break;
+         case TAG_VARNAME:
+            assert( length==14 );   /* 1 int + 10 char */
+            read_int4( f, &var );
+            read_bytes( f, v->VarName[var], 10 );
+            break;
+         case TAG_NR:
+            /* Number of rows for all variables */
+            assert( length==4 );
+            read_int4( f, &v->Nr );
+            break;
+         case TAG_NC:
+            /* Number of columns for all variables */
+            assert( length==4 );
+            read_int4( f, &v->Nc );
+            break;
+         case TAG_NL:
+            /* Number of levels for all variables */
+            assert( length==4 );
+            read_int4( f, &nl );
+            for (i=0;i<v->NumVars;i++) {
+               v->Nl[i] = nl;
+            }
+            break;
+         case TAG_NL_VAR:
+            /* Number of levels for one variable */
+            assert( length==8 );
+            read_int4( f, &var );
+            read_int4( f, &v->Nl[var] );
+            break;
+         case TAG_LOWLEV_VAR:
+            /* Lowest level for one variable */
+            assert( length==8 );
+            read_int4( f, &var );
+            read_int4( f, &v->LowLev[var] );
+            break;
+
+         case TAG_TIME:
+            /* Time stamp for 1 timestep */
+            assert( length==8 );
+            read_int4( f, &time );
+            read_int4( f, &v->TimeStamp[time] );
+            break;
+         case TAG_DATE:
+            /* Date stamp for 1 timestep */
+            assert( length==8 );
+            read_int4( f, &time );
+            read_int4( f, &v->DateStamp[time] );
+            break;
+
+         case TAG_MINVAL:
+            /* Minimum value for a variable */
+            assert( length==8 );
+            read_int4( f, &var );
+            read_float4( f, &v->MinVal[var] );
+            break;
+         case TAG_MAXVAL:
+            /* Maximum value for a variable */
+            assert( length==8 );
+            read_int4( f, &var );
+            read_float4( f, &v->MaxVal[var] );
+            break;
+         case TAG_COMPRESS:
+            /* Compress mode */
+            assert( length==4 );
+            read_int4( f, &v->CompressMode );
+            break;
+         case TAG_UNITS:
+            /* physical units */
+            assert( length==24 );
+            read_int4( f, &var );
+            read_bytes( f, v->Units[var], 20 );
+            break;
+
+         /*
+          * Vertical coordinate system
+          */
+         case TAG_VERTICAL_SYSTEM:
+            assert( length==4 );
+            read_int4( f, &v->VerticalSystem );
+            if (v->VerticalSystem<0 || v->VerticalSystem>3) {
+               printf("Error: bad vertical coordinate system: %d\n",
+                      v->VerticalSystem );
+            }
+            break;
+         case TAG_VERT_ARGS:
+            read_int4( f, &numargs );
+            assert( numargs <= MAXVERTARGS );
+            read_float4_array( f, v->VertArgs, numargs );
+            assert( length==numargs*4+4 );
+            break;
+         case TAG_HEIGHT:
+            /* height of a grid level */
+            assert( length==8 );
+            read_int4( f, &lev );
+            read_float4( f, &v->VertArgs[lev] );
+            break;
+         case TAG_BOTTOMBOUND:
+            assert( length==4 );
+            read_float4( f, &v->VertArgs[0] );
+            break;
+         case TAG_LEVINC:
+            assert( length==4 );
+            read_float4( f, &v->VertArgs[1] );
+            break;
+
+         /*
+          * Map projection information
+          */
+         case TAG_PROJECTION:
+            assert( length==4 );
+            read_int4( f, &v->Projection );
+            if (v->Projection<0 || v->Projection>4) { /* WLH 4-21-95 */
+               printf("Error while reading header, bad projection (%d)\n",
+                       v->Projection );
+               return 0;
+            }
+            break;
+         case TAG_PROJ_ARGS:
+            read_int4( f, &numargs );
+            assert( numargs <= MAXPROJARGS );
+            read_float4_array( f, v->ProjArgs, numargs );
+            assert( length==4*numargs+4 );
+            break;
+         case TAG_NORTHBOUND:
+            assert( length==4 );
+            if (v->Projection==0 || v->Projection==1 || v->Projection==4) {
+               read_float4( f, &v->ProjArgs[0] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_WESTBOUND:
+            assert( length==4 );
+            if (v->Projection==0 || v->Projection==1 || v->Projection==4) {
+               read_float4( f, &v->ProjArgs[1] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_ROWINC:
+            assert( length==4 );
+            if (v->Projection==0 || v->Projection==1 || v->Projection==4) {
+               read_float4( f, &v->ProjArgs[2] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_COLINC:
+            assert( length==4 );
+            if (v->Projection==0 || v->Projection==1 || v->Projection==4) {
+               read_float4( f, &v->ProjArgs[3] );
+            }
+            else if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[5] );
+            }
+            else if (v->Projection==3) {
+               read_float4( f, &v->ProjArgs[4] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_LAT1:
+            assert( length==4 );
+            if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[0] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_LAT2:
+            assert( length==4 );
+            if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[1] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_POLE_ROW:
+            assert( length==4 );
+            if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[2] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_POLE_COL:
+            assert( length==4 );
+            if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[3] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_CENTLON:
+            assert( length==4 );
+            if (v->Projection==2) {
+               read_float4( f, &v->ProjArgs[4] );
+            }
+            else if (v->Projection==3) {
+               read_float4( f, &v->ProjArgs[1] );
+            }
+            else if (v->Projection==4) { /* WLH 4-21-95 */
+               read_float4( f, &v->ProjArgs[5] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_CENTLAT:
+            assert( length==4 );
+            if (v->Projection==3) {
+               read_float4( f, &v->ProjArgs[0] );
+            }
+            else if (v->Projection==4) { /* WLH 4-21-95 */
+               read_float4( f, &v->ProjArgs[4] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_CENTROW:
+            assert( length==4 );
+            if (v->Projection==3) {
+               read_float4( f, &v->ProjArgs[2] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_CENTCOL:
+            assert( length==4 );
+            if (v->Projection==3) {
+               read_float4( f, &v->ProjArgs[3] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+         case TAG_ROTATION:
+            assert( length==4 );
+            if (v->Projection==4) { /* WLH 4-21-95 */
+               read_float4( f, &v->ProjArgs[6] );
+            }
+            else {
+               SKIP( 4 );
+            }
+            break;
+
+         case TAG_END:
+            /* end of header */
+            end_of_header = 1;
+            lseek( f, length, SEEK_CUR );
+            break;
+
+         default:
+            /* unknown tag, skip to next tag */
+            printf("Unknown tag: %d  length=%d\n", tag, length );
+            lseek( f, length, SEEK_CUR );
+            break;
+      }
+
+   }
+
+   v5dVerifyStruct( v );
+
+   /* Now we're ready to read the grid data */
+
+   /* Save current file pointer */
+   v->FirstGridPos = ltell(f);
+
+   /* compute grid sizes */
+   v->SumGridSizes = 0;
+   for (var=0;var<v->NumVars;var++) {
+      v->GridSize[var] = 8 * v->Nl[var] + v5dSizeofGrid( v, 0, var );
+      v->SumGridSizes += v->GridSize[var];
+   }
+
+   return 1;
+#undef SKIP
+}
+
+
+
+
+/*
+ * Open a v5d file for reading.
+ * Input:  filename - name of v5d file to open
+ *         v - pointer to a v5dstruct in which to put header info or NULL
+ *             if a struct should be dynamically allocated.
+ * Return:  NULL if error, else v or a pointer to a new v5dstruct if v was NULL
+ */
+v5dstruct *v5dOpenFile( const char *filename, v5dstruct *v )
+{
+   int fd;
+
+   fd = open( filename, O_RDONLY );
+   if (fd==-1) {
+      /* error */
+      return 0;
+   }
+
+   if (v) {
+      v5dInitStruct( v );
+   }
+   else {
+      v = v5dNewStruct();
+      if (!v) {
+         return NULL;
+      }
+   }
+
+   v->FileDesc = fd;
+   v->Mode = 'r';
+   if (read_v5d_header( v )) {
+      return v;
+   }
+   else {
+      return NULL;
+   }
+}
+
+
+
+
+/*
+ * Read a compressed grid from a v5d file.
+ * Input:  v - pointer to v5dstruct describing the file
+ *         time, var - which timestep and variable
+ *         ga, gb - arrays to store grid (de)compression values
+ *         compdata - address of where to store compressed grid data.
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dReadCompressedGrid( v5dstruct *v, int time, int var,
+                           float *ga, float *gb, void *compdata )
+{
+   int pos, n, k;
+
+   if (time<0 || time>=v->NumTimes) {
+      printf("Error in v5dReadCompressedGrid: bad timestep argument (%d)\n",
+             time);
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Error in v5dReadCompressedGrid: bad var argument (%d)\n",
+             var);
+      return 0;
+   }
+
+   if (v->FileFormat) {
+      /* old COMP* file */
+      return read_comp_grid( v, time, var, ga, gb, compdata );
+   }
+
+   /* move to position in file */
+   pos = grid_position( v, time, var );
+   lseek( v->FileDesc, pos, SEEK_SET );
+
+   /* read ga, gb arrays */
+   read_float4_array( v->FileDesc, ga, v->Nl[var] );
+   read_float4_array( v->FileDesc, gb, v->Nl[var] );
+
+   /* read compressed grid data */
+   n = v->Nr * v->Nc * v->Nl[var];
+   if (v->CompressMode==1) {
+      k = read_block( v->FileDesc, compdata, n, 1 )==n;
+   }
+   else if (v->CompressMode==2) {
+      k = read_block( v->FileDesc, compdata, n, 2 )==n;
+   }
+   else if (v->CompressMode==4) {
+      k = read_block( v->FileDesc, compdata, n, 4 )==n;
+   }
+   if (!k) {
+      /* error */
+      printf("Error in v5dReadCompressedGrid: read failed, bad file?\n");
+   }
+   return k;
+
+
+/*
+   n = v->Nr * v->Nc * v->Nl[var] * v->CompressMode;
+   if (read( v->FileDesc, compdata, n )==n)
+      return 1;
+   else
+      return 0;
+*/
+}
+
+
+
+
+/*
+ * Read a grid from a v5d file, decompress it and return it.
+ * Input:  v - pointer to v5dstruct describing file header
+ *         time, var - which timestep and variable.
+ *         data - address of buffer to put grid data
+ * Output:  data - the grid data
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dReadGrid( v5dstruct *v, int time, int var, float data[] )
+{
+   float ga[MAXLEVELS], gb[MAXLEVELS];
+   void *compdata;
+   int bytes;
+
+   if (time<0 || time>=v->NumTimes) {
+      printf("Error in v5dReadGrid: bad timestep argument (%d)\n", time);
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Error in v5dReadGrid: bad variable argument (%d)\n", var);
+      return 0;
+   }
+
+   /* allocate compdata buffer */
+   if (v->CompressMode==1) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(unsigned char);
+   }
+   else if (v->CompressMode==2) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(unsigned short);
+   }
+   else if (v->CompressMode==4) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(float);
+   }
+   compdata = (void *) malloc( bytes );
+   if (!compdata) {
+      printf("Error in v5dReadGrid: out of memory (needed %d bytes)\n", bytes);
+      return 0;
+   }
+
+   /* read the compressed data */
+   if (!v5dReadCompressedGrid( v, time, var, ga, gb, compdata )) {
+      return 0;
+   }
+
+   /* decompress the data */
+   v5dDecompressGrid( v->Nr, v->Nc, v->Nl[var], v->CompressMode,
+                      compdata, ga, gb, data );
+
+   /* free compdata */
+   free( compdata );
+   return 1;
+}
+
+
+
+
+/**********************************************************************/
+/*****                   Output Functions                         *****/
+/**********************************************************************/
+
+
+
+static int write_tag( v5dstruct *v, int tag, int length, int newfile )
+{
+   if (!newfile) {
+      /* have to check that there's room in header to write this tagged item */
+      if (v->CurPos+8+length > v->FirstGridPos) {
+         printf("Error: out of header space!\n");
+         /* Out of header space! */
+         return 0;
+      }
+   }
+
+   if (write_int4( v->FileDesc, tag )==0)  return 0;
+   if (write_int4( v->FileDesc, length )==0)  return 0;
+   v->CurPos += 8 + length;
+   return 1;
+}
+
+
+
+/*
+ * Write the information in the given v5dstruct as a v5d file header.
+ * Note that the current file position is restored when this function
+ * returns normally.
+ * Input:  f - file already open for writing
+ *         v - pointer to v5dstruct
+ * Return:  1 = ok, 0 = error.
+ */
+static int write_v5d_header( v5dstruct *v )
+{
+   int var, time, filler, maxnl;
+   int f;
+   int newfile;
+
+   if (v->FileFormat!=0) {
+      printf("Error: v5d library can't write comp5d format files.\n");
+      return 0;
+   }
+
+   f = v->FileDesc;
+
+   if (!v5dVerifyStruct( v ))
+      return 0;
+
+   /* Determine if we're writing to a new file */
+   if (v->FirstGridPos==0) {
+      newfile = 1;
+   }
+   else {
+      newfile = 0;
+   }
+
+   /* compute grid sizes */
+   v->SumGridSizes = 0;
+   for (var=0;var<v->NumVars;var++) {
+      v->GridSize[var] = 8 * v->Nl[var] + v5dSizeofGrid( v, 0, var );
+      v->SumGridSizes += v->GridSize[var];
+   }
+
+   /* set file pointer to start of file */
+   lseek( f, 0, SEEK_SET );
+   v->CurPos = 0;
+
+   /*
+    * Write the tagged header info
+    */
+#define WRITE_TAG( V, T, L )  if (!write_tag(V,T,L,newfile))  return 0;
+
+   /* ID */
+   WRITE_TAG( v, TAG_ID, 0 );
+
+   /* File Version */
+   WRITE_TAG( v, TAG_VERSION, 10 );
+   write_bytes( f, FILE_VERSION, 10 );
+
+   /* Number of timesteps */
+   WRITE_TAG( v, TAG_NUMTIMES, 4 );
+   write_int4( f, v->NumTimes );
+
+   /* Number of variables */
+   WRITE_TAG( v, TAG_NUMVARS, 4 );
+   write_int4( f, v->NumVars );
+
+   /* Names of variables */
+   for (var=0;var<v->NumVars;var++) {
+      WRITE_TAG( v, TAG_VARNAME, 14 );
+      write_int4( f, var );
+      write_bytes( f, v->VarName[var], 10 );
+   }
+
+   /* Physical Units */
+   for (var=0;var<v->NumVars;var++) {
+      WRITE_TAG( v, TAG_UNITS, 24 );
+      write_int4( f, var );
+      write_bytes( f, v->Units[var], 20 );
+   }
+
+   /* Date and time of each timestep */
+   for (time=0;time<v->NumTimes;time++) {
+      WRITE_TAG( v, TAG_TIME, 8 );
+      write_int4( f, time );
+      write_int4( f, v->TimeStamp[time] );
+      WRITE_TAG( v, TAG_DATE, 8 );
+      write_int4( f, time );
+      write_int4( f, v->DateStamp[time] );
+   }
+
+   /* Number of rows */
+   WRITE_TAG( v, TAG_NR, 4 );
+   write_int4( f, v->Nr );
+
+   /* Number of columns */
+   WRITE_TAG( v, TAG_NC, 4 );
+   write_int4( f, v->Nc );
+
+   /* Number of levels, compute maxnl */
+   maxnl = 0;
+   for (var=0;var<v->NumVars;var++) {
+      WRITE_TAG( v, TAG_NL_VAR, 8 );
+      write_int4( f, var );
+      write_int4( f, v->Nl[var] );
+      WRITE_TAG( v, TAG_LOWLEV_VAR, 8 );
+      write_int4( f, var );
+      write_int4( f, v->LowLev[var] );
+      if (v->Nl[var]+v->LowLev[var]>maxnl) {
+         maxnl = v->Nl[var]+v->LowLev[var];
+      }
+   }
+
+   /* Min/Max values */
+   for (var=0;var<v->NumVars;var++) {
+      WRITE_TAG( v, TAG_MINVAL, 8 );
+      write_int4( f, var );
+      write_float4( f, v->MinVal[var] );
+      WRITE_TAG( v, TAG_MAXVAL, 8 );
+      write_int4( f, var );
+      write_float4( f, v->MaxVal[var] );
+   }
+
+   /* Compress mode */
+   WRITE_TAG( v, TAG_COMPRESS, 4 );
+   write_int4( f, v->CompressMode );
+
+   /* Vertical Coordinate System */
+   WRITE_TAG( v, TAG_VERTICAL_SYSTEM, 4 );
+   write_int4( f, v->VerticalSystem );
+   WRITE_TAG( v, TAG_VERT_ARGS, 4+4*MAXVERTARGS );
+   write_int4( f, MAXVERTARGS );
+   write_float4_array( f, v->VertArgs, MAXVERTARGS );
+
+   /* Map Projection */
+   WRITE_TAG( v, TAG_PROJECTION, 4 );
+   write_int4( f, v->Projection );
+   WRITE_TAG( v, TAG_PROJ_ARGS, 4+4*MAXPROJARGS );
+   write_int4( f, MAXPROJARGS );
+   write_float4_array( f, v->ProjArgs, MAXPROJARGS );
+
+   /* write END tag */
+   if (newfile) {
+      /* We're writing to a brand new file.  Reserve 10000 bytes */
+      /* for future header growth. */
+      WRITE_TAG( v, TAG_END, 10000 );
+      lseek( f, 10000, SEEK_CUR );
+
+      /* Let file pointer indicate where first grid is stored */
+      v->FirstGridPos = ltell( f );
+   }
+   else {
+      /* we're rewriting a header */
+      filler = v->FirstGridPos - ltell(f);
+      WRITE_TAG( v, TAG_END, filler-8 );
+   }
+
+#undef WRITE_TAG
+
+   return 1;
+}
+
+
+
+/*
+ * Open a v5d file for writing.  If the named file already exists,
+ * it will be deleted.
+ * Input:  filename - name of v5d file to create.
+ *         v - pointer to v5dstruct with the header info to write.
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dCreateFile( const char *filename, v5dstruct *v )
+{
+   mode_t mask;
+   int fd;
+
+   mask = 0666;
+   fd = open( filename, O_WRONLY | O_CREAT | O_TRUNC, mask );
+   if (fd==-1) {
+      printf("Error in v5dCreateFile: open failed\n");
+      v->FileDesc = -1;
+      v->Mode = 0;
+      return 0;
+   }
+   else {
+      /* ok */
+      v->FileDesc = fd;
+      v->Mode = 'w';
+      /* write header and return status */
+      return write_v5d_header(v);
+   }
+}
+
+
+
+/*
+ * Open a v5d file for updating/appending and read the header info.
+ * Input:  filename - name of v5d file to open for updating.
+ *         v - pointer to v5dstruct in which the file header info will be
+ *             put.  If v is NULL a v5dstruct will be allocated and returned.
+ * Return:  NULL if error, else v or a pointer to a new v5dstruct if v as NULL
+ */
+v5dstruct *v5dUpdateFile( const char *filename, v5dstruct *v )
+{
+   int fd;
+
+   fd = open( filename, O_RDWR );
+   if (fd==-1) {
+      return NULL;
+   }
+
+   if (!v) {
+      v = v5dNewStruct();
+      if (!v) {
+         return NULL;
+      }
+   }
+
+   v->FileDesc = fd;
+   v->Mode = 'w';
+
+   if (read_v5d_header( v )) {
+      return v;
+   }
+   else {
+      return NULL;
+   }
+}
+
+
+
+/*
+ * Write a compressed grid to a v5d file.
+ * Input:  v - pointer to v5dstruct describing the file
+ *         time, var - which timestep and variable
+ *         ga, gb - the GA and GB (de)compression value arrays
+ *         compdata - address of array of compressed data values
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dWriteCompressedGrid( const v5dstruct *v, int time, int var,
+                            const float *ga, const float *gb,
+                            const void *compdata )
+{
+   int pos, n, k;
+
+   /* simple error checks */
+   if (v->Mode!='w') {
+      printf("Error in v5dWriteCompressedGrid: file opened for reading,");
+      printf(" not writing.\n");
+      return 0;
+   }
+   if (time<0 || time>=v->NumTimes) {
+      printf("Error in v5dWriteCompressedGrid: bad timestep argument (%d)\n",
+             time);
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Error in v5dWriteCompressedGrid: bad variable argument (%d)\n",
+             var);
+      return 0;
+   }
+
+   /* move to position in file */
+   pos = grid_position( v, time, var );
+   if (lseek( v->FileDesc, pos, SEEK_SET )<0) {
+      /* lseek failed, return error */
+      printf("Error in v5dWrite[Compressed]Grid: seek failed, disk full?\n");
+      return 0;
+   }
+
+   /* write ga, gb arrays */
+   k = 0;
+   if (write_float4_array( v->FileDesc, ga, v->Nl[var] ) == v->Nl[var] &&
+       write_float4_array( v->FileDesc, gb, v->Nl[var] ) == v->Nl[var]) {
+      /* write compressed grid data (k=1=OK, k=0=Error) */
+      n = v->Nr * v->Nc * v->Nl[var];
+      if (v->CompressMode==1) {
+         k = write_block( v->FileDesc, compdata, n, 1 )==n;
+      }
+      else if (v->CompressMode==2) {
+         k = write_block( v->FileDesc, compdata, n, 2 )==n;
+      }
+      else if (v->CompressMode==4) {
+         k = write_block( v->FileDesc, compdata, n, 4 )==n;
+      }
+   }
+
+   if (k==0) {
+      /* Error while writing */
+      printf("Error in v5dWrite[Compressed]Grid: write failed, disk full?\n");
+   }
+   return k;
+
+/*
+   n = v->Nr * v->Nc * v->Nl[var] * v->CompressMode;
+   if (write_bytes( v->FileDesc, compdata, n )!=n) {
+      printf("Error in v5dWrite[Compressed]Grid: write failed, disk full?\n");
+      return 0;
+   }
+   else {
+      return 1;
+   }
+*/
+}
+
+
+
+
+/*
+ * Compress a grid and write it to a v5d file.
+ * Input:  v - pointer to v5dstruct describing the file
+ *         time, var - which timestep and variable (starting at 0)
+ *         data - address of uncompressed grid data
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dWriteGrid( v5dstruct *v, int time, int var, const float data[] )
+{
+   float ga[MAXLEVELS], gb[MAXLEVELS];
+   void *compdata;
+   int n, bytes;
+   float min, max;
+
+   if (v->Mode!='w') {
+      printf("Error in v5dWriteGrid: file opened for reading,");
+      printf(" not writing.\n");
+      return 0;
+   }
+   if (time<0 || time>=v->NumTimes) {
+      printf("Error in v5dWriteGrid: bad timestep argument (%d)\n", time);
+      return 0;
+   }
+   if (var<0 || var>=v->NumVars) {
+      printf("Error in v5dWriteGrid: bad variable argument (%d)\n", var);
+      return 0;
+   }
+
+   /* allocate compdata buffer */
+   if (v->CompressMode==1) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(unsigned char);
+   }
+   else if (v->CompressMode==2) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(unsigned short);
+   }
+   else if (v->CompressMode==4) {
+      bytes = v->Nr * v->Nc * v->Nl[var] * sizeof(float);
+   }
+   compdata = (void *) malloc( bytes );
+   if (!compdata) {
+      printf("Error in v5dWriteGrid: out of memory (needed %d bytes)\n",
+             bytes );
+      return 0;
+   }
+
+   /* compress the grid data */
+   v5dCompressGrid( v->Nr, v->Nc, v->Nl[var], v->CompressMode, data,
+                    compdata, ga, gb, &min, &max );
+
+   /* update min and max value */
+   if (min<v->MinVal[var])
+      v->MinVal[var] = min;
+   if (max>v->MaxVal[var])
+      v->MaxVal[var] = max;
+
+   /* write the compressed grid */
+   n = v5dWriteCompressedGrid( v, time, var, ga, gb, compdata );
+
+   /* free compdata */
+   free( compdata );
+
+   return n;
+}
+
+
+
+/*
+ * Close a v5d file which was opened with open_v5d_file() or
+ * create_v5d_file().
+ * Input: f - file descriptor
+ * Return:  1 = ok, 0 = error
+ */
+int v5dCloseFile( v5dstruct *v )
+{
+   int status = 1;
+
+   if (v->Mode=='w') {
+      /* rewrite header because writing grids updates the minval and */
+      /* maxval fields */
+      lseek( v->FileDesc, 0, SEEK_SET );
+      status = write_v5d_header( v );
+      lseek( v->FileDesc, 0, SEEK_END );
+      close( v->FileDesc );
+   }
+   else if (v->Mode=='r') {
+      /* just close the file */
+      close(v->FileDesc);
+   }
+   else {
+      printf("Error in v5dCloseFile: bad v5dstruct argument\n");
+      return 0;
+   }
+   v->FileDesc = -1;
+   v->Mode = 0;
+   return status;
+}
+
+
+
+
+/**********************************************************************/
+/*****           Simple v5d file writing functions.               *****/
+/**********************************************************************/
+
+
+
+static v5dstruct *Simple = NULL;
+
+
+
+/*
+ * Create a new v5d file specifying both a map projection and vertical
+ * coordinate system.  See README file for argument details.
+ * Return:  1 = ok, 0 = error.
+ */
+int v5dCreate( const char *name, int numtimes, int numvars,
+               int nr, int nc, const int nl[],
+               const char varname[MAXVARS][10],
+               const int timestamp[], const int datestamp[],
+               int compressmode,
+               int projection,
+               const FLOAT proj_args[],
+               int vertical,
+               const FLOAT vert_args[] )
+{
+   int var, time, maxnl, i;
+
+   /* initialize the v5dstruct */
+   Simple = v5dNewStruct();
+
+   Simple->NumTimes = numtimes;
+   Simple->NumVars = numvars;
+   Simple->Nr = nr;
+   Simple->Nc = nc;
+   maxnl = nl[0];
+   for (var=0;var<numvars;var++) {
+      if (nl[var]>maxnl) {
+         maxnl = nl[var];
+      }
+      Simple->Nl[var] = nl[var];
+      Simple->LowLev[var] = 0;
+      strncpy( Simple->VarName[var], varname[var], 10 );
+      Simple->VarName[var][9] = 0;
+   }
+
+   /* time and date for each timestep */
+   for (time=0;time<numtimes;time++) {
+      Simple->TimeStamp[time] = timestamp[time];
+      Simple->DateStamp[time] = datestamp[time];
+   }
+
+   Simple->CompressMode = compressmode;
+
+   /* Map projection and vertical coordinate system */
+   Simple->Projection = projection;
+#ifdef VPP
+   { 
+       int i;
+       for (i=0;i<MAXPROJARGS;i++)
+        Simple->ProjArgs[i] =  (float)proj_args[i];
+   }
+#else
+   memcpy( Simple->ProjArgs, proj_args, MAXPROJARGS*sizeof(float) );
+#endif
+   Simple->VerticalSystem = vertical;
+   if (vertical == 3) {
+     /* convert pressures to heights */
+     for (i=0; i<MAXVERTARGS; i++) {
+       if (vert_args[i] > 0.000001) {
+         Simple->VertArgs[i] = pressure_to_height((float)vert_args[i]);
+       }
+       else Simple->VertArgs[i] = 0.0;
+     }
+   }
+   else {
+#ifdef VPP
+   { 
+       int i;
+       for (i=0;i<MAXVERTARGS;i++)
+          Simple->VertArgs[i] =  (float)vert_args[i];
+   }    
+#else
+     memcpy( Simple->VertArgs, vert_args, MAXVERTARGS*sizeof(float) );
+#endif
+   }
+
+   /* create the file */
+   if (v5dCreateFile( name, Simple )==0) {
+     printf("Error in v5dCreateSimpleFile: unable to create %s\n", name );
+     return 0;
+   }
+   else {
+      return 1;
+   }
+}
+
+
+
+/*
+ * Create a new v5d file using minimal information.
+ * Return:  1 = ok, 0 = error.  See README file for argument details.
+ */
+int v5dCreateSimple( const char *name, int numtimes, int numvars,
+                     int nr, int nc, int nl,
+                     const char varname[MAXVARS][10],
+                     const int timestamp[], const int datestamp[],
+                     float northlat, float latinc,
+                     float westlon, float loninc,
+                     float bottomhgt, float hgtinc )
+{
+   int nlvar[MAXVARS];
+   int compressmode, projection, vertical;
+   FLOAT proj_args[100], vert_args[MAXLEVELS];
+   int i;
+
+   for (i=0;i<numvars;i++) {
+      nlvar[i] = nl;
+   }
+
+   compressmode = 1;
+
+   projection = 1;
+   proj_args[0] = northlat;
+   proj_args[1] = westlon;
+   proj_args[2] = latinc;
+   proj_args[3] = loninc;
+
+   vertical = 1;
+   vert_args[0] = bottomhgt;
+   vert_args[1] = hgtinc;
+
+   return v5dCreate( name, numtimes, numvars, nr, nc, nlvar,
+                     varname, timestamp, datestamp, compressmode,
+                     projection, proj_args, vertical, vert_args );
+}
+
+
+
+/*
+ * Set lowest levels for each variable (other than default of 0).
+ * Input: lowlev - array [NumVars] of ints
+ * Return:  1 = ok, 0 = error
+ */
+int v5dSetLowLev( int lowlev[] )
+{
+  int var;
+
+  if (Simple) {
+     for (var=0;var<Simple->NumVars;var++) {
+        Simple->LowLev[var] = lowlev[var];
+     }
+     return 1;
+  }
+  else {
+     printf("Error: must call v5dCreate before v5dSetLowLev\n");
+     return 0;
+  }
+}
+
+
+/*
+ * Set the units for a variable.
+ * Input:  var - a variable in [1,NumVars]
+ *         units - a string
+ * Return:  1 = ok, 0 = error
+ */
+int v5dSetUnits( int var, const char *units )
+{
+  if (Simple) {
+     if (var>=1 && var<=Simple->NumVars) {
+        strncpy( Simple->Units[var-1], units, 19 );
+        Simple->Units[var-1][19] = 0;
+        return 1;
+     }
+     else {
+        printf("Error: bad variable number in v5dSetUnits\n");
+        return 0;
+     }
+  }
+  else {
+     printf("Error: must call v5dCreate before v5dSetUnits\n");
+     return 0;
+  }
+}
+
+
+
+/*
+ * Write a grid to a v5d file.
+ * Input:  time - timestep in [1,NumTimes]
+ *         var - timestep in [1,NumVars]
+ *         data - array [nr*nc*nl] of floats
+ * Return:  1 = ok, 0 = error
+ */
+int v5dWrite( int time, int var, const FLOAT data[] )
+{
+   if (Simple) {
+      if (time<1 || time>Simple->NumTimes) {
+         printf("Error in v5dWrite: bad timestep number: %d\n", time );
+         return 0;
+      }
+      if (var<1 || var>Simple->NumVars) {
+         printf("Error in v5dWrite: bad variable number: %d\n", var );
+      }
+#ifdef VPP
+      {
+         float *rdata;
+         int i,irep;
+         int size = Simple->Nr * Simple->Nc * Simple->Nl[var-1]; 
+         rdata = (float *)malloc(size * 4);
+         if (!rdata){
+             printf("Error in v5dWrite: out of memory\n");
+             return 0;
+         }
+         for (i=0;i<size;i++)
+             rdata[i] = (float)data[i];
+         irep = v5dWriteGrid( Simple, time-1, var-1, rdata );
+         free(rdata);
+         return irep;
+
+      }
+#else      
+      return v5dWriteGrid( Simple, time-1, var-1, data );
+#endif
+   }
+   else {
+      printf("Error: must call v5dCreate before v5dWrite\n");
+      return 0;
+   }
+}
+
+
+
+/*
+ * Close a v5d file after the last grid has been written to it.
+ * Return:  1 = ok, 0 = error
+ */
+int v5dClose( void )
+{
+   if (Simple) {
+     int ok = v5dCloseFile( Simple );
+     v5dFreeStruct( Simple );
+     return ok;
+   }
+   else {
+     printf("Error: v5dClose: no file to close\n");
+     return 0;
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                FORTRAN-callable simple output              *****/
+/**********************************************************************/
+
+
+/*
+ * Create a v5d file.  See README file for argument descriptions.
+ * Return:  1 = ok, 0 = error.
+ */
+#ifdef UNDERSCORE
+   int v5dcreate_
+#else
+#  ifdef _CRAY
+     int V5DCREATE
+#  else
+     int v5dcreate
+#  endif
+#endif
+           ( const char *name, const int *numtimes, const int *numvars,
+             const int *nr, const int *nc, const int nl[],
+             const char varname[][10],
+             const int timestamp[], const int datestamp[],
+             const int *compressmode,
+             const int *projection,
+             const FLOAT proj_args[],
+             const int *vertical,
+             const FLOAT vert_args[] )
+{
+   char filename[100];
+   char names[MAXVARS][10];
+   int i, maxnl, args;
+
+   /* copy name to filename and remove trailing spaces if any */
+   copy_string( filename, name, 100 );
+
+   /*
+    * Check for uninitialized arguments
+    */
+   if (*numtimes<1) {
+      printf("Error: numtimes invalid\n");
+      return 0;
+   }
+   if (*numvars<1) {
+      printf("Error: numvars invalid\n");
+      return 0;
+   }
+   if (*nr<2) {
+      printf("Error: nr invalid\n");
+      return 0;
+   }
+   if (*nc<2) {
+      printf("Error: nc invalid\n");
+      return 0;
+   }
+   maxnl = 0;
+   for (i=0;i<*numvars;i++) {
+      if (nl[i]<1) {
+         printf("Error: nl(%d) invalid\n", i+1);
+         return 0;
+      }
+      if (nl[i]>maxnl) {
+         maxnl = nl[i];
+      }
+   }
+
+   for (i=0;i<*numvars;i++) {
+      if (copy_string2( names[i], varname[i], 10)==0) {
+         printf("Error: unitialized varname(%d)\n", i+1);
+         return 0;
+      }
+   }
+
+   for (i=0;i<*numtimes;i++) {
+      if (timestamp[i]<0) {
+         printf("Error: times(%d) invalid\n", i+1);
+         return 0;
+      }
+      if (datestamp[i]<0) {
+         printf("Error: dates(%d) invalid\n", i+1);
+         return 0;
+      }
+   }
+
+   if (*compressmode != 1 && *compressmode != 2 && *compressmode != 4) {
+      printf("Error: compressmode invalid\n");
+      return 0;
+   }
+
+   switch (*projection) {
+      case 0:
+         args = 4;
+         break;
+      case 1:
+         args = 0;
+         if (IS_MISSING(proj_args[0])) {
+            printf("Error: northlat (proj_args(1)) invalid\n");
+            return 0;
+         }
+         if (IS_MISSING(proj_args[1])) {
+            printf("Error: westlon (proj_args(2)) invalid\n");
+            return 0;
+         }
+         if (IS_MISSING(proj_args[2])) {
+            printf("Error: latinc (proj_args(3)) invalid\n");
+            return 0;
+         }
+         if (IS_MISSING(proj_args[3])) {
+            printf("Error: loninc (proj_args(4)) invalid\n");
+            return 0;
+         }
+         break;
+      case 2:
+         args = 6;
+         break;
+      case 3:
+         args = 5;
+         break;
+      case 4:
+         args = 7;
+         break;
+      default:
+         args = 0;
+         printf("Error: projection invalid\n");
+         return 0;
+   }
+   for (i=0;i<args;i++) {
+      if (IS_MISSING(proj_args[i])) {
+         printf("Error: proj_args(%d) invalid\n", i+1);
+         return 0;
+      }
+   }
+
+   switch (*vertical) {
+      case 0:
+/* WLH 31 Oct 96  -  just fall through 
+         args = 4;
+         break;
+*/
+      case 1:
+         args = 0;
+         if (IS_MISSING(vert_args[0])) {
+            printf("Error: bottomhgt (vert_args(1)) invalid\n");
+            return 0;
+         }
+         if (IS_MISSING(vert_args[1])) {
+            printf("Error: hgtinc (vert_args(2)) invalid\n");
+            return 0;
+         }
+         break;
+      case 2:
+      case 3:
+         args = maxnl;
+         break;
+      default:
+         args = 0;
+         printf("Error: vertical invalid\n");
+         return 0;
+   }
+   for (i=0;i<args;i++) {
+      if (IS_MISSING(vert_args[i])) {
+         printf("Error: vert_args(%d) invalid\n", i+1);
+         return 0;
+      }
+   }
+
+   return v5dCreate( filename, *numtimes, *numvars, *nr, *nc, nl,
+                     (const char(*)[10]) names, timestamp, datestamp,
+                     *compressmode,
+                     *projection, proj_args, *vertical, vert_args );
+}
+
+
+
+
+/*
+ * Create a simple v5d file.  See README file for argument descriptions.
+ * Return:  1 = ok, 0 = error.
+ */
+#ifdef UNDERSCORE
+  int v5dcreatesimple_
+#else
+#  ifdef _CRAY
+     int V5DCREATESIMPLE
+#  else
+     int v5dcreatesimple
+#  endif
+#endif
+           ( const char *name, const int *numtimes, const int *numvars,
+             const int *nr, const int *nc, const int *nl,
+             const char varname[][10],
+             const int timestamp[], const int datestamp[],
+             const float *northlat, const float *latinc,
+             const float *westlon, const float *loninc,
+             const float *bottomhgt, const float *hgtinc )
+{
+   int compressmode, projection, vertical;
+   FLOAT projarg[100], vertarg[MAXLEVELS];
+   int varnl[MAXVARS];
+   int i;
+
+   for (i=0;i<MAXVARS;i++) {
+      varnl[i] = *nl;
+   }
+
+   compressmode = 1;
+
+   projection = 1;
+   projarg[0] = *northlat;
+   projarg[1] = *westlon;
+   projarg[2] = *latinc;
+   projarg[3] = *loninc;
+
+   vertical = 1;
+   vertarg[0] = *bottomhgt;
+   vertarg[1] = *hgtinc;
+
+#ifdef UNDERSCORE
+   return v5dcreate_
+#else
+#  ifdef _CRAY
+   return V5DCREATE
+#  else
+
+   return v5dcreate
+#  endif
+#endif
+                   ( name, numtimes, numvars, nr, nc, varnl,
+                     varname, timestamp, datestamp, &compressmode,
+                     &projection, projarg, &vertical, vertarg );
+}
+
+
+
+/*
+ * Set lowest levels for each variable (other than default of 0).
+ * Input: lowlev - array [NumVars] of ints
+ * Return:  1 = ok, 0 = error
+ */
+#ifdef UNDERSCORE
+   int v5dsetlowlev_
+#else
+#  ifdef _CRAY
+     int V5DSETLOWLEV
+#  else
+     int v5dsetlowlev
+#  endif
+#endif
+          ( int *lowlev )
+{
+   return v5dSetLowLev(lowlev);
+}
+
+
+
+/*
+ * Set the units for a variable.
+ * Input: var - variable number in [1,NumVars]
+ *        units - a character string
+ * Return:  1 = ok, 0 = error
+ */
+#ifdef UNDERSCORE
+   int v5dsetunits_
+#else
+#  ifdef _CRAY
+     int V5DSETUNITS
+#  else
+     int v5dsetunits
+#  endif
+#endif
+          ( int *var, char *name )
+{
+   return v5dSetUnits( *var, name );
+}
+
+
+
+/*
+ * Write a grid of data to the file.
+ * Input:  time - timestep in [1,NumTimes]
+ *         var - timestep in [1,NumVars]
+ *         data - array [nr*nc*nl] of floats
+ * Return:  1 = ok, 0 = error
+ */
+#ifdef UNDERSCORE
+   int v5dwrite_
+#else
+#  ifdef _CRAY
+     int V5DWRITE
+#  else
+     int v5dwrite
+#  endif
+#endif
+          ( const int *time, const int *var, const FLOAT *data )
+{
+   return v5dWrite( *time, *var, data );
+}
+
+
+
+/*
+ * Specify the McIDAS GR3D file number and grid number which correspond
+ * to the grid specified by time and var.
+ * Input:  time, var - timestep and variable of grid (starting at 1)
+ *         mcfile, mcgrid - McIDAS grid file number and grid number
+ * Return:  1 = ok, 0 = errror (bad time or var)
+ */
+#ifdef UNDERSCORE
+   int v5dmcfile_
+#else
+#  ifdef _CRAY
+     int V5DMCFILE
+#  else
+     int v5dmcfile
+#  endif
+#endif
+         ( const int *time, const int *var,
+           const int *mcfile, const int *mcgrid )
+{
+   if (*time<1 || *time>Simple->NumTimes) {
+      printf("Bad time argument to v5dSetMcIDASgrid: %d\n", *time );
+      return 0;
+   }
+   if (*var<1 || *var>Simple->NumVars) {
+      printf("Bad var argument to v5dSetMcIDASgrid: %d\n", *var );
+      return 0;
+   }
+
+   Simple->McFile[*time-1][*var-1] = (short) *mcfile;
+   Simple->McGrid[*time-1][*var-1] = (short) *mcgrid;
+   return 1;
+}
+
+
+
+/*
+ * Close a simple v5d file.
+ */
+#ifdef UNDERSCORE
+   int v5dclose_( void )
+#else
+#  ifdef _CRAY
+     int V5DCLOSE( void )
+#  else
+     int v5dclose( void )
+#  endif
+#endif
+{
+   return v5dClose();
+}
diff --git a/lib/vis5d/src/v5d.h b/lib/vis5d/src/v5d.h
new file mode 100644 (file)
index 0000000..97d2441
--- /dev/null
@@ -0,0 +1,310 @@
+
+/* Vis5D version 5.1 */
+
+/*
+Vis5D system for visualizing five dimensional gridded data sets
+Copyright (C) 1990 - 1996 Bill Hibbard, Brian Paul, Dave Santek,
+and Andre Battaiola.
+
+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; either version 1, or (at your option)
+any later version.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifndef V5D_H
+#define V5D_H
+
+
+/*
+ * A numeric version number which we can test for in utility programs which
+ * use the v5d functions.  For example, we can do tests like this:
+ * #if V5D_VERSION > 42
+ *      do something
+ * #else
+ *      do something else
+ * #endif
+ *
+ * If V5D_VERSION is not defined, then its value is considered to be zero.
+ */
+
+#define V5D_VERSION 42
+
+
+/*
+ * Define our own 1 and 2-byte data types.  We use these names to avoid
+ * collisions with types defined by the OS include files.
+ */
+typedef unsigned char V5Dubyte;     /* Must be 1 byte, except for cray */
+typedef unsigned short V5Dushort;   /* Must be 2 byte, except for cray */
+
+
+
+#define MISSING 1.0e35
+#define IS_MISSING(X)  ( (X) >= 1.0e30 )
+
+
+/* Limits on 5-D grid size:  (must match those in v5df.h!!!) */
+#define MAXVARS     100
+#define MAXTIMES    400
+#define MAXROWS     800
+#define MAXCOLUMNS  800 
+#define MAXLEVELS   100
+
+
+#ifdef VPP
+#define FLOAT double
+#else
+#define FLOAT float
+#endif
+
+/************************************************************************/
+/***                                                                  ***/
+/*** Functions for writing v5d files.  See README file for details.   ***/
+/*** These are the functions user's will want for writing file        ***/
+/*** converters, etc.                                                 ***/
+/***                                                                  ***/
+/************************************************************************/
+
+extern int v5dCreateSimple( const char *name,
+                            int numtimes, int numvars,
+                            int nr, int nc, int nl,
+                            const char varname[MAXVARS][10],
+                            const int timestamp[],
+                            const int datestamp[],
+                            float northlat, float latinc,
+                            float westlon, float loninc,
+                            float bottomhgt, float hgtinc );
+
+
+extern int v5dCreate( const char *name,
+                      int numtimes, int numvars,
+                      int nr, int nc, const int nl[],
+                      const char varname[MAXVARS][10],
+                      const int timestamp[],
+                      const int datestamp[],
+                      int compressmode,
+                      int projection,
+                      const FLOAT proj_args[],
+                      int vertical,
+                      const FLOAT vert_args[] );
+
+
+extern int v5dWrite( int time, int var, const FLOAT data[] );
+
+extern int v5dClose( void );
+
+
+extern int v5dSetLowLev( int lowlev[] );
+
+extern int v5dSetUnits( int var, const char *units );
+
+
+
+/************************************************************************/
+/***                                                                  ***/
+/*** Definition of v5d struct and function prototypes.                ***/
+/*** These functions are used by vis5d and advanced v5d utilities.    ***/
+/***                                                                  ***/
+/************************************************************************/
+
+#define MAXPROJARGS 100
+#define MAXVERTARGS (MAXLEVELS+1)
+
+/*
+ * This struct describes the structure of a .v5d file.
+ */
+typedef struct {
+    /* PUBLIC (user can freely read, sometimes write, these fields) */
+        int NumTimes;                   /* Number of time steps */
+        int NumVars;                    /* Number of variables */
+        int Nr;                         /* Number of rows */
+        int Nc;                         /* Number of columns */
+        int Nl[MAXVARS];                /* Number of levels per variable */
+        int LowLev[MAXVARS];            /* Lowest level per variable */
+        char VarName[MAXVARS][10];      /* 9-character variable names */
+        char Units[MAXVARS][20];        /* 19-character units for variables */
+        int TimeStamp[MAXTIMES];        /* Time in HHMMSS format */
+        int DateStamp[MAXTIMES];        /* Date in YYDDD format */
+        float MinVal[MAXVARS];          /* Minimum variable data values */
+        float MaxVal[MAXVARS];          /* Maximum variable data values */
+
+        /* This info is used for external function computation */
+        short McFile[MAXTIMES][MAXVARS];/* McIDAS file number in 1..9999 */
+        short McGrid[MAXTIMES][MAXVARS];/* McIDAS grid number in 1..? */
+
+        int VerticalSystem;             /* Which vertical coordinate system */
+        float VertArgs[MAXVERTARGS];    /* Vert. Coord. Sys. arguments... */
+
+        /*
+        IF VerticalSystem==0 THEN
+                -- Linear scale, equally-spaced levels in generic units
+                VertArgs[0] = Height of bottom-most grid level in generic units
+                VertArgs[1] = Increment between levels in generic units
+        ELSE IF VerticalSystem==1 THEN
+                -- Linear scale, equally-spaced levels in km
+                VertArgs[0] = Height of bottom grid level in km
+                VertArgs[1] = Increment between levels in km
+        ELSE IF VerticalSystem==2 THEN
+                -- Linear scale, Unequally spaced levels in km
+                VertArgs[0] = Height of grid level 0 (bottom) in km
+                ...                ...
+                VertArgs[n] = Height of grid level n in km
+        ELSE IF VerticalSystem==3 THEN
+                -- Linear scale, Unequally spaced levels in mb
+                VertArgs[0] = Pressure of grid level 0 (bottom) in mb
+                ...             ...
+                VertArgs[n] = Pressure of grid level n in mb
+        ENDIF
+        */
+
+        int Projection;                     /* Which map projection */
+        float ProjArgs[MAXPROJARGS];        /* Map projection arguments... */
+
+        /*
+        IF Projection==0 THEN
+                -- Rectilinear grid, generic units
+                ProjArgs[0] = North bound, Y coordinate of grid row 0
+                ProjArgs[1] = West bound, X coordiante of grid column 0
+                ProjArgs[2] = Increment between rows
+                ProjArgs[3] = Increment between colums
+                NOTES: X coordinates increase to the right, Y increase upward.
+                NOTES: Coordinate system is right-handed.
+        ELSE IF Projection==1 THEN
+                -- Cylindrical equidistant (Old VIS-5D)
+                -- Rectilinear grid in lat/lon
+                ProjArgs[0] = Latitude of grid row 0, north bound, in degrees
+                ProjArgs[1] = Longitude of grid column 0, west bound, in deg.
+                ProjArgs[2] = Increment between rows in degrees
+                ProjArgs[3] = Increment between rows in degrees
+                NOTES: Coordinates (degrees) increase to the left and upward.
+        ELSE IF Projection==2 THEN
+                -- Lambert conformal
+                ProjArgs[0] = Standared Latitude 1 of conic projection
+                ProjArgs[1] = Standared Latitude 2 of conic projection
+                ProjArgs[2] = Row of North/South pole
+                ProjArgs[3] = Column of North/South pole
+                ProjArgs[4] = Longitude which is parallel to columns
+                ProjArgs[5] = Increment between grid columns in km
+        ELSE IF Projection==3 THEN
+                -- Polar Stereographic
+                ProjArgs[0] = Latitude of center of projection
+                ProjArgs[1] = Longitude of center of projection
+                ProjArgs[2] = Grid row of center of projection
+                ProjArgs[3] = Grid column of center of projection
+                ProjArgs[4] = Increment between grid columns at center in km
+        ELSE IF Projection==4 THEN
+                -- Rotated
+                ProjArgs[0] = Latitude on rotated globe of grid row 0
+                ProjArgs[1] = Longitude on rotated globe of grid column 0
+                ProjArgs[2] = Degrees of latitude on rotated globe between
+                                grid rows
+                ProjArgs[3] = Degrees of longitude on rotated globe between
+                                grid columns
+                ProjArgs[4] = Earth latitude of (0, 0) on rotated globe
+                ProjArgs[5] = Earth longitude of (0, 0) on rotated globe
+                ProjArgs[6] = Clockwise rotation of rotated globe in degrees
+        ENDIF
+        */
+
+        int CompressMode;        /* 1, 2 or 4 = # bytes per grid point */
+        char FileVersion[10];    /* 9-character version number */
+
+    /* PRIVATE (not to be touched by user code) */
+        unsigned int FileFormat; /* COMP5D file version or 0 if .v5d */
+        int FileDesc;            /* Unix file descriptor */
+        char Mode;               /* 'r' = read, 'w' = write */
+        int CurPos;              /* current position of file pointer */
+        int FirstGridPos;        /* position of first grid in file */
+        int GridSize[MAXVARS];   /* size of each grid */
+        int SumGridSizes;        /* sum of GridSize[0..NumVars-1] */
+} v5dstruct;
+
+
+
+extern float pressure_to_height( float pressure);
+
+extern float height_to_pressure( float height );
+
+
+
+
+extern int v5dYYDDDtoDays( int yyddd );
+
+extern int v5dHHMMSStoSeconds( int hhmmss );
+
+extern int v5dDaysToYYDDD( int days );
+
+extern int v5dSecondsToHHMMSS( int seconds );
+
+
+extern void v5dPrintStruct( const v5dstruct *v );
+
+
+extern v5dstruct *v5dNewStruct( void );
+
+extern void v5dFreeStruct( v5dstruct* v );
+
+extern void v5dInitStruct( v5dstruct *v );
+
+extern int v5dVerifyStruct( const v5dstruct *v );
+
+
+extern void v5dCompressGrid( int nr, int nc, int nl, int compressmode,
+                             const float data[], void *compdata,
+                             float ga[], float gb[],
+                             float *minval, float *maxval );
+
+
+extern void v5dDecompressGrid( int nr, int nc, int nl, int compressmode,
+                               void *compdata,
+                               float ga[], float gb[],
+                               float data[] );
+
+
+extern int v5dSizeofGrid( const v5dstruct *v, int time, int var );
+
+
+extern v5dstruct *v5dOpenFile( const char *filename, v5dstruct *v );
+
+
+extern int v5dCreateFile( const char *filename, v5dstruct *v );
+
+
+extern v5dstruct *v5dUpdateFile( const char *filename, v5dstruct *v );
+
+
+extern int v5dCloseFile( v5dstruct *v );
+
+
+extern int v5dReadCompressedGrid( v5dstruct *v,
+                                  int time, int var,
+                                  float *ga, float *gb,
+                                  void *compdata );
+
+
+extern int v5dReadGrid( v5dstruct *v, int time, int var, float data[] );
+
+
+extern int v5dWriteCompressedGrid( const v5dstruct *v,
+                                   int time, int var,
+                                   const float *ga, const float *gb,
+                                   const void *compdata );
+
+
+extern int v5dWriteGrid( v5dstruct *v, int time, int var, const float data[] );
+
+
+
+#endif
diff --git a/lib/vis5d/src/vis5d.h b/lib/vis5d/src/vis5d.h
new file mode 100644 (file)
index 0000000..6996f3f
--- /dev/null
@@ -0,0 +1,102 @@
+
+/* Vis5D version 5.1 */
+
+/*
+Vis5D system for visualizing five dimensional gridded data sets
+Copyright (C) 1990-1997 Bill Hibbard, Brian Paul, Dave Santek,
+and Andre Battaiola.
+
+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; either version 1, or (at your option)
+any later version.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/*
+ * This configuration file contains options which can be safely
+ * changed by the user.
+ */
+
+
+
+#ifndef VIS5D_H
+#define VIS5D_H
+
+
+/*
+ * Amount of physical RAM in megabytes:
+ * vis5d normally uses a bounded amount of memory to avoid swapping.
+ * When the limit is reached, the least-recently-viewed graphics will
+ * be deallocated.  If MBS is set to 0, however, vis5d will use ordinary
+ * malloc/free and not deallocate graphics (ok for systems with a lot
+ * of memory (>=128MB)).
+ */
+/* Default Value: 32 */
+#define MBS 128
+
+
+
+/* Default topography file: */
+#define TOPOFILE "/home/chajpmnt/chajp/ADD/data/EARTH.TOPO"
+
+
+/* Default map lines files: */
+#define WORLDFILE "/home/chajpmnt/chajp/ADD/data/OUTLSUPW"
+#define USAFILE "/home/chajpmnt/chajp/ADD/data/OUTLUSAM"
+
+
+/* Default filename of Tcl startup commands: */
+#define TCL_STARTUP_FILE "vis5d.tcl"
+
+
+/* Default directory to search for user functions: */
+#define FUNCTION_PATH "userfuncs"
+
+
+/* Default animation rate in milliseconds: */
+#define ANIMRATE 100
+
+
+/* Default scale and exponent values for logrithmic vertical coordinate system: */
+#define DEFAULT_LOG_SCALE  1012.5
+#define DEFAULT_LOG_EXP  -7.2
+
+
+#define DEFAULT_SOUNDFONTNAME "6x12"
+
+/**********************************************************************/
+/**********************************************************************/
+/***          USERS:  DON'T CHANGE ANYTHING BEYOND THIS POINT       ***/
+/**********************************************************************/
+/**********************************************************************/
+
+/*
+ * Define BIG_GFX to allow larger isosurfaces, contour slices, etc. if
+ * there's enough memory.
+#if MBS==0 || MBS>=128
+#  define BIG_GFX
+#endif
+ */
+
+#define BIG_GFX
+
+
+/*
+ * Shared by code above and below API:
+ */
+#define MAX_LABEL   1000
+#define MAX_FUNCS   100
+
+
+
+#endif
diff --git a/readme/LATEX/Makefile b/readme/LATEX/Makefile
new file mode 100644 (file)
index 0000000..a69c6f9
--- /dev/null
@@ -0,0 +1,13 @@
+tools.ps : tools.dvi
+       dvips -o $@ $<
+
+tools.dvi : tools.tex
+       latex tools.tex
+       latex tools.tex
+       latex tools.tex
+
+clean:
+       rm -f *.aux *.log *.toc *.dvi
+
+realclean: clean
+       rm -f *.ps
diff --git a/readme/LATEX/conv2dia.tex b/readme/LATEX/conv2dia.tex
new file mode 100644 (file)
index 0000000..e6596ca
--- /dev/null
@@ -0,0 +1,102 @@
+\section{Conversion of FM synchronous file to diachronic format}
+Short description is given here, readers must refer to the original documentation on the Meso-NH web site:
+``{\sc traitement graphique des fichiers synchrones produits par le mod\`ele
+mesonh}, J. Duron''. 
+
+\subsection{Synchronous and diachronic formats} \label{diachro_file}
+The Meso-NH graphic utility ({\tt diaprog}) works on FM files which are on
+diachronic format. A diachronic FM file is either
+\begin{itemize}
+\item
+a file produced during the simulation 
+which contain time series of self-documented informations
+(e.g. file with name CEXP.1.CSEG.000).
+An information is one of the following: 
+\subitem - a
+3-dimensional, 2-dimensional, 1-dimensional or 0-dimensional field (eventually
+time-averaged, or compressed in one direction): type {\sc cart}, 
+\subitem - a set of vertical profiles at points checking some criteria:
+type {\sc mask}, 
+\subitem - spectral coefficients obtained by FFT along the X or Y direction:
+type {\sc spxy},
+\subitem - pseudo-observations (ground station: type {\sc ssol};
+dropsonde: type {\sc drst}; radiosonde: type {\sc rspl};
+airborne radar: type {\sc rapl}).
+ \\
+A diachronic file can contains informations of one or several previous types
+stored at different time frequency.
+For a whole description about the diachronic file type, reader must refer
+to the original documentation on the Meso-NH web site:
+``{\sc cr\'eation et exploitation de fichiers diachroniques}, J. Duron''. 
+\end{itemize}
+or
+\begin{itemize}
+\item a `pseudo'-diachronic file resulting of the conversion of a synchronous
+file (e.g. with name CEXP.1.CSEG.00n where n$>$0).
+Recall that such a file contains all the pronostic fields of the model at one 
+instant (initial or during the simulation).
+When converted it is a 'pseudo'-diachronic file, because it contains only one 
+instant and one type of diachronic information ({\sc cart}).
+The next subsection presents the conversion tool (named \texttt{conv2dia})
+to apply to synchronous files, necessary step to use \texttt{diaprog} graphic
+tool.
+\end{itemize}
+
+\subsection{{\tt conv2dia} tool}
+The conversion tool works on files produced by
+the initialisation programs ({\sc prep\_pgd, prep\_ideal\_case,
+prep\_real\_case}), the model simulation, or the post-processing program
+({\tt\sc diag}). It allows to convert one synchronous file onto one diachronic 
+file, as well as merge several synchronous files with chronological times
+(outputs of one run, or files initialised from large-scale model)
+onto one diachronic file.
+
+With {\tt conv2dia.elim} tool, you can choose not to convert all the fields of
+the input file(s). The pronostic fields at $t-dt$ instant, or at $t$ instant,
+or any other fields can be eliminated.
+With {\tt conv2dia.select} tool, you have to indicate the fields to select
+for conversion.
+This is done to reduce the size of the output file.
+
+The output file contains informations whose type is {\sc cart} stored in arrays
+with size of {\tt (IIU*IJU*IKU), (IIU*IJU), (IIU*IKU),} or 1.
+
+
+\subsection{Example}
+
+Only the binary (\textsc{LFI}) part of the input FM files is required
+in the current directory (split the FM file with the {\tt fm2deslfi} 
+script if not).
+
+All characters typed on keyboard are saved in {\tt dirconv.elim} or 
+{\tt dirconv.select} file, it can be appended and used as input (after being 
+renamed) for the next call of the tool
+\newline (e.g.  {\tt conv2dia.elim < dirconv.elim.ex}).
+
+Below is the example of questions when {\tt conv2dia.elim} is invoked.
+
+\small
+\begin{tabular}{l}
+\\
+\\
+{\tt ENTER NUMBER OF INPUT FM FILES}  \\
+{\tt\it 2 }  \\
+{\tt ENTER FM FILE NAME}  \\
+{\tt\it CEXP.1.CSEG.001}  \\
+{\tt ENTER FM FILE NAME}  \\
+{\tt\it CEXP.1.CSEG.002}  \\
+{\tt ENTER DIACHRONIC FILE NAME}  \\
+{\tt\it CEXP.1.CSEG.1-2.dia}  \\
+{\tt DELETION OF PARAMETERS AT TIME t-dt ? (enter 1) } \\
+{\tt DELETION OF PARAMETERS AT TIME t    ? (enter 2) } \\
+{\tt NO DELETION                         ? (enter 0) } \\
+{\tt\it 2 }  \\
+{\tt Do you want to suppress others parameters ? (y/n) }\\
+{\tt\it y }  \\
+{\tt Enter their names in UPPERCASE  (1/1 line) }\\
+{\tt End by END}\\
+{\tt\it DTHCONV }  \\
+{\tt\it DRVCONV }  \\
+{\tt\it END }  \\
+\end{tabular}
+\normalsize
diff --git a/readme/LATEX/extract.tex b/readme/LATEX/extract.tex
new file mode 100644 (file)
index 0000000..6f9585e
--- /dev/null
@@ -0,0 +1,436 @@
+\section{Dealing with diachronic files}
+The Meso-NH program of post-processing ({\sc diag}) treats synchronous 
+files from initialization or simulation. 
+For a given need, one wants to work on fields stored in
+a diachronic file before exploration with {\tt diaprog} or with another
+graphical tool to possibly compare with observations.
+
+\begin{itemize}
+\item The \texttt{extractdia} tool allows to extract fields from a diachronic 
+file, on the whole domain or on a part of it, to interpole them (horizontal
+grid and/or vertical grid) and to write 
+them in some other given formats (section \ref{extractdia}). 
+This program is based on a routine of reading and a routine of writing of 
+diachronic variables: 
+they are the essential source lines to deal with a diachronic file.
+These 2 routines can be used in the user own program to match his personal
+needs. An example of such a program \texttt{exrwdia.f90} and how to compile it
+is given in section \ref{exrwdia}.
+\end{itemize}
+
+Some other tools based on the 2 routines of reading and writing
+are also available to allow easier comparisons with observation 
+data (sections \ref{mnh2obs} and \ref{obs2mnh}):
+\begin{itemize}
+\item \texttt{mesonh2obs} to get MesoNH field values at given 
+observation points (the format of output file is ASCII),
+\item \texttt{obs2mesonh} to put observation values on a
+given MesoNH grid (the output file has diachronic FM format),
+observations can then be plotted with \texttt{diaprog} tool.
+\item \texttt{compute\_r00\_pc} to catenate evolution of Lagrangian tracers 
+back to the model start (as done in {\sc diag} program, see documentation 
+``Lagrangian trajectory and air-mass tracking analyses with
+MesoNH by means of Eulerian passive tracers'', Gheusi and Stein, 2005).
+\end{itemize}
+
+The figure \ref{outils_dia} resumes the input and output of these tools.
+\begin{figure}[htb] 
+\centerline{\psfig{file=outils_dia.eps,width=10cm,angle=270} } 
+\caption{\label{outils_dia}}
+\end{figure}
+\\
+
+\underline{Remark}:
+ for all the following tools, the input diachronic files can be located
+in another directory than the one in which the tool is invoked (as
+for \texttt{diaprog}). In this case, initialise the following shell variable
+\begin{verbatim}
+export DIRLFI=directory_files_diachro
+\end{verbatim}
+
+Shell links will be automatically performed during the execution and
+will be removed by the mesonh-shell-tool \texttt{rmlink} at the execution end.
+
+
+\subsection{Extracte fields, domain, change format with
+{\tt extractdia} tool}\label{extractdia}
+
+The input file is a FM diachronic file, either a `true' diachronic one 
+(its name is ended by {\bf .000} and it contains time series of informations 
+obtained during the run of the model),
+or a `pseudo'-diachronic one (it is the result of the conversion of a 
+synchronous file, see section \ref{diachro_file}), compressed (with {\tt lfiz})
+or not.
+
+The format of the output file is chosen by the user among one of the following:
+\begin{itemize}
+\item a FM {\sc diac}hronic file, 
+\item an ASCII file with 
+{\sc l}atitude-{\sc l}ongitude-{\sc h}eight-{\sc v}alue or
+latitude-longitude-height-value,
+\item ASCII files with {\sc free} format defined by the user (one file per field),
+\item a {\sc cdl} file (converted to NetCDF format at the end of the program,
+with \texttt{ncgen} utility of NetCDF package inside the mesonh-shell-tool \texttt{tonetcdf}),
+\item a {\sc grib} file (in the future),
+\item a {\sc Vis5D} file (in the future).
+\end{itemize}
+The main program is an interactive one: 
+the name of input diachronic file, the output format, 
+the coordinates of the part of the domain,
+the name of fields to be read and written are required.
+All that is typed on keyboard is saved in {\tt dirextr.}fmt
+file, it can be appended and used as input (after renaming it) for the next call
+of the tool \\
+(e.g. {\tt mv dirextr.DIAC dirDIAC1 ; extractdia < dirDIAC1}).
+\\
+\\
+The advantages for each output format are the following:
+
+\begin{itemize}
+\item the wind direction (dd) and wind intensity (ff) could be asked.
+\item fields are eventually interpolated according output format,
+first vertically and then horizontally.
+For vertical interpolation, the user specifies the type of levels (Z or P), 
+the number of levels and their values (in m or in hPa). No vertical interpolation if the type of levels is K (model levels).
+
+For horizontal interpolation on regular grid in longitude and latitude, the program chooses the optimum values computed for the model grid. 
+
+If interpolations are required, the wind components are transformed in zonal and meridian components.
+
+These interpolations do not allow interpolation in a required cross-section, the {\sc ficval} file obtained during a {\tt diaprog} session gives this interpolation.
+\item for the {\sc diac}hronic format, the output file will be reduced in size
+since it contains only some fields on a part of the domain without any interpolations .
+It can still be plotted with {\tt diaprog}.
+\item for the {\sc ll*v}/ll*v format, the fields can be interpolated onto a 
+regular grid in longitude and latitude ({\sc lalo} option) or can remained on 
+the conformal model grid.
+({\sc llzv}/llzv option for interpolation on constant altitude levels,
+{\sc llpv}/llpv option for interpolation on constant pression levels
+{\sc llhv}/lhzv option to stay on MesoNH vertical levels).
+Three header lines give zoom, unit, variable name and temporal informations and
+are followed by four values on each line.
+\item for the {\sc cdl} format, the fields can be horizontally interpolated
+onto a regular grid in longitude and latitude ({\sc lalo} option),
+and eventually vertically on some prescribed levels 
+({\sc zcdl} option for interpolation on constant altitude levels,
+{\sc pcdl} option for interpolation on constant pression levels,
+{\sc kcdl} option to stay on MesoNH vertical levels).
+The CDL format is transformed to binary Netdcf format at the end of the program run by the mesonh-shell-tool \texttt{tonetcdf}.
+\item the {\sc free} format allows to get the interpolated values (vertical or horizontal interpolations) without any geographical locations: just values list are available after one header line.
+\ignore{
+\item for the {\sc grib} format, the fields can be horizontally interpolated
+onto a regular grid in longitude and latitude and are vertically interpolated
+on constant Z-levels or P-levels.
+}%ignore
+\end{itemize}
+
+
+\subsection{Personal modifications: \texttt{exrwdia} program}\label{exrwdia}
+The \texttt{extractdia} program uses 2 routines of reading
+(\texttt{readvar.f90}) and writing (\texttt{writevar.f90}) of MesoNH variables
+as they are stored in diachronic files (that is in 6-dimensional arrays).
+These 2 routines can be used in your own program:
+an example of such a program is \texttt{exrwdia.f90}.
+The source code contains extended comments,
+and there are some examples of computation with the extracted fields 
+(module and direction of components of wind, interpolation on some Z levels, 
+maximum of a 3D field along the vertical direction, vertical average between two
+Z levels). 
+
+The use of this method need to be familiar with the Mesonh specificities:
+ seven grids (Gal-Chen) for the storage of the variables, the U,V wind components are
+ referenced in the Mesonh grid and are different from the Uzonal and Vmeridian
+ components.
+
+\subsubsection{Routines of reading and writing}
+A diachronic file contain time series of informations that are
+self-documented (section \ref{diachro_file}). 
+The self-documentation is provided by the header of the file, which contains
+a list of pre-defined records, and each field (or information)
+is stored by several records, the number of them varies
+from 8 to 11, according to the type of the information
+({\sc cart, mask, spxy, ssol, drst, rspl} or {\sc rapl}).
+
+The subroutine \texttt{readvar.f90} reads the required field. At the first call,
+the file is opened, its header is read 
+(the dimensions of the total domain ({\sc imax, jmax, kmax}), 
+the orography...)
+and some characteristics are computed
+(the conformal coordinates, the map factor...).
+The required field is then read and available in a 6-dimensional array: 
+{\sc xvar}(i,j,k,t,n,p)\footnote{For a whole description of the diachronic file
+type, reader must refer to the original documentation on the Meso-NH web site:
+``{\sc cr\'eation et exploitation de fichiers diachroniques}, J. Duron''.}.
+
+The subroutine \texttt{writevar.f90} writes the field if the wanted output
+format is {\sc dia}chronic one.
+If it is the first call the header is written, then
+the field is stored by the same number of records than when it was read.
+
+
+The personal code can be inserted in the main program between the call of the
+two previous subroutines. For the {\sc free} format, the writing code lines
+are to be written in the main program.
+
+\subsubsection{Compilation}
+You have to 
+\begin{itemize}
+\item create a sub-directory {\tt src} to put your own source files
+\item copy {\tt\$MESONH/MAKE/tools/diachro/src/EXTRACTDIA/exrwdia.f90} to {\tt src/my\_prog.f90} and modify it
+\item initialize the shell variable {\tt ARCH} which refers to your system and the compiler used (see 
+examples as the suffix of files in {\tt \$MESONH/MAKE/conf} directory).
+\item compile with \\
+{\tt gmaketools PROG=my\_prog OBJS="my\_routine1.o my\_routine2.o" } \\ 
+(the \$MESONH/MAKE/tools/diachro/{\tt Makefile.exrwdia} version will be used).
+\end{itemize}
+
+\noindent To update the routines dependances directly inside the  Makefile:
+\begin{itemize}
+\item initialize the following shell variables:
+\begin{itemize}
+\item {\tt MNH\_LIBTOOLS} which is the directory where the reference sources
+for the libraries and tools are,
+\item {\tt ARCH} which refers to your system and the compiler used (see 
+examples as the suffix of files in {\tt \$MNH\_LIBTOOLS/conf} directory). 
+\end{itemize}
+\item copy the {\tt \$MNH\_LIBTOOLS/tools/diachro/Makefile.exrwdia} file in your working directory, 
+rename it to \texttt{Makefile},
+\item compile with {\tt gmake}
+\end{itemize}
+
+
+\subsection{Compare to observations with 
+{\tt mesonh2obs} tool \label{mnh2obs}}
+\subsubsection{Input and output}
+The \texttt{mesonh2obs} tool allows to interpolate MesoNH fields 
+at given points (such as points where observation data are available). 
+
+The input files are an ASCII file indicated the position of the points by their
+latitude and longitude coordinates as well as vertical dimension if a vertical profile is required, and one or several diachronic FM file(s) with fields to interpolate
+at previous points.
+
+Each output file, one for each input FM file, is an ASCII one with six possible
+options for lines format
+(\textsc{llhv}, llhv, \textsc{llzv}, llzv, \textsc{llpv}, llpv).
+
+In the input ASCII file, each line indicates the location of one point,
+all lines have the same format, one of the following :\\
+\begin{tabular}{l|ll}
+ lon lat & and altitudes will be asked by the {\tt mesonh2obs} program\\
+ lat lon & and altitudes will be asked by the {\tt mesonh2obs} program\\
+ lon lat altitude(m) & \\
+ lat lon altitude(m) & \\   
+\end{tabular} \\
+
+The output ASCII file contains lines with the same format, one of the 
+following according to the option: \\
+\begin{tabular}{l|ll}
+ lon lat model\_level\_altitude(m)& option \textsc{llhv} \\
+ lat lon model\_level\_altitude(m)& option llhv \\
+ lon lat altitude(m) & option \textsc{llzv}&
+ --interpolation routine \texttt{zinter.f90} for 3D fields\\
+ lat lon altitude(m) & option llzv& \hspace*{1cm} " \\
+ lon lat pression(hPa) & option \textsc{llpv} &
+ --interpolation routine \texttt{pinter.f90} for 3D fields\\
+ lat lon pression(hPa) & option llpv& \hspace*{1cm} "   (pressure variable is read in input FM file) \\
+\end{tabular} \\
+
+
+\subsubsection{Usage}
+The tool is an interactive one: the option for the lines format of the output
+file, the name of the ASCII file with the location of
+the observation points are first asked. 
+Then the name of the input diachronic files is asked in a loop, and the 
+name of the fields to interpolate in a second loop:
+\begin{verbatim}
+    mesonh2obs << eof
+format_output_file # line format of output file (LLHV/llhv/LLZV/llzv/LLPV/llpv)
+format_input_file  # LL (lon,lat)ou ll (lat,lon)
+altitude_in_input_file # O (altitude_in_m on the third colon)/N 
+if N, number_vertical_levels # number of vertical levels above 
+                             # each lat,lon points
+      list_of_these_levels   # exemple: (in metres or hPa): 500 1500
+obs_file                   # name of the Obs file 
+0                          # control prints (0/1/2/3)
+diachronic_file1           # file with fields to be interpolated (without .lfi)
+field1_of_diachronic_file1 # field to be interpolated
+field2_of_diachronic_file1
+END                        # end of extraction in diachronic_file1
+diachronic_file2           # file with fields to be interpolated (without .lfi)
+fieldi_of_diachronic_file2 # field to be interpolated
+fieldj_of_diachronic_file2
+END                        # end of extraction in diachronic_file2
+END                        # end of diachronic files list
+eof
+\end{verbatim}
+ If \texttt{field\_of\_diachronic\_file} contains 'AC' string 
+(for ACcumulated precipitation), you can substract values of the same field
+from a previous diachronic file. Then after line 
+\texttt{field('AC')\_of\_diachronic\_file}, answer the question: 
+\begin{verbatim}
+"- ACcumulated rain, do you want to make difference with a previous instant
+(o\/O\/y\/Y\/n\/N) ?"
+\end{verbatim}
+if \texttt{Y$/$O}, indicate the name of \texttt{diachronic\_file\_previous}
+(without .lfi) in a second supplementary line. 
+
+\subsubsection{Method}
+The main program retrieves first the $X$ and $Y$ conformal coordinates of each 
+observation point, then for each read field interpolates it vertically 
+if required (vertical profile field with option \textsc{llzv}, llzv, \textsc{llpv} or llpv, \textsc{llhv}, llhv),
+and finally interpolates horizontally the field and the array of the vertical
+profile.
+
+
+
+
+\subsection{Compare to observations with 
+\texttt{obs2mesonh} tool \label{obs2mnh}}
+\subsubsection{Input and output}
+The \texttt{obs2mesonh} tool allows to replace observations on a MesoNH grid.
+The output file has diachronic FM format: it can be used as input for 
+\texttt{diaprog} to plot observations in the same background as MesoNH fields.
+
+The input files are one or several ASCII file(s), each of it contains the
+values of one type of observation (one value per line, all lines have the same
+format: (date-)lon-lat-(alt\_in\_meters-)value or 
+(date-)lat-lon-(alt\_in\_meters-)value),
+and a diachronic FM file which spatial grid will be
+used to replace previous observation values.
+
+The output file is a diachronic file with the orography and the grids of the
+input diachronic one, each field corresponds to each input observation file.
+One or two fields are added for each observation field treated: N\_field\_name 
+for the number of observation averaged in each grid points and if 2D type, ALT\_field\_name for the altitudes of the observation.
+
+\subsubsection{Usage}
+The tool is an interactive one:
+\begin{verbatim}
+    obs2mesonh << eof
+file_diachronic_with_zs    # initialize MesoNH spatial and temporal grids
+0/1/2/3                 # verbosity level
+LL                      # format of obs file (LL=lon lat alt value, 
+                        #                     ll=lat lon alt value)
+file1_obs               # name of obs file (undefined value=999.0)
+name_new_field1         # name of the obs field  in output file
+unit_new_field1         # free characters string for unit
+1D/2D/3D                # profil of the  obs field 
+                        # for the 2D case, only K=1 will be initialised
+LL                      # format of obs file (LL=lon lat alt value, 
+                        #                     ll=lat lon alt value)
+file2_obs
+name_new_field2
+unit_new_field2
+1D/2D/3D
+END                     # closing of output diachronic file
+eof
+\end{verbatim}
+
+\subsubsection{Method}
+For each observation read in an input file: \\
+- the MesoNH grid point I,J containing this observation is searching, \\
+- then for observation with 3D profil, the vertical level K is searched
+(the MesoNH vertical grid (Gal-Chen) at I,J is taken into account); 
+for observation with 2D or 1D profil, the first level K=1 is attributed,\\
+- the value of the observation is stored on grid point (I,J,K). \\
+If several values are stored at the same grid point, arithmetic average of 
+values is done (when unit is $dBz$, the average is computed in $Ze$).
+If there is no values at a grid point, undefined value is put. 
+The observations whose altitude is below the altitude of the first MesoNH level are stored at level K=1, a warning message is printed in this case.
+
+The wind components are considered zonal and meridian in the observation and
+are transformed to wind components in the Mesonh grid.
+
+\subsubsection{Plotting with \texttt{diaprog}}
+For plotting observation values with \texttt{diaprog}, you have to use the
+pixel mode
+\texttt{LSPOT=T}: this option is recommended for sparse data since there is
+no interpolation of values for graphic plotting.
+For superpose with simulated field, do not forget to fix the extrema
+and interval of plotting for the 2 fields in order to compare them.
+Here is an example of directives for \texttt{diaprog} to plot observed values
+and superpose them with simulated fields:
+\begin{verbatim}
+LINVWB=T
+!
+LCOLAREA=T LISO=F 
+LSPOT=T    ! no interpolation 
+_file1_'file_obs'
+T2M
+y          ! yes to draw a black line around obs pixel
+0 0
+!
+_file2_'file_sim'
+NIMNMX=1 XDIAINT_T2M=2. XISOMIN_T2M=-8. XISOMAX_T2M=24.
+T2M_ON_    ! for superpose
+n          ! no black border
+T2M_file1_
+y          ! yes to draw a black line around obs pixel
+0 0
+quit
+\end{verbatim}
+
+
+\subsection{Catenation of Lagrangian trajectory with
+\texttt{compute\_r00\_pc} tool}
+\subsubsection{Input and output}
+The \texttt{compute\_r00\_pc} tool allows to compute advanced 
+diagnostics. 
+related to Lagrangian tracers activated during the model simulation
+(\texttt{LLG=.TRUE.} in namelist \texttt{NAM\_CONF}): it is based on the subroutine \texttt{compute\_r00} used in the DIAG program.
+See section 2.2 of documentation
+``Lagrangian trajectory and air-mass tracking analyses with
+MesoNH by means of Eulerian passive tracers'' (Gheusi and Stein, 2005).
+
+The input files are one or several diachronic FM file(s) containing Lagrangian
+tracers (\texttt{LGXM,LGYM,LGZM}) simply converted by \texttt{conv2dia} after
+simulation, or after {\sc diag} (in the latter case, only Lagrangian
+basic diagnostics were asked: \texttt{LTRAJ=.TRUE.} 
+in namelist \texttt{NAM\_DIAG} with the namelist
+\texttt{NAM\_STO\_FILE} empty, and additional diagnostic fields can be asked:
+\texttt{CISO='EV'} and \texttt{LMOIST\_E=.T.} 
+for the example of \ref{sss:compute.nam}), 
+and an ASCII file named \texttt{compute\_r00.nam} with namelist format.
+
+The output file is a diachronic file containing advanced diagnostics: initial
+ coordinates resulting from catenation process, initial values of basic 
+diagnostic fields (present in the input diachronic files) that the Lagrangian
+parcels had at initial time(s). 
+
+
+\subsubsection{Usage} \label{sss:compute.nam}
+The ASCII file \texttt{compute\_r00.nam} looks as the following:
+\begin{verbatim}
+&NAM_STO_FILE CFILES(1)='AR40_mc2_19990921.00d.Z',
+              CFILES(2)='AR40_mc2_19990920.12d.Z',
+              CFILES(3)='AR40_mc2_19990920.00d.Z',
+              CFILES(4)='AR40_mc2_19990919.12d.Z', 
+              CFILES(5)='AR40_mc2_19990919.00d.Z',
+              NSTART_SUPP(1)=3                   /
+&NAM_FIELD  CFIELD_LAG(1)='THETAE',
+            CFIELD_LAG(2)='POVOM' /
+\end{verbatim}
+The namelist \texttt{NAM\_STO\_FILE} is the same as in the file
+ \texttt{DIAG1.nam}. The namelist \texttt{NAM\_FIELD} indicates the other
+quantities for which initial values have to be computed.
+\\
+
+Then to run the tool,
+\begin{verbatim}
+#  initialise the following shell variable (optional if input file 
+#  is in the current directory):
+export DIRLFI=directory_files_diachro
+#  initialise the variable ARCH (LXNAGf95 for PC, HPf90 for HP)
+export ARCH=LXNAGf95
+#  execute 
+$MESONH/MAKE/tools/diachro/$ARCH/compute_r00_pc
+\end{verbatim}
+
+
+
+\subsubsection{Method}
+The structure of the program and the interpolation subroutine
+ (\texttt{interpxyz}) are the same as in the {\sc diag} program,
+ the subroutines of reading and writing are those for handling diachronic files
+ (\texttt{readvar} and \texttt{writevar}).
diff --git a/readme/LATEX/fic1.eps b/readme/LATEX/fic1.eps
new file mode 100644 (file)
index 0000000..958cd57
--- /dev/null
@@ -0,0 +1,1085 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 676 567 842
+%%Title: fic1
+%%CreationDate: Wed Apr  2 12:35:31 2008
+%%Creator: Tgif-4.1.45-QPL written by William Chia-Wei Cheng (bill.cheng@acm.org)
+%%ProducedBy: (unknown)
+%%Pages: 1
+%%DocumentFonts: (atend)
+%%EndComments
+%%BeginProlog
+
+/tgifdict 86 dict def
+tgifdict begin
+
+/tgifarrowtipdict 8 dict def
+tgifarrowtipdict /mtrx matrix put
+
+/TGAT % tgifarrowtip
+ { tgifarrowtipdict begin
+      /dy exch def
+      /dx exch def
+      /h exch def
+      /w exch def
+      /y exch def
+      /x exch def
+      /savematrix mtrx currentmatrix def
+      x y translate
+      dy dx atan rotate
+      0 0 moveto
+      w neg h lineto
+      w neg h neg lineto
+      savematrix setmatrix
+   end
+ } def
+
+/tgifpatdict 10 dict def
+
+/tgifpatbyte
+ { currentdict /retstr get exch
+   pat i cellsz mod get put
+ } def
+
+/tgifpatproc
+ { 0 1 widthlim {tgifpatbyte} for retstr
+   /i i 1 add def
+ } def
+
+/TGPF % tgifpatfill
+ { tgifpatdict begin
+      /h exch def
+      /w exch def
+      /lty exch def
+      /ltx exch def
+      /cellsz exch def
+      /pat exch def
+
+      /widthlim w cellsz div cvi 1 sub def
+      /retstr widthlim 1 add string def
+      /i 0 def
+
+      tgiforigctm setmatrix
+      ltx lty translate
+      w h true [1 0 0 1 0 0] {tgifpatproc} imagemask
+      ltx neg lty neg translate
+   end
+ } def
+
+/pat3 <8000000008000000> def
+/pat4 <8800000022000000> def
+/pat5 <8800220088002200> def
+/pat6 <8822882288228822> def
+/pat7 <aa55aa55aa55aa55> def
+/pat8 <77dd77dd77dd77dd> def
+/pat9 <77ffddff77ffddff> def
+/pat10 <77ffffff77ffffff> def
+/pat11 <7fffffff7fffffff> def
+/pat12 <8040200002040800> def
+/pat13 <40a00000040a0000> def
+/pat14 <ff888888ff888888> def
+/pat15 <ff808080ff080808> def
+/pat16 <f87422478f172271> def
+/pat17 <038448300c020101> def
+/pat18 <081c22c180010204> def
+/pat19 <8080413e080814e3> def
+/pat20 <8040201008040201> def
+/pat21 <8844221188442211> def
+/pat22 <77bbddee77bbddee> def
+/pat23 <c1e070381c0e0783> def
+/pat24 <7fbfdfeff7fbfdfe> def
+/pat25 <3e1f8fc7e3f1f87c> def
+/pat26 <0102040810204080> def
+/pat27 <1122448811224488> def
+/pat28 <eeddbb77eeddbb77> def
+/pat29 <83070e1c3870e0c1> def
+/pat30 <fefdfbf7efdfbf7f> def
+/pat31 <7cf8f1e3c78f1f3e> def
+
+/TGMAX
+ { exch dup 3 1 roll exch dup 3 1 roll gt { pop } { exch pop } ifelse
+ } def
+/TGMIN
+ { exch dup 3 1 roll exch dup 3 1 roll lt { pop } { exch pop } ifelse
+ } def
+/TGSW { stringwidth pop } def
+
+/bd { bind def } bind def
+
+/GS { gsave } bd
+/GR { grestore } bd
+/NP { newpath } bd
+/CP { closepath } bd
+/CHP { charpath } bd
+/CT { curveto } bd
+/L { lineto } bd
+/RL { rlineto } bd
+/M { moveto } bd
+/RM { rmoveto } bd
+/S { stroke } bd
+/F { fill } bd
+/TR { translate } bd
+/RO { rotate } bd
+/SC { scale } bd
+/MU { mul } bd
+/DI { div } bd
+/DU { dup } bd
+/NE { neg } bd
+/AD { add } bd
+/SU { sub } bd
+/PO { pop } bd
+/EX { exch } bd
+/CO { concat } bd
+/CL { clip } bd
+/EC { eoclip } bd
+/EF { eofill } bd
+/IM { image } bd
+/IMM { imagemask } bd
+/ARY { array } bd
+/SG { setgray } bd
+/RG { setrgbcolor } bd
+/SD { setdash } bd
+/W { setlinewidth } bd
+/SM { setmiterlimit } bd
+/SLC { setlinecap } bd
+/SLJ { setlinejoin } bd
+/SH { show } bd
+/FF { findfont } bd
+/MS { makefont setfont } bd
+/AR { arcto 4 {pop} repeat } bd
+/CURP { currentpoint } bd
+/FLAT { flattenpath strokepath clip newpath } bd
+/TGSM { tgiforigctm setmatrix } def
+/TGRM { savematrix setmatrix } def
+
+end
+
+%%EndProlog
+%%Page: 1 1
+
+%%PageBoundingBox: 0 676 567 842
+tgifdict begin
+/tgifsavedpage save def
+
+1 SM
+1 W
+
+0 SG
+
+72 0 MU 72 11.695 MU TR
+72 128 DI 100.000 MU 100 DI DU NE SC
+
+GS
+
+/tgiforigctm matrix currentmatrix def
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      368 16 M
+      GS
+            0 SG
+            /Courier FF [17 0 0 -17 0 0] MS
+            (prepmodel  MAINPROG=) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      160 64 M
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_PGD) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_PGD) SH
+      GR
+      0 17 RM
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_NEST_PGD) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_NEST_PGD) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      336 64 M
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_IDEAL_CASE) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_IDEAL_CASE) SH
+      GR
+      0 17 RM
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_REAL_CASE) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (PREP_REAL_CASE) SH
+      GR
+      0 17 RM
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (DIAG) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (DIAG) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      640 64 M
+      GS
+        GS
+        0
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (MODEL) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Helvetica FF [14 0 0 -14 0 0] MS
+            (MODEL) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      160 160 M
+      GS
+        GS
+        0
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (physiographic output) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (physiographic output) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      320 160 M
+      GS
+        GS
+        0
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (synchronous output) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (synchronous output) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      576 160 M
+      GS
+        GS
+        0
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (synchronous outputs) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (synchronous outputs) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      864 160 M
+      GS
+        GS
+        0
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (diachronic output) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (diachronic output) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 137 161 M 183 161 L 183 180 L 137 180 L CP 1 SG F
+   0 SG
+   NP 137 161 M 183 161 L 183 180 L 137 180 L CP EC NP
+   pat26 8 136 160 56 24 TGPF
+GR
+   GS
+      1 W
+      160 176 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (PGD.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            1.000 0.000 0.000 RG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (PGD.lfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 329 193 M 375 193 L 375 212 L 329 212 L CP 1 SG F
+   0 SG
+   NP 329 193 M 375 193 L 375 212 L 329 212 L CP EC NP
+   pat26 8 328 192 56 24 TGPF
+GR
+   GS
+      1 W
+      352 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            1.000 0.000 0.000 RG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT.lfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      272 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT.des) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT.des) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      496 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n.des) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n.des) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 577 193 M 702 193 L 702 212 L 577 212 L CP 1 SG F
+   0 SG
+   NP 577 193 M 702 193 L 702 212 L 577 212 L CP EC NP
+   pat26 8 576 192 128 24 TGPF
+GR
+   GS
+      1 W
+      640 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            1.000 0.000 0.000 RG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n.lfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      800 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000.des) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000.des) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 881 193 M 1006 193 L 1006 212 L 881 212 L CP 1 SG F
+   0 SG
+   NP 881 193 M 1006 193 L 1006 212 L 881 212 L CP EC NP
+   pat4 8 880 192 128 24 TGPF
+GR
+   GS
+      1 W
+      944 208 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0.000 0.000 1.000 RG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000.lfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      48 192 M
+      GS
+        GS
+        0
+            /Courier FF [12 0 0 -12 0 0] MS
+            (fm2deslfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Courier FF [12 0 0 -12 0 0] MS
+            (fm2deslfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      320 176 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (INIT) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      576 176 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.00n) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      864 176 M
+      GS
+        GS
+        0
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0 SG
+            /Times-Italic FF [14 0 0 -14 0 0] MS
+            (CEXP.1.CSEG.000) SH
+      GR
+   GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      336 176 M
+      16 16 atan DU cos 8.000 MU 352 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      352 192 8.000 3.000 16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      352 192 8.000 3.000 16 16 TGAT
+   CP F
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      640 176 M
+      16 16 atan DU cos 8.000 MU 656 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      656 192 8.000 3.000 16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      656 192 8.000 3.000 16 16 TGAT
+   CP F
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      928 176 M
+      16 16 atan DU cos 8.000 MU 944 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      944 192 8.000 3.000 16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      944 192 8.000 3.000 16 16 TGAT
+   CP F
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      800 176 M
+      16 -16 atan DU cos 8.000 MU 784 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      784 192 8.000 3.000 -16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      784 192 8.000 3.000 -16 16 TGAT
+   CP F
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      512 176 M
+      16 -16 atan DU cos 8.000 MU 496 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      496 192 8.000 3.000 -16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      496 192 8.000 3.000 -16 16 TGAT
+   CP F
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   NP
+      304 176 M
+      16 -16 atan DU cos 8.000 MU 288 exch SU
+      exch sin 8.000 MU 192 exch SU L
+   TGSM
+   1 W
+   S
+GR
+GS
+   TGSM
+   NP
+      288 192 8.000 3.000 -16 16 TGAT
+   1 SG CP F
+   0 SG
+   NP
+      288 192 8.000 3.000 -16 16 TGAT
+   CP F
+GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 109 273 M 483 273 L 483 292 L 109 292 L CP 1 SG F
+   0 SG
+   NP 109 273 M 483 273 L 483 292 L 109 292 L CP EC NP
+   pat26 8 104 272 384 24 TGPF
+GR
+   GS
+      1 W
+      296 288 M
+      GS
+        GS
+        0
+            /Times-Bold FF [14 0 0 -14 0 0] MS
+            (synchronuous files: PGD.lfi, INIT.lfi, CEXP.1.CSEG.00n.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            1.000 0.000 0.000 RG
+            /Times-Bold FF [14 0 0 -14 0 0] MS
+            (synchronuous files: PGD.lfi, INIT.lfi, CEXP.1.CSEG.00n.lfi) SH
+      GR
+   GR
+
+% TEXT
+NP
+0 SG
+GS
+   NP 658 273 M 894 273 L 894 292 L 658 292 L CP 1 SG F
+   0 SG
+   NP 658 273 M 894 273 L 894 292 L 658 292 L CP EC NP
+   pat4 8 656 272 240 24 TGPF
+GR
+   GS
+      1 W
+      776 288 M
+      GS
+        GS
+        0
+            /Times-Bold FF [14 0 0 -14 0 0] MS
+            (diachronic file: CEXP.1.CSEG.000.lfi) TGSW 
+        AD
+        GR
+      2 DI NE 0 RM
+            0.000 0.000 1.000 RG
+            /Times-Bold FF [14 0 0 -14 0 0] MS
+            (diachronic file: CEXP.1.CSEG.000.lfi) SH
+      GR
+   GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   [4 4] 0 SD
+   NP
+      240 32 M
+      240 152 L
+   TGSM
+   1 W
+   S
+   [] 0 SD
+GR
+
+% POLY/OPEN-SPLINE
+0 SG
+GS
+   [4 4] 0 SD
+   NP
+      416 32 M
+      416 152 L
+   TGSM
+   1 W
+   S
+   [] 0 SD
+GR
+
+% TEXT
+NP
+0 SG
+   GS
+      1 W
+      64 208 M
+      GS
+        GS
+        0
+            /Times-Roman FF [14 0 0 -14 0 0] MS
+            (\() TGSW 
+        AD
+            /Times-Roman FF [12 0 0 -12 0 0] MS
+            (on the computer where )