#!/usr/bin/env perl
##Program to get operons from gis ##By Vivek##
#TASS_3.0
use POSIX ;

# This parts processes the input format in to all argument type
$len     = @ARGV;
$set     = 0;
@temparg = ();
$above   = 3;
$below   = 3;
$keep    = 0;
$debug   =0 ;
$changed = "temp.changed";
$sec = .1;
$tryagain = 2;
$debug       = 0;
$threads     = 8;
$que         = 0 ;
$batch       = 100;
$basedir = "$ENV{PROTEINWORLD}";
$tass_path = "$basedir/tools/bin" ;
$input_file = "";
$yes_bulk = 0;
$parallel = 1;
$pbatch  = 20;
$pthreads = 20;
$psleep   = 0.1;

### Check for the different options
if ( $ARGV[0] ne "-help" ) {
    if ( $len > 0 ) {
        $j = 0;
        while ( $j < $len ) {
            if ( $ARGV[$j] !~ /^-/) {
                $set = 1;
                if ( -e $ARGV[$j] ) {
                    $changed = "$ARGV[$j].changed" ;
                    $input_file =  $ARGV[$j] ;
                    open( in2, "<$ARGV[$j]" );
                    while (<in2>) {
                        chomp($_);
                        s/^\s+// ;  ##remove leading spaces
                        s/\s+$// ;  ##remove trailing spaces
                        push @temparg, $_ if $_ !~ /^$/ ;
                    }
                    close(in2);
                }
                else {
                    @t = ();
                    @t = split( /,/, $ARGV[$j] );
                    push (@temparg, @t);
                }
            }

            elsif ( $ARGV[$j] eq "-a" ) {
                $above = $ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-b" ) {
                $below = @ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-change" ) {
                $keep = 1;
            }
            elsif ( $ARGV[$j] eq "-debug" ) {
                $debug = 1;
            }
            elsif ( $ARGV[$j] eq "-tryagain" ) {
                $tryagain = @ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-batch" ) {
                $batch = $ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-bulk" ) {
                $yes_bulk = 1;
            }
            elsif ( $ARGV[$j] eq "-p" ) {
                $parallel = $ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-pb" ) {
                $pbatch = $ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-pt" ) {
                $pthreads = $ARGV[ $j + 1 ];
                $j++;
            }
            elsif ( $ARGV[$j] eq "-ps" ) {
                $psleep = $ARGV[ $j + 1 ];
                $j++;
            }

            elsif ( $ARGV[$j] eq "-que" ) {
                $que = 1;
            }

            $j++;
        }
    }

### If no input file, assume input comes from a pipe
    if ( $set == 0 ) {
        @ARGV = ();
        if ( !( -t STDIN ) ) {
            while (<>) {
                chomp($_);
                s/^\s+// ;  ##remove leading spaces
                s/\s+$// ;  ##remove trailing spaces
                if ( $_ !~ /^$/ ) {
                    $set = 1;
                    push @temparg, $_;
                }
            }
        }
    }
}

$len = @temparg;

### Die statement
if ( $ARGV[0] eq "-help" or $len == 0 ) {
    die
"Program to get operons from gi.\nUSAGE: gi2operons <gi_list_filename> <gi1 gi2 gi3...> or <gi1, gi2 ...>
     -a <num>         :  Default $above lines_above
     -b <num>         :  Default $below lines below,
     -change          :  Changes input acc to new acc in query line. Default is to keep old acc in query line
     -tryagain <num>  :  Default tries 3 times if operon not retreived with a delay of $sec .
                         To turn off use 0.
     -que             :  To send the queries to farm. You need a SGE account.
     -batch <num>     :  Number of files in each batch sent to the que. Default is 100.
                         Reducing the batch to 10 or 20 increases the speed, but for big numbers it will flood the que.
     -bulk            :  Default is to run one by one. Bulk will get all CDS in one shot
     -p  <0or1or2>    :  To run the bulk in parallel. 0 no parallel, 1 seqfetch , 2 efetch  . Default is $parallel
     -pb <num>        :  Batches for parallel runs . Default $pbatch
     -pt  <num>       :  Threads to be used for parallel. Default is $pthreads
     -ps  <num>       :  sleep to be used between each parallel run to prevent failure. Default is $psleep
     -debug           :  Write current step to STDERR . Default off.

     Changed gis will be written to temp.changed or <input>.changed as original\\tchanged
     eg- gi2operons te -a 2 -b 4
     cat te | gi2operons -a 2 -b 4
     cat te | gi2operons -a 7 -b 7 -bulk -p 0       #to turn off parallel but get bulk seqfetch
     cat te | gi2operons -a 7 -b 7 -que -bulk -p 1


     \n";
}

