ncmpigen(1)
πΈ ncmpigen β the CDL glow-up machine π
okay bestie, listen. <rainbow>ncmpigen</rainbow> is the manual page you're reading rn, and honestly? it's giving factory. it takes a CDL file and turns it into a netCDF file, or into C code, or into Fortran code. three looks, one icon. π
β¨ NAME β¨
ncmpigen β from a CDL file generate a netCDF file, a C program, or a Fortran program π¦
β¨ SYNOPSIS β¨
ncmpigen [-b] [-c] [-f] [-n] [-o netcdf_filename] [-v file_format]
input_file
β¨ DESCRIPTION β¨
so like. ncmpigen generates either a netCDF file, or C source code, or Fortran source code β whatever it takes to create a netCDF file. the input to ncmpigen is a description of a netCDF file, written in a little language called CDL (network Common Data form Language), which is described below. π
and here's the thing β if you don't pass any options at all when you invoke ncmpigen? it just checks the syntax of your input CDL file. that's it. it reads it, vibe checks it, and produces error messages for any violations of CDL syntax it finds. no notes, just β¨validationβ¨.
the other options are what let you actually do stuff:
- create the corresponding netCDF file ποΈ
- generate a C program that uses the netCDF C interface to create the netCDF file
- generate a Fortran program that uses the netCDF Fortran interface to create the same netCDF file
ncmpigen also slays in tandem with its companion program ncmpidump, and together they can do some simple operations on netCDF files. for example, say you wanna rename a dimension in a netCDF file: use ncmpidump to get a CDL version of the netCDF file, edit the CDL file to change the name of the dimensions, and then use ncmpigen to generate the corresponding netCDF file from the edited CDL file. team work makes the dream work fr fr π«Ά
β¨ OPTIONS β¨
-bβ create a (binary) netCDF file. if the-ooption is absent, a default file name will be constructed from the netCDF name (the one specified after thenetcdfkeyword in the input) by appending the.ncextension. and heads up bestie β οΈ β if a file already exists with the specified name, it will be overwritten. no warning, no take-backs.-cβ generate C source code that will create a netCDF file matching the netCDF specification. the C source code is written to standard output. π-fβ generate Fortran source code that will create a netCDF file matching the netCDF specification. the Fortran source code is written to standard output. π-onetcdf_file β name for the binary netCDF file created. if this option is specified, it implies the-boption. (this option is necessary because netCDF files cannot be written directly to standard output, since standard output is not seekable. it's giving main character who can't sit still π)-nβ like the-boption, except it creates a netCDF file with the obsolete.cdfextension instead of the.ncextension, in the absence of an output filename specified by the-ooption. this option is only supported for backward compatibility β it's a legacy queen, respect her, but don't build your whole personality on her π-vfile_format β file format of the output netCDF file. the value of file_format can be:1orclassicfor CDF-1 format2or64-bit-offsetis CDF-25or64-bit-variablefor CDF-5
the default (if this option is not given) is CDF-1, the classic format. β
β¨ EXAMPLES β¨
check the syntax of the CDL file foo.cdl:
ncmpigen foo.cdl
from the CDL file foo.cdl, generate an equivalent binary netCDF file named x.nc:
ncmpigen -o x.nc foo.cdl
from the CDL file foo.cdl, generate a C program containing the netCDF function invocations necessary to create an equivalent binary netCDF file named x.nc:
ncmpigen -c -o x.nc foo.cdl
β¨ USAGE β¨
π CDL Syntax Summary π
okay bestie, here's the whole vibe. Below is an example of CDL syntax β it describes a netCDF file that's got several named dimensions (lat, lon, and time), variables (Z, t, p, rh, lat, lon, time), variable attributes (units, long_name, valid_range, _FillValue), and some actual data. The CDL keywords are in boldface, iykyk. (This example is just here to show off the syntax; a real CDL file would have a way fuller set of attributes so the data is more completely self-describing.)
netcdf foo { // an example netCDF specification in CDL
dimensions:
lat = 10, lon = 5, time = unlimited ;
variables:
long lat(lat), lon(lon), time(time);
float Z(time,lat,lon), t(time,lat,lon);
double p(time,lat,lon);
long rh(time,lat,lon);
// variable attributes
lat:long_name = "latitude";
lat:units = "degrees_north";
lon:long_name = "longitude";
lon:units = "degrees_east";
time:units = "seconds since 1992-1-1 00:00:00";
Z:units = "geopotential meters";
Z:valid_range = 0., 5000.;
p:_FillValue = -9999.;
rh:_FillValue = -1;
data:
lat = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90;
lon = -140, -118, -96, -84, -52;
}
Every single CDL statement ends with a semicolon, periodt. Spaces, tabs, and newlines? Use them however you want for readability, no gatekeeping. Comments can follow // on any line. π
A CDL description is made of three optional parts: dimensions, variables, and data β each one kicking off with the keyword dimensions:, variables:, and data respectively. The variables part can hold variable declarations and attribute assignments. β¨
A netCDF dimension is what defines the shape of one or more of the multidimensional variables chillin' inside the netCDF file. A dimension's got a name and a size. At most one dimension in a netCDF file can have the unlimited size β which lowkey means a variable using that dimension can grow to literally any length (think: a record number in a file π).
A variable represents a multidimensional array of values that are all the same type. A variable's got a name, a data type, and a shape described by its list of dimensions. Each variable can also have associated attributes (more on those below) plus data values. The name, data type, and shape of a variable get specified by its declaration in the variables section of a CDL description. A variable is allowed to have the same name as a dimension; by convention that kind of variable is one-dimensional and holds the coordinates of the dimension it names. Dimensions don't need to have corresponding variables, fr fr. π¦
A netCDF attribute holds info about a netCDF variable or about the whole netCDF dataset. Attributes are how you specify stuff like units, special values, max and min valid values, scaling factors, offsets, and parameters. Attribute info is represented by single values or arrays of values. For example, "units" is an attribute represented by a character array like "celsius". An attribute's got an associated variable, a name, a data type, a length, and a value. Unlike variables β which are meant for data β attributes are meant for metadata (aka data about data, the meta of it all π
).
In CDL, an attribute is designated by a variable and attribute name, separated by :. You can also assign global attributes that aren't attached to any variable, applying to the netCDF as a whole, by putting : before the attribute name. The data type of an attribute in CDL comes from the type of the value you assign to it. The length of an attribute is the number of data values assigned to it, or the number of characters in the character string assigned to it. Multiple values get assigned to non-character attributes by separating the values with commas. All values assigned to one attribute must be the same type, no mixing. π
The names for CDL dimensions, variables, and attributes must begin with an alphabetic character or _, and the characters after that can be alphanumeric, _, or -.
The optional data section of a CDL specification is where netCDF variables can get initialized. The syntax is simple, slay: a variable name, an equals sign, and a comma-delimited list of constants (possibly separated by spaces, tabs and newlines) terminated with a semicolon. For multi-dimensional arrays, the last dimension varies fastest. So row-order, not column order, is what's used for matrices. If you supply fewer values than are needed to fill a variable, it gets extended with a type-dependent fill value β and you can override that by supplying a value for a distinguished variable attribute named _FillValue. The types of the constants don't have to match the type declared for the variable; coercions happen to convert integers to floating point, for example. And the constant _ can be used to designate the fill value for a variable. π₯
π Primitive Data Types π
char characters
byte 8-bit data
short 16-bit signed integers
long 32-bit signed integers
int (synonymous with long)
float IEEE single precision floating point (32 bits)
real (synonymous with float)
double IEEE double precision floating point (64 bits)
Aside from the added byte data type and the lack of unsigned, CDL supports the same primitive data types as C. The names of the primitive data types are reserved words in CDL, so the names of variables, dimensions, and attributes must not be type names. In declarations, type names can be written in either upper or lower case. β¨
Bytes differ from characters in that they're meant to hold a full eight bits of data, and the zero byte has no special significance the way it does for character data. ncmpigen converts byte declarations to char declarations in the output C code, and to the nonstandard BYTE declaration in output Fortran code.
Shorts can hold values between -32768 and 32767. ncmpigen converts short declarations to short declarations in the output C code, and to the nonstandard INTEGER*2 declaration in output Fortran code.
Longs can hold values between -2147483648 and 2147483647. ncmpigen converts long declarations to long declarations in the output C code, and to INTEGER declarations in output Fortran code. int and integer are accepted as synonyms for long in CDL declarations. Now that there are platforms with 64-bit representations for C longs, it might be better to use the int synonym so you avoid confusion, bestie. π
Floats can hold values between about -3.4+38 and 3.4+38. Their external representation is as 32-bit IEEE normalized single-precision floating point numbers. ncmpigen converts float declarations to float declarations in the output C code, and to REAL declarations in output Fortran code. real is accepted as a synonym for float in CDL declarations.
Doubles can hold values between about -1.7+308 and 1.7+308. Their external representation is as 64-bit IEEE standard normalized double-precision floating point numbers. ncmpigen converts double declarations to double declarations in the output C code, and to DOUBLE PRECISION declarations in output Fortran code.
π CDL Constants π
Constants assigned to attributes or variables can be any of the basic netCDF types. The syntax is similar to C syntax, except that type suffixes must be appended to shorts and floats to tell them apart from longs and doubles. π
A byte constant is represented by a single character or multiple-character escape sequence wrapped in single quotes. For example:
'a' // ASCII `a'
'\0' // a zero byte
'\n' // ASCII newline character
'\33' // ASCII escape character (33 octal)
'\x2b' // ASCII plus (2b hex)
'\377' // 377 octal = 255 decimal, non-ASCII
Character constants are enclosed in double quotes. A character array can be represented as a string enclosed in double quotes. The usual C string escape conventions are honored. For example:
"a" // ASCII `a'
"Two\nlines\n" // a 10-character string with two embedded newlines
"a bell:\007" // a string containing an ASCII bell
Heads up bestie: the netCDF character array "a" would fit in a one-element variable, since no terminating NULL character is assumed. However, a zero byte in a character array is interpreted as the end of the significant characters by the ncmpidump program, following the C convention. So a NULL byte should not be embedded in a character string unless it's at the end: use the byte data type instead for byte arrays that contain the zero byte. NetCDF and CDL have no string type, only fixed-length character arrays, which can be multi-dimensional. π
short integer constants are meant for representing 16-bit signed quantities. The form of a short constant is an integer constant with an s or S appended. If a short constant begins with 0, it's interpreted as octal β except if it begins with 0x, then it's interpreted as a hexadecimal constant. For example:
-2s // a short -2
0123s // octal
0x7ffs //hexadecimal
Long integer constants are meant for representing 32-bit signed quantities. The form of a long constant is an ordinary integer constant, though it's acceptable to append an optional l or L. If a long constant begins with 0, it's interpreted as octal β except if it begins with 0x, then it's interpreted as a hexadecimal constant. Examples of valid long constants include:
-2
1234567890L
0123i // octal
0x7ff // hexadecimal
Floating point constants of type float are appropriate for representing floating point data with about seven significant digits of precision. The form is the same as a C floating point constant with an f or F appended. For example, all of these are acceptable float constants:
-2.0f
3.14159265358979f // will be truncated to less precision
1.f
.
Floating point constants of type double are appropriate for representing floating point data with about sixteen significant digits of precision. The form of a double constant is the same as a C floating point constant. An optional d or D may be appended. For example, all of these are acceptable double constants:
-2.0
3.141592653589793
1.0e-20
1.d
π BUGS π
ok bestie, listen, nobody's perfect and neither is ncmpigen, so let's do the vibe check on what's lowkey broken π«Ά
- The programs that
ncmpigengenerates when you use the-cor-fflag store their data in variables using initialization statements β and girl, those will fail to produce compilable programs if you try to throw a large dataset at them π because the resulting statements may blow past the line length or the number of continuation statements that your compiler allows. it's giving not scalable fr fr. - The CDL syntax makes it super easy to assign what looks like an array of variable-length strings to a netCDF variable... but plot twist π those strings just get concatenated into a single array of characters, because netCDF simply cannot represent an array of variable-length strings inside one netCDF variable. it's not you, it's the format π
- NetCDF and CDL do not yet support a type corresponding to a 64-bit integer. no cap, it just doesn't exist yet π
π SEE ALSO π
go read your sisters, bestie, they ate:
π DATE π
July 1, 2026
and that's a wrap on ncmpigen(1), bestie π you're officially a CDL generator girlie now, main character energy only π this whole thing came to you straight from PnetCDF 1.15.0, printed 2026-11-02 β go forth and generate, slay, and remember: read the BUGS section before you blame yourself π¦β¨
π¦ where this page comes from
- ubuntu stonking: pnetcdf-bin 1.15.0-3build1 Β· Northwestern
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms