Count PDF pages from stdin with Ghostscript (PostScript) - shell

Well I found on stackoverflow how to count pages of PDF file using Ghostscript by executing the following command on a shell
gs -q -dNODISPLAY -c "($PATH_TO_PDF) (r) file runpdfbegin pdfpagecount = quit"')
I would like to get the pdf from stdin.
I'll played a little bit around, but with no success.
My approach was:
gs -q -dNODISPLAY - -c "(%stdin) (r) file runpdfbegin pdfpagecount = quit"')
I get no output.
Any hints or suggestions?

You cannot work with PDF files from stdin, as the PDF format makes it more or less essential to be able to have random access to all parts of the file.
In the cases where Ghostscript reads a PDF file from stdin it first copies it to a local file then works on that, so it isn't working from stdin anyway.
In short, this can't be done.

This works:
gs -q -dNODISPLAY -c "($PATH_TO_PDF) (r) file runpdfbegin pdfpagecount = quit";
I think the problem with your attempt to use
gs -q -dNODISPLAY -c "($PATH_TO_PDF) (r) file runpdfbegin pdfpagecount = quit"')
was the unmatched closing bracket after QUIT

It can be done.
String ars = "-q -dNODISPLAY -dNOPAUSE -sDEVICE=tiffg3 -r150.4 -o" + outputImagesPath + "%d.tiff -sPAPERSIZE=a4 " + inputPDFFile + " -c quit";
Process proc = new Process();
proc.StartInfo.FileName = ghostScriptPath;
proc.StartInfo.Arguments = ars;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
//Raise Your Complete Job Event Here And User Directory.GetFiles("..").Count

Related

RGI output filename does not match snakefile output filename

The problem is:
A software called "RGI" will automatically append .txt as suffix to the output file. So if my sampleID is 7. Then the actual RGI output file will be 7.txt, which is different from the output file (7) defind in the snakefile rule. And snakemake will report errors like Job Missing files after 20 seconds. However, RGI still appends .txt as suffix even if you have preset a suffix (and the actual output file will look like 7.txt.txt).
How can I solve the problem?
The following is a part of my code:
rule rgi:
output:
cardTxt = "{sampleId}/annotation/rgi/{sampleId}"
input:
faa = rules.prokka.output.faa,
cardDb = config['rgi']['cardDb']
shell:
"""
rgi load -i {input.cardDb}
rgi main -i {input.faa} -t protein -o {output.cardTxt} --include_loose --clean
"""
Strip the .txt prefix from the output filename before passing it to rgi. I do this here using bash string manipulation but you can do it in other ways:
rule rgi:
input:
faa = rules.prokka.output.faa,
cardDb = config['rgi']['cardDb'],
output:
cardTxt = "{sampleID}/annotation/rgi/{sampleID}.txt",
shell:
"""
card=${{{output.cardTxt}%.txt}}
rgi load -i {input.cardDb}
rgi main -i {input.faa} -t protein -o $card --include_loose --clean
"""
(I assume you want .txt to be part of the output filename. I.e. you are ok with 7.txt)

Gnuplot how to set a variable to standard-input if not passed

I have a gnuplot script (plot.script) that is invoked like
C:> ffmpeg -i '.\my_awesome_audio_file.wav' -filter_complex aformat=channel_layouts=mono -acodec pcm_s16le -ar 4000 -f data - | gnuplot -e "fileout='plot';fileformat='png';wid=500;" .\plot.script
Now I'd want to default filein variable to stdin if it is not passed as argument. This because I want to be able to call this script as a 1-liner command with ffmpeg data generation and also as step-by-step procedure
My idea was to use
if(!exists('filein')){
filein = '-';
}
but this throws warning: Skipping data file with no valid points
if i print the variable datafile I got - (I expected something like stdin).
this is the plot.script script:
if(!exists('filein')){
filein = '-';
}
if (!exists("hei")){
hei = 4444;
}
if (!exists("wid")){
wid = 5555;
}
if(!exists("fileformat")){
fileformat = 'png';
}
if(!exists("fileout")){
fileout = 'risultato';
}
fileout = fileout . '.' . fileformat;
if(!exists("dataformat")){
dataformat = '%int16';
}
if(fileformat eq 'png'){
set terminal png transparent size larghezza,altezza;
}else{
set terminal fileformat size wid,hei;
}
set output fileout;
unset key;
unset tics;
unset border;
set lmargin 0;
set rmargin 0;
set tmargin 0;
set bmargin 0;
print filein;
plot filein binary filetype=bin format=dataformat endian=little array=1:0 with lines linecolor "0x009900";
But I also want to call this command-by-command:
generate the data-file:
c:> ffmpeg -i '.\my_awesome_audio_file.wav' -filter_complex aformat=channel_layouts=mono -acodec pcm_s16le -ar 4000 -f data audio.dat
plot the data:
c:> gnuplot -e "filein='audio.dat';fileout='plot';fileformat='png';wid=500;" .\plot.script
There are probably a lot of ways you might deal with this, but my suggestion is to have gnuplot plot from a pipe opened by the shell command that calls it. It is then up to the shell to fill that pipe either via cat from an existing file or by directing a stream to it. Here is the relevant section from the documentation (see help pipes)
On systems with an fdopen() function, data can be read from an arbitrary file
descriptor attached to either a file or pipe. To read from file descriptor
`n` use `'<&n'`. This allows you to easily pipe in several data files in a
single call from a POSIX shell:
$ gnuplot -p -e "plot '<&3', '<&4'" 3<data-3 4<data-4
$ ./gnuplot 5< <(myprogram -with -options)
gnuplot> plot '<&5'

Multiple Processes - Python

I am looking to run multiple instances of a command line script at the same time. I am new to this concept of "multi-threading" so am at bit of a loss as to why I am seeing the things that I am seeing.
I have tried to execute the sub-processing in two different ways:
1 - Using multiple calls of Popen without a communicate until the end:
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum1 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum1{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum2 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum2{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
command = 'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum3 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum3{}'.format(i), str(i))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(stdoutdata, stderrdata) = process.communicate()
this starts up each of the command line item but only completes the last entry leaving the other 2 hanging.
2 - Attempting to implement an example from Python threading multiple bash subprocesses? but nothing happens except for a printout of the commands (program hangs with no command line arguments running as observed in windows task manager:
import threading
import Queue
import commands
import time
workspace = r'F:\Processing\SM'
image = 't08r_e'
image_name = (image.split('.'))[0]
i = 0
process_image_tif = workspace + '\\{}{}.tif'.format((image.split('r'))[0], str(i))
# thread class to run a command
class ExampleThread(threading.Thread):
def __init__(self, cmd, queue):
threading.Thread.__init__(self)
self.cmd = cmd
self.queue = queue
def run(self):
# execute the command, queue the result
(status, output) = commands.getstatusoutput(self.cmd)
self.queue.put((self.cmd, output, status))
# queue where results are placed
result_queue = Queue.Queue()
# define the commands to be run in parallel, run them
cmds = ['raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum1 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum1{}'.format(i), str(i)),
'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum2 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum2{}'.format(i), str(i)),
'raster2pgsql -I -C -e -s 26911 %s -t 100x100 -F p839.%s_image_sum_sum3 | psql -U david -d projects -h pg3' % (workspace + '\\r_sumsum3{}'.format(i), str(i)),
]
for cmd in cmds:
thread = ExampleThread(cmd, result_queue)
thread.start()
# print results as we get them
while threading.active_count() > 1 or not result_queue.empty():
while not result_queue.empty():
(cmd, output, status) = result_queue.get()
print(cmd)
print(output)
How can I run all of these commands at the same time achieving a result at the end? I am running in windows, pyhton 2.7.
My first try didn't work because of the repeated definitions of stdout and sterror. Removing these definitions causes expected behavior.

Command does not return results in SWIFT

I'm trying to run a command line tool and taking the result.
I checked it in terminal:
/usr/bin/exiftool -filename -directory -createdate -model "/Users/dirk/Desktop\" -t -S -q -r -f >"RenamerOutfile0.txt"
This runs fine and delivers result in file.
Using SWIFT I tried this:
let task = NSTask()
task.launchPath = "/usr/bin/exiftool"
task.arguments = ["-filename -directory -createdate -model \"/Users/dirk/Desktop\" -t -S -q -r -f"]
let pipe = NSPipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
Unfortunatly nothing happens. data is assigned 0 byte - no result.
If I insert the redirection to file no file is created.
Any idea what's the difference in calling the tool from terminal than with this task?
I found a workaround:
let x = system("/usr/bin/exiftool -filename -directory -createdate -model \"/Users/dirk/Desktop\" -t -S -q -r -f >\"/var/tmp/RenamerOutfile0.txt\"")
This works fine. Maybe because I added the path /var/tmp for output file? Doesn't matter! :-)

ghostscript unexpectedly returned exit value 1

Calling ghostscript from a Perl script I get this error:
"/usr/local/bin/gs" unexpectedly returned exit value 1
In $! this string can be found: "Inappropriate ioctl for device" - I am not sure, if this is related to the gs error.
Searching for the documentation of ghostscript, I found this page:
http://www.ghostscript.com/doc/current/API.htm#return_codes
Unfortunatley 1 is not listed there.
Any idea what's going wrong here?
EDIT: After changing the code a bit, I realized that the file given to gs was a JPEG and not a PDF. That's probably the reason but does not explain the exit-code of 1.
For the reference here is the Perl-code which throws the above error message:
my ($stdout, $stderr, $exit) = capture {
my $cmd = '/usr/local/bin/gs';
my #args = (qw( -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=- )) ;
push #args, $tmp_fn;
use IPC::System::Simple qw(system);
system($cmd, #args);
};
die "ERROR compressing pdf: $stderr" if $stderr;

Resources