antsnc.pl
author A.M. Thurnherr <athurnherr@yahoo.com>
Sat, 24 Jul 2021 09:38:16 -0400
changeset 46 70e566505a12
parent 25 47b4a3600f5a
child 47 dde46143288c
child 48 534f2a6c7735
permissions -rw-r--r--
V7.3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     1
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     2
#                    A N T S N C . P L 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     3
#                    doc: Mon Jul 17 11:59:37 2006
25
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     4
#                    dlm: Fri Jan 15 10:17:51 2016
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     5
#                    (c) 2006 A.M. Thurnherr
25
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
     6
#                    uE-Info: 25 56 NIL 0 0 72 2 2 4 NIL ofnI
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     7
#======================================================================
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     8
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
     9
# ANTS netcdf library
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    10
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    11
# HISTORY:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    12
#	Jul 17, 2006: - created
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    13
#	Jul 21, 2006: - documented
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    14
#				  - added NC-encoding routines
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    15
#	Jul 22: 2006: - BUG: pseudo %PARAMs were written as well
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    16
#				  -	BUG: var ATTRs were not enconded correctly
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    17
#				  - added type support
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    18
#	Jul 23, 2006: - improved type magic
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    19
#	Sep  1, 2006: - BUG: removing trainling 0s had not worked
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    20
#	Sep 23, 2006: - fiddled
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    21
#	Jul 11, 2008: - adapted to new pseudo %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    22
#	Jul 16, 2008: - remove \0s from strings in NC_stringify
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    23
#	Mar 20, 2008: - added progress output to NC_stringify
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    24
#	Jul 21, 2009: - allowed for suppression of %PARAMs
25
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
    25
