Perl Statistics::R generates blank plot image (jpeg) - perl

I am currently using ActiveState Perl 5.14 and the R project version 2.13.2. Within Perl I am using Statistics::R version 0.08. According to ActiveState the more recent versions of Statistics::R (through 0.24) failed to pass scrutiny and are therefore not available through the PPM.
History: I have been successfully using Perl to access R for some time to perform analysis. Now I want to generate JPEG images of the results of the analysis for easy visualization.
Here's the problem: I can generate the images successfully from within the R console. However, when I run the same commands through Perl I only get a blank image. My console code includes (simplified, of course):
x<-c(1,2,3,4,5)
y<-c(5,4,3,2,1)
jpeg("C:/temp.jpg")
plot(x,y)
dev.off()
And my Perl commands include (also simplified):
$R = Statistics::R->new();
$R->start_sharedR
$R->send("x<-c(1,2,3,4,5)");
$R->send("y<-c(5,4,3,2,1)");
$R->send('jpeg("C:/temp.jpg")');
$R->send("plot(x,y)");
$R->send("dev.off()");
Any suggestions? I know that there are other plotting options accessible to Perl. I have eliminated some (GD Graph) because X-axis data is not treated as numeric. I'd prefer to keep it in R if at all possible since I'm already interacting in that package for the analysis. Thanks!

Forget Statistics::R. Just use a system call. At least it's what I do!
my $path_to_r = "C:/Program Files/R/bin/Rscript.exe";
my $cmd = "x<-c(1,2,3,4,5);";
$cmd .= "y<-c(5,4,3,2,1);";
$cmd .= 'jpeg("C:/temp.jpg");';
$cmd .= "plot(x,y);";
$cmd .= "dev.off()";
system($path_to_r . " -e '" . $cmd . "'");
If your R script grows up a bit or if it takes input from the parameters, write it in a file and Rscript.exe this file.

