Project

General

Profile

Convert monthly .nc file so monthly files are daily

Added by Jonathan Tinsley 8 months ago

Hi,

I need to convert the data within my annual .nc files from monthly into daily, setting the daily value for each day of each month to the monthly value for that month. My data contains PET values for each month per year from 1983 to 2016.

I have tried a number of different strategies but each has not rendered the results I require.

e.g.

$ cdo inttime,1983-01-01,00:00:00,1day cru_ts4.06.pet.dat_d1983.nc cru_ts4.06.pet.dat_dailyagg_d1983.nc
cdo inttime: Processed 28800000 values from 1 variable over 12 timesteps [3.14s 68MB]

The resultant file however only contained 335 timesteps:

$ cdo sinfo cru_ts4.06.pet.dat_dailyagg_d1983.nc
File format : NetCDF
-1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID
1 : unknown Run v instant 1 1 2400000 1 F32 : -1
Grid coordinates :
1 : lonlat : points=2400000 (1500x1600)
lon : -19.975 to 54.975 by 0.05 degrees_east
lat : -39.975 to 39.975 by 0.05 degrees_north
Vertical coordinates :
1 : surface : levels=1
Time coordinate :
time : 335 steps
RefTime = 1900-01-01 00:00:00 Units = days Calendar = gregorian
YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss
1983-01-01 00:00:00 1983-01-02 00:00:00 1983-01-03 00:00:00 1983-01-04 00:00:00
1983-01-05 00:00:00 1983-01-06 00:00:00 1983-01-07 00:00:00 1983-01-08 00:00:00
1983-01-09 00:00:00 1983-01-10 00:00:00 1983-01-11 00:00:00 1983-01-12 00:00:00
1983-01-13 00:00:00 1983-01-14 00:00:00 1983-01-15 00:00:00 1983-01-16 00:00:00
1983-01-17 00:00:00 1983-01-18 00:00:00 1983-01-19 00:00:00 1983-01-20 00:00:00
1983-01-21 00:00:00 1983-01-22 00:00:00 1983-01-23 00:00:00 1983-01-24 00:00:00
1983-01-25 00:00:00 1983-01-26 00:00:00 1983-01-27 00:00:00 1983-01-28 00:00:00
1983-01-29 00:00:00 1983-01-30 00:00:00 1983-01-31 00:00:00 1983-02-01 00:00:00
1983-02-02 00:00:00 1983-02-03 00:00:00 1983-02-04 00:00:00 1983-02-05 00:00:00
1983-02-06 00:00:00 1983-02-07 00:00:00 1983-02-08 00:00:00 1983-02-09 00:00:00
1983-02-10 00:00:00 1983-02-11 00:00:00 1983-02-12 00:00:00 1983-02-13 00:00:00
1983-02-14 00:00:00 1983-02-15 00:00:00 1983-02-16 00:00:00 1983-02-17 00:00:00
1983-02-18 00:00:00 1983-02-19 00:00:00 1983-02-20 00:00:00 1983-02-21 00:00:00
1983-02-22 00:00:00 1983-02-23 00:00:00 1983-02-24 00:00:00 1983-02-25 00:00:00
1983-02-26 00:00:00 1983-02-27 00:00:00 1983-02-28 00:00:00 1983-03-01 00:00:00
................................................................................
..............
1983-10-04 00:00:00 1983-10-05 00:00:00 1983-10-06 00:00:00 1983-10-07 00:00:00
1983-10-08 00:00:00 1983-10-09 00:00:00 1983-10-10 00:00:00 1983-10-11 00:00:00
1983-10-12 00:00:00 1983-10-13 00:00:00 1983-10-14 00:00:00 1983-10-15 00:00:00
1983-10-16 00:00:00 1983-10-17 00:00:00 1983-10-18 00:00:00 1983-10-19 00:00:00
1983-10-20 00:00:00 1983-10-21 00:00:00 1983-10-22 00:00:00 1983-10-23 00:00:00
1983-10-24 00:00:00 1983-10-25 00:00:00 1983-10-26 00:00:00 1983-10-27 00:00:00
1983-10-28 00:00:00 1983-10-29 00:00:00 1983-10-30 00:00:00 1983-10-31 00:00:00
1983-11-01 00:00:00 1983-11-02 00:00:00 1983-11-03 00:00:00 1983-11-04 00:00:00
1983-11-05 00:00:00 1983-11-06 00:00:00 1983-11-07 00:00:00 1983-11-08 00:00:00
1983-11-09 00:00:00 1983-11-10 00:00:00 1983-11-11 00:00:00 1983-11-12 00:00:00
1983-11-13 00:00:00 1983-11-14 00:00:00 1983-11-15 00:00:00 1983-11-16 00:00:00
1983-11-17 00:00:00 1983-11-18 00:00:00 1983-11-19 00:00:00 1983-11-20 00:00:00
1983-11-21 00:00:00 1983-11-22 00:00:00 1983-11-23 00:00:00 1983-11-24 00:00:00
1983-11-25 00:00:00 1983-11-26 00:00:00 1983-11-27 00:00:00 1983-11-28 00:00:00
1983-11-29 00:00:00 1983-11-30 00:00:00 1983-12-01 00:00:00
cdo sinfo: Processed 1 variable over 335 timesteps [0.03s 13MB].

