(filename3,filename4,unpackshort=True,
    zlib=True,complevel=6,shuffle=True,fletcher32=False,
    clobber=False,lsd_dict=None,nchunk=10,quiet=False,classic=0,
    vars=None,istart=0,istop=-1)
convert a netcdf 3 file (filename3) to a netcdf 4 file
    The default format is 'NETCDF4', but can be set
    to NETCDF4_CLASSIC if classic=1.
    If unpackshort=True, variables stored as short
    integers with a scale and offset are unpacked to floats.
    in the netcdf 4 file.  If the lsd_dict is not None, variable names
    corresponding to the keys of the dict will be truncated to the decimal place
    specified by the values of the dict.  This improves compression by
    making it 'lossy'..
    If vars is not None, only variable names in the list
    will be copied (plus all the dimension variables).
    The zlib, complevel and shuffle keywords control
    how the compression is done.
convert a netcdf 3 file (filename3) to a netcdf 4 file
    The default format is 'NETCDF4', but can be set
    to NETCDF4_CLASSIC if classic=1.
    If unpackshort=True, variables stored as short
    integers with a scale and offset are unpacked to floats.
    in the netcdf 4 file.  If the lsd_dict is not None, variable names
    corresponding to the keys of the dict will be truncated to the decimal place
    specified by the values of the dict.  This improves compression by
    making it 'lossy'..
    If vars is not None, only variable names in the list
    will be copied (plus all the dimension variables).
    The zlib, complevel and shuffle keywords control
    how the compression is done.
