Question

I have written the following code in Perl. The code is reading a pdb file and getting some values. Ignore the top part of the code,where everything is working perfect. Problem is in the sub-routine part, where I try to store arrays in the hash3 with model as key another key position the array values can be accessed inside the if condition using this :

$hash3{$model}{$coordinates}[1].

but when I go out of all foreach loop and try to access the elements I only get one value. Please look at the end foreach loop and tell me is it the wrong way to access the hash values.

The pdb file I am using can be downloaded from this link http://www.rcsb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId=1NZS

#!/usr/bin/perl
open(IN,$ARGV[0]);

my @phosphosites;
my $model=1;
my %hash3;
while(<IN>)
  {
    #findmod(@line);
    #finddist;
    #findfreq;
    if((/^MODRES/) && (/PHOSPHO/))
      {
        @line=split;
        push(@phosphosites, $line[2]);
        #print "$line[4]";
      }
    foreach $elements (@phosphosites){
      if(/^HETATM\s+\d+\s+CA\s+$i/)
        {
          @line1=split;
          #print "$line1[5]";
          #print "$line1[6] $line1[7] $line1[8]\n";
          push(@phosphositesnum, $line1[5]);
        }
    }
    $pos=$line1[5];
    #findspatial(\@line,\@line1);
  }

my @ori_data=removeDuplicates(@phosphositesnum);
sub removeDuplicates {
  my %seen = ();
  my @vals = ();

  foreach my $i (@_) {
    unless ($seen{$i}) {
      push @vals, $i;
      $seen{$i} = 1;
    }
  }

  return @vals;
}

$a=(@phosphosites);
print "$a\n";
print "@phosphosites\n";
print "@ori_data\n";

close(IN);

open(IN1,$ARGV[0]);
my (@data)=<IN1>;
spatial(\@ori_data);
sub spatial {

  my @spatial_array1=@{$_[0]};

  foreach $coordinates(@spatial_array1)
    {
      $model=1;
      {foreach $data1(@data){



        if($data1=~ m/^HETATM\s+\d+\s+CA\s+[A-Z]*\s+[A-Z]*\s+$coordinates/)
          {
            @cordivals=split(/\s+/,$data1);
            push @{ $sphash{$model} },[$cordivals[6], $cordivals[7], $cordivals[8]];
            $hash3{$model}{$coordinates}= \@cordivals;
            #print "$model $coordinates $hash3{$model}{$coordinates}[6] $hash3{$model}{$coordinates}[7] $hash3{$model}{$coordinates}[8]\n";
            #print "$model $sphash{$model}[$i][0] $sphash{$model}[$i][1] $sphash{$model}[$i][2]\n";

          }

        elsif($data1=~ m/^ENDMDL/)
          {
            $model++;
          }
        #print "$model $coordinates $hash3{$model}{$coordinates}[6] $hash3{$model}{$coordinates}[7] $hash3{$model}{$coordinates}[8]\n";


      }
     }
    }

    #foreach $z1 (sort keys %hash3)
    #  {
    #    foreach $z2(@spatial_array1){
    #      print "$z1 $z2";
    #      print "$hash3{$z1}{$z2}[6]\n";
    #      print "$z2\n";
    #    }
    #  }
}

After using the Data::Dumper option it is giving me this kind of output

$VAR1 = {
      '11' => {
                '334' => [
                           'HETATM',
                           '115',
                           'CA',
                           'SEP',
                           'A',
                           '343',
                           '-0.201',
                           '-2.884',
                           '1.022',
                           '1.00',
                           '99.99',
                           'C'
                         ],

                '342' => $VAR1->{'11'}{'334'},

                '338' => $VAR1->{'11'}{'334'},

                '335' => $VAR1->{'11'}{'334'},
                '340' => $VAR1->{'11'}{'334'},

                '343' => $VAR1->{'11'}{'334'},

                '336' => $VAR1->{'11'}{'334'}
              },

      '7' => {

               '334' => $VAR1->{'11'}{'334'},

               '342' => $VAR1->{'11'}{'334'},

               '338' => $VAR1->{'11'}{'334'},

               '335' => $VAR1->{'11'}{'334'},

               '340' => $VAR1->{'11'}{'334'},

               '343' => $VAR1->{'11'}{'334'},

               '336' => $VAR1->{'11'}{'334'}

             },

      '2' => {

               '334' => $VAR1->{'11'}{'334'},

               '342' => $VAR1->{'11'}{'334'},
               ...
Was it helpful?

Solution

Change:

@cordivals=split(/\s+/,$data1);

to:

my @cordivals=split(/\s+/,$data1);

What seems to be happening is that all the hash elements contain references to the same array variable, because you're not making the variable local to that iteration.

In general, you should use my with all variables.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top