aaaaa
aaaaa

Reputation: 183

CDO - Resample netcdf files from monthly to daily timesteps

I have a netcdf file that has monthly global data from 1991 to 2000 (10 years).

Using CDO, how can I modify the netcdf from monthly to daily timesteps by repeating the monthly values each day of each month?

for eaxample,

convert from 
Month 1, value = 0.25

to 
Day 1, value = 0.25
Day 2, value = 0.25
Day 3, value = 0.25
....
Day 31, value = 0.25

convert from 
Month 2, value = 0.87

to 
Day 1, value = 0.87
Day 2, value = 0.87
Day 3, value = 0.87
....
Day 28, value = 0.87

Thanks

############## Update

my monthly netcdf has the monthly values not on the first day of each month, but in sparse order. e.g. on the 15th, 7th, 9th, etc.. however one value for each month.

Upvotes: 1

Views: 1435

Answers (4)

Jonathan Tinsley
Jonathan Tinsley

Reputation: 35

If the issue is that your monthly 'days' are variable, I would advise you to set the day of each monthly file to be constant, e.g. 01.

infiles=$(ls your_file*.nc)

for f in $infiles
do
    outfile="${f%.*}_01.nc" 
    cdo setday,1 \
        $f $outfile
done

You can then apply the code as advised by Robert Wilson

Upvotes: 0

aaaaa
aaaaa

Reputation: 183

I could not find a solution with CDO but I solved the issue with R, as follows:

library(dplyr)
library(ncdf4)
library(reshape2)

## Read ncfile
ncpath="~/my/path/"
ncname="my_monthly_ncfile" 
ncfname=paste(ncpath, ncname, ".nc", sep="")
ncin=nc_open(ncfname)
var=ncvar_get(ncin, "nc_var")

## melt ncfile
var=melt(var)
var=var[complete.cases(var), ] ## remove any NA

## split ncfile by gridpoint (lat and lon) into a list
var=split(var, list(var$lat, var$lon))
var=var[lapply(var,nrow)>0] ## remove any empty list element 

## create new list and replicate, for each gridpoint, each monthly value n=30 times
var_rep=list()
for (i in 1:length(var)) {
  var_rep[[i]]=data.frame(value=rep(var[[i]]$value, each=30))
}

Upvotes: -1

ClimateUnboxed
ClimateUnboxed

Reputation: 8107

You can use inttime which interpolates in time at the interval required, but this is not exactly what you asked for as it doesn't repeat the monthly values and your series will be smoothed by the interpolation.

If we assume your dataset starts on the 1st January at time 00:00 (you don't state in the question) then the command would be

cdo inttime,1991-01-01,00:00:00,1day in.nc out.nc

This performs a simple linear interpolation between steps.

Note: This is fine for fields like temperature and seems to be want you ask for, but readers should note that one has to be more careful with flux fields such as rainfall, where one might want to scale and/or change the units appropriately.

Upvotes: 1

Robert Wilson
Robert Wilson

Reputation: 3417

The question is perhaps ambiguously worded. Adrian Tompkins' answer is correct for interpolation. However, you are actually asking to set the value for each day of the month to that for the first day of the month. You could do this by adding a second CDO call as follows:

cdo -inttime,1991-01-01,00:00:00,1day in.nc temp.nc

cdo -monadd -gtc,100000000000000000 temp.nc in.nc out.nc

Just set the value after gtc to something much higher than anything in your data.

Upvotes: 2

Related Questions