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.
still produces the error.
The type error is going away only with putting a number
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.
results in message
TypeError: can't multiply sequence by non-int of type 'float'
Shortening the line to
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