问题
I'm generating 3D coordinates (x,y,z) to a file with the following code.
for (my $x = 0.000; $x < 4.200; $x += 1.400) {
for (my $y = 0.000; $y < 4.200; $y += 1.400) {
for (my $z = 0.000; $z < 4.200; $z += 1.400) {
push @arr_grid, "$x $y $z\n";
}
}
}
foreach (@arr_grid) {
say "HETATM 1 O HOH 1 $_ O";
}
Now, my problem is that I want to get the output with a precise format (PDB) with Index values like,
1-6 7-11 13-16 18-20 23-26 31-38 39-46 47-54 77-78
(Name) (S.No) (x) (y) (z)
HETATM 1 O HOH 1 -8.863 16.944 14.289 N
HETATM 100 O HOH 16 -15.352 11.525 5.325 N
HETATM 117 O HOH 16 -12.954 9.717 5.182 C
HETATM 126 O HOH 17 -19.225 11.667 -0.391 C
HETATM 1005 O HOH 97 9.246 23.287 11.503 O
Here the x,y,z coordinates shoulb be of data type real(8.2) and others are right justified. x,y,z values are not those generated from program. I placed arbitrary values. Please help me.
回答1:
You want to use perl's format options for presenting output data in predefined ways.
You can read about it here.
Your example, rewritten a bit:
for ($x = 0.000; $x < 4.200; $x += 1.400) {
for ($y = 0.000; $y < 4.200; $y += 1.400) {
for ($z = 0.000; $z < 4.200; $z += 1.400) {
write;
}
}
}
format STDOUT_TOP =
1-6 7-11 13-16 18-20 23-26 31-38 39-46 47-54 77-78
(Name) (S.No) (x) (y) (z)
.
format STDOUT =
HETATM 1 O HOH 1 @<<<<<< @<<<<<< @<<<<<< N
$x $y $z
.
The FORMAT_TOP
is printed every $=
(or $FORMAT_LINES_PER_PAGE
) so reset this variable if you want it printed more rarely or a ridiculously high number if you want it printed only once.
Output example:
1-6 7-11 13-16 18-20 23-26 31-38 39-46 47-54 77-78
(Name) (S.No) (x) (y) (z)
HETATM 1 O HOH 1 0 0 0 N
HETATM 1 O HOH 1 0 0 1.4 N
HETATM 1 O HOH 1 0 0 2.8 N
HETATM 1 O HOH 1 0 0 4.2 N
HETATM 1 O HOH 1 0 1.4 0 N
HETATM 1 O HOH 1 0 1.4 1.4 N
HETATM 1 O HOH 1 0 1.4 2.8 N
HETATM 1 O HOH 1 0 1.4 4.2 N
I have got one more problem: when I'm printing numbers with decimal points like
HETATM 1 O HOH 1 -10 -3.4 -8 N
HETATM 1 O HOH 1 -10 -3.4 -6.6 N
HETATM 1 O HOH 1 -10 -3.4 -5.2 N
HETATM 1 O HOH 1 -10 -3.4 -3.8 N
HETATM 1 O HOH 1 -10 -3.4 -2.4 N
HETATM 1 O HOH 1 -10 -3.4 -1 N
HETATM 1 O HOH 1 -10 -3.4 0.4 N
HETATM 1 O HOH 1 -10 -3.4 1.8 N
HETATM 1 O HOH 1 -10 -3.4 3.2 N
HETATM 1 O HOH 1 -10 -3.4 4.6 N
HETATM 1 O HOH 1 0 -3.4 6 N
In the above columns, I need to print the dot of decimal in the same index. When I'm doing calculations and updating values, the dots in decimals are shifting. i need output like
HETATM 1 O HOH 1 -10 -3.4 -8.0 N
HETATM 1 O HOH 1 -10 -3.4 -6.6 N
HETATM 1 O HOH 1 -10 -3.4 -5.2 N
HETATM 1 O HOH 1 -10 -3.4 -3.8 N
HETATM 1 O HOH 1 -10 -3.4 -2.4 N
HETATM 1 O HOH 1 -10 -3.4 -1.0 N
HETATM 1 O HOH 1 -10 -3.4 0.4 N
HETATM 1 O HOH 1 -10 -3.4 1.8 N
HETATM 1 O HOH 1 -10 -3.4 3.2 N
HETATM 1 O HOH 1 -10 -3.4 4.6 N
HETATM 1 O HOH 1 -10 -3.4 6.0 N
Edit 1:
Example to a dumpfile:
open(DUMPFILE,">output.txt");
for ($x = 0.000; $x < 4.200; $x += 1.400) {
for ($y = 0.000; $y < 4.200; $y += 1.400) {
for ($z = 0.000; $z < 4.200; $z += 1.400) {
write DUMPFILE;
}
}
}
close(DUMPFILE);
format DUMPFILE_TOP =
1-6 7-11 13-16 18-20 23-26 31-38 39-46 47-54 77-78
(Name) (S.No) (x) (y) (z)
.
format DUMPFILE =
HETATM 1 O HOH 1 @<<<<<< @<<<<<< @<<<<<< N
$x $y $z
.
回答2:
Presumably, you could replace the existing:
push @arr_grid, "$x $y $z\n";
with some suitable variation of:
push @arr_grid, sprintf("%8.2f %8.2f %8.2f\n", $x, $y, $z);
This gives you control over the format of the numbers.
回答3:
You can use printf
to specify spacing, alignment, and significant digits. Something like this might work:
my @arr_grid;
for (my $x = 0.000; $x < 4.200; $x += 1.400) {
for (my $y = 0.000; $y < 4.200; $y += 1.400) {
for (my $z = 0.000; $z < 4.200; $z += 1.400) {
push @arr_grid, [$x, $y, $z];
}
}
}
foreach (@arr_grid) {
printf "HETATM%5d %2s%2s HOH 1 %8.3f%8.3f%8.3f\n", 1, 'O', '', @$_;
}
It might might make more sense though to use a perl module designed for the PDB format such as Chemistry::File::PDB or Bio::Structure::IO::pdb
来源:https://stackoverflow.com/questions/8775050/print-output-in-predefined-format-perl