My attempt appears to have not produced daily values for December. Anyone able to advise what I can do please? Maybe a different strategy is required. Thanks in advance.

Best regards

Jonathan


Replies (8)

RE: Convert monthly .nc file so monthly files are daily - Added by Karin Meier-Fleischer 8 months ago

Hi Jonathan,

the operator inttime 'performs linear interpolation between timesteps'. You need to add the data for the next month to get the december daily times.

With a data set 1983-01-01 to 1984-01-01 set values of each day of a month to its value:

cdo -monadd -gtc,100000000 -inttime,1983-01-01,00:00:00,1day cru_ts4.06.pet.dat_d1983.nc cru_ts4.06.pet.dat_d1983.nc outfile.nc

RE: Convert monthly .nc file so monthly files are daily - Added by Jonathan Tinsley 8 months ago

Hi Karin,

Thank you for your help.

I completed the steps as advised, but it remains to have only processed 335 time steps instead of 366. The data for December should be the PET value for December across all days of December, and given that data is in the file, I am unsure why it is not producing daily PET values for December as it has for other months?

$ cdo -monadd -gtc,100000000 -inttime,1983-01-01,00:00:00,1day cru_ts4.06.pet.dat_d1983.nc cru_ts4.06.pet.dat_d1983.nc test.nc
cdo(1) gtc: Process started
cdo(2) inttime: Process started
cdo(2) inttime: Processed 28800000 values from 1 variable over 12 timesteps.
cdo(1) gtc: Processed 804000000 values from 1 variable over 335 timesteps.
cdo monadd: Processed 832800000 values from 2 variables over 347 timesteps [4.54s 32MB].

However, this resulted in the same problem..

