In Perl, how do I reference a value within a loop after I exited a loop still in another loop -
i've been working on days. so, project work protein data bank files (*.ent) using perl. have whole huge directory full of them, , need calculate distance between atoms cd1 , od2. if od2 not present, calculate distance between atom cd1 , oe2. never both atoms present in file. isn't issue me now, can directly print out values in each file within if , elsif condtional.
but when exit if/elsif conditional, memory of values in each file, goes away. again, i've done lot of hard work open whole loop of files print solutions each file.
essentially, in order calculate distance, need calculate radial distance 2 points: p(x1,y1,z1) , q(x2,y2,z2), point p x,y,z coordinates of cd1 atom, , point q x,y,z distance of od2 or oe2. called them alternatives cd1 atom coordinates.
pq distance = sqrt[(x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2]
in order deal 800 (*.ent) files, used foreach loop iterative on files in directory, , while loop loop through them. there several columns of *.ent files separated variable amounts of white-space, separated each line array based on conditions, , array @fields, $fields[2] counting 0 third column of .ent file being processed, or 3rd column atom name.
from i've parsed *.ent files see, though files have more information. separated each line if contained atom.
atom 1 cb glu 9 53.764 15.456 11.540 1.00 0.00 c atom 2 cg glu 9 53.265 15.125 12.928 1.00 0.00 c atom 3 cd glu 9 54.264 15.606 13.972 1.00 0.00 c atom 4 oe1 glu 9 55.435 15.909 13.653 1.00 0.00 o atom 5 oe2 glu 9 53.831 15.724 15.123 1.00 0.00 o1- atom 6 cb trp 16 51.989 19.241 13.113 1.00 0.00 c atom 7 cg trp 16 53.254 19.906 13.560 1.00 0.00 c atom 8 cd1 trp 16 54.518 19.371 13.545 1.00 0.00 c atom 9 cd2 trp 16 53.380 21.238 14.053 1.00 0.00 c ...
there more lines of atoms need. -----------
\the first 3 columns containing decimals read file right left x-y-z coordinates. starting counting zero, column 2 atom name (this important me it's basis of calculation), , column 3 amino acid abbreviation 2 amino acids in file. not important because important atoms cd1, od2, or oe2 ones matter, , don't repeat repeat can't mix atoms up, , referring right atoms in each residue.
my entire perl script calculate distance looks this. it's lot!
#!/usr/bin/perl use strict; use warnings; use 5.010; use math::complex; # program take *.gjf files in directory , calcualte distance of oe2 of glutamate cd1 of trypotphan, # calculate distance of od2 of aspartate cd1 of trypotphan. # logic: if residue =~ asp, calculate distance of od2 cd1 # logic: if residue =~ glu, calculte distance of oe2 cd1. # 3d distance = sqrt[(x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2] # formula distance between points (x1, y1, z1), , (x2, y2, z2) in three-dimmensional space, or in sphere. # x1, y1, z1 = od2 atom of aspartate, or oe2 atom of glutamate. # x2, y2, z2 = cd1 atom of tryptophan. print "watch , learn!\n"; # because i'm badass biological programmer solving complex problem. @files = <*.ent>; # save files in current directory array. $file_array; # used calculate how many pdb files in directory foreach $file (@files) # foreach loop loops through pdb files in directory individually. { ($base,$ext) = split (/\./,$file); # split files along period (.) base , extension. print "filename $file\n"; print "basename = $base \n"; print "extension = $ext \n"; $outfile_cd1_distance = join('_', $base, "cd1_dist"); # *_cd1_dist.ent denotes file of distance solution file. $outfile_cd1_distance = join('.', $outfile_cd1_distance, "txt"); # pdb extension has added file. open (my $fh, '<:encoding(utf-8)', $file) # open file read from. # ent file. or die "could not open file $file $!"; open(my $coordinates, '>', $outfile_cd1_distance) or die "could not open file $outfile_cd1_distance $!"; \# open file write to. # coordinates pdb coordinates. $counter; $counter = 0; while (my $line =<$fh>) # while loop goes through rows of original pdb files till reaches end. { chomp $line; $counter++; if ($line =~ m/atom/) { # print "$line\n"; @fields = split(/\s+/, $line); # save fields 2,3, 6,7,8 $atom = $fields[2]; $residue = $fields[3]; $x_coordinate = $fields[6]; $y_coordinate = $fields[7]; $z_coordinate = $fields[8]; # parsed, calculate distance. # $delta_x = $x_cd1_coordinate - $x_alt_coordinate; # $delta_x_squared = $delta_x * $delta_x; # $delta_y = $y_cd1_coordinate - $y_alt_coordinate; # $delta_y_squared = $delta_y * $delta_y; # $delta_z = $z_cd1_coordinate - $z_alt_coordinate; # $delta_z_squared = $delta_z * $delta_z; # $sum_of_squares_diff = $delta_x_squared + $delta_y_squared + $delta_z_squared; # $cd1_distance = sqrt($sum_of_squares_diff); if ($fields[2] =~ m /cd1/) { $x_cd1_coordinate = $x_coordinate; $y_cd1_coordinate = $y_coordinate; $z_cd1_coordinate = $z_coordinate; \# print "$x_cd1_coordinate"; \# print "$z_cd1_coordinate\n"; } elsif ($fields[2] =~ m/od2|oe2/) { $x_alt_coordinate = $x_coordinate; $y_alt_coordinate = $y_coordinate; $z_alt_coordinate = $z_coordinate; # print "$x_alt_coordinate\n"; # print "$x_coordinate"; } print "\$x_cd1_coordinate\n"; # $x_coordinate = $ echo $line | awk '{print $3}'; # print $x_coordinate; } } # ending while loop } #ending foreach loop $file_array = scalar(@files); print "\ni processed $file_array ent files ... computing distance cd1\n";
end of script:
what issue while can issue print statements in if ($field conditionals) print the 6 variables need calculate equation of line, , print values. when exit if conditional , try print 1 of 6 variables inside if-conditional, while out of if-conditional not work.
basically, issue i'm in 1 room , program in room when try execute formula commented out in program. if can see x,y,z coordinates 1 point when in loop.
do understand problem? can offer suggestions?
thank you!
hey, know guys right variable scope. should have declared variables higher within while loop of program. met colleague , fixed program!
#!/usr/bin/perl use strict; use warnings; use 5.010; use math::complex; # program take *.gjf files in directory , calcualte distance of oe2 of glutamate cd1 of trypotphan, # calculate distance of od2 of aspartate cd1 of trypotphan. # logic: if residue =~ asp, calculate distance of od2 cd1 # logic: if residue =~ glu, calculte distance of oe2 cd1. # 3d distance = sqrt[(x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2] # formula distance between points (x1, y1, z1), , (x2, y2, z2) in three-dimmensional space, or in sphere. # x1, y1, z1 = od2 atom of aspartate, or oe2 atom of glutamate. # x2, y2, z2 = cd1 atom of tryptophan. print "watch , learn!\n"; # because i'm badass biological programmer solving complex problem. @files = <*.ent>; # save files in current directory array. $file_array; # used calculate how many pdb files in directory foreach $file (@files) # foreach loop loops through pdb files in directory individually. { ($base,$ext) = split (/\./,$file); # split files along period (.) base , extension. print "filename $file\n"; print "basename = $base \n"; print "extension = $ext \n"; $outfile_cd1_distance = join('_', $base, "cd1_dist"); # *_cd1_dist.ent denotes file of distance solution file. $outfile_cd1_distance = join('.', $outfile_cd1_distance, "txt"); # pdb extension has added file. open (my $fh, '<:encoding(utf-8)', $file) # open file read from. # ent file. or die "could not open file $file $!"; open(my $coordinates, '>', $outfile_cd1_distance) or die "could not open file $outfile_cd1_distance $!"; \# open file write to. # coordinates pdb coordinates. $counter; $counter = 0; ($x_cd1_coordinate, $y_cd1_coordinate, $z_cd1_coordinate); ($x_alt_coordinate, $y_alt_coordinate, $z_alt_coordinate); while (my $line =<$fh>) # while loop goes through rows of original pdb files till reaches end. { chomp $line; $counter++; if ($line =~ m/atom/) { # print "$line\n"; @fields = split(/\s+/, $line); # save fields 2,3, 6,7,8 $atom = $fields[2]; $residue = $fields[3]; $x_ref_cd1_coordinate; $x_coordinate = $fields[6]; $y_coordinate = $fields[7]; $z_coordinate = $fields[8]; if ($fields[2] =~ m/cd1/) { $x_cd1_coordinate = $x_coordinate; $y_cd1_coordinate = $y_coordinate; $z_cd1_coordinate = $z_coordinate; #my $x_ref_cd1_coordinate = \$x_cd1_coordinate; # print "$x_cd1_coordinate"; # print "$z_cd1_coordinate\n"; } elsif ($fields[2] =~ m/od2|oe2/) { $x_alt_coordinate = $x_coordinate; $y_alt_coordinate = $y_coordinate; $z_alt_coordinate = $z_coordinate; # print "$x_alt_coordinate\n"; # print "$x_coordinate"; } # print ref $x_cd1_coordinate # $x_coordinate = $ echo $line | awk '{print $3}'; # print $x_coordinate; } } # ending while loop print "this x cd1 $x_cd1_coordinate\n"; print "this y alt $y_alt_coordinate\n"; # parsed, calculate distance. $delta_x = $x_cd1_coordinate - $x_alt_coordinate; $delta_x_squared = $delta_x * $delta_x; $delta_y = $y_cd1_coordinate - $y_alt_coordinate; $delta_y_squared = $delta_y * $delta_y; $delta_z = $z_cd1_coordinate - $z_alt_coordinate; $delta_z_squared = $delta_z * $delta_z; $sum_of_squares_diff = $delta_x_squared + $delta_y_squared + $delta_z_squared; $cd1_distance = sqrt($sum_of_squares_diff); # print distance screen , files: print "this distance $cd1_distance\n"; print $coordinates "$cd1_distance\n"; } #ending foreach loop $file_array = scalar(@files); print "\ni processed $file_array ent files ... computing distance cd1\n";
i'm glad able right script this. i've read perl scripts calculate distance between residues, function calls made 0 sense me, i'm glad able write program calculate distance between 2 atoms!
Comments
Post a Comment