Reputation: 31
I am attempting to make a script that calculates the centroid of two amino acids then finds the distance between the two centroids. Obviously to do this I need all of the x,y,z coordinates which I have and can get at just fine. However, when I attempt to find the average of each of these I am simply getting the last value. Right now I have a fairly lengthy bit of code but the part that is giving me trouble is:
for (my $line = 1; $line <= $#data; ++$line) {
if (($data[$line] =~ m/\s+$resid1\s+P/)&&($data[$line] =~ m/P\s+$resnum1\s+/)) {
chomp $data[$line];
my @splitline = (split /\s+/, $data[$line]);
#print "$splitline[1] $splitline[3] $splitline[5] $splitline[6] $splitline[7] $splitline[8]\n";
#atom# #residue #resid #x-coor #y-coor #z-coor
#calculate the average x coordinate
my @xcoordinate_array;
push @xcoordinate_array, $splitline[6];
$xsum =sum(@xcoordinate_array);
$xaverage=($xsum/$#xcoordinate_array);
print "@xcoordinate_array \n";
#calculate the average y coordinate
my @ycoordinate_array;
push @ycoordinate_array, $splitline[7];
$ysum =sum(@ycoordinate_array);
$yaverage =($xsum/$#ycoordinate_array);
#calculate the average z coordinate
my @zcoordinate_array;
push @zcoordinate_array, $splitline[8];
$zsum =sum(@zcoordinate_array);
$zaverage=($zsum/$#zcoordinate_array);
}
}
Basically what this is supposed to do is search for some residue name (resid1
), then some residue number (resnum1
), read that line into an array (@splitline
) (whose important contents are explained on line 5), then it is supposed to put each type of value into its individual array and use a subroutine (sum
) to add the whole array and then divide by the number of things in the array.
However, when I print any of the averages it is only the last value. I understand why this is happening, however I cannot calculate the average outside of the loop since perl throws a fit saying that I cannot access the @xcoordinate_array
outside of the loop. I understand that it is just overriding the array every time it goes the loop however I was hoping that it would add each value onto the array and at the end give the correct value.
So what I am asking is, how do I fix it so that I can get the array "full" with each value?
Upvotes: 0
Views: 975
Reputation: 36448
You're re-creating the arrays, and calculating an average of a single element, for each matching line. Declare the arrays outside, and print their values after you're done with the file:
my (@xcoordinate_array, @ycoordinate_array, @zcoordinate_array);
for (my $line = 1; $line <= $#data; ++$line) {
if (($data[$line] =~ m/\s+$resid1\s+P/) && ($data[$line] =~ m/P\s+$resnum1\s+/)) {
chomp $data[$line];
my @splitline = (split /\s+/, $data[$line]);
push @xcoordinate_array, $splitline[6];
push @ycoordinate_array, $splitline[7];
push @zcoordinate_array, $splitline[8];
}
}
#calculate the average x coordinate
if (@xcoordinate_array > 0) {
$xsum = sum(@xcoordinate_array);
$xaverage = $xsum / @xcoordinate_array;
}
#calculate the average y coordinate
if (@ycoordinate_array > 0) {
$ysum = sum(@ycoordinate_array);
$yaverage = $ysum / @ycoordinate_array;
}
#calculate the average z coordinate
if (@zcoordinate_array > 0) {
$zsum = sum(@zcoordinate_array);
$zaverage = $zsum / @zcoordinate_array;
}
Upvotes: 2