-
Notifications
You must be signed in to change notification settings - Fork 7
/
GFFTransform.pm
65 lines (57 loc) · 1.86 KB
/
GFFTransform.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# GFF transform stuff
sub check_validity {
my $seqname = uc shift;
unless (defined $name{$seqname}) {
warn "Warning: no mapping for $seqname in $transformation_file\n";
$name{$seqname} = $seqname;
$start{$seqname} = 1;
$dir{$seqname} = 1;
}
}
sub transform {
my ($seqname,@oldpos) = @_;
$seqname = uc $seqname;
check_validity($seqname);
my @newpos;
foreach (@oldpos) { push @newpos, ($_ - 1) * $dir{$seqname} + $start{$seqname} }
($name{$seqname}, @newpos);
}
sub back_transform {
my ($seqname,$start,$end) = @_;
unless (exists $oldnames{$seqname}) { return ([$seqname,$start,$end]) }
my (@result,$oldname);
foreach $oldname (@{$oldnames{$seqname}}) {
die "Can't cope with backwards-oriented sequences" if $end{$oldname} < $start{$oldname};
next if $end{$oldname} < $start;
my $effend = $end <= $end{$oldname} ? $end : $end{$oldname};
push @result, [$oldname,$start+1-$start{$oldname},$effend+1-$start{$oldname}];
$start = $effend + 1;
last if $start > $end;
}
if ($start <= $end) { return () }
@result;
}
sub read_transformation {
my ($file) = @_;
$transformation_file = $file;
local *TRANSFORM;
open TRANSFORM, $file or die "Couldn't open $file: $!";
while (<TRANSFORM>) {
chomp;
my ($seqname,$source,$feature,$start,$end,$score,$strand,$frame,$group) = split /\t/, $_, 9;
my ($oldname,$oldstart,$oldend) = split /\s+/, $group;
$oldname = uc $oldname;
$name{$oldname} = $seqname;
$start{$oldname} = $start;
$end{$oldname} = $end;
$dir{$oldname} = $end > $start ? 1 : -1;
}
close TRANSFORM;
}
sub sort_seqnames {
my ($oldname,$newname);
while (($oldname,$newname) = each %name) { push @{$oldnames{$newname}}, $oldname }
@newnames = sort keys %oldnames;
foreach $newname (@newnames) { @{$oldnames{$newname}} = sort { $start{$a} <=> $start{$b} } @{$oldnames{$newname}} }
}
1;