###program begins
###################
####QUE and die#####
if ($que == 1 ) {
   open( in, "pwd | " );
   @te = <in>;
   close(in);
   $pwd = $te[0];
   chomp $pwd ;
   $options = "";
   $options .= "-change " if   $keep == 1 ;
   $options .= "-tryagain $tryagain ";
   $options .= "-bulk " if $yes_bulk == 1;
   $options .= "-p $parallel " if $parallel > 0;
   $options .= "-pt $pthreads " if $pthreads != 20;
   $options .= "-pb $pbatch "   if $pbatch   != 20;
   $options .= "-ps $psleep "   if $psleep != 0.1;

   #   $options .= "-debug " if $debug == 1 ;


   $totfile = @temparg;
   $num_batch = ceil($totfile/$batch);
   $newbatch  = $batch ;
   $x1 = 1 ;
   $x_bno = 1;
   print  STDERR "sending to farm\n" ;
   @temp = ();
   @resultfiles = ();
   @query  =();
   @qarray = ();

   foreach $item (@temparg) {
      push (@temp , $item) ;
      if ( $x1 == $newbatch or $x1 == $totfile) {
          $filebase    = $item;
          @queargs = ();
          $input  = "$pwd/$filebase".".batch$x_bno" .".queop.in" ;
          open ( T , ">$input" );
          print T join( "\n", @temp );
          print T "\n";
          close T;
          $result   = "$input".".op" ;
          $errfiles = "$input".".err" ;
          push (@resultfiles,$result);
          $queargs = "$input -a $above -b $below $options ";
          print STDERR ".";
          print STDERR "qsub -V -v SGE_FACILITIES -P unified -l h_rt=28800,h_vmem=8G,mem_free=4G -o $result -e $errfiles -m n $tass_path/gi2operons $queargs\n" if $debug == 1;
        # open ( Q , "qsub -V -v SGE_FACILITIES -P unified -l h_rt=28800,h_vmem=4G,mem_free=2G  -o $result -e $errfiles -m n $tass_path/gi2operons $queargs|");
          open ( Q , "qsub -V -v SGE_FACILITIES -P unified -l h_rt=28800,h_vmem=8G,mem_free=4G  -o $result -e $errfiles -m n $tass_path/gi2operons $queargs|");
        # open ( Q , "qsub -V -v SGE_FACILITIES -P unified -l h_rt=28800,h_vmem=8G,mem_free=4G,m_mem_free=4G  -o $result -e $errfiles -m n $tass_path/gi2operons $queargs|");
          sleep 1;
          $qt = <Q>;
          close Q;
          #chomp $qt;
          push (@qarray , $qt);
          $x_bno++;
          $newbatch = $batch * $x_bno;
          @temp = ();
     }
     $x1++;
   }

   ######Results##
   qmonitor(\@qarray);
   print STDERR "All jobs done \n" if $debug == 1;



    print STDERR "Reading results \n" if $debug == 1;
    if ($num_batch == 1) {
       system ("cat $resultfiles[0]");
    } else {
       @blastclust = ();
       @errors = ();
       foreach (@resultfiles ) {
          @results = ();
          open (in , "cat $_ 2>/dev/null|");
          @results = <in> ;
          close in;
          $bc_title = 0;
          $error_title = 0 ;
          foreach $line (@results) {
               chomp $line;
               next if $line eq "" ;
               $error_title++ if  $line =~ /^Gis without accession numbers/;
               $error_title = 3 if  $line =~ /^Gis for blastclust are/;
               $bc_title++    if  $line =~ /^Gis for blastclust are/;

                if ($error_title == 1) {
                  push (@errors , $line) if $line !~ /^Gis without accession numbers/;
                } elsif ($bc_title == 1) {
                  push (@blastclust , $line) if $line !~ /^Gis for blastclust are/;
                } else {
                  print "$line\n";
                }
          }
       }
       $bc_title =  @blastclust;
       $error_title = @errors;
       if ($error_title > 0){
          print "\nGis without accession numbers. Please get another gi\n";
          print join( "\n", @errors ) ;
          print "\n";
       }
       if ($bc_title > 0){
          print "\nGis for blastclust are\n";
          print join( "\n", @blastclust ) ;
          print "\n";
       }

    }
   system ("rm  *.queop.in.op") if $debug == 0;
   system ("rm  *.queop.in") if $debug == 0;
   exit;
}

#######END OF QUE MODULE###########
#########################################


###########gi2operon BEGINS############
%gbrecs = ();
@changedacc = ();


if ($yes_bulk == 1 ) {
     ##Temp file
     $file_bool = 0;
     while ( $file_bool == 0 ) {
         $rand       = rand();
         $rand       = $rand * 1000000;
         $rand_file = "/tmp/temp.$rand";
         $file_bool  = 1 if !( -e $rand_file );
     }
     $file_bool = 0;
     while ( $file_bool == 0 ) {
         $rand       = rand();
         $rand       = $rand * 1000000;
         $rand_file1 = "/tmp/temp.$rand";
         $file_bool  = 1 if !( -e $rand_file1 );
     }


     if ($parallel == 0) {
         if ($input_file eq "" ) {
            open (T, ">$rand_file") ;
            print T join( "\n", @temparg );
            print T "\n";
            close T;
            $input_file = $rand_file;
         }
         ############First Bulk step - seqfetch
         print STDERR "bulk:seqfetch." if $debug == 1 ;
         open( identity, "seqfetch -idfile $input_file   -t 3  -display-gi F   2>/dev/null| " ) ;
         @bulk = <identity>;
         close(identity);
      } elsif ($parallel > 0 ) { ### break and send parallel to 1 or 2

             print STDERR "parallel:$parallel." if $debug == 1 ;

             $totfile = scalar(@temparg);
             $newbatch  = $pbatch ;
             $x1 = 1 ;
             $x_bno = 1;
             @temp = ();
             @bulk = ();
             # system (">$rand_file"); #Emptying file
             # system (">$rand_file1"); #Emptying file
             foreach $item (@temparg) {
                push (@temp , $item) ;
                if ( $x1 == $newbatch or $x1 == $totfile) {
                    open( fh, ">$rand_file1" );
                    print fh join("\n",@temp) ;
                    close fh;

                    print STDERR "." if $debug == 1 ;
                    open (Q, "cat $rand_file1 | parallel -j $pthreads seqfetch -t 3 -display-gi F -s {}  2>/dev/null| ") if $parallel == 1      ;
                    open (Q, "cat $rand_file1 | parallel -j $pthreads \'epost -db protein -format acc -id {}  2>/dev/null | elink -target nuccore  2>/dev/null| efetch -format acc 2>/dev/null | efetch -db nuccore -format gbwithparts 2>/dev/null\'| ") if $parallel == 2   ;
                    sleep $psleep;
                    @qt = <Q>;
                    close Q;
                    push (@bulk , @qt);
                    $x_bno++;
                    $newbatch = $pbatch * $x_bno;
                    @temp = ();
                 }
                 $x1++;
             }
            #system ("cp $rand_file errfile1\n");
            print STDERR "\n Done parallel\n" if $debug == 1;

         #send to seqfetch if $parallel == 1
         #print STDERR "bulk:parallel:seqfetch." if $debug == 1 ;
         #open (identity,"cat $input_file  | parallel -j $pthreads seqfetch  -t 3  -display-gi F -s {}  2>/dev/null| " ) ;
         #@bulk = <identity>;
         #close(identity);

         #send to efetch if $parallel == 2
         #print STDERR "bulk:parallel:efetch."  if $debug == 1 ;

      }
     parsebulk ();

### check which WP did not get bulk and see if there is replacement acc for WPs in nr ssl
#Maintain a record of the WP and its equivalent acc
#
#
#
#     #adding the WP replacement acc to the list
#     open (T, ">$input_file") ;
#     print T join( "\n", @additional_ac );
#     close T;
#
# $element_acc = $gilines[$i];    # for later use if input is old acc (and not gi)
#             if ($element_acc ne $pr_name) {
#               $new_gi = 1; }
#             else {
#               $new_gi = 0 ;
#             }
#

}
unlink ( $rand_file);
unlink ( $rand_file1);
#######