$ cdo sinfo test.nc
File format : NetCDF
-1 : Institut Source T Steptype Levels Num Points Num Dtype : Parameter ID
1 : unknown Run v instant 1 1 2400000 1 F32 : -1
Grid coordinates :
1 : lonlat : points=2400000 (1500x1600)
lon : -19.975 to 54.975 by 0.05 degrees_east
lat : -39.975 to 39.975 by 0.05 degrees_north
Vertical coordinates :
1 : surface : levels=1
Time coordinate :
time : 335 steps
RefTime = 1900-01-01 00:00:00 Units = days Calendar = gregorian
YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss
1983-01-01 00:00:00 1983-01-02 00:00:00 1983-01-03 00:00:00 1983-01-04 00:00:00
1983-01-05 00:00:00 1983-01-06 00:00:00 1983-01-07 00:00:00 1983-01-08 00:00:00
1983-01-09 00:00:00 1983-01-10 00:00:00 1983-01-11 00:00:00 1983-01-12 00:00:00
1983-01-13 00:00:00 1983-01-14 00:00:00 1983-01-15 00:00:00 1983-01-16 00:00:00
1983-01-17 00:00:00 1983-01-18 00:00:00 1983-01-19 00:00:00 1983-01-20 00:00:00
1983-01-21 00:00:00 1983-01-22 00:00:00 1983-01-23 00:00:00 1983-01-24 00:00:00
1983-01-25 00:00:00 1983-01-26 00:00:00 1983-01-27 00:00:00 1983-01-28 00:00:00
1983-01-29 00:00:00 1983-01-30 00:00:00 1983-01-31 00:00:00 1983-02-01 00:00:00
1983-02-02 00:00:00 1983-02-03 00:00:00 1983-02-04 00:00:00 1983-02-05 00:00:00
1983-02-06 00:00:00 1983-02-07 00:00:00 1983-02-08 00:00:00 1983-02-09 00:00:00
1983-02-10 00:00:00 1983-02-11 00:00:00 1983-02-12 00:00:00 1983-02-13 00:00:00
1983-02-14 00:00:00 1983-02-15 00:00:00 1983-02-16 00:00:00 1983-02-17 00:00:00
1983-02-18 00:00:00 1983-02-19 00:00:00 1983-02-20 00:00:00 1983-02-21 00:00:00
1983-02-22 00:00:00 1983-02-23 00:00:00 1983-02-24 00:00:00 1983-02-25 00:00:00
1983-02-26 00:00:00 1983-02-27 00:00:00 1983-02-28 00:00:00 1983-03-01 00:00:00
................................................................................
..............
1983-10-04 00:00:00 1983-10-05 00:00:00 1983-10-06 00:00:00 1983-10-07 00:00:00
1983-10-08 00:00:00 1983-10-09 00:00:00 1983-10-10 00:00:00 1983-10-11 00:00:00
1983-10-12 00:00:00 1983-10-13 00:00:00 1983-10-14 00:00:00 1983-10-15 00:00:00
1983-10-16 00:00:00 1983-10-17 00:00:00 1983-10-18 00:00:00 1983-10-19 00:00:00
1983-10-20 00:00:00 1983-10-21 00:00:00 1983-10-22 00:00:00 1983-10-23 00:00:00
1983-10-24 00:00:00 1983-10-25 00:00:00 1983-10-26 00:00:00 1983-10-27 00:00:00
1983-10-28 00:00:00 1983-10-29 00:00:00 1983-10-30 00:00:00 1983-10-31 00:00:00
1983-11-01 00:00:00 1983-11-02 00:00:00 1983-11-03 00:00:00 1983-11-04 00:00:00
1983-11-05 00:00:00 1983-11-06 00:00:00 1983-11-07 00:00:00 1983-11-08 00:00:00
1983-11-09 00:00:00 1983-11-10 00:00:00 1983-11-11 00:00:00 1983-11-12 00:00:00
1983-11-13 00:00:00 1983-11-14 00:00:00 1983-11-15 00:00:00 1983-11-16 00:00:00
1983-11-17 00:00:00 1983-11-18 00:00:00 1983-11-19 00:00:00 1983-11-20 00:00:00
1983-11-21 00:00:00 1983-11-22 00:00:00 1983-11-23 00:00:00 1983-11-24 00:00:00
1983-11-25 00:00:00 1983-11-26 00:00:00 1983-11-27 00:00:00 1983-11-28 00:00:00
1983-11-29 00:00:00 1983-11-30 00:00:00 1983-12-01 00:00:00
cdo sinfo: Processed 1 variable over 335 timesteps [0.02s 13MB].

RE: Convert monthly .nc file so monthly files are daily - Added by Karin Meier-Fleischer 8 months ago

As I said the time steps will be generated between the first and the last timestep.

You can duplicate the December data and set the timestep for it to January 1984 and run it again.

  1. extract December
  2. set time to 1984-01-01
  3. merge the input file and the new 1984-01-01 data
cdo -O -mergetime cru_ts4.06.pet.dat_d1983.nc \
       -settaxis,1984-01-01,00:00:00,1day \
       -seltimestep,-1 cru_ts4.06.pet.dat_d1983.nc tmp.nc

And then do

cdo -monadd -gtc,100000000 -inttime,1983-01-01,00:00:00,1day tmp.nc tmp.nc outfile.nc

It generates a file containing 366 time steps.

RE: Convert monthly .nc file so monthly files are daily - Added by Jonathan Tinsley 8 months ago

Hi Karin,

Amazing, thank you for this information, it worked now! Apologies, I didn't know how to duplicate the data so that is very useful to know now.

Best regards

Jonathan

RE: Convert monthly .nc file so monthly files are daily - Added by Jonathan Tinsley 8 months ago

Hi Karin,

I tried to make a shell script for this, but I can't get it to work..

1st script

#!home/bin/In

infiles=$(ls cru_ts4.06.pet.dat_*_01.nc)

for f in $infiles \
for i in $(seq 1984 2017)
  do
  outfile="${f%.*}_temp.nc" 
   cdo -O -mergetime $f \
       -settaxis,$i-01-01,00:00:00,1day \
       -seltimestep,-1 $f $outfile

done

second shell script

#!home/bin/In

infiles=$(ls cru_ts4.06.pet.dat_*_01_temp.nc)

for f in $infiles
    do
     outfile="${f%.*}_366.nc" 
     cdo -monadd -gtc,100000000 -inttime,'$f*'-01-01,00:00:00,1day $f $f $outfile

done

Do you have any advice on what I am doing wrong?

Jonathan

RE: Convert monthly .nc file so monthly files are daily - Added by Karin Meier-Fleischer 8 months ago

About the first script: First line? The infiles variable is not needed, the \ after the first loop is wrong, and a done is missing. Btw the first loop is not needed.

Try the following (maybe you have to change the file name):

#!/usr/bin/env bash

for i in $(seq 1983 2017)
do
  f=$HOME/Downloads/cru_ts4.06.pet.dat_d${i}_01_temp.nc
  outfile="${f%.*}_temp.nc" 
  cdo -O -mergetime ${f} \
         -settaxis,${i}-01-01,00:00:00,1day \
         -seltimestep,-1 ${f} ${outfile}
done

RE: Convert monthly .nc file so monthly files are daily - Added by Jonathan Tinsley 7 months ago

Hi Karin,

Thank you for your help. I tried it and it was giving me some errors. I managed to get it to work using this code though:

#!/bin/bash

infiles=$(ls cru_ts4.06.pet.dat_*_01.nc)
for f in $infiles; do
    outfile="${f%.*}_temp.nc" 
    year=$(echo "$f" | grep -oP '\d{4}' | head -1)  # Extract the first year found in the file name
    if [ -n "$year" ]; then
        next_year=$((year + 1))
        cdo -O -mergetime "$f" \
        -settaxis,"$next_year"-01-01,00:00:00,1day \
        -seltimestep,-1 "$f" "$outfile" 
    else
        echo "Failed to extract year from filename: $f" 
    fi
done

RE: Convert monthly .nc file so monthly files are daily - Added by Jonathan Tinsley 7 months ago

And then for the second part of what I needed to do, I did this:

#!/bin/bash

infiles=$(ls cru_ts4.06.pet.dat_*_01_temp.nc)

for f in $infiles; do
    outfile="${f%.*}_366.nc" 
    # Extract the year from the filename using substring
    year=$(echo "$f" | grep -oP '\d{4}' | head -1)

    if [ -n "$year" ]; then
        # Use the extracted year to construct the start date in the correct format
        start_date="${year}-01-01" 

        cdo -monadd -gtc,100000000 -inttime,"$start_date",00:00:00,1day "$f" "$f" "$outfile" 
    else
        echo "Failed to extract year from filename: $f" 
    fi
done

# Loop to remove the additional timestep from each file
for f in $infiles; do
    outfile="${f%.*}_366.nc" 
    cdo -delete,timestep=-1 "$outfile" "${outfile%.nc}_final.nc" 
done

Maybe this will help someone else with same problem in future

    (1-8/8)