File 1: ID start stop a 12 15 a 12 17 a 13 14 a 14 19 b 10 15 b 12 15 ... #### file 2: Position Tag #a 1 0 2 1 3 0 4 0 ... 10 0 11 1 12 1 13 0 14 0 ... #b 1 0 2 1 3 0 4 0 ... 10 0 11 0 12 1 13 1 14 1 ... #### #!/usr/bin/perl use strict; use Getopt::Long; use Data::Dumper; my ($optInput1, $optInput2); GetOptions ('i=s' => \$optInput1, 't=s' => \$optInput2); open (IN, "<", $optInput1)|| die "$!"; open (IN1, "<", $optInput2)|| die "$!"; my %hash_pos; # set my intervals while (){ chomp; /^([^\t]*)\t([^\t]*)\t([^\t]*)/; $hash_pos{$1}->{$2}->{$3} =0; } close IN1; my %hash_stop; my $p =0; my $id = ""; #count tags per interval while(my $t = ){ chomp($t); if ($t =~/#(.*)\s/){ $p=0; $id = $1; %hash_stop = (); next; } $p++; # sometimes the first column is set to 0 $t =~/^(\d+)\t(\d+)/; # set start and stop boundaries for each interval # if start position has been reached if(exists $hash_pos{$id}->{$p}){ foreach my $o (keys %{$hash_pos{$id}->{$p}}){ $hash_stop{$p}->{$o}=1; } } # foreach interval count ++ if tag == 1 foreach my $keyu (keys %hash_stop){ foreach my $key (keys %{$hash_stop{$keyu}}){ $hash_pos{$id}->{$keyu}->{$key}++ if $2 eq '1'; # if end reached you are don with this # delete it from the hash_stop delete($hash_stop{$keyu}->{$key}) if $p == $key; } } } close IN; print Dumper(\%hash_pos); #### a 12 15 a 12 17 a 13 14 a 14 19 b 10 15 b 12 15 #### #a 1 0 2 1 3 0 4 0 5 0 6 1 7 0 8 1 9 1 10 1 11 0 12 0 13 0 14 1 15 1 16 1 17 1 18 1 19 0 20 0 21 0 #b 1 0 2 1 3 0 4 0 5 0 6 1 7 0 8 1 9 1 10 1 11 0 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 0 20 0 21 0 #### ./test.pl -i file.2 -t file.1 #### $VAR1 = { 'a ' => { '12' => { '17' => 0 } }, 'a' => { '13' => { '14' => 1 }, '12' => { '15' => 2 }, '14' => { '19' => 5 } }, 'b' => { '10' => { '15' => 5 }, '12' => { '15' => 4 } } }; #### without the mistake in my input file 1 $VAR1 = { 'a' => { '13' => { '14' => 1 }, '12' => { '17' => 4, '15' => 2 }, '14' => { '19' => 5 } }, 'b' => { '10' => { '15' => 5 }, '12' => { '15' => 4 } } }; #### #!/usr/bin/perl use strict; use Getopt::Long; use Data::Dumper; my ($i1, $i2); GetOptions ('i=s' => \$i1, 't=s' => \$i2); open (IN, "<", $i1)|| die "$!"; open (IN1, "<", $i2)|| die "$!"; my %hash1; # set my intervals while (){ chomp; /^([^\t]*)\t([^\t]*)\t([^\t]*)/; $hash1{$1}->{$2}->{$3} =0; } close IN1; my %hash2; my $p =0; my $id = ""; #count tags per interval while(){ chomp; if (/#(.*)/){ $p=0; $id = $1; %hash2 = (); next; } $p++; # sometimes the first column is set to 0 /^(\d+)\t(\d+)/; if(exists $hash1{$id}->{$p}){ foreach my $o (keys %{$hash1{$id}->{$p}}){ $hash2{$p}->{$o}=1; } } foreach my $key1 (keys %hash2){ foreach my $key2 (keys %{$hash2{$key1}}){ $hash1{$id}->{$key1}->{$key2}++ if $2 eq '1'; delete($hash2{$key1}->{$key2}) if $p == $key2; } } } close IN; print Dumper(\%hash1);