Menu

changing string value of a variable in netcdf file

Help
2019-07-05
2023-11-14
  • Galina Stefanova

    Dear all,
    I am trying to change the value of a variable in a netcdf file using nco. The variable has a single value and it is the ensemble_member_id which is a string with length 27 characters.
    I am using the following command (1):

    ncap2 -O -s 'ensemble_member_id="HadREM3-RA11M-r001i1p01113"' INFILE OUTFILE

    This works very well.
    However, since I have 12 different IDs I would like to somehow automate this and wanted to add the RIP number which varies in the ID above as a variable, so I started testing - see below:

    RIPnumber=(r001i1p01113)
    echo $RIPnumber
    newID="HadHadREM3-RA11M-$RIPnumber"
    echo $newID

    All of this works well, but when I try command (2):

    ncap2 -O -s 'ensemble_member_id="$newID"' INFILE OUTFILE

    this does not work. I tried different combinations of expressing the variable (for example, ${newID}, but no success.

    Could anyone help me add the RIP number to the above command (2) as a variable?
    Thank you so much for your help.
    Galia

     
    • Charlie Zender

      Charlie Zender - 2019-07-05

      Try
      ncap2 -O -s ensemble_member_id=\"$newID\" INFILE OUTFILE

       
  • Galina Stefanova

    Yes, it works :)
    Thank you so much, Charlie !

    This was very very helpful!

     
  • Margarida Samso Cabre

    Dear NCO Team,

    I re-open this discussion to ask about a similar issue. In this case, the variable should have a list of 3 strings, so I tried something like this without success:

    ncap2 -O -s "basin={\"atlantic_artic_ocean\", \"indian_pacific_ocean\", \"global_ocean\"}" /msftyz_Omon_MRI-ESM2-0_ssp370_r1i1p1f1_gnz_201501-210012.nc-ts0 msftyz_Omon_MRI-ESM2-0_ssp370_r1i1p1f1_gnz_201501-210012.nc-ts02

    ~~~
    ncdump -v basin msftyz_Omon_MRI-ESM2-0_ssp370_r1i1p1f1_gnz_201501-210012.nc-ts02 | grep -A4 "basin =" basin = 3 ;
    strlen = 21 ;
    lev = 61 ;
    bnds = 2 ;
    time = UNLIMITED ; // (1 currently)

    --
    basin =
    "aig",
    "",
    "" ;
    }
    ~~~
    How could the list of 3 strings be added to basin?
    I attach the input file.
    Thank you very much in advance.
    Best regards,
    Marga

     
    • Charlie Zender

      Charlie Zender - 2022-06-16

      You just need a dimension (here lon) for the number of basins and to use the right syntax and output filetype, all documented in the manual, e.g.:

      zender@spectral:~$ ncap2 -O -4 -s 'basin[lon]={"atlantic_artic_ocean"s, "indian_pacific_ocean"s, "global_ocean"s, "fourth_basin"s}' ~/nco/data/in.nc ~/foo.nc
      zender@spectral:~$ ncks -v basin ~/foo.nc
      netcdf foo {
        dimensions:
          lon = 4 ;
      
        variables:
          string basin(lon) ;
      
          float lon(lon) ;
            lon:long_name = "Longitude (typically midpoints)" ;
            lon:units = "degrees_east" ;
      
        data:
          basin = "atlantic_artic_ocean", "indian_pacific_ocean", "global_ocean", "fourth_basin" ;
      
          lon = 0, 90, 180, 270 ;
      
      } // group /
      
       
  • Margarida Samso Cabre

    Dear Charlie,

    Thank you very much for your prompt reply. I tested the command with the dimension, like you wrote above, and it works perfectly. Thanks a lot, you saved my day!

    Best wishes,

    Marga

     
  • Dánnell Quesada

    Dear Charlie,

    Hope you do not mind me posting in this old thread but it is highly related. I need to add further string variables in an automated way, since the length of the dimension and amount of variables can change. I created a csv file with the required format (individual data between double quotes, followed by "s," , please find a small subset in the attachments), and a short script to parse them:

    ## Working but with `\'`
    csv=/path/to/extra_vars_9.csv
    
    while IFS=, read -r label values; do
        # Remove trailing "s" from label
        i=$(echo "$label" | sed 's/"s$//' | sed 's+"++g')
        echo $i
        printf -v values %s "$( echo $values | sed "s+'+'\\\''+g" )"
        printf -v str2 "%s[stationID]={%s}" "$i" "$values"
        printf -v command "ncap2 -A -4 -h -s '%s' obs.nc test.nc\n" "$str2"
        echo
        echo $command
        bash -c "$command"
        echo
    done < $csv
    

    The related "obs.nc" file is also in the attachments. The latter was obtained through quite some trial and error, but is working now except for the fact that some station names containing single quotes ' show now also the backslash needed to avoid errors. e.g . "UST'-TSIL'MA" is shown as "UST\'-TSIL\'MA", and I would like to avoid this behaviour. Do you have tips on how to solve this?

    Thanks in advance!

    Cheers,

    Dánnell

     

    Last edit: Dánnell Quesada 2023-11-13
    • Charlie Zender

      Charlie Zender - 2023-11-14

      Hi Dánnell,
      The backslash prints because that is the correct syntax to protect special characters in CDL. To avoid them, either omit special characters from your variable names (e.g.., follow the netCDF NUG standard that restricts variables names to alphanumeric characters and underscores), or create a filter that eliminates the backslash from the CDL printing.
      CZ

       
  • Dánnell Quesada

    Dear Charlie,

    Thanks for the quick reply!

    Indeed, the backslashes are seen with e.g. ncdump or ncks --cdl but when I read it in e.g. R or python it reads as intended. These special characters are not in the variable names, but in the data itself . Thanks again!

    Cheers,

    Dánnell

     

Log in to post a comment.

MongoDB Logo MongoDB