SwiftNetCDF is a library to read and write NetCDF files in Swift with type safety.
Installation
SwiftNetCDF requires the NetCDF C client library which can be installed on Mac with brew install netcdf or on Linux with sudo apt install libnetcdf-dev.
Add SwiftNetCDF as a dependency to your Package.swift
import SwiftNetCDF
let data = [Int32(0), 3, 4, 6, 12, 45, 89, ...]
var file = try NetCDF.create(path: "test.nc", overwriteExisting: true)
try file.setAttribute("TITLE", "My data set")
let dimensions = [
try file.createDimension(name: "LAT", length: 10),
try file.createDimension(name: "LON", length: 5)
]
let variable = try file.createVariable(name: "MyData", type: Int32.self, dimensions: dimensions)
try variable.write(data)
Read NetCDF files
import SwiftNetCDF
guard let file = try NetCDF.open(path: "test.nc", allowUpdate: false) else {
fatalError("File test.nc does not exist")
}
guard let title: String = try file.getAttribute("TITLE")?.read() else {
fatalError("TITLE attribute not available or not a String")
}
guard let variable = file.getVariable(name: "MyData") else {
fatalError("No variable named MyData available")
}
guard let typedVariable = variable.asType(Int32.self) else {
fatalError("MyData is not a Int32 type")
}
let data2 = try typedVariable.read(offset: [1,1], count: [2,2])
Using groups, unlimited dimensions and compression
import SwiftNetCDF
let file = try NetCDF.create(path: "test.nc", overwriteExisting: true)
// Create new group. Analog the `getGroup(name: )` function can be used for existing groups
let subGroup = try file.createGroup(name: "GROUP1")
let dimLat = try subGroup.createDimension(name: "LAT", length: 10)
let dimLon = try subGroup.createDimension(name: "LON", length: 5, isUnlimited: true)
var lats = try subGroup.createVariable(name: "LATITUDES", type: Float.self, dimensions: [dimLat])
var lons = try subGroup.createVariable(name: "LONGITUDES", type: Float.self, dimensions: [dimLon])
try lats.write((0..<10).map(Float.init))
try lons.write((0..<5).map(Float.init))
// `data` is of type `VariableGeneric<Float>`. Define functions can be accessed via `data.variable`
var data = try subGroup.createVariable(name: "DATA", type: Float.self, dimensions: [dimLat, dimLon])
// Enable compression, shuffle filter and chunking
try data.defineDeflate(enable: true, level: 6, shuffle: true)
try data.defineChunking(chunking: .chunked, chunks: [1, 5])
/// Because the latitude dimension is unlimted, we can write more than the defined size
let array = (0..<1000).map(Float.init)
try data.write(array, offset: [0, 0], count: [10, 100])
/// The check the new dimension count
XCTAssertEqual(data.dimensionsFlat, [10, 100])
// even more data at an offset
try data.write(array, offset: [0, 100], count: [10, 100])
XCTAssertEqual(data.dimensionsFlat, [10, 200])
Discover the structure of a NetCDF file
import SwiftNetCDF
guard let file = try NetCDF.open(path: "test.nc", allowUpdate: false) else {
fatalError("File test.nc does not exist")
}
/// Recursively print all groups
func printGroup(_ group: Group) {
print("Group: \(group.name)")
for d in group.getDimensions() {
print("Dimension: \(d.name) \(d.length) \(d.isUnlimited)")
}
for v in group.getVariables() {
print("Variable: \(v.name) \(v.type.asExternalDataType()!)")
for d in v.dimensions {
print("Variable dimension: \(d.name) \(d.length) \(d.isUnlimited)")
}
}
for a in try! group.getAttributes() {
print("Attribute: \(a.name) \(a.length) \(a.type.asExternalDataType()!)")
}
for subgroup in group.getGroups() {
printGroup(subgroup)
}
}
// The root entry point of a NetCDF file is also a `Group`
printGroup(file)
SwiftNetCDF
SwiftNetCDF is a library to read and write NetCDF files in Swift with type safety.
Installation
SwiftNetCDF requires the NetCDF C client library which can be installed on Mac with
brew install netcdf
or on Linux withsudo apt install libnetcdf-dev
.Add
SwiftNetCDF
as a dependency to yourPackage.swift
Usage
Output:
Features
Float
,Double
,String
,Int8
,Int16
,Int32
,Int64
,Int
,UInt16
,UInt32
,UInt64
andUInt
nil
for missing files, variables, attributes or data-type mismatchLimitations
Quick function reference
SwiftNetCDF uses a simple data structures to organise access to NetCDF functions. The most important once are listed below.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
License
MIT