Forum Navigation
You need to log in to create posts and topics.

Python import problems

I've been having slightly odd problems importing ovito on a cluster. If I have a script as so in ~/bin as an executable:

#!/usr/bin/env python
import ovito
def main():
    print('got here')
main()

and call it in a directory, it will give the expected output. If instead I submit the script as a job to the cluster, then the script will print the expected output, but also give the following error message:

QStandardPaths: error creating runtime directory /run/user/38834 (Permission denied)

If I remove the import ovito statement, then this message disappears. Please can you advise how this problem may be arising?

Hi Christopher,

This is indeed a behavior I haven't seen before. I've tried to find out who or what is printing this warning message to the terminal. My guess is that it is the Qt library used by OVITO, which is trying to create and initialise a configuration file (or something else) somewhere on the local machine. This seems to be the corresponding code line in the Qt library being responsible:

https://github.com/qt/qtbase/blob/6c1e352803a6efbd8b14e5296434e22165b65084/src/corelib/io/qstandardpaths_unix.cpp#L130

Qt seems to rely on the XDG Base Directory specification, which specifies how to discover writable locations on a Unix/Linux machine, where programs can store their data. Perhaps the cluster your are using is not properly configured according to this standard specification, I am not sure. Looking at the Qt source code, I would think it can help to set the XDG_RUNTIME_DIR environment variable while the job is running. Note that it must point to a valid location in the filesystem (see the XDG specification):

$XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.

I suggest you talk to the people managing your computing cluster. They should know best how the machine is configured and can tell us in which filesystem locations programs are supposed to store runtime data.

-Alex

Hi Alex,

Thanks for the reply on this. I've done some more debugging, and I think I've established that it's not this that is the problem.

My code constructs a surface from selected particles, and increases the surface construction radius. As it does this, it then uses the locate_point method to test a set of coordinates at each radius, and counts how many are inside or outside. So the code is as follows:

#open a file
pipeline = import_file(f)

#select Water molecules
pipeline.modifiers.append(SelectTypeModifier(property = 'Particle Type', types = {'ETH', 'GL1'}))

#construct a surface from the water molecules
mod1 = ConstructSurfaceModifier(radius = 10,only_selected = True,smoothing_level =8)

#and append it to the pipeline
pipeline.modifiers.append(mod1)

#beyond this range of probe sphere radii, the number inside the surface diverges dramatically.
loops = np.linspace(6,15,2)

ins = np.zeros(0)
out = np.zeros(0)

print(loops)

for i in loops:
try:
mod1.radius = i

#compute the pipeline
data = pipeline.compute()

#get the surface mesh
mesh = data.surfaces['surface']

#clear the pipeline of the selected water molecules
pipeline.modifiers.append(ClearSelectionModifier())

#now select the central butanediol molecule
pipeline.modifiers.append(SelectTypeModifier(property = 'Particle Type', types = bd_types))

#recompute the pipeline
data1 = pipeline.compute()

#find the particle indices of the selected butanediol particles
sel = np.where(data1.particles.selection[:]>0)[0]

#now find the positions of the butanediol particles
BD_position = data1.particles.positions[:][sel]

a = np.array(BD_position)

inside_surface = 0
outside_surface = 0

#print(mesh, type(mesh), BD_position.shape)

#for every position of a molecule...
for j in a:

#test whether the position is inside the water surface or not.
# pos = mesh.locate_point(j)
print(i, j)

# #keep count of whether it is or not.
# if pos == -1:
# outside_surface = outside_surface + 1
# elif pos == 0:
# inside_surface = inside_surface + 1

ins = np.append(ins, inside_surface)
out = np.append(out, outside_surface)

 

(apologies if the formatting of that doesn't quite work)

 

I've had to comment out most of that final for loop (for j in a: etc) because the locate_point() method appears to be what's not working: when I try to locate any point, the method doesn't work and the script just doesn't run. This problem persists when I don't run the job in a venv, and instead run it through the ovitos environment, so it's something happening at that point.

As I say, the script executes as expected when I simply execute it in the directory with the simulation snapshots in, so I'm unsure what's happening. Is there something that doesn't make sense in my code for finding the point with respect to the surface that is likely to break it under any particular circumstance?