Page 1 of 1

type error in a formula using visad.Field Impl data

Posted: Thu Jan 05, 2017 2:11 pm
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

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

Posted: Thu Jan 05, 2017 2:50 pm
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

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

Posted: Mon Jan 16, 2017 4:49 pm
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

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

Posted: Wed Jan 18, 2017 4:25 pm
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

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

Posted: Wed Jan 18, 2017 4:45 pm
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...

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

Posted: Sun Jan 22, 2017 4:32 pm
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

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

Posted: Sun Jan 22, 2017 4:52 pm
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