I'm trying to plot netCDF data using cartopy + matplotlib (contourf) call, however on some occasions the data generate invalid polygon instances through contourf and the following error is thrown (Sample), followed by other exceptions:
TopologyException: side location conflict at -83.68749999996696 36.937499999989356
When running the code using contour (not contourf), the plot works, and I can see the invalid geometry in the contours. I am able to address this issue in the contourf call by NAN-ing the value of the point at the location of the side-location conflict.
aLatName = "PRISM_Latitude"
aLonName = "PRISM_Longitude"
tLat = 36.937499999989356
tLon = -83.68749999996696
aLat = np.abs(array[aLatName] - tLat)
aLon = np.abs(array[aLonName] - tLon)
c = np.maximum(aLon, aLat)
([xloc], [yloc]) = np.where(c == np.min(c))
array["data"][yloc, xloc] = np.nan
I'm wondering if there is a way to capture the coordinates of the side location conflict in a try-except block so I can then try the nan approach to fix the issue.
5/30 Edit: I did some rabbit hole digging through the call stack to find out more information and it seems like the error message shown above is not a python exception being thrown but an exception being thrown in C++ and then passed along through the python interpreter, specifically the GEOS library (https://github.com/libgeos/geos/blob/70b1662e9b8f5118f9eef26529e9eeb9eb466544/src/geomgraph/EdgeEndStar.cpp#L312). From what I know about C++ / Python exceptions, I cannot directly "catch" this exception in python unless it exists as a python object already so it looks like this is a dead end, but perhaps this may provide some information to others who may be stuck with a similar problem.
Related
I want to make it so that my program will stop running and print object is out of bounds if an object goes say into the negative z part of the plane in blender.
the objects name is Cube.031. I will sudo code what I want to do I just am not sure about sure how to do the syntax for it.
if(Cube.031.zLocation < 0)
print(object is out of bounds)
end
If you know some programming, learning python won't take long.
For the blender specific info, almost everything is accessed through the bpy module, the API reference is online.
You can refer to an object by name in bpy.data.objects[]. There are also other lists available, like bpy.context.selected_objects[] and bpy.context.visible_objects[].
An objects location is an array of three values (x,y,z), you can either access the z location as location.z or location[2].
import bpy
obj = bpy.data.objects['Cube.031']
if obj.location.z < 0:
print('object is out of bounds')
If you wanted to go through all selected objects
for obj in bpy.context.selected_objects:
if obj.location.z < 0:
print('object {} is out of bounds'.format(obj.name))
Note that v2.80 is due for release soon and has some changes to the API, if you are just starting with blender you may want to start with 2.80. You will also find blender.stackexchange a better place to ask for blender specific help.
This question already has answers here:
What causes a Python segmentation fault?
(8 answers)
Closed 3 years ago.
I'm fairly new to Python and I am having real trouble because I run into it this Segmentation fault: 11 error.
Here is a simple code example that produces this error every time:
import grequests
class Url(object):
pass
a = Url()
a.url = 'http://www.heroku.com'
a.result = 0
b = Url()
b.url = 'http://www.google.com'
b.result = 0
c = Url()
c.url = 'http://www.wordpress.com'
c.result = 0
urls = [a, b, c]
rs = (grequests.get(u.url) for i, u in enumerate(urls))
grequests.map(rs)
What is absolutely bizarre is that if I replace the urls = ... line with this:
urls = [a, b]
Then I get no error, and the script runs fine.
If I change that to just
urls = [c]
Then I also get no error, and the script runs fine.
If I change c.url = ... to
c.url = "http://yahoo.com"
And revert urls = ... back to
urls = [a, b, c]
Then I do get the segmentation fault: 11 error.
Being a memory issue sounds like a possibility though I'm not sure how to fix it.
I've been stuck on this for a number of days, so any help, no matter how small, is greatly appreciated.
For reference, I'm using macOS High Sierra (10.13.5) and installed Python 3.7.0 using Brew.
Segmentation fault (violation) is caused by an invalid memory reference. Trying to access an address that should not be accessible for current process (could also be buffer overrun or entirely bogus or uninitialized pointer). Usually it would be indicative of a bug in the underlying code or a problem during binary build (linking).
This problem lies not in your Python script, even though you may be able to trigger it by modifying your python code. Even if you for instance exhausted buffers used in a module or by the interpreter itself, it should still handle that situation gracefully.
Given your script, either gevent (dependency of grequests) or your Python (and/or bits of its standard library) are likely places where a segfault could have occurred (or a library is being used that causes it). Perhaps try rebuilding them? Where there any substantial changes around them on your system since the time you've built them? Perhaps they are trying to run against libraries other than they've been originally built against?
You can also allow your system to dump cores (I presume MacOS being essentially BSD can do that) and inspect (load it into a debugger such as gdb) the coredump to see what exactly crashed and what was going on at the time.
I am working with Baxter robot and what I am trying to do is get the position of an object using augmented reality markers and move the hand to that position in order to grasp it.
I am using the ar_tools package to get the position/orientation of the object, but that with respect to the head_camera which I am using. The last couple of days I've been experimenting with how to change that reference frame (head_camera) to the base frame as this frame is used by moveit to make the plans. I have tried to set the frame_id of the header of the message I receive from the ar_tools manually to 'base':
pose_target.header.frame_id = 'base'
but the position and orientation I am getting are still WRT the head_camera. I also tried to do:
self.tl.lookupTransform("/base", "/head_camera", self.t)
where self.t = self.tl.getLatestCommonTime("/head_camera", "/base"), but I was getting an extrapolation error. It was something like
the transformation requires to extrapolate in the past
(I can't really remember now and I'm not in the lab.) Then I thought I might need to run the lookupTransform from the head_cam to head, from head to torso and from torso to Baxter's base.
Could someone guide me on how to change the frame of the marker of the ar_tools from head_camera to base?
Also, for the extrapolation error, is there a way to do this in a static way?
There is a slightly more straightforwards way to do this, presuming you're reviving a PoseStamped message from ar_tools:
on_received_pose(pose):
'''
Handler for your poses from ar_tools
'''
if self.tl.waitForTransform(pose.header.frame_id, "/base", pose.header.stamp, rospy.Duration(0.1)): # this line prevents your extrapolation error, it waits up to 0.1 seconds for the transform to become valid
transd_pose = self.tl.transformPose("/base",pose)
# do whatever with the transformed pose here
else:
rospy.logwarn('Couldn\'t Transform from "{}" to "/base" before timeout. Are you updating TF tree sufficiently?'.format(pose.header.frame_id))
You're getting that extrapolation error likely because the transform network wasn't fully formed at the time you got your first message; tf refuses to extrapolate, it will only interpolate, so if you haven't received at least one transform message for every frame both before and after (or exactly at) the timestamp you're trying to transform to, it will throw an exception. That added if statement checks to see if it can actually perform the transform before trying to do so. You could of course also just surround the transformPose() call in a try/catch block instead, but I feel that for tf this makes it more explicit what you're trying to do.
In general, check out the simple ROS tf Python Tutorial for more examples/modes of operation.
I'm trying to find the distances between residues of a protein in pymol using a python script, which calls the pymol command cmd.get_distance. However, sometimes there are multiple atom assignments, which causes an error:
GetDistance-Error: Selection 2 doesn't contain a single atom/vertex.
I want to skip over sites that have this problem so I'm trying to use try/pass:
try:
cmd.get_distance(atom2)
except GetDistance-Error:
pass
However, it tells me that there is no such error message:
NameError: global name 'GetDistance' is not defined.
How do I tell it to pass this error? isn't GetDistance-Error the error?
I stumbled over the same issue. I want to catch the error from pymols cmd.get_distance. In my case, one (or both) of the selections does not contain an atom at all (instead of 2).
This answer will not clarify handling error in pymol scripting but resolve the issue itself.
So instead of catching the error, you could check before if there is exactly 1 atom in your selection.
Erroneous code:
PyMOL>dist = cmd.get_distance("///A/44/CA","///A/60/CA")
GetDistance-Error: Selection 1 doesn't contain a single atom/vertex.
Optimized code:
PyMOL>p1 = cmd.select("p1","///A/44/CA")
PyMOL>p2 = cmd.select("p2","///A/60/CA")
PyMOL>dist = "N/A"
PyMOL>if p1 == 1 and p2 == 1: dist = cmd.get_distance("p1","p2")
So instead of catching the error, you check the requirements (one atom per selection) for the get_distance command. If you run a continuous code, the dist = "N/A" is needed, otherwise you will falsely get the last assignment of the distance.
Alright, so a couple days ago I decided to try and write a primitive wrapper for the PARI library. Ever since then I've been playing with ctypes library in loading the dll and accessing the functions contained using code similar to the following:
from ctypes import *
libcyg=CDLL("<path/cygwin1.dll") #It needs cygwin to be loaded. Not sure why.
pari=CDLL("<path>/libpari-gmp-2.4.dll")
print pari.fibo #fibonacci function
#prints something like "<_FuncPtr object at 0x00BA5828>"
So the functions are there and they can potentially be accessed, but I always receive an access violation no matter what I try. For example:
pari.fibo(5) #access violation
pari.fibo(c_int(5)) #access violation
pari.fibo.argtypes = [c_long] #setting arguments manually
pari.fibo.restype = long #set the return type
pari.fibo(byref(c_int(5))) #access violation reading 0x04 consistently
and any variation on that, including setting argtypes to receive pointers.
The Pari .dll is written in C and the fibonacci function's syntax within the library is GEN fibo(long x).
Could it be the return type that's causing these errors, as it is not a standard int or long but a GEN type, which is unique to the PARI library? Any help would be appreciated. If anyone is able to successfully load the library and use ANY function from within python, please tell; I've been at this for hours now.
EDIT: Seems as though I was simply forgetting to initialize the library. After a quick pari.pari_init(4000000,500000) it stopped erroring. Now my problem lies in the in the fact that it returns a GEN object; which is fine, but whenever I try to reference the address to which it points, it's always 33554435, which I presume is still an address. I'm trying further commands and I'll update if I succeed in getting the correct value of something.
You have two problems here, one give fibo the correct return type and two convert the GEN return type to the value you are looking for.
Poking around the source code a bit, you'll find that GEN is defined as a pointer to a long. Also, at looks like the library provides some converting/printing GENs. I focused in on GENtostr since it would probably be safer for all the pari functions.
import cytpes
pari = ctypes.CDLL("./libpari.so.2.3.5") #I did this under linux
pari.fibo.restype = ctypes.POINTER(ctypes.c_long)
pari.GENtostr.restype = ctypes.POINTER(ctypes.c_char)
pari.pari_init(4000000,500000)
x = pari.fibo(100)
y = pari.GENtostr(x)
ctypes.string_at(y)
Results in:
'354224848179261915075'