#	Jan 15, 2016: - BUG: %DEPS pseudo-%PARAM was encoded
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    26
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    27
# NOTES:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    28
#	- multi-valued attribs are not loaded by getInfo()
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    29
#	- spaces in NC strings are replaced by underscores
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    30
#	- data filling is disabled, because of a bug in the NetCDF library
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    31
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    32
# NetCDF Library Bug:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    33
#	The library appears to have incorrect default _FillValue types for
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    34
#	integer data types. The error appears if the "setfill" line is commented
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    35
#	out and the following command is run:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    36
#		listNC -ct dbk100.nc | NCode -o TEMP.nc time
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    37
#	NB: The error occurs when the 1st variable value is written, NOT when
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    38
#	    the first Q_time value is written. However, when all the Q_ fields
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    39
#		are ommitted, the error disappears.
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    40
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    41
use NetCDF;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    42
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    43
#----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    44
# string representation of NC types
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    45
#----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    46
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    47
sub NC_typeName($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    48
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    49
	my($tp) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    50
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    51
	return 'byte'	if ($tp == NetCDF::BYTE);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    52
	return 'char'	if ($tp == NetCDF::CHAR);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    53
	return 'short'	if ($tp == NetCDF::SHORT);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    54
	return 'long'	if ($tp == NetCDF::LONG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    55
	return 'float'	if ($tp == NetCDF::FLOAT);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    56
	return 'double' if ($tp == NetCDF::DOUBLE);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    57
	croak("$0: unknown NetCDF type #$tp\n");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    58
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    59
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    60
sub NC_type($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    61
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    62
	my($tn) = lc($_[0]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    63
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    64
	return  NetCDF::BYTE	if ($tn eq 'byte');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    65
	return  NetCDF::CHAR	if ($tn eq 'char');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    66
	return  NetCDF::SHORT	if ($tn eq 'short');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    67
	return  NetCDF::LONG	if ($tn eq 'long');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    68
	return  NetCDF::FLOAT	if ($tn eq 'float');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    69
	return  NetCDF::DOUBLE 	if ($tn eq 'double');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    70
	croak("$0: unknown NetCDF type <$tn>\n");
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    71
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    72
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    73
#--------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    74
# test whether given NC type is numeric
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    75
#--------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    76
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    77
sub NC_isNumeric($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    78
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    79
	my($tp) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    80
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    81
	return 1 if ($tp == NetCDF::BYTE);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    82
	return 1 if ($tp == NetCDF::SHORT);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    83
	return 1 if ($tp == NetCDF::LONG);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    84
	return 1 if ($tp == NetCDF::FLOAT);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    85
	return 1 if ($tp == NetCDF::DOUBLE);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    86
	return 0;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    87
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    88
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    89
#----------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    90
# test whether given NC type is character
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    91
#----------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    92
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    93
sub NC_isChar($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    94
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    95
	return $_[0] == NetCDF::CHAR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    96
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    97
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    98
#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
    99
# convert character- to string array
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   100
#-----------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   101
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   102
sub NC_stringify($@)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   103
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   104
	my($len,@chars) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   105
	my(@strings);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   106
	my($nStrings) = @chars/$len;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   107
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   108
	print(STDERR "$0: extracting $nStrings strings")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   109
		if ($nStrings > 1000);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   110
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   111
	while (@chars) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   112
		print(STDERR ".") if ($nStrings>1000 && $n++%1000 == 0);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   113
		push(@strings,pack("c$len",@chars));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   114
		$strings[$#strings] =~ s/ /_/g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   115
		$strings[$#strings] =~ s/\0//g;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   116
		splice(@chars,0,$len);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   117
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   118
	print(STDERR "\n") if ($nStrings > 1000);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   119
	return @strings;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   120
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   121
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   122
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   123
# open netcdf file and read (most) metadata into hash
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   124
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   125
#	INPUT:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   126
#		<filename>
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   127
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   128
#	OUTPUT:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   129
#		$NC{id}								netcdf id
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   130
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   131
#		@NC{attrName}[]						names of global attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   132
#		%NC{AttrType}{$aName}				types of global attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   133
#		%NC{AttrLen}{$aName}				# of elts in global attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   134
#		%NC{Attr}{$aName}					vals of scalar global attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   135
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   136
#		$NC{unlim_dimId}					dim id of unlimited dim
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   137
#		@NC{dimName}[$dimId]				dim names
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   138
#		%NC{dimID}{$dName}					dim ids
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   139
#		%NC{dimLen}{$dName}					# elts in dim
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   140
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   141
#		@NC{varName}[$varId]				var names
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   142
#		%NC{varType}{$vName}				var types
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   143
#		%NC{varId}{$vName}					var ids
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   144
#		@%NC{varDimIDs}{$vName}[]			dims of vars, e.g. u(lon,lat)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   145
#		@%NC{varAttrName}{$vName}[]			names of var attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   146
#		%%NC{varAttrType}{$vName}{$aName}	types of var attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   147
#		%%NC{varAttrLen}{$vName}{$aName}	# of elts in var attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   148
#		%%NC{varAttr}{$vName}{$aName}		vals of scalar var attrs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   149
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   150
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   151
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   152
sub NC_readMData($)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   153
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   154
	my($fn) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   155
	my(%NC);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   156
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   157
	$NC{id} = NetCDF::open($ARGV[0],NetCDF::NOWRITE);	# open
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   158
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   159
	my($nd,$nv,$nga,$udi);								# get nelts
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   160
	NetCDF::inquire($NC{id},$nd,$nv,$nga,$udi);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   161
	$NC{unlim_dimId} = $udi;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   162
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   163
	for (my($d)=0; $d<$nd; $d++) {						# dimensions
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   164
		my($dnm,$ln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   165
		NetCDF::diminq($NC{id},$d,$dnm,$ln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   166
		$NC{dimName}[$d] = $dnm;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   167
		$NC{dimId}{$dnm} = $d;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   168
		$NC{dimLen}{$dnm} = $ln;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   169
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   170
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   171
	for (my($v)=0; $v<$nv; $v++) {						# vars & var-attribs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   172
		my($vnm,$vtp,$nvd,$nva);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   173
		my(@dids) = ();
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   174
		NetCDF::varinq($NC{id},$v,$vnm,$vtp,$nvd,\@dids,$nva);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   175
		$NC{varName}[$v] = $vnm;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   176
		$NC{varId}{$vnm} = $v;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   177
		$NC{varType}{$vnm} = $vtp;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   178
		@{$NC{varDimIds}{$vnm}} = @dids[0..$nvd-1];
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   179
		
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   180
		for (my($a)=0; $a<$nva; $a++) {					# var-attribs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   181
			my($anm,$atp,$aln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   182
			NetCDF::attname($NC{id},$v,$a,$anm);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   183
			$NC{varAttrName}{$vnm}[$a] = $anm;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   184
			NetCDF::attinq($NC{id},$v,$anm,$atp,$aln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   185
			$NC{varAttrType}{$vnm}{$anm} = $atp;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   186
			$NC{varAttrLen}{$vnm}{$anm} = $aln;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   187
			if ($atp == NetCDF::BYTE || $atp == NetCDF::CHAR || $aln == 1) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   188
				my($val) = "";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   189
				NetCDF::attget($NC{id},$v,$anm,\$val);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   190
				$val =~ s{\0+$}{} if ($atp == NetCDF::CHAR);	# trailing \0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   191
				$NC{varAttr}{$vnm}{$anm} = $val;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   192
			}		
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   193
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   194
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   195
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   196
	for (my($a)=0; $a<$nga; $a++) {						#  global attribs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   197
		my($anm,$atp,$aln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   198
		NetCDF::attname($NC{id},NetCDF::GLOBAL,$a,$anm);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   199
		$NC{attrName}[$a] = $anm;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   200
		NetCDF::attinq($NC{id},NetCDF::GLOBAL,$anm,$atp,$aln);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   201
		$NC{attrType}{$anm} = $atp;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   202
		$NC{attrLen}{$anm} = $aln;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   203
		if ($atp == NetCDF::BYTE || $atp == NetCDF::CHAR || $aln == 1) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   204
			my($val) = "";
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   205
			NetCDF::attget($NC{id},NetCDF::GLOBAL,$anm,\$val);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   206
			$val =~ s{\0+$}{} if ($atp == NetCDF::CHAR);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   207
			$NC{attr}{$anm} = $val;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   208
		}	    
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   209
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   210
	
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   211
	return %NC;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   212
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   213
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   214
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   215
# create new nc file and write metadata
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   216
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   217
#	INPUT:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   218
#		<filename>
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   219
#		<abscissa>			name of unlimited dimension
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   220
#		<suppress-params>	if true, don't write %PARAMs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   221
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   222
#	OUTPUT:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   223
#		<netcdf id>
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   224
#
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   225
#	NOTES:
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   226
#		- netcdf types can be set with %<var>:NC_type to
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   227
#			byte, long, short, double
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   228
#		- string types are as in old PASCAL convention (e.g. string80)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   229
#		- default type is NetCDF::DOUBLE
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   230
#		- %<var>:NC_type are not added to ATTRIBs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   231
#----------------------------------------------------------------------
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   232
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   233
sub NC_writeMData($$$)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   234
{
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   235
	my($fn,$abscissa,$suppress_params) = @_;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   236
	my(%attrDone,@slDim,@NCtype);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   237
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   238
	my($ncId) = NetCDF::create($fn,NetCDF::CLOBBER);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   239
	NetCDF::setfill($ncId,NetCDF::NOFILL);				# NetCDF library bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   240
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   241
														# DIMENSIONS
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   242
	my($aid) = NetCDF::dimdef($ncId,$abscissa,NetCDF::UNLIMITED);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   243
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   244
	for (my($f)=0; $f<=$#antsLayout; $f++) {			# types
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   245
		my($tpa) = $antsLayout[$f] . ':NC_type';
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   246
		my($sl) = ($P{$tpa} =~ m{^string(\d+)$});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   247
		if ($sl > 0) {									# string
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   248
			$slDim[$f] = NetCDF::dimdef($ncId,"$antsLayout[$f]:strlen",$sl);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   249
			$NCtype[$f] = NetCDF::CHAR;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   250
		} elsif (defined($P{$tpa})) {					# custom
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   251
			$NCtype[$f] = NC_type($P{$tpa});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   252
		} else {										# default
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   253
			$NCtype[$f] = NetCDF::DOUBLE;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   254
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   255
#		printf(STDERR "type %s set to %s\n",$antsLayout[$f],NC_typeName($NCtype[$f]));
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   256
		undef($P{$tpa});								# do not add to ATTRIBs
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   257
    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   258
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   259
	for (my($f)=0; $f<=$#antsLayout; $f++) {			# VARIABLES
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   260
		my($vid);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   261
		if (defined($slDim[$f])) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   262
			$vid = NetCDF::vardef($ncId,$antsLayout[$f],$NCtype[$f],[$aid,$slDim[$f]]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   263
		} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   264
			$vid = NetCDF::vardef($ncId,$antsLayout[$f],$NCtype[$f],[$aid]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   265
		}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   266
		croak("$0: varid != fnr (implementation restriction)")
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   267
			unless ($vid == $f);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   268
		foreach my $anm (keys(%P)) {					# variable attributes
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   269
			next unless defined($P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   270
			my($var,$attr) = ($anm =~ m{([^:]+):(.*)});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   271
			next unless ($var eq $antsLayout[$f]);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   272
			$attrDone{$anm} = 1;						# mark
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   273
			if (numberp($P{$anm}) || lc($P{$anm}) eq nan) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   274
				NetCDF::attput($ncId,$f,$attr,NetCDF::DOUBLE,$P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   275
			} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   276
				NetCDF::attput($ncId,$f,$attr,NetCDF::CHAR,$P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   277
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   278
        }		                  
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   279
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   280
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   281
	unless ($suppress_params) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   282
		foreach my $anm (keys(%P)) {					# GLOBAL ATTRIBUTES
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   283
			next unless defined($P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   284
			next if ($anm eq 'FILENAME' || $anm eq 'DIRNAME' || # skip pseudo 
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   285
					 $anm eq 'BASENAME' || $anm eq 'EXTN' ||
25
A.M. Thurnherr <athurnherr@yahoo.com>
parents: 0
diff changeset
   286
					 $anm eq 'PATHNAME' || $anm eq 'DEPS' ||
0
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   287
					 $anm eq 'RECNO'	|| $anm eq 'LINENO');
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   288
			next if $attrDone{$anm};
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   289
			if (numberp($P{$anm}) || lc($P{$anm}) eq nan) {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   290
				NetCDF::attput($ncId,NetCDF::GLOBAL,$anm,NetCDF::DOUBLE,$P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   291
			} else {
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   292
				NetCDF::attput($ncId,NetCDF::GLOBAL,$anm,NetCDF::CHAR,$P{$anm});
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   293
			}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   294
	    }
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   295
	}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   296
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   297
	NetCDF::endef($ncId);
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   298
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   299
	return $ncId;
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   300
}
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   301
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
diff changeset
   302
1;