BioPerl/BioGraphics only prints one value instead of all - perl

I am trying to plot SNPs onto a gene (or below). The code I have is the following:
#!/usr/bin/perl
use strict;
use warnings;
use Bio::Graphics;
use Bio::SeqFeature::Generic;
my #SNPs = "408777 408900 409100 409480";
my $gene_name = "GSTd10";
my $scaffold = "KB668289";
my $gene_start = 408763;
my $gene_end = 409489;
my $length = $gene_end - $gene_start + 50;
open my $png, ">", "$gene_name.png" or die "Cannot open $gene_name.png: $!\n";
#Create a panel for the image#
my $panel=Bio::Graphics::Panel->new(-offset => $gene_start, -length => $length, -width => 1000, -pad_left => 100, -pad_right => 10, -pad_top => 10);
my $track_whole=$panel->add_track(-glyph => 'graded_segments', -label => 1, -bgcolor => 'black', -font2color => 'black',);
my $feature= Bio::SeqFeature::Generic->new(-display_name => $gene_name, -start => $gene_start, -end => $gene_end,);
$track_whole->add_feature($feature);
my $track=$panel->add_track(-glyph => 'graded_segments', -label => 1, -bgcolor =>'blue', -min_score => 0, -max_score => 30, -font2color => 'black');
foreach my $SNP (#SNPs)
{
my $feature= Bio::SeqFeature::Generic->new(-label => $SNP, -start => $SNP, -end => $SNP);
$track->add_feature($feature);
}
#This will print out the final panel i.e. you must have created an object called $panel above
print $png $panel -> png;
Whenever I run this script, I only get printed one line.
Where is the mistake in order to print all values in #SNPs? In addition, is there a way of printing ^ instead of a block?

In this line
my #SNPs = "408777 408900 409100 409480";
You're just creating an array with a single element of that whole string.
Try
my #SNPs = qw(408777 408900 409100 409480);

Related

Can't draw lines in GooCanvas

In a Perl/Gtk3 script and using GooCanvas, I can easily draw a rectangle, or an ellipsis, or whatever, but it seems to be impossible to draw a simple line.
Lines are drawn with a call to Goo::CanvasPolyline->new(). The line's coordinates a specified by a call to Goo::CanvasPoints->new(), but that call creates the following error:
GLib-ERROR **: ../../../../glib/gmem.c:105: failed to allocate 18446744069314558208 bytes at /usr/lib/x86_64-linux-gnu/perl5/5.26/Glib/Object/Introspection.pm line 67.
Aborted (core dumped)
I've tried the Perl module Goo::Canvas and the more modern GooCanvas2; both produce the same error.
I wasn't able to find any working code examples; merely the non-working script below, which Google found on $RANDOM_WEBSITE.
#!/usr/bin/perl -w
use strict;
use warnings;
use Gtk3 -init;
Glib::Object::Introspection->setup(basename => 'GooCanvas', version => '2.0', package => 'Goo');
my $window = Gtk3::Window->new('toplevel');
$window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
$window->set_size_request(640, 600);
$window->set_title("Gtk3 GooCanvas with Perl Gobject Introspection");
$window->signal_connect(destroy => sub { Gtk3->main_quit });
my $swin = Gtk3::ScrolledWindow->new;
$swin->set_shadow_type('in');
$window->add($swin);
my $canvas = Goo::Canvas->new; # Gobject Introspection of Gtk3 Goo version
$canvas->set_size_request(800, 650);
$canvas->set_bounds(0, 0, 1000, 1000);
$swin->add($canvas);
my $root = $canvas->get_root_item();
# first point set
my $pts_ref = [50,50,180,120,90,100,50,50];
my $points = Goo::CanvasPoints->new(
$pts_ref,
);
my $line = Goo::CanvasPolyline->new(
'parent' => $root,
'close-path' => 0,
'points' => $points, #in Gtk2 could just use $pts_ref
'stroke-color' => 'black',
'line-width' => 3,
);
my $ellipse = Goo::CanvasEllipse->new(
'parent' => $root,
'center-x' => 20,
'center-y' => 20,
'width' => +60,
'height' => +60,
'stroke-color' => 'goldenrod',
'line-width' => 8,
'fill-color-rgba' => 0x3cb37180,
);
$root->translate(200,200);
$window->show_all();
Gtk3->main;
__END__
my $points = Goo::CanvasPoints->new( $pts_ref );
According to the documentation the constructor should take the number of points to reserve, not the reference to the points array. So you could try:
[...]
# first point set
my $pts_ref = [50,50,180,120,90,100,50,50];
my $num_points = (scalar #$pts_ref)/2;
my $points = Goo::CanvasPoints->new( $num_points );
# Set the points:
my $j = 0;
for my $i (0..($num_points -1)) {
my $x = $pts_ref->[$j];
my $y = $pts_ref->[$j+1];
$points->set_point($i, $x, $y);
$j += 2;
}
[...]

How to get "Var1" value of dumper in perl

When i use below code then it gives output, But i want "width", "file_media_type", "file_ext" values, But I am unable to get this value in individual. I am very new with Perl Please help me!
Code
use warnings ;
use strict;
use Image::Info qw[image_info];
use Data::Dumper;
my $file = 'd:\perl\test\a.jpg';
my $info = Dumper(image_info($file));
print $info;
Output
$VAR1 = {
'width' => 45,
'file_media_type' => 'image/png',
'file_ext' => 'png',
'PNG_Chunks' => [
'IHDR',
'gAMA',
'cHRM',
'IDAT',
'IEND'
],
'Chunk-cHRM' => ' z% Çâ ·  ÇF u0 O` :ù ?o',
'PNG_Filter' => 'Adaptive',
'color_type' => 'RGB',
'height' => 20,
'Gamma' => '0.45454',
'resolution' => '1/1',
'SampleFormat' => 'U8',
'Compression' => 'Deflate'
};
image_info($file) returns a hash reference. Looking at the dump you know the keys available (the keys are strings before =>)
$info = image_info($file);
foreach my $key ( qw/width file_media_type file_ext/ ){
print "$key:$info->{$key}\n";
}

perl tk gui to show script stdout and stderr in text widget

I have a GUI that runs a script from a command button, but how can I get it to display output in the text widget?
If I wanted to display the output via a logfile insert, could I have the command on the same button/sub as the run button?
use warnings;
use strict;
use Tk;
use Tk::Text ;
use POSIX 'strftime';
my $DATE = strftime("Report.pl for %dth %b %Y" , localtime());
my $mw = MainWindow->new;
my $filename = "c:\\Temp\\perl.txt";
$mw->geometry("720x500");
$mw->title(" backupadmin ");
my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x');
my $left_frame = $main_frame->Frame(-background => "snow2")->pack(-side => 'left', -fill => 'y');
my $right_frame = $main_frame->Scrolled("Text", -scrollbars => 'se',-background => "black",-foreground => "yellow",-height => '44')->pack(-expand => 1, -fill => 'both');
my $failures_button = $left_frame->Button(-text => " $DATE ",
-command => [\&runscript])->pack;
my $Close_button = $left_frame->Button(-text => ' Close ',
-command => [$mw => 'destroy'])->pack;
my $Help_button = $left_frame->Button(-text => " Help Guide ",
-command => [\&load_file])->pack(-side => "bottom");
my $Close_help = $left_frame->Button(-text => ' Close Help ',
-command => [$right_frame => \&clear_file])->pack(-side => "bottom");
MainLoop;
sub runscript {
system("report.pl");
}
sub load_file {
open (FH, "$filename");
while (<FH>) { $right_frame->insert("end", $_); }
close (FH);
}
sub clear_file {
$right_frame->('quit');
}
If your report.pl script outputs to STDOUT, then you could try something like this in your runscript callback:
sub runscript {
right_frame->delete('1.0','end');
my $text = `report.pl`;
$right_frame->insert('end', $text);
}
Alternatively, if report.pl outputs to c:\temp\perl.txt then you could try the following:
sub runscript {
right_frame->delete('1.0','end');
system("report.pl");
load_file();
}

Perl get value of variable from while(1) loop when sub() change it

I got a small problem.
When I create thread in main block of script, which should get the $txt value in while(1) loop, in the same time program create TopLevel window and there is a Text() object in $txt string.
I want to read values from Text() object, only when Text() object will be created, but not earlier.
In my example $txt should be a global variable, but my thread read $txt variable only by 'undef'.
Is it possible to read variable from while(1) loop, when other subroutines change it?
I must watch $txt var in thread, because when i try start thread in makeTop(), Tk gives me error about non-exist string.
Thanks for advices.
CODE:
use Tk;
use threads;
use warnings;
$mw = new MainWindow;
our $txt = undef;
my $lab = $mw->Label( -text=>"Main window.", -font => "ansi 12 bold")->pack;
my $but = $mw->Button( -text=>"Create Toplevel", -command => \&makeTop)->pack;
my $thr = threads->create('urls_couter');
MainLoop;
sub urls_couter {
while (1) {
if (defined $txt){
$txt->get('1.0','end');
}
}
}
sub makeTop {
my $top = $mw->Toplevel();
$fr = $top->Frame()->grid( -row => 1, -column => 1 );
$fr2 = $top->Frame()->grid( -row => 2, -column => 1 );
my $top_lab = $fr->Label( -text => "URLs (each on a separate line) : ",
-font => "ansi 12 bold")->pack;
$txt = $fr->Text( -width => 44, -height => 20)->pack;
$txt->insert('end', "xxxxxxx");
my $but_close =
$fr2->Button(
-text => "Ready!",
-command => sub { my #urls = split("\n", $txt->get('1.0','end-1c')); },
-relief => "raised",
-font => "ansi 12 bold")->grid( -padx => 100, -row => 1, -column => 1 );
$fr2->Button(
-text => "Close",
-command => sub { destroy $top; },
-relief => "raised",
-font => "ansi 12 bold")->grid( -pady => 10, -row => 1, -column => 2 );
}
According to this
As just mentioned, all variables are, by default, thread local. To use shared variables, you need to also load threads::shared:
thread local means you won't see changes outside your thread, so after you create your thread, each thread (logically) has it's own copy of all the variables.

RegSvr32 registering yet nothing actually registered

A rather odd experience. Using the latest PDK (v7.3) from ActiveState, I used perlctrl to build a COM DLL. Perlctrl ran without a hitch. OLEView read the typelib okay. RegSvr32 registered it okay. However ... there's no sign of it in registry, and anything that tries to use it fails. I hunted for the various UIDs using RegEdit and they're just not there.
The code is below. It's a wrapping of Lingua::ZH::WordSegmenter, but with the encoding changed to utf8 rather than gbk.
It's probably something obvious ...
package ZHWordSeg;
use strict;
use warnings;
use utf8;
use ws;
use Encode;
use constant STX => chr( 2 ); #[
use constant ETX => chr( 3 ); #]
use constant FS => chr( 28 ); #^
use constant RS => chr( 30 ); #~
use constant TAB_SEPARATOR => 0;
use constant CARET_SEPARATOR => 1;
use constant FS_SEPARATOR => 2;
use constant SPACE_SEPARATOR => 3;
use constant AS_ARRAY => 4;
use feature 'switch';
our $segmenter;
sub ZHWordSeg_Setup {
my $dic = shift;
my $dic_encoding = shift;
my $separator = shift;
my $verbose = shift;
$dic_encoding = 'utf8' unless defined( $dic_encoding );
$separator = " " unless defined( $separator );
$verbose = 0 unless defined( $verbose );
if ( defined( $dic ) ) {
$segmenter = ws->new( dic => $dic, dic_encoding => $dic_encoding, seperator => $separator, verbose => $verbose );
} else {
$segmenter = ws->new( dic_encoding => $dic_encoding, seperator => $separator, verbose => $verbose );
}
}
sub ZHWordSeg {
my $source = shift;
print STDERR $source;
my $sepcode = shift;
$source = encode("utf8",$source);
my $stringres = $segmenter->seg($source);
my #arrayres;
given ($sepcode) {
when (TAB_SEPARATOR) {
$stringres =~ tr/ /\t/;
return $stringres;
}
when (CARET_SEPARATOR) {
$stringres =~ tr/ /^/;
$stringres .= "^";
return $stringres;
}
when (FS_SEPARATOR) {
$stringres =~ s/ /FS/eg;
$stringres .= FS;
return $stringres;
}
when (SPACE_SEPARATOR) {
return $stringres;
}
default {
#arrayres = split( / /, $stringres );
return \#arrayres;
}
}
}
sub SetDictionary {
my ($source) = shift;
my $res = set_dic($source);
return $res;
}
1;
=pod
=begin PerlCtrl
%TypeLib = (
PackageName => 'ZHWordSeg',
DocString => 'Chinese word segmentation',
HelpContext => 1,
TypeLibGUID => '{F6C9BD66-7CA1-4610-B77F-E219A7122C18}', # do NOT edit this line
ControlGUID => '{45D47C6A-2B9A-4D62-9CFD-F18C95DC00C5}', # do NOT edit this line either
DispInterfaceIID=> '{007E4E7A-3B75-4DC3-864C-7746860941B3}', # or this one
ControlName => 'BOCWS',
ControlVer => 2, # increment if new object with same ProgID
# create new GUIDs as well
ProgID => 'ZHWordSeg.BOCWS',
LCID => 0,
DefaultMethod => 'ChineseWordSegmenter',
Methods => {
'ChineseWordSegmenter' => {
RetType => VT_VARIANT,
TotalParams => 2,
NumOptionalParams => 1,
ParamList =>
[ 'source' => VT_BSTR,
'sepcode' => VT_I4
]
},
'ChineseWordSegmenter_Setup' => {
RetType => VT_VARIANT,
TotalParams => 4,
NumOptionalParams => 4,
ParamList =>
[ 'dic' => VT_BSTR,
'dic_encoding' => VT_BSTR,
'separator' => VT_BSTR,
'verbose' => VT_BSTR
]
}
}, # end of 'Methods'
Properties => {
TAB_SEPARATOR => {
DocString => "Separate items with TAB (0x0)",
Type => VT_I4,
DispID => 3,
ReadOnly => 1,
},
CARET_SEPARATOR => {
DocString => "Separate items with ^ (0x1)",
Type => VT_I4,
DispID => 4,
ReadOnly => 1,
},
FS_SEPARATOR => {
DocString => "Separate items with ascii 28 (0x2)",
Type => VT_I4,
DispID => 5,
ReadOnly => 1,
},
SPACE_SEPARATOR => {
DocString => "Separate items with space (0x3)",
Type => VT_I4,
DispID => 6,
ReadOnly => 1,
},
AS_ARRAY => {
DocString => "Separate items as array (0x4)",
Type => VT_I4,
DispID => 7,
ReadOnly => 1,
}
}, # end of 'Properties'
); # end of %TypeLib
=end PerlCtrl
=cut
This is the .perlctrl file, in case it matters:
#!C:\Program Files\ActiveState Perl Dev Kit 7.3 Deployment\bin\lib\pai.exe
PAP-Version: 1.0
Packer: C:\Program Files\ActiveState Perl Dev Kit 7.3 Deployment\bin\perlctrl.exe
Script: ZHWordSeg.ctrl
Cwd: P:\BOCWS
Byref: 0
Clean: 0
Date: 2008-10-24 18:05:42
Debug: 127.0.0.1:2000
Dependent: 0
Dyndll: 0
Exe: BOCWS.dll
Force: 1
Gui: 0
Hostname: xi
No-Compress: 0
No-Gui: 0
No-Logo: 0
Runlib:
Shared: none
Singleton: 0
Tmpdir:
Verbose: 0
Version-Comments:
Version-CompanyName:
Version-FileDescription: Wrapper of Lingua::ZH::WordSegmenter.pm
Version-FileVersion: 1.0
Version-InternalName: ZHWordSeg
Version-LegalCopyright:
Version-LegalTrademarks:
Version-OriginalFilename: ZHWordSeg.ctrl
Version-ProductName: BOChineseWordSegmenter
Version-ProductVersion: 1.0
Warnings: 0
Xclude: 1
The only "solution" that I've found was suggested over on news:comp.os.ms-windows.programmer.win32
i am not a PDK user but from experience i can tell you, that you should check the DllRegister exports code and what it internally does, since this is what the regsvr32 calls and this code is creating the registry keys for your com server/proxy, etc, ...
You can track the registry for changes with sysinternal tools like regmon or procmon, just to make sure!
Ultimately, I gave up and went back to a previous version that worked and tweaked it.