using ncap to modify a variable in SHELL

Help
Paul S.
2014-05-06
2014-05-08
  • Paul S.

    Paul S. - 2014-05-06

    Hi Dr. Zender and NCOers,

    I tried to modify a character variable in a bunch of netcdf files. One of them is like:
    ncdump test_in.nc
    ...
    char Times(Time, DateStrLen) ;
    Time = UNLIMITED ; // (1 currently)
    DateStrLen = 19 ;
    ...
    Times =
    "1991-01-01_00:00:00" ;

    Using
    ncap2 -s 'Times(:,0:3)=("2091")' test_in.nc test_out.nc
    ncdump test_out.nc, I got
    Times =
    "2091-01-01_00:00:00" ;

    But when I tried this in SHELL, e.g.,
    yearfuture="2091";
    ncap2 -s "Times(:,0:3)=("${yearfuture}")" test_in.nc test_out.nc
    I also tried
    ncap2 -s "Times(:,0:3)="${yearfuture}"" test_in.nc test_out.nc
    also tried
    ncap2 -s "Times(:,0:3)=${yearfuture}" test_in.nc test_out.nc

    ncdump test_out.nc, then I got:
    Times =
    "++++-01-01_00:00:00" ;

    Could you please help on this? Thanks!

     
  • Charlie Zender

    Charlie Zender - 2014-05-07

    Hello Paul,

    Getting this to work from the shell is challenging.
    As far as I can tell it show ncap2 needs a new function that
    converts numbers to formatted strings without saving those
    strings as variables in the file, e.g., int2string(1999)="1999".
    Unfortunately this functionality may be hard to implement.
    I hope Henry chimes in on this possibility.

    For a shorter term workaround, try something like this.
    Here date_rec is a record array of date strings (like yours).
    The record length is 10 and the length of the year is four,
    so ncap2 needs 40 characters to do what you want:

    year=1999199919991999199919991999199919991999
    ncap2 -O -v -s "date_rec(:,0:3)=\"$year\"" ~/nco/data/in.nc ~/foo.nc

    In other words the shell variable needs to have the correct
    number of characters (that part can also be scripted).
    Then protect the quotes ncap2 sees with backslashes and you're set.

    cz

     
  • Charlie Zender

    Charlie Zender - 2014-05-07

    zender@roulee:~$ ncks -H -C -v date_rec ~/nco/data/in.nc
    time[0]=1 char_dmn_lng26[0] date_rec[0--25]='2010-11-01T00:00:00.000000'
    time[1]=2 char_dmn_lng26[0] date_rec[26--51]='2010-11-01T01:00:00.000000'
    time[2]=3 char_dmn_lng26[0] date_rec[52--77]='2010-11-01T02:00:00.000000'
    time[3]=4 char_dmn_lng26[0] date_rec[78--103]='2010-11-01T03:00:00.000000'
    time[4]=5 char_dmn_lng26[0] date_rec[104--129]='2010-11-01T04:00:00.000000'
    time[5]=6 char_dmn_lng26[0] date_rec[130--155]='2010-11-01T05:00:00.000000'
    time[6]=7 char_dmn_lng26[0] date_rec[156--181]='2010-11-01T06:00:00.000000'
    time[7]=8 char_dmn_lng26[0] date_rec[182--207]='2010-11-01T07:00:00.000000'
    time[8]=9 char_dmn_lng26[0] date_rec[208--233]='2010-11-01T08:00:00.000000'
    time[9]=10 char_dmn_lng26[0] date_rec[234--259]='2010-11-01T09:00:00.000000'

    zender@roulee:~$ year=1999199919991999199919991999199919991999
    zender@roulee:~$ ncap2 -O -v -s "date_rec(:,0:3)=\"$year\"" ~/nco/data/in.nc ~/foo.nc
    zender@roulee:~$ ncks -H -C -v date_rec ~/foo.nc
    time[0]=1 char_dmn_lng26[0] date_rec[0--25]='1999-11-01T00:00:00.000000'
    time[1]=2 char_dmn_lng26[0] date_rec[26--51]='1999-11-01T01:00:00.000000'
    time[2]=3 char_dmn_lng26[0] date_rec[52--77]='1999-11-01T02:00:00.000000'
    time[3]=4 char_dmn_lng26[0] date_rec[78--103]='1999-11-01T03:00:00.000000'
    time[4]=5 char_dmn_lng26[0] date_rec[104--129]='1999-11-01T04:00:00.000000'
    time[5]=6 char_dmn_lng26[0] date_rec[130--155]='1999-11-01T05:00:00.000000'
    time[6]=7 char_dmn_lng26[0] date_rec[156--181]='1999-11-01T06:00:00.000000'
    time[7]=8 char_dmn_lng26[0] date_rec[182--207]='1999-11-01T07:00:00.000000'
    time[8]=9 char_dmn_lng26[0] date_rec[208--233]='1999-11-01T08:00:00.000000'
    time[9]=10 char_dmn_lng26[0] date_rec[234--259]='1999-11-01T09:00:00.000000'

     
  • Paul S.

    Paul S. - 2014-05-07

    Hi Charlie,

    Thanks for the tips. This dirty trick works for my tests.

    When the length of record is 1, by changing parenthesis to backslash, it works.

    i.e.,
    (1) ncap2 -s "Times(:,0:3)=("${yearfuture}")" test_in.nc test_out.nc
    yields
    Times =
    "++++-01-01_00:00:00" ;
    to
    (2) ncap2 -s "Times(:,0:3)=\"${yearfuture}"\" test_in.nc test_out.nc
    yields
    Times =
    "2091-01-01_00:00:00" ;

    BTW,
    (3) ncap2 -s "Times(:,0:3)=\"${yearfuture}\"" test_in.nc test_out.nc
    it (3) also yields the same result as (2)

    Thanks for your replies!

     
  • Charlie Zender

    Charlie Zender - 2014-05-07

    Henry, is there a better way to do this? e.g., is int2string() function above workable? would need to circumvent creating temporary dimensions... or could print() somehow be modified to work, e.g.,
    ncap2 -O -v -s "date_rec(:,0:3)=print($year,%4d)" ~/nco/data/in.nc ~/foo.nc

     
  • henry Butowsky

    henry Butowsky - 2014-05-08

    Hi Charlie -
    will try and write a str2long function this weekend - It will return a character attribute ?
    ..Henry

     
  • Charlie Zender

    Charlie Zender - 2014-05-08

    we need something like

    char * long2str(long foo,char *format);

    that takes a number foo and a C-format string and returns a string that can be
    used internally by ncap2 any place a string is needed, e.g., the above situation where a string of length 4 was needed for the year. Thanks!

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks