1

I need to mask a variable into a var.nc file using a landsea mask from mask.nc

I'm using NCO as follows:

ncks -h -A -v mask_var mask.nc var.nc
ncap2 -h -s 'where(mask_var!=1) var_to_mask= var_to_mask@_FillValue' IN.nc OUT.nc

The problem is the number of timesteps on which the variables are defined. In particular,

mask_var(t,y,x) with t=1
var_to_mask(t,y,x,) with t=12

So, the first command correctly copies mask_var for t=1; for t>1 mask_var is NaN.

Is there a way to replicate mask_var for all the other timesteps?

Thanks

ClimateUnboxed
  • 7,106
  • 3
  • 41
  • 86
Fab
  • 1,145
  • 7
  • 20
  • 40

2 Answers2

2

In NCO's ncap2, the rank of the variable in the where() condition must match the rank of the variable in the clause. I think this explains the behavior you see and I think you can solve this by first creating a mask of the same rank as the variable and then using that mask:

ncks -h -A -v mask_var mask.nc var.nc
ncap2 -h -s 'big_mask_var=0*var_to_mask+mask_var;where(big_mask_var!=1) var_to_mask= var_to_mask@_FillValue' IN.nc OUT.nc

NB: big_mask_var can be created as a RAM variable that will not appear in OUT.nc. Exercise left for the reader.

Charlie Zender
  • 5,929
  • 14
  • 19
1

I'm not very good at NCO, but I think you can also do this easily in CDO and will venture an alternative answer based on that. You didn't say clearly in your question what exactly the mask is and how you want to mask, but from the code you have I infer that

  • the mask file has a floating variable between 0 and 1
  • you only want to keep the variable values where mask=1, and set everything else to missing (rather than zero) ?

If this is the case then you could do this:

cdo setrtomiss,-999,0.999 mask.nc maskmiss.nc
cdo mul maskmiss.nc var.nc varmasked.nc

The first line sets up a mask with missing 0.999 and below, and otherwise keeping the value untouched, and the second multiplies. CDO automatically "fills" the missing timeslots by duplication if one file has one timestep only, getting around your problem. If you are worried about rounding (or your mask has values > 1) then a safer mask definition would be

cdo gec,1 mask.nc mask2.nc
cdo setctomiss,0 mask2.nc mask3.nc  

mask2 in this case contains 1 if the original was >=1, and 0 otherwise, which is then mapped to missing in the second step.

I think you can pipe the whole thing in one single command and avoid intermediate files in this way:

cdo mul -setctomiss,0 -gec,1 mask.nc var.nc varmasked.nc 

One last thing as a footnote, just in case it is of interest, it is easy to also create a land-sea mask on the fly in CDO using a built in topography dataset, as per my answer here: NetCDF: How to mask/filter out non-land values in global dataset, preferably using Python and/or NCO? This can be very useful as you sometimes don't have a mask dataset at the same resolution and it saves you remapping a coarser scale mask in accurately .

ClimateUnboxed
  • 7,106
  • 3
  • 41
  • 86