2012-01-08 7 views
3

Je génère des coordonnées 3D (x, y, z) dans un fichier avec le code suivant.Impression au format prédéfini Perl

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"; 
} 

Maintenant, mon problème est que je veux obtenir la sortie avec un format précis (APB) avec des valeurs d'index comme,

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 

Voici les x, y, z shoulb être des données type réel (8.2) et d'autres sont justifiés à droite. Les valeurs x, y, z ne sont pas celles générées par le programme. J'ai placé des valeurs arbitraires. Aidez-moi, s'il vous plaît.

+0

Je ne comprends pas votre question. Perl n'est pas un langage strictement typé, donc il n'a pas nativement un concept de "type de données réel". –

+0

@JackManey, que je veux obtenir la sortie comme je l'ai montré, j'ai mentionné les valeurs d'index sur la première ligne, je n'ai pas besoin de deux premières lignes en sortie. juste pour faire comprendre, j'ai écrit les deux premières lignes. – gthm

+0

Il existe quelques modules perl qui lisent/écrivent des fichiers PDB. Jetez un oeil à https://metacpan.org/module/Chemistry::File::PDB – JRideout

Répondre

1

On peut supposer que vous pouvez remplacer l'existant:

 push @arr_grid, "$x $y $z\n"; 

avec une variation appropriée de:

 push @arr_grid, sprintf("%8.2f %8.2f %8.2f\n", $x, $y, $z); 

Cela vous permet de contrôler le format des numéros.

1

Vous pouvez utiliser printf pour spécifier l'espacement, l'alignement et les chiffres significatifs. Quelque chose comme cela pourrait fonctionner:

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', '', @$_; 
} 

Il pourrait peut-être plus logique que d'utiliser un module Perl conçu pour le format PDB tels que Chemistry::File::PDB ou Bio::Structure::IO::pdb

+0

Oui, mais je ne veux utiliser aucun module. je veux apprendre. – gthm

+1

@gthmgeeky, c'est une bonne chose à essayer, mais comme vous allez remarquer que certains cas spéciaux (souvent appelés cas de coin) peuvent devenir très difficile. La même chose se produit pour les données séparées par des virgules (csv); il semble que cela devrait être facile, mais ce n'est pas le cas. Une fois que vous avez eu du plaisir à apprendre, il est généralement préférable de profiter des modules disponibles, car ils ont souvent traité tous les cas de coin pour vous. –

+1

+1 pour les modules CPAN –

4

Vous souhaitez utiliser les options de format de Perl pour la présentation des données de sortie de manières prédéfinies. Vous pouvez lire à ce sujet here.

Votre exemple, réécrite un peu:

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 
. 

Le FORMAT_TOP est imprimé tous les $= (ou $FORMAT_LINES_PER_PAGE) afin de réinitialiser cette variable si vous voulez imprimer plus rarement ou un nombre ridiculement élevé si vous voulez imprimer seulement une fois que.

Exemple de sortie:

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 

J'ai un autre problème: quand je suis chiffres d'impression avec des points décimaux comme

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 

Dans les colonnes ci-dessus, je dois imprimer le point de décimal dans le même index. Lorsque je fais des calculs et que je mets à jour des valeurs, les points en décimales sont décalés. i besoin d'une sortie comme

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:
Exemple à un 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 
. 
+1

+1 pour les formats, une fonctionnalité Perl sous-utilisée, et peut-être exactement le bon outil ici –

+0

J'entends [Perl6 :: Form] (http://search.cpan.org/perldoc?Perl6::Form) (formes Perl6 pour Perl5) sont beaucoup mieux que ceux intégrés. – ikegami

+0

@Mattias, Comment écrire ce formulaire de sortie dans un fichier? comme output.txt autre que le programme >> output.txt – gthm