type error in a formula using visad.Field Impl data

Post any questions, ideas, or topics related to Jython and Python scripting.
Post Reply
User avatar
hproe
Posts: 504
Joined: Sat Nov 27, 2010 3:46 pm

type error in a formula using visad.Field Impl data

Post by hproe »

Hi -

I have started to develop a formula for near-constant-contrast adjustment of VIIRS DNB radiances. However, when trying to use variables of visad.Field Impl data type I get the following error:
Type Error: radians(): 1st arg can't be coerced to double
org.python.core.PyException

Here is a snippet of the formula that produces the error:

Code: Select all

def NCC(lunZA):
 import math as m
 gTheta=cos(m.radians(lunZA))
 return

I have searched in the web but not found useful answers, i.e. that make me understand what to do. Can give me a hint, please?
HP
User avatar
joleenf
Posts: 1123
Joined: Mon Jan 19, 2009 7:16 pm

Re: type error in a formula using visad.Field Impl data

Post by joleenf »

Hi HP,

Since the math method is coming from the jython interface, you would have to convert the flat field to an array and then evaluate each index in the array:

lunZA.getValues() # this gets an array of floats

Alternatively, I think it would be faster to use a math.pi*180 conversion. This multiplication can be applied directly to the visad.Field

gTheta=cos(lunZA*math.pi/180)

Joleen
User avatar
hproe
Posts: 504
Joined: Sat Nov 27, 2010 3:46 pm

Re: type error in a formula using visad.Field Impl data

Post by hproe »

Hi -

Thanks to Joleen, for the hints. I have decided to follow (Tommy Jasmin's methinks) code found in the VIIRS Formulas plugin. With this background I have been able to do a proof-of-concept script. For the time being, the script has to be run through a formula, because it uses metadata that cannot be accessed directly from the script (see Inquiry 2475, urgent as it refers to pixel metadata) and from the Field Selector (see Inquiry 2477, less urgent as it refers single numbers per granule that can be retrieved from netCDF tools), i.e. on the long run I prefer to run it in the background.

Anyway, in writing the code I have hit on a for-loop construct that never ends:

Code: Select all

 for i,rad in enumerate(dnbRadG):
  rad=rad/cos(lZAG[i]*pi/180)

whereas the alternative construct works:

Code: Select all

 for i in range(len(dnbRadG)):
  dnbRadG[i]=dnbRadG[i]/cos(lZAG[i]*pi/180)

dnbRadG is the swath-to-gridded DNB radiation and lZAG is swath-to-gridded lunar zenith angle. Both arrays obviously are of the same dimensions. To me the first construct looks more elegant (and maybe more efficient than the second one?).

I have staged the file NCC.jar on the SSEC server. It contains the formula plugin, the script for the formula and sample DNB file. The formula and script have been reduced to the bare minimum just showing the problem. Any idea what I do wrong? Perhaps, you also see a more efficient way to go through the pixel array, bearing in mind that the final for-loop will contain a couple of if clauses depending on lZA.

cheers, HP
User avatar
hproe
Posts: 504
Joined: Sat Nov 27, 2010 3:46 pm

Re: type error in a formula using visad.Field Impl data

Post by hproe »

Hi -

I have come around the problem of enumerate - its argument has to be of type float(). So, my for-loop looks now like:

Code: Select all

lZAG=noUnit(lZAG) # lZAG = gridded lunar Zenith Angle (as given in my formula code staged on the SSEC server)
lZAG=lZAG.getValues()
for i,ZA in enumerate(lZAG):
 ZA=1/cosDegrees(ZA) #A

This code produces the message
TypeError: cosDegrees(): 1st arg can't be coerced to visad.Data

Substituting line A with e.g.

Code: Select all

ZA=cosDegrees(56)

still produces the error.
The type error is going away only with putting a number

Code: Select all

ZA=.5

The stripped lZAG and ZA used in the loop is of type array.array. Why then still the allusion to visad?

HP
User avatar
tomw
Posts: 296
Joined: Tue Dec 23, 2008 3:40 pm

Re: type error in a formula using visad.Field Impl data

Post by tomw »

HP --

VisAD (in JPythonMethods) has two methods: cos(data) and cosDegrees(data). The "data" in both cases is a VisAD "Data" object, and the methods operate on all the "values" therein.

Therefore, "cosDegrees(.5)" would produce an error because .5 is not a VisAD Data object. If you need to compute the cosine of floats, then you must use the Python "math.cos()" method.

Code: Select all

>>> from visad import Real
>>> from visad.python.JPythonMethods import *
>>> import math
>>> math.cos(.5)
0.8775825618903728
>>> cos(.5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cos(): 1st arg can't be coerced to visad.Data
>>> cos(Real(.5))
0.8775825618903728
>>> f = field([.2, .3, .5, .7])
>>> cos(f)
FlatField
    (domain -> Generic_1_nullUnit)
0.9800665974617004, 0.9553365111351013, 0.8775825500488281, 0.7648422122001648


Hope that helps...
User avatar
hproe
Posts: 504
Joined: Sat Nov 27, 2010 3:46 pm

Re: type error in a formula using visad.Field Impl data

Post by hproe »

Hi Tom -

Thanks for the help. But also when using math.cos I still get stuck in the for-loop.

Code: Select all

ZA=math.cos(ZA*math.pi/180)
results in message
TypeError: can't multiply sequence by non-int of type 'float'
Shortening the line to

Code: Select all

ZA=math.cos(ZA)
then gives
TypeError: cos(): 1st arg can't be coerced to double
Note that lZAG and thus ZA are of type array.array.

HP
User avatar
tomw
Posts: 296
Joined: Tue Dec 23, 2008 3:40 pm

Re: type error in a formula using visad.Field Impl data

Post by tomw »

HP --

The "math.cos()" function only takes a number, not an array.

If you have a VisAD Data object, which I assume you do because you're using "getValues()", then why not just use the JPythonMethods "cos" (or "cosDegrees") methods?

Otherwise, if you are looping over the elements in the array, then you'd have to do something like "math.cos(ZA[some_index])". (I'm not at all familiar with your data, so cannot be more specific...sorry!)

tom
Post Reply