$i        = 0;
$no       = 0;
@blastgis = ();
foreach $element (@temparg) {
        @input1 = ();
        $gilines[$i] = $element;
        $try_count = 0;

        START:

        $element =~ s/\s+$//;
        $element =~ s/^\s+//;

        $cds_count      = 0;
        @t                    = ();
        $bool_first_cds = 0;
        $bool_gene      = 0;
        $bool_locus     = 0;
        $bool_pid       = 0;
        $bool_prd       = 0;
        $bool_gi        = 0;
        $bool_type      = 0;
        $bool_trans     = 0;
        $empty          = 0;
        @gen1           = ();
        @array_cds      = ();
        @array_comp     = ();
        @array_falet    = ();
        @array_gi       = ();
        @array_type     = ();
        @array_gene     = ();
        @array_locus    = ();
        @array_pid      = ();
        @array_prd      = ();
        $new_gi         = 0 ;
        $templine = "";
        $ref_count = -1;
        $element_acc = $gilines[$i];    # for later use if input is old acc (and not gi)

        if ($element =~ /^\d+$/) {     #if input is gi and not accession
              open( relink2, "efetch -db protein -format acc -id $element 2>/dev/null|" );
              @relink2 =  <relink2>;
              close(relink2);
              chomp $relink2[0];
              $element =  $relink2[0];
              $element_acc =  $relink2[0];   #replace gi with acc
        }
        ##

        if ($gbrecs{$element} ) {
             print STDERR "$element foundbefore." if $debug == 1 ;
             @gen1 =   @{$gbrecs{$element}} ;

        }
        else {

            #############Module to speed up  ##using seqfetch first
            print STDERR "$element:seqfetch." if $debug == 1 ;
            open( identity, " seqfetch -s $element   -t 3  -display-gi F   2>/dev/null| " ) ;
            @gen1 = <identity>;  # replacing the @gen1
            close(identity);
        }
        ###checking if genbank file is complete##
        $empty = checkempty (\@gen1,$element) ;


        #############using efetch if the above failed  ##checking first  nt acc from list
        if ($empty == 0) {
           print STDERR "efetch." if $debug == 1 ;
           open( relink1, "echo $element |  epost -db protein -format acc 2>/dev/null | elink -target nuccore  2>/dev/null| efetch -format acc 2>/dev/null|" );
           @relink1 =  <relink1>;
           close(relink1);
           $nt_name = $relink1[0] ;  ##first element
           #   $nt_name = pop (@relink1) ;   ##last element
           chomp $nt_name;
           $nt_name =~ s/^\s+//;
           $nt_name =~ s/\s+$//;
           %seen = ();
           if ($nt_name ne "") {
               if (     $gbrecs{$nt_name} ) {
                    print STDERR "foundbefore." if $debug == 1 ;
                @gen1 =   @{$gbrecs{$nt_name}} ;
               }
               else {
                  @gen1 = ();
                  if ($nt_name !~ /^XM/ ) {         #not mRNA
                    print STDERR "gbwithparts." if $debug == 1 ;
                    open( identity, "efetch -db nuccore -id $nt_name -format gbwithparts 2>/dev/null| " ) ;
                    @gen1 = <identity>;  # replacing the @gen1
                    close(identity);
                    $gbrecs{$nt_name} = [@gen1] ;
                    $seen{$nt_name}++;
                  }
                }
           }
           ###checking if genbank file is complete##
           $empty = checkempty (\@gen1,$element) ;
        }

        ##for wp going to nr ssl  if the above failed
        #if ($empty == 0) {
        #
        #
        #       $empty = checkempty (\@gen1,$element) ;
        #}
        ######going to IPG if the above two failed
        if ($empty == 0) {
                 print STDERR "ipg." if $debug == 1 ;
                 #open( relink1, "esearch -db protein -query $element |  efetch -format ipg 2>/dev/null|  tail -n +2 | cut -f 3,7 |" );
                 ##open( relink1, "efetch -db protein -id $element -format ipg 2>/dev/null|  tail -n +2 | cut -f 2,6 |" );
                 #@relink1 =  <relink1>;
                 #close(relink1);

                 open( relinkfull1, "efetch -db ipg -id $element -format ipg 2>/dev/null|" );
                 @relinkfull1 =  <relinkfull1>;
                 close(relinkfull1);

                 @relink1 = () ;
                 foreach ( @relinkfull1) {       ##getting column numbers on the fly
                          @t_rel = split( /\t/, $_ );
                          if ($t_rel[0] eq "Id") {
                             $colt_no = 0;
                            foreach $col_t (@t_rel) {
                                 $colt_no1 = $colt_no if $col_t eq "Nucleotide Accession" ;
                                 $colt_no2 = $colt_no if $col_t eq "Protein" ;
                                 $colt_no++
                            }
                          next ;
                          }

                          push (@relink1,"$t_rel[$colt_no1]\t$t_rel[$colt_no2]\n")  ;

                 }
                 #print STDERR "relink\n@relinkfull1\n@relink1\n" if $debug == 1 ;



                 foreach $item (@relink1) {
                    print STDERR "." if $debug == 1 ;
                    chomp($item);
                    ($nt_name , $pr_name) = split (/\t/,$item) ;
                    $nt_name =~ s/^\s+//;
                    $nt_name =~ s/\s+$//;
                    next if  $nt_name eq "";
                    next if  $seen{$nt_name} ;
                    if ($element_acc ne $pr_name) {
                      $new_gi = 1; }
                    else {
                      $new_gi = 0 ;
                    }
                    $element =  $pr_name ;  # to store the new gi

                    if ($gbrecs{$nt_name} ) {
                        print STDERR "foundbefore." if $debug == 1 ;
                        @gen1 =  @{$gbrecs{$nt_name}} ;
                    }
                    elsif ($nt_name !~ /^XM/ ) {         #not mRNA
                      open( identity, "efetch -db nuccore -id $nt_name -format gbwithparts 2>/dev/null| " ) ;
                      @gen1 = <identity>;  # replacing the @gen1
                      close(identity);
                      $gbrecs{$nt_name} = [@gen1] ;
                      $seen{$nt_name}++;
                    }

                    ###checking if genbank file is complete##
                    $empty = checkempty (\@gen1,$element) ;

                    last if  $empty > 10;
                 }
        }

        if ($empty == 0 and $try_count < $tryagain) {    ##trying for connectivity issues, already tried once
           $try_count++ ;
           $element =  $gilines[$i] ;
           print STDERR "trying $element again $try_count after sleeping for $sec seconds \n" if $debug == 1;
           sleep ($sec) ;
           goto START ;

        }

        ####################
        ###
        if ($empty > 10 ) {
              savegenarray() if !($gbrecs{$element} );
              print STDERR "getop." if $debug == 1 ;
              #   $file_has_gene_line = 0;
              $gen_j = 0;
              foreach $item (@gen1) {
                  chomp($item);
                  $genline = $item;
                  #####finding and counting gene CDS##
                  if ($genline =~ m/^(     CDS             |     rRNA            |     tRNA            |     ncRNA           )/){
                  #if ( $genline =~ /^     gene            / or ($file_has_gene_line  == 0 and $genline =~ m/^(     CDS             |     rRNA            |     tRNA            |     ncRNA           )/)) {
                      $cds_count++ if  $bool_first_cds != 0 ;

                      ##Getting NT bound and check complement
                      @t = ();
                      @t = split( /\s/, $genline );
                      $array_cds[$cds_count]  = pop(@t);
                      @t = ();
                      $array_comp[$cds_count] = "+";
                      $array_comp[$cds_count] = "-" if $array_cds[$cds_count] =~ /complement/  ;
                      $array_cds[$cds_count] =~ s/\<//;
                      $array_cds[$cds_count] =~ s/\>//;

                      ###appending next line if it exists
                      $j1 = $gen_j;
                      while ($gen1[$j1] !~ /^\s+\//) {
                          $tempgenline  = $gen1[$j1];
                          $tempgenline =~ s/^\s+//;
                          $tempgenline =~ s/\s+$//;
                          #print "before:: $array_cds[$cds_count]\n";
                          $array_cds[$cds_count]  .= ",$tempgenline" ;
                          #print "after$subgen[$j]:: $array_cds[$cds_count]\n";
                          $j1++ ;
                      }
                      #cleaning nucleotide bound
                      #@t = split( /\(/, $array_cds[$cds_count] );
                      #   $array_cds[$cds_count] = pop(@t);
                      $array_cds[$cds_count] =~ s/complement//g;
                      $array_cds[$cds_count] =~ s/join//g;
                      $array_cds[$cds_count] =~ s/>//g;
                      $array_cds[$cds_count] =~ s/<//g;
                      $array_cds[$cds_count] =~ s/\(//g;
                      $array_cds[$cds_count] =~ s/\)//g;
                      $array_cds[$cds_count] =~ s/,//g;
                      @t = split( /\.\./, $array_cds[$cds_count] );
                      $t1 =  @t ;
                      if ($t1 > 2 ) {
                        $t1 = pop (@t) ;
                        $array_cds[$cds_count]  = "$t[0]..$t1";
                      }

                      $bool_first_cds = 1;
                      $bool_gene      = 0;
                      $bool_locus     = 0;
                      $bool_pid       = 0;
                      $bool_prd       = 0;
                      $bool_gi        = 0;
                      $bool_type      = 0;
                      $bool_pseudo    = 0;
                      $bool_trans      = 0;
                  }
                  #####finding gene##
                  if ( $genline =~ /gene="/  and $bool_gene == 0 ) {
                      @t = split( /"/, $genline );
                      $array_gene[$cds_count] = pop(@t);
                      @t                     = ();
                      $bool_gene              = 1;
                  }
                  #####finding type##
                  if ( $genline =~ /^     CDS             / and $bool_type == 0 ) {
                      $array_type[$cds_count] = "CDS";
                      $bool_type              = 1;
                  }
                  if ( $genline =~ /^     rRNA            / and $bool_type == 0 ) {
                      $array_type[$cds_count] = "rRNA";
                      $bool_type              = 1;
                  }
                  if ( $genline =~ /^     tRNA            / and $bool_type == 0 ) {
                      $array_type[$cds_count] = "tRNA";
                      $bool_type              = 1;
                  }
                  if ( $genline =~ /^     ncRNA           / and $bool_type == 0 ) {
                      $array_type[$cds_count] = "ncRNA";
                      $bool_type              = 1;
                  }

                  #####finding pseudogene tag##
                  if ( $genline =~ /^\s+\/pseudo$/  and $bool_pseudo == 0 and  $array_type[$cds_count] eq "CDS") {
                      $array_type[$cds_count] = "PSE"  ;
                      $bool_pseudo              = 1;
                  }
                  #####finding locus tag##
                  if ( $genline =~ /locus_tag="/  and $bool_locus == 0) {
                      @t = split( /"/, $genline );
                      $array_locus[$cds_count] = pop(@t);
                      @t                      = ();
                      $bool_locus              = 1;
                  }
                  #####finding protein_id##
                  if ( $genline =~ /protein_id="/  and $bool_pid == 0) {
                      @t = split( /"/, $genline );
                      $array_pid[$cds_count] = pop(@t);
                      @t                    = ();
                      $bool_pid              = 1;
                      @temp_pid = split( /\./, $array_pid[$cds_count] );
                      @temp_element = split( /\./, $element );
                      #if ( $array_pid[$cds_count] eq $element ) {        ##for new format gis
                      if ( $temp_pid[0] eq $temp_element[0] ) {        ##for new format gis
                        push( @changedacc, "$element_acc\t$array_pid[$cds_count]" ) if $new_gi == 1;
                        $array_pid[$cds_count] = $element_acc if $new_gi == 1 && $keep == 0 ;   ## to replace acc if they differ due to identity obtained for old gi
                        $array_gi[$cds_count] = $gilines[$i] if $gilines[$i] =~ /^\d+$/ ;  ## #if input is gi and not accession
                        $ref_count = $cds_count;
                      }
                  }
                  #####finding product##
                  if ( $genline =~ /product="/  and $bool_prd == 0) {
                      @t = split( /"/, $genline );
                      $array_prd[$cds_count] = pop(@t);
                      @t                    = ();
                      $bool_prd              = 1;
                  }

                  #####finding translation##
                  if ( $genline =~ /translation="/  and $bool_trans == 0) {
                      @t = split( /"/, $genline );
                      $templine             = pop(@t);
                      @t                    = ();
                      $templine =~ s/\s+$//;
                      $array_falet[$cds_count] = length($templine);
                      $bool_trans              = 1;
                      ##closing everything else
                      $bool_gene      = 1;
                      $bool_locus     = 1;
                      $bool_pid       = 1;
                      $bool_prd       = 1;
                      $bool_gi        = 1;
                      $bool_type      = 1;
                      $bool_pseudo    = 1;
                      #
                  }
                  if ( $bool_trans == 1 and $genline !~ /translation="/) {
                      $templine =  $genline ;
                      $templine =~ s/^\s+//;
                      $templine =~ s/\s+$//;
                      if ($templine =~ /"/) {
                         $templine =~ s/"//;
                         $bool_trans   = 0;
                      }
                      $array_falet[$cds_count] += length($templine);
                  }
                  ######finding GI##
                  if ( $genline =~ /="GI:/  and $bool_gi == 0) {
                      @t = split( /:/, $genline );
                      $array_gi[$cds_count] = pop(@t);
                      @t                    = ();
                      $bool_gi              = 1;
                      $array_gi[$cds_count] =~ s/"//;
                      if ( $array_gi[$cds_count] == $element ) {
                          $array_gi[$cds_count] = $gilines[$i]  if $new_gi == 1;   ## to replace gis if they differ due to identity obtained for the WP problem
                          $ref_count = $cds_count;
                      }
                  }
                  $gen_j++ ; ##keeping track of line number for eukaryotes NTbound
                  last if $genline =~ /ORIGIN/ ;

              }

              ######
              if ($ref_count == -1) {
                 print STDERR "No-op." if $debug == 1 ;
                 $no_access[$no] = $gilines[$i];
                 $no++;
                 $i++;
                 next;
              }
              print STDERR "done\n" if $debug == 1 ;
              #######Printing Operons###############
              ###Getting NT accession from genbank file##
              @input = grep ( /VERSION/, @gen1);
              chomp($input[0]);
              @s = split( /VERSION\s+/, $input[0] );
              chomp $s[1];
              $acno[$i]       = $s[1];

              ###Getting organism from genbank file##
              @input = grep ( /ORGANISM\s/, @gen1);
              chomp($input[0]);
              $input[0] =~ s/^\s+//;
              $input[0] =~ s/\s+$//;
              print  "$input[0]  accession no is $acno[$i] Protein is $gilines[$i]\n";

              ####ABOVE
              ## To get proper above if there are RNA inbetween
              $new_above = 0 ;
              $m = 0;
              while ( -$m < $above and $val >=0 ) {
                   $new_above++;
                   $val = $ref_count - $new_above ;
                   $m-- if $array_type[$val] =~ /CDS/ ;
              }
              #
              print ".   ";
              printf "%-18s %-3s %-5s %-20s %-6s %-8s %-20s %-10s %-45s\n", cds, dir, len,
                pid, type, gene, locus, gi, product;
              for ( $m = $new_above ; $m >= 1 ; $m-- ) {
                  $val = $ref_count - $m;
                  if ( $val >= 0 ) {
                    if (  $array_type[$val] eq "CDS") {
                      push( @blastgis, $array_pid[$val] );
                      $array_falet[$val] = getfaletters ($array_pid[$val]) if !$array_falet[$val] ;
                    }
                      print ".   ";
                      printf "%-18s %-3s %-5s %-20s %-6s %-8s %-20s %-10s %-45s\n",
                        map { $_ || "." }
                        ($array_cds[$val], $array_comp[$val], $array_falet[$val],
                        $array_pid[$val],  $array_type[$val],  $array_gene[$val], $array_locus[$val],
                        $array_gi[$val], $array_prd[$val]);
                   }
             }

              #Query
              $array_falet[$ref_count] = getfaletters ($array_pid[$ref_count]) if !$array_falet[$ref_count] ;

              print "--> ";
              printf "%-18s %-3s %-5s %-20s %-6s %-8s %-20s %-10s %-45s\n",
                map { $_ || "." }
                ($array_cds[$ref_count],   $array_comp[$ref_count],
                $array_falet[$ref_count], $array_pid[$ref_count],   $array_type[$ref_count],
                $array_gene[$ref_count],  $array_locus[$ref_count],
                $array_gi[$ref_count],   $array_prd[$ref_count]);

              #BELOW
              # To get proper below if there are RNA inbetween
              $new_below = 0 ;
              $m = 0;
              while ( $m < $below and $val <= $cds_count ) {
                   $new_below++;
                   $val = $ref_count + $new_below ;
                   $m++ if $array_type[$val] =~ /CDS/ ;
              }
              #

              for ( $m = 1 ; $m <= $new_below ; $m++ ) {
                  $val = $ref_count + $m;
                  if ( $val <= $cds_count) {
                    if ( $array_type[$val] eq "CDS") {
                      push( @blastgis, $array_pid[$val] );
                      $array_falet[$val] = getfaletters ($array_pid[$val]) if !$array_falet[$val] ;
                    }
                    print ".   ";
                      printf "%-18s %-3s %-5s %-20s %-6s %-8s %-20s %-10s %-45s\n",
                        map { $_ || "." }
                        ($array_cds[$val], $array_comp[$val], $array_falet[$val],
                        $array_pid[$val],  $array_type[$val],  $array_gene[$val], $array_locus[$val],
                        $array_gi[$val], $array_prd[$val]);
                   }
              }
              print "---------------------------------------\n";
        }
        else {   ## no operon retreived
              $no_access[$no] = $gilines[$i];
              $no++;
        }

    $i++;
}

############################################
## printing Gis without accession numbers. #
############################################
if ( $no > 0 ) {
    print "\n \nGis without accession numbers. Please get another gi\n";
    print join( "\n", @no_access );
    print "\n";
    #$no1 = 0;
    #while ( $no1 < $no ) {
    #    print "$no_access[$no1] \n";
    #    $no1++;
    #}
}

############################################
## printing Gis for blastclust. #
############################################
@blastgis_in  = sort (@blastgis);
$prev         = 'nonesuch';
@blastgis_out = grep( $_ ne $prev && ( ($prev) = $_ ), @blastgis_in );
print "\n\nGis for blastclust are\n";
print join( "\n", @blastgis_out );
print "\n";

############################################
## printing changed gis to file. #
############################################
$len = 0;
$len  = @changedacc;
if ($len > 0) {
   open (T, ">$changed") ;
   print T join( "\n", @changedacc );
   print T "\n";
   close T;
}
####END

sub getfaletters {
   $sub_input = $_[0]  ;
   chomp ($sub_input);
   open( fa, "$tass_path/gi2fasta $sub_input 2>/dev/null| faletters 2>/dev/null |" );
   @letters = <fa>;
   chomp($letters[0]);
   close(fa);
   return $letters[0] ;
}


sub checkempty {
   ($one_ref, $subelement) = @_;
   @subgen = @{ $one_ref };
   $subempty = @subgen;
   ##checking if genbank file is complete##
   @subinput = ();
   @subinput1 = ();
   @subinput1 = grep ( /$element/, @subgen);
   chomp($subinput1[0]);
   @subinput = grep ( /ORIGIN/, @subgen); ##END OF FILE
   chomp($subinput[0]);
   #print "here $subinput[0]  , $subinput1[0]  \n" ;
   if ( $subinput[0] eq "" or $subinput1[0] eq "") {
      $subempty = 0 ;
   } else {
      $subempty = 0 if  $subinput1[0] !~ /$subelement/ or $subinput[0] !~ /ORIGIN/;
   }
   return $subempty ;
}

sub qmonitor {
   $sleep   = 15 ;
   warn  "\n" if ($debug == 1);
   @temp = @{$_[0]};

   print STDERR "\nMonitoring Que\n";

   while (1) {
       print STDERR ".";
       $match = 0;
       @t = ();
       open(QSTAT1,"qstat |") || die "qstat failed to run";
       @qstatar = <QSTAT1>;
       foreach (@qstatar) {
           next if $_ =~ /^job-ID/;
           next if $_ =~ /^--/;
           s/^\s+//;
           @temp2 = split (/\s+/, $_);
           @t = grep( /$temp2[0]/i, @temp );
           $match++ if $t[0] ne "" ;
       }
       close QSTAT1;
       if ( $match > 0) {
           warn "Processes listed are still running:$match\n" if ($debug == 1);
       } else {
           last;
       }
       sleep $sleep;
   }
   print STDERR "\n";

}

sub parsebulk {
   # break bulk in to individual @gen1 and in each loop send to sub savegenearray
   @gen1 = ();
   foreach (@bulk) {
      push (@gen1 , $_) ;
      if ($_ =~ /^\/\//) {
         savegenarray();
         @gen1 = ();
      }
   }
}

sub savegenarray {
        ###Getting NT accession from genbank file##
        @temp_input = grep ( /VERSION/, @gen1);
        chomp($temp_input[0]);
        @s = split( /VERSION\s+/, $temp_input[0] );
        chomp $s[1];
        $temp_accno       = $s[1];
        return if $found_nuc_record{$temp_accno} > 0;    # return and save no more if the record has been seen and stored before
        print STDERR "storing gen for nucacc $temp_accno\n" if $debug == 1 ;
        @{$gbrecs{$temp_accno}} = @gen1 ;   # storing genbank array with nucleotide key
        $found_nuc_record{$temp_accno}++;

        #making temparg into regex
        $names = '(' . ( join '|', @temparg ) . ')';
        #print STDERR "$names\n";
        # $regex = qr /$names/;
        @out = grep(/protein_id=/, @gen1);   # grepping all protein ids from genbank

        foreach (@out){
            chomp;
            @s = ();
            @s = split( /\"/, $_ );
            #print STDERR "$s[1] $names\n";
            next if $found_acc_record{$s[1]} > 0;
            if ($_ =~ m/$names/) {
                print STDERR "storing gen for $s[1]\n" if $debug == 1;
                @{$gbrecs{$s[1]}} = @gen1 if $s[1] ne "";  # storing genbank array with protein acc key
                $found_acc_record{$s[1]}++;
            }
        }



}
