#!/usr/bin/perl use strict; use warnings; use threads; use Thread::Queue; our %hs_arr; my $filename = $ARGV[0]; my $num_threads = 20; # You can adjust this based on your machine's capabilities # Queues for threads my $work_queue = Thread::Queue->new(); my $result_queue = Thread::Queue->new(); # Thread pool creation my @threads; for (1..$num_threads) { push @threads, threads->create(\&process_lines); } # Main thread reading the file and enqueuing work open my $fh, '<', $filename or die "Cannot open file $filename: $!"; while (my $line = <$fh>) { chomp $line; $work_queue->enqueue($line); } close $fh; $work_queue->end(); for my $thr (@threads){ $thr->join(); } #print "all threads completed\n"; # Collecting results #my @results; while (defined(my $result = $result_queue->dequeue_nb())) { print "$result"; } #exit; # Wait for all threads to complete #threads->exit(); # Output the results sub process_lines { while (defined(my $line = $work_queue->dequeue())) { # Process the line (this is your existing line processing logic) my $result = process_line($line); $result_queue->enqueue($result); } } sub process_line { my ($line) = @_; #my $i++; #print "$i\t$line\n"; my %hs_qrc; # Your existing line processing logic goes here my (@methy, @refmethy, @ar); my ($qlen, $direct, $rs, $i, $methyref); @ar=split(/\t/, $line); $qlen = qlencigar($ar[5]); $direct = ($ar[1] & 16) ? 1 : 0; #print "$qlen\t$direct\n"; ($rs, %hs_qrc) = cigarparse($ar[5], $qlen, $ar[3], $direct); %hs_arr = (); @methy=split(/,/,$ar[6]); for($i=0;$i<=$#methy;$i++){ if($hs_qrc{$methy[$i]}){ push @refmethy,$hs_qrc{$methy[$i]}; }else{ push @refmethy,-1; } } $rs = $rs -1; $methyref = join(',', @refmethy); #print "$rs\t$ar[6]\t$methyref\n"; my $output="$line\t$methyref\t$qlen\t$rs\t$direct\n"; #print "$line\n"; return $output; # return the processed line } sub cigarparse{ my ($cigar,$qlen,$refstart,$direct)=@_; my ($q_s, $q_e, $r_s, $r_e); my ($num, $type); my %hs_q2r; $r_s = $refstart; if($direct==0){ $q_s=1; while($cigar=~/(\d+)(\D)/g){ $num = $1; $type = $2; if($type eq '='){ $q_e = $q_s+$num; $r_e = $r_s+$num; %hs_q2r = hasharr($q_s, $q_e, $r_s, $r_e); } if($type eq 'X'){ $r_e=$r_s+$num; $q_e=$q_s+$num; } if($type eq 'D'){ $r_e=$r_e+$num; } if($type eq 'I'){ $q_e=$q_e+$num; } if($type eq 'S'){ $q_s=$q_s+$num; next; } $q_s=$q_e; $r_s=$r_e; } }else{ $q_s=$qlen; while($cigar=~/(\d+)(\D)/g){ $num = $1; $type = $2; if($type eq '='){ $q_e = $q_s-$num; $r_e = $r_s+$num; %hs_q2r = hasharr($q_s, $q_e, $r_s, $r_e); } if($type eq 'X'){ $r_e=$r_s+$num; $q_e=$q_s-$num; } if($type eq 'D'){ $r_e=$r_e+$num; } if($type eq 'I'){ $q_e=$q_e-$num; } if($type eq 'S'){ $q_s=$q_s-$num; next; } $q_s=$q_e; $r_s=$r_e; } } return ($r_s, %hs_q2r); } sub qlencigar{ my ($cigar) = @_; #print "$cigar\n"; my $qlen = 0; my ($num,$type); while($cigar=~/(\d+)(\D)/g){ $num = $1; $type = $2; #print "$num\t$type\n"; if($type=~/[=XSI]/){ $qlen+=$num; } } return $qlen; } sub hasharr{ my ($qs, $qe, $rs, $re)=@_; my ($i,$j); my (@keys, @values); #our %hs_arr; if($qs > $qe){ for($i=$qs;$i>$qe;$i--){ push @keys,$i; } }else{ for($i=$qs;$i<$qe;$i++){ push @keys,$i; } } if($rs > $re){ for($j=$rs;$j>$re;$j--){ push @values,$j; } }else{ for($j=$rs;$j<$re;$j++){ push @values,$j; } } for(my $m = 0; $m < scalar(@keys); $m++){ $hs_arr{$keys[$m]} = $values[$m]; } return %hs_arr; }