barronh / pseudonetcdf

PseudoNetCDF like NetCDF except for many scientific format backends
GNU Lesser General Public License v3.0
76 stars 35 forks source link

"unsupported operand type(s)" error #52

Closed bukim1 closed 6 years ago

bukim1 commented 6 years ago

Hi,

I was trying to execute the following line to get a derived variable and received an error as follows:

f = PNC("--expr=NOX=NO+NO2",ipath1).ifiles[0] Traceback (most recent call last): File "", line 1, in File "/data1/bkim/anaconda3/lib/python3.6/site-packages/PseudoNetCDF/pncparse.py", line 781, in PNC ifiles, outargs = pncparse(args=args, ifiles=ifiles, parser=parser, kwds) File "/data1/bkim/anaconda3/lib/python3.6/site-packages/PseudoNetCDF/pncparse.py", line 638, in pncparse out = pncprep(args) File "/data1/bkim/anaconda3/lib/python3.6/site-packages/PseudoNetCDF/pncparse.py", line 843, in pncprep fs = [pncexpr(expr, f) for f in fs] File "/data1/bkim/anaconda3/lib/python3.6/site-packages/PseudoNetCDF/pncparse.py", line 843, in fs = [pncexpr(expr, f) for f in fs] File "/data1/bkim/anaconda3/lib/python3.6/site-packages/PseudoNetCDF/core/_functions.py", line 849, in pncexpr exec(comp, None, vardict) File "none", line 1, in TypeError: unsupported operand type(s) for +: 'netCDF4._netCDF4.Variable' and 'netCDF4._netCDF4.Variable'**

I can pass this error by using "--expr=NOX=NO[:]+NO2[:]"

barronh commented 6 years ago

You're opening a NetCDF file, which is sort of a special case -- and that seems dumb, but is true.

In order to preserve the disk access, the variables are maintained as netCDF4.Variable objects instead of PseudoNetCDF.PseudoNetCDFVariable objects. At this time, that has prevented me from adding operator interfaces to the NetCDF variables.

There are several ways to solve this. You're using PNC, so I'll start there.

Using PNC

1) As you note, it will work if you simply add slices to the expression (e.g., NOX=NO[:] + NO2[:]). 2) When a NetCDF file is subset in almost anyway, the variables are changed to PseudoNetCDF. So you could force a subset to memory using any processing (e.g., '--slice=TSTEP,None,None' or '-v NO,NO2').

Using pncopen

I have moved all my work to using this model. pncopen provides access to file objects, which gives more control over the order of operations. It also has a diskless keyword that takes any file and makes an in memory copy. The in memory copy is PseudoNetCDF, so the operators work as expected.

import PseudoNetCDF as pnc
f = pnc.pncopen(ipath1, diskless=True).eval('NOX=NO+NO2')