Nextflow - Channel.watchPath() method - python

I am trying to use nextflow to gain some concurrency from my python scripts so some of my dataflow doesn't use the traditional nextflow ideals.
In my first process I create files by invoking a python script, in my second process I want to use those files created
I created a new channel that watches for the path where the files are created but nothing seems to happen. I tested with the .fromPath method and my process is successful, so I am not sure whats going wrong?
mutFiles = Channel.watchPath(launchDir + '/output/mutFiles/*.mutfile')
process structurePrediction{
input:
file mutFiles
output:
stdout results
"""
test.py ${mutFiles}
"""
}

Related

Python logging doesn't work when script is called from another program

I have a python script that I use with LibreOffice Calc to do some more advanced macros. I need to debug this script and I'm trying to use logging for this. Logging works fine when the script is called from the command line, but it doesn't work at all when the script is called by LibreOffice.
Here is my logging test code:
import logging
logging.basicConfig(filename='test.log', level=logging.INFO)
logging.warning('test')
As requested, here is the LibreOffice Basic script that calls the Python script (this was mostly just a copy/paste from a guide on how to call Python scripts from LO):
function cev(a as String) as double
Dim scriptPro As Object, myScript As Object
Dim a1(1), b1(0), c1(0) as variant
a1(0) = ThisComponent
a1(1) = a
scriptPro = ThisComponent.getScriptProvider()
myScript = scriptPro.getScript( _
"vnd.sun.star.script:Cell_Functions.py$calcEffectValue?language=Python&location=user")
cev = myScript.invoke(a1, b1, c1)
end function
The basic script is called on a single cell using CEV(cellAddress), which passes the contents of the cell through to the Python script as a string.
Well, I updated to LibreOffice 7 and this started working. The Python version in LO 7 is 3.8 instead of 3.5, so maybe that made the difference.
Maybe it is working but you just don't know where test.log file is getting placed when it runs from LibreOffice. Try providing an absolute file path for test.log, like let's say C:/test.log.

How to run multiple python scripts using single python(.py) script

I have written multiple python scripts that are to be run sequentially to achieve a goal. i.e:
my-directory/
a1.py,
xyz.py,
abc.py,
....,
an.py
All these scripts are in the same directory and now I want to write a single script that can run all these .py scripts in a sequence. To achieve this goal, I want to write a single python(.py) script but don't know how to write it. I have windows10 so the bash script method isn't applicable.
What's the best possible way to write an efficient migration script in windows?
using a master python script is a possibility (and it's cross platform, as opposed to batch or shell). Scan the directory and open each file, execute it.
import glob,os
os.chdir(directory) # locate ourselves in the directory
for script in sorted(glob.glob("*.py")):
with open(script) as f:
contents = f.read()
exec(contents)
(There was a execfile method in python 2 but it's gone, in python 3 we have to read file contents and pass it to exec, which also works in python 2)
In that example, order is determined by the script name. To fix a different order, use an explicit list of python scripts instead:
for script in ["a.py","z.py"]:
That method doesn't create subprocesses. It just runs the scripts as if they were concatenated together (which can be an issue if some files aren't closed and used by following scripts). Also, if an exception occurs, it stops the whole list of scripts, which is probably not so bad since it avoids that the following scripts work on bad data.
You can name a function for all the script 2 like this:
script2.py
def main():
print('Hello World!')
And import script2 function with this:
script1.py
from script2.py import *
main()
I hope this is helpful (tell me if I didn't answer to your question I'm Italian..)

Why doesn't the rest of the code after call() work? [duplicate]

I have a python script which when run, logs information on the terminal, i want to send this logging information to a text file,
To achieve this in the beginning of the file i am inserting
import subprocess
subprocess.call(['script', 'logfile'])
and at the end of the file,i put in,
subprocess.call(['exit'])
The problem with this is when it calls the first commandscript logfile,it terminates the script,
Any suggestions on how i could make this work would be really helpful,Thanks in advance
The problem is that subprocess.call isn't returning until the shell spawned by script exits, at which point your Python script will resume.
The simplest way to do what you want is to call script itself with your Python script as an argument. Instead of
#!/usr/bin/python
import subprocess
subprocess.call(['script', 'logfile'])
# Rest of your Python code
subprocess.call(['exit'])
you will use
#!/usr/bin/python
import os
import sys
if '_underscript' not in os.environ:
os.environ['_underscript'] = "yes"
cmd_args = ['script', 'logfile', 'python'] + sys.argv
os.execvp('script', cmd_args)
# Rest of your Python code
The environment variable prevents your script from entering an infinite loop of re-running itself with script. When you run your Python script, it first checks its environment for a variable that should not yet exist. If it doesn't, it sets that variable, then runs script to re-run the Python script. execvp replaces your script with the call to script; nothing else in the Python script executes. This second time your script runs, the variable _underscript does exist, meaning the if block is skipped and the rest of your script runs as intended.
Seems like that's the expected behaviour of subprocess.call(...). If you want to capture the output of the script to a file, you'll need to open a new file handler in write mode, and tell the subprocess.call where to direct the stdout, which is the terminal output you typically would see.
Try:
import subprocess
f = open('/tmp/mylogfile.log', 'w')
subprocess.call(['/path/to/script'], stdout=f)
f.close()
Then in the terminal you can run tail /tmp/mylogfile.log to confirm.
I'm not sure the last exit call is required for what you're trying to achieve.
You can read more in the python docs, depending which version of Python you're using. https://docs.python.org/2/library/subprocess.html
The file doesn't need to pre-exist. Hope that helps!

python pickle issue with cron job

I am using python pickle to create an object and store in config file. Without cron job, I am able to run the script and able to generate config.pkl. However, once I put it in cron job and I am not able to generate config.pkl, but the log "calling generateConfig" is generated. The file has the execute permission.
Below are the function and cron job.
def generateConfig():
print "calling generateConfig"
configDict = {"test1":"value1","test2":"value2"}
output = open('config.pkl','wb')
pickle.dump(configDict, output)
output.close
crontab:
00 05 * * * /user/bin/python ~/job/process.py
Since you're not providing a path for config.pkl, my guess would be it's going to dump that file into the home directory of the user running it; if it's not being put there, try searching your system. If no error is being logged then it's likely that file is somewhere, just not where you're expecting it to be.
It's also good practice to wrap anything that could generate an exception (writing files, for instance) in a try/catch and explicitly either handling or logging problems so you at least maintain control over your script's execution; in this case, if you ended up attempting to pickle a resource, your script could die without closing that file handle. Using 'with open(...) as output: is a good option.

Starting jython program from python using subprocess module?

I have a jython server script (called rajant_server.py) that interacts with a java api file to communicate over special network radios. I have a python program which acts as a client (and does several other things as well). Currently, I have to start the server first by opening a command/terminal window and typing:
cd [path to directory containing rajant_server.py
jython rajant_server.py
Once the server successfully connects it waits for the client, which I start by running:
cd [path to directory containing python client program]
python main.py
When the client connects, the server prints out information (currently for debug) in it's command/terminal window, and the client program prints out debug information in it's command/terminal window. What I want to do is do away with the complex process by calling jython from my 'main.py' program using the subprocess module.
The problem is two fold:
1 - I need the rajant_server.py program to open in it's own terminal/command window
2 - jython needs to be run in the directory where the rajant_server.py file is stored, in other words, typing the following into the command/Terminal Window doesn't work (don't ask me why):
jython C:/code_dir/comm/server/rajant_server.py
but:
cd C:/code_dir/comm/server
jython rajant_server.py
does work.
Okay... I just got something to work. It seems like a bit of a hack, so I would still love ideas on a better approach. Here is what I am currently doing:
serverfile = r'rajant_server_v2.py'
serverpath = os.path.join(os.path.realpath('.'),'Comm',serverfile)
serverpath = os.path.normpath(serverpath)
[path,file] = os.path.split(serverpath)
command = '/C jython '+file+'\n'
savedir = os.getcwd()
os.chdir(path)
rajantserver = subprocess.Popen(["cmd",command],\
creationflags = subprocess.CREATE_NEW_CONSOLE)
#Change Directory back
os.chdir(savedir)
#Start Client
rajant = rajant_comm.rajant_comm()
rajant.start()
If you have a solution that will work in both linux & windows you would be my hero. For some reason I couldn't change the stdin or stdout specifications on the subprocess when I added creationflags = subprocess.CREATE_NEW_CONSOLE.
The Popen function in subprocess accepts an optional parameter 'cwd', to define the current working directory of the child process.
rajantserver = subprocess.Popen(["cmd",command],\
creationflags = subprocess.CREATE_NEW_CONSOLE,\
cwd = path)
You can get rid of the os.getcwd call and the two os.chdir calls this way. If you want to be able to use this script on Linux, you have to do without 'cmd'. So call Popen with ["jython", file] as first argument.
EDIT: I've just seen that CREATE_NEW_CONSOLE is not defined in the subprocess module when running on Linux. Use this:
creationflags = getattr(subprocess,"CREATE_NEW_CONSOLE",0),\
This will be the same as before, except it falls back to the default value 0 when the subprocess module does not define CREATE_NEW_CONSOLE.

Categories