convert a netcdf 3 file ( filename3 ) to a netcdf 4 file The default format is NETCDF4 but can be set to NETCDF4_CLASSIC if classic = 1 . If unpackshort = True variables stored as short integers with a scale and offset are unpacked to floats . in the netcdf 4 file . If the lsd_dict is not None variable names corresponding to the keys of the dict will be truncated to the decimal place specified by the values of the dict . This improves compression by making it lossy .. If vars is not None only variable names in the list will be copied ( plus all the dimension variables ) . The zlib complevel and shuffle keywords control how the compression is done .
def _nc3tonc4(filename3,filename4,unpackshort=True,
    zlib=True,complevel=6,shuffle=True,fletcher32=False,
    clobber=False,lsd_dict=None,nchunk=10,quiet=False,classic=0,
    vars=None,istart=0,istop=-1):
    """convert a netcdf 3 file (filename3) to a netcdf 4 file
    The default format is 'NETCDF4', but can be set
    to NETCDF4_CLASSIC if classic=1.
    If unpackshort=True, variables stored as short
    integers with a scale and offset are unpacked to floats.
    in the netcdf 4 file.  If the lsd_dict is not None, variable names
    corresponding to the keys of the dict will be truncated to the decimal place
    specified by the values of the dict.  This improves compression by
    making it 'lossy'..
    If vars is not None, only variable names in the list
    will be copied (plus all the dimension variables).
    The zlib, complevel and shuffle keywords control
    how the compression is done."""

    from netCDF4 import Dataset

    ncfile3 = Dataset(filename3,'r')
    if classic:
        ncfile4 = Dataset(filename4,'w',clobber=clobber,format='NETCDF4_CLASSIC')
    else:
        ncfile4 = Dataset(filename4,'w',clobber=clobber,format='NETCDF4')
    mval = 1.e30 # missing value if unpackshort=True
    # create dimensions. Check for unlimited dim.
    unlimdimname = False
    unlimdim = None
    # create global attributes.
    if not quiet: sys.stdout.write('copying global attributes ..\n')
    #for attname in ncfile3.ncattrs():
    #    setattr(ncfile4,attname,getattr(ncfile3,attname))
    ncfile4.setncatts(ncfile3.__dict__)
    if not quiet: sys.stdout.write('copying dimensions ..\n')
    for dimname,dim in ncfile3.dimensions.items():
        if dim.isunlimited():
            unlimdimname = dimname
            unlimdim = dim
            ncfile4.createDimension(dimname,None)
            if istop == -1: istop=len(unlimdim)
        else:
            ncfile4.createDimension(dimname,len(dim))
    # create variables.
    if vars is None:
       varnames = ncfile3.variables.keys()
    else:
       # variables to copy specified
       varnames = vars
       # add dimension variables
       for dimname in ncfile3.dimensions.keys():
           if dimname in ncfile3.variables.keys() and\
              dimname not in varnames:
               varnames.append(dimname)
    for varname in varnames:
        ncvar = ncfile3.variables[varname]
        if not quiet: sys.stdout.write('copying variable %s\n' % varname)
        # quantize data?
        if lsd_dict is not None and varname in lsd_dict:
            lsd = lsd_dict[varname]
            if not quiet: sys.stdout.write('truncating to least_significant_digit = %d\n'%lsd)
        else:
            lsd = None # no quantization.
        # unpack short integers to floats?
        if unpackshort and hasattr(ncvar,'scale_factor') and hasattr(ncvar,'add_offset'):
            dounpackshort = True
            datatype = 'f4'
        else:
            dounpackshort = False
            datatype = ncvar.dtype
        # is there an unlimited dimension?
        if unlimdimname and unlimdimname in ncvar.dimensions:
            hasunlimdim = True
        else:
            hasunlimdim = False
        if dounpackshort:
            if not quiet: sys.stdout.write('unpacking short integers to floats ...\n')
            sys.stdout.write('')
        # is there missing value?
        if hasattr(ncvar, '_FillValue'):
            fillvalue3 = ncvar._FillValue
        elif hasattr(ncvar, 'missing_value'):
            fillvalue3 = ncvar.missing_value
        else:
            fillvalue3 = None
        if fillvalue3 is not None:
            fillvalue4 = fillvalue3 if not dounpackshort else mval
        else:
            fillvalue4 = None
        var = ncfile4.createVariable(varname,datatype,ncvar.dimensions, fill_value=fillvalue4, least_significant_digit=lsd,zlib=zlib,complevel=complevel,shuffle=shuffle,fletcher32=fletcher32)
        # fill variable attributes.
        attdict = ncvar.__dict__
        if '_FillValue' in attdict: del attdict['_FillValue']
        if dounpackshort and 'add_offset' in attdict:
            del attdict['add_offset']
        if dounpackshort and 'scale_factor' in attdict:
            del attdict['scale_factor']
        if dounpackshort and 'missing_value' in attdict:
            attdict['missing_value'] = fillvalue4
        var.setncatts(attdict)
        # fill variables with data.
        if hasunlimdim: # has an unlim dim, loop over unlim dim index.
            # range to copy
            if nchunk:
                start = istart; stop = istop; step = nchunk
                if step < 1: step = 1
                for n in range(start, stop, step):
                    nmax = n+nchunk
                    if nmax > istop: nmax=istop
                    var[n-istart:nmax-istart] = ncvar[n:nmax]
            else:
                var[0:len(unlimdim)] = ncvar[:]
        else: # no unlim dim or 1-d variable, just copy all data at once.
            var[:] = ncvar[:]
        ncfile4.sync() # flush data to disk
    # close files.
    ncfile3.close()
    ncfile4.close()
def _nc3tonc4 ( filename3 , filename4 , unpackshort = True , zlib = True , complevel = 6 , shuffle = True , fletcher32 = False , clobber = False , lsd_dict = None , nchunk = 10 , quiet = False , classic = 0 , vars = None , istart = 0 , istop = - 1 ) : from netCDF4 import Dataset ncfile3 = Dataset ( filename3 , 'r' ) if classic : ncfile4 = Dataset ( filename4 , 'w' , clobber = clobber , format = 'NETCDF4_CLASSIC' ) else : ncfile4 = Dataset ( filename4 , 'w' , clobber = clobber , format = 'NETCDF4' ) mval = 1.e30 # missing value if unpackshort=True # create dimensions. Check for unlimited dim. unlimdimname = False unlimdim = None # create global attributes. if not quiet : sys . stdout . write ( 'copying global attributes ..\n' ) #for attname in ncfile3.ncattrs(): #    setattr(ncfile4,attname,getattr(ncfile3,attname)) ncfile4 . setncatts ( ncfile3 . __dict__ ) if not quiet : sys . stdout . write ( 'copying dimensions ..\n' ) for dimname , dim in ncfile3 . dimensions . items ( ) : if dim . isunlimited ( ) : unlimdimname = dimname unlimdim = dim ncfile4 . createDimension ( dimname , None ) if istop == - 1 : istop = len ( unlimdim ) else : ncfile4 . createDimension ( dimname , len ( dim ) ) # create variables. if vars is None : varnames = ncfile3 . variables . keys ( ) else : # variables to copy specified varnames = vars # add dimension variables for dimname in ncfile3 . dimensions . keys ( ) : if dimname in ncfile3 . variables . keys ( ) and dimname not in varnames : varnames . append ( dimname ) for varname in varnames : ncvar = ncfile3 . variables [ varname ] if not quiet : sys . stdout . write ( 'copying variable %s\n' % varname ) # quantize data? if lsd_dict is not None and varname in lsd_dict : lsd = lsd_dict [ varname ] if not quiet : sys . stdout . write ( 'truncating to least_significant_digit = %d\n' % lsd ) else : lsd = None # no quantization. # unpack short integers to floats? if unpackshort and hasattr ( ncvar , 'scale_factor' ) and hasattr ( ncvar , 'add_offset' ) : dounpackshort = True datatype = 'f4' else : dounpackshort = False datatype = ncvar . dtype # is there an unlimited dimension? if unlimdimname and unlimdimname in ncvar . dimensions : hasunlimdim = True else : hasunlimdim = False if dounpackshort : if not quiet : sys . stdout . write ( 'unpacking short integers to floats ...\n' ) sys . stdout . write ( '' ) # is there missing value? if hasattr ( ncvar , '_FillValue' ) : fillvalue3 = ncvar . _FillValue elif hasattr ( ncvar , 'missing_value' ) : fillvalue3 = ncvar . missing_value else : fillvalue3 = None if fillvalue3 is not None : fillvalue4 = fillvalue3 if not dounpackshort else mval else : fillvalue4 = None var = ncfile4 . createVariable ( varname , datatype , ncvar . dimensions , fill_value = fillvalue4 , least_significant_digit = lsd , zlib = zlib , complevel = complevel , shuffle = shuffle , fletcher32 = fletcher32 ) # fill variable attributes. attdict = ncvar . __dict__ if '_FillValue' in attdict : del attdict [ '_FillValue' ] if dounpackshort and 'add_offset' in attdict : del attdict [ 'add_offset' ] if dounpackshort and 'scale_factor' in attdict : del attdict [ 'scale_factor' ] if dounpackshort and 'missing_value' in attdict : attdict [ 'missing_value' ] = fillvalue4 var . setncatts ( attdict ) # fill variables with data. if hasunlimdim : # has an unlim dim, loop over unlim dim index. # range to copy if nchunk : start = istart stop = istop step = nchunk if step < 1 : step = 1 for n in range ( start , stop , step ) : nmax = n + nchunk if nmax > istop : nmax = istop var [ n - istart : nmax - istart ] = ncvar [ n : nmax ] else : var [ 0 : len ( unlimdim ) ] = ncvar [ : ] else : # no unlim dim or 1-d variable, just copy all data at once. var [ : ] = ncvar [ : ] ncfile4 . sync ( ) # flush data to disk # close files. ncfile3 . close ( ) ncfile4 . close ( )