On Thu, Jan 5, 2012 at 3:29 PM, Tom Roche <tom_ro...@pobox.com> wrote:
> > How to programmatically (i.e., without no or minimal handcoding) copy > a netCDF file? (Without calling > > > system("cp whatever wherever") > > [...] > > So I'm wondering, can anyone point me to, or provide, code that copies > a netCDF file both > > * completely: all coordinate variables, all data variables and their > attributes, and all global attributes, such that > > $ diff -wB <( ncdump -h source.nc ) <( ncdump -h target.nc ) | wc -l > 0 > > * programmatically: no or minimal hand-coding of, e.g., attribute > names and values, missing-value value. > > ? If not, can this be done in principle, or are there steps that must > (at least currently) necessarily be hand-coded? > > Hi Tom, yes, this can be done in principle, although it would be a pain. Mostly because a netcdf file is a surprisingly complicated object, so asking for R script that copies one "programmatically" is actually asking quite a lot. You might think that it should be as easy as "grab THIS var ... then grab THAT var .. then write them both to the output file." But that fails, because vars have dims, and in classic netcdf files the dims are identified by name. What if one var has a lon dim with 360 entries, and the other has a lon dim with 128 entries? Putting them both into the same file will give an error. What I'd suggest is keeping focused on your goal. Since "cp file1.nc file2.nc" accomplished a complete copy of your netcdf file in a few seconds of typing, simply copying the file generally isn't the point of an R script. If I wanted to copy a var from an existing file to a new file, manipulating it along the way, I'd do something like this (untested code off the top of my head): varname = 'temperature' file_in = 'data1.nc' file_out = 'data2.nc' # Get var to copy ncid_in = open.ncdf( file1 ) var = ncid_in$var[[varname]] # Make new output dims that are copies of input dims ndims = var$ndims dim_out = list() for( idim in 1:ndims ) { dim_in = var$dim[[idim]] dim_out[[idim]] = dim.def.ncdf( dim_in$name, dim_in$units, dim_in$vals, unlim=dim_in$unlim ) } # Make output var that is copy of input var var_out = var.def.ncdf( var$name, var$units, dim_out, var$missval ) ncid_out = create.ncdf( file_out, var_out ) # Loop over timesteps to avoid running out of memory sz = var$varsize nt = sz[ndims] for( it in 1:nt ) { # Goal of following lines is to construct a 'start' array that is (1,1,...,it) and a count array # that is (nx,ny,....,1) start = array(1,ndims-1) count = sz[1:(ndims-1)] start = c(start, it) # Get just this timestep count = c(count, 1) # Get just this timestep data = get.var.ncdf( ncid_in, var, start=start, count=count ) # ... Manipulate data here ... put.var.ncdf( ncid_out, var_out, data, start=start, count=count ) sync.ncdf( ncid_out ) # always a good idea to keep your file sync'ed } close.ncdf( ncid_out ) Hope that gets you started, --Dave -- David W. Pierce Division of Climate, Atmospheric Science, and Physical Oceanography Scripps Institution of Oceanography, La Jolla, California, USA (858) 534-8276 (voice) / (858) 534-8561 (fax) dpie...@ucsd.edu [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.