It works fine for me with Statistics R::0.27, but not with 0.08, the only version I could find in Active perl's package manager. In order to install 0.27, I had to use cpan command line. Make test fails but make install was fine. Bit of a life-saver.
(By the way I'm a relative noob. Using cpan command line was pretty easy however.
Type i /Statistics-R/ from cpan command line, then
install FANGLY/Statistics-R-0.27.tar.gz (or whatever the relevant file is. I'm using a windows system so RSPerl annoyingly not an option for me. I note that latest Statistics::R version is dated March 2012 so perhaps some of the previously documented (piping?) problems have been solved. You may also need to install a 'maker'; in my case it was 'dmake', not 'nmake'. Pretty easy, you can get a version of make from M$ website and copy that + .err file into PERL\bin dir. But help on this is available elsewhere. Hope this helps!)

Related

colorgcc perl script with output to non-tty enabled writing to C dependency files

Ok, so here's my issue. I have written a build script in bash that pipes output to tee and sorts different output to different log files (so I can summarize errors/warnings at the end and get some statistics on files built). I wanted to use the colorgcc perl script (colorgcc.1.3.2) to colorize the output from gcc and had found in other places that this won't work piping to tee, since the script checks if it is writing to something that is not a tty. Having disabled this check everything was working until I did a full build and discovered some of the code we receive from another group builds C dependency files (we don't control this code, changing it or the build process for these isn't really an option).
The problem is that these .d files have the form as follows:
filename.o filename.d : filename.c \
dependant_file1.h \
dependant_file2.h (and so on for however many dependencies there are)
This output from GCC gets written into the .d file, but, since it is close enough to a warning/error message colorgcc outputs color codes (believe it's the check for filename:lineno:message but not 100% sure, could be filename:message check in the GCCOUT while loop). I've tried editing the regex to attempt to not match this but my perl-fu is admittedly pretty weak. So what I end up with is a color code on each line for these dependency files, which obviously causes the build to fail.
I ended up just replacing the check for ! -t STDOUT with a check for a NO_COLOR envar I set and unset in the build script for these directories (emulates the previous behavior of no color for non-tty). This works great if I run the full script, but doesn't if I cd into the directory and just run make (obviously setting and unsetting manually would work but this is a pain to do every time). Anyone have any ideas how to prevent this script from writing color codes into dependency files?
Here's how I worked around this. I added the following to colorgcc to search the gcc input for the flag to generate the .d files and just directly called the compiler in that case. This was inserted in place of the original TTY check.
for each $argnum (0 .. $#ARGV)
{
if ($ARGV[$argnum] =~ m/-M{1,2}/)
{
exec $compiler, #ARGV
or die("Couldn't exec");
}
}
I don't know if this is the proper 'perl' way of doing this sort of operation but it seems to work. Compiling inside directories that build .d files no longer inserts color codes and the source file builds do (both to terminal and my log files like I wanted). I guess sometimes the answer is more hacks instead of "hey, did you try giving up?".

perl glob matching files on windows vs linux

I have the following code in a cgi script that just bundles up xml files into a zip for downloading:
my $obj = Archive::Zip->new();
foreach my $xml_file (glob(File::Spec->catfile($in_path,"*.xml")))
{
$obj->addFile($xml_file);
}
$obj->writeToFileNamed($zipfile_name);
This works fine on unit tests and when I run it on Linux, but when installed on windows, I get:
Can't call method "desiredCompressionLevel" on an undefined value at /usr/share/perl5/Archive/Zip/Archive.pm line 249.
In both cases, it works fine on Linux and under unit test, but fails when installed on windows (there are xml files in the directory that should be picked up...).
I think choroba's comment is correct. Since it only happens when you install on windows rather than when you test on windows, I'll bet that it is a "C:\Program Files" space issue. It is listed in the docs for perl's File::Glob:
Due to historical reasons, CORE::glob() will also split its
argument on whitespace, treating it as multiple patterns, whereas
bsd_glob() considers them as one pattern.
This could easily break things. The docs recommend using bsd_glob() instead of glob in this case.
I can cut and paste your code and run it on windows with $in_path == ".", but it breaks when I use $in_path = "C:\Path With Spaces". Also, with spaces, I am pretty sure it will fail on linux as well.

Is there a documentation about "Config_heavy.pl" keys?

After installing perl you can find a Config_heavy.pl file e.g. in /usr/lib/perl5/5.18/mach/Config_heavy.pl and I wonder if there is a commentation of all key/value pairs one can find in it. The of them are clear, but sometimes I'm not sure.
Calling perl -V shows all these values in there.
I guess what I really want to know is, which values are really 'hard', because not only in this file so a change would have no effect, an which have an effect after change? E.g. which can I change to have an effect in CPAN like adding a '-I.' to the ccflags to have CPAN searching for local headers included with <> instead of "" (you can find this in Authen::PAM ;) ).
So if there is some more information do find about the keys in this file, I would be happy to learn about them.
From the command line,
perldoc Config
You shouldn't change that file.
I think the following will do the trick to install Authen::PAM:
wget http://search.cpan.org/CPAN/authors/id/N/NI/NIKIP/Authen-PAM-0.16.tar.gz
tar xvzf Authen-PAM-0.16.tar.gz
cd Authen-PAM-0.16
perl Makefile.PL CCFLAGS='-I.'
make test
make install

Finding the path of installed program from MATLAB?

Can I find out from the MATLAB command line what is the installation path of specific program?
Or can I find the path for a registered program (Windows reg equivalent)?
This won't be 100% reliable, but this will get the right answer most of the time:
function p = findOnSystemPath(f)
p = '';
path = getenv('path');
dirs = regexp(path,pathsep,'split');
for iDirs = 1:numel(dirs)
tp = fullfile(dirs{iDirs},f);
if exist(p,'file')
p = tp;
break
end
end
Sample usage:
>> findOnSystemPath('runemacs.exe')
ans =
C:\Program Files (x86)\emacs\bin\runemacs.exe
Depending on your OS, you might be able to get this information from the system directly:
which is available on Unix systems and Windows systems with Cygwin installed:
>> [~,p] = system(sprintf('which "%s"',f))
p =
C:/Program Files (x86)/emacs-mw-a/bin/runemacs.exe
where is available on Windows 2003 and later:
>> [~,p] = system(sprintf('where "%s"',f))
p =
C:\Program Files (x86)\emacs-mw-a\bin\runemacs.exe
And in some cases, you can pull this information from the registry using winqueryreg, for example:
>> notepadEdit = winqueryreg('HKEY_CLASSES_ROOT','Applications\notepad.exe\shell\edit\command')
notepadEdit =
C:\Windows\system32\NOTEPAD.EXE %1
Call the DOS/bash command which, e.g.,
!which matlab
!which notepad
(Or use system instead of the !.)
EDIT: It seems that there isn't a direct equivalent in Windows. I had cygwin installed on the (Win XP) machine I tried it on, and the command succeeded. Alternatively, take a look at these answers on stackoverflow and superuser.
This depends on what you know about the OS and what properties your program has.
On Linux I usually do something like:
[error, path] = system(sprintf('which "%s"',programName));
It doesn't look pretty and it's far from portable (I suppose it will not work on Windows, perhaps only if you install Cygwin or something similar). It's far easier in Unix since most executables are accessible from the "path" (the environment variable "path"), while in Windows most executables are either stored in the Windows directory (which is in the default path, so they are found) or in a Program Files directory which is not as far as I recall.
Error = 0 when the program is found and path then obviously contains the path to the executable.
For Windows I guess you can search all directories for the program, but that might be somewhat tedious.
MATLAB is not really designed to be used as a tool to search files anywhere on the drive. That's a task best left to the OS, and what Egon suggested is what you should be doing. Simply replace which with the equivalent in DOS (you should know this already, else just ask another question in the MS-DOS/Windows tag. It probably has already been answered.).
If you are really hell bent on using MATLAB to search the drive, then you can do the following
addpath(genpath('C:\')); %#' I am not sure which way the slash is
which filename
Beware, the first step will take a while.

Does 'use lib' work for UNC paths?

My hosted scripts have been moved and no longer work.
The specified CGI application
misbehaved by not returning a complete
set of HTTP headers.
I notice that someone at my host company has modified my scripts so that where I used to have
use lib 'd:/myorig/LIB';
I now have
use lib '//newhost/LIB';
Should this work?
I tried 1800 INFORMATION's suggestion and ran the minimal script of
#!perl -w
use lib '//whatever/lib';
print "success";
...which gave the same result.
Update: ysth's suggestion of FatalsToBrowser did indeed reveal more information. It looks like the path (added by someone from the hosting company) might be wrong.
Update2: The hosting company now says that these scripts, unchanged from the previous host mind, are throwing lots of syntax errors. "Since we cannot debug your scripts for you we suggest you contact the original programmer and ask them for help". <grinds teeth>
Partial Resolution: The hosting company finally realised they hadn't set permissions correctly. They still aren't right, and (aargh) they don't allow site owners to set folder permissionsn, not even on folders within their own sites.
I don't know if it should work or not, but my intuition is that it would be okay. However, the two use lib lines you posted are not equivalent.
# go to the 'd' drive and use the 'myorigLIB' directory on that drive
use lib 'd:/myorigLIB';
# go to the 'newhostLIB' server - no path is specified - this looks invalid to me
use lib '//newhostLIB';
Perhaps you need to specify the path to the share on the server? Also, you might need to look at permissions? Maybe the user the CGI is running as cannot access that network path?
Also, you could write a simple (non CGI) program to test your theory and just run it:
#!perl -w
use lib '//whatever/lib';
print "success";
Then just run that on the server if you can and see what happens.
No the path is incomplete it needs both a server name and a complete path. It is a bad practice as well because it requires that two machines be monitored rather than one for your application to function.
The specified CGI application misbehaved by not returning a complete set of HTTP headers.
That's a non-error. If you are lucky, your hosting company will make an error log available to you that will show the actual error that perl is dying with. If not,
consider using
use CGI::Carp "fatalsToBrowser";
for testing. (If you are paranoid (which is not a bad thing to be), you will refrain from leaving that enabled once you are done testing, since errors can commonly provide information about your code or even your database that may help a black hat exploit security holes.)
I know I ran into trouble trying to use mapped drives and unc paths from apache because the apache user was not allowed to use network drives. That was difficult to figure out -- but it's possible to do it. That may be a related problem.
#!perl -w
print "HTTP/1.0 200 OK\nContent-Type: text/plain\n\n";
my $path = "//whatever/lib";
print "\nExists ", -e $path;
print "\nDirectory ", -d $path;
print "\nReadable ", -r $path;
print "\nListing:\n";
print "\t$_\n" for glob "$path/*";