File Coverage

blib/lib/HackaMol/Roles/ReadYAMLRole.pm
Criterion Covered Total %
statement 18 117 15.3
branch 0 20 0.0
condition n/a
subroutine 6 9 66.6
pod 0 2 0.0
total 24 148 16.2


line stmt bran cond sub pod time code
1             package HackaMol::Roles::ReadYAMLRole;
2             $HackaMol::Roles::ReadYAMLRole::VERSION = '0.051';
3             # ABSTRACT: Read files with molecular information
4 11     11   7329 use Moose::Role;
  11         35  
  11         78  
5 11     11   57627 use HackaMol::PeriodicTable qw(%KNOWN_NAMES _trim);
  11         30  
  11         1194  
6 11     11   87 use Math::Vector::Real;
  11         33  
  11         586  
7 11     11   99 use Carp;
  11         32  
  11         746  
8 11     11   6758 use List::MoreUtils qw(singleton);
  11         140844  
  11         79  
9              
10             with qw(
11             HackaMol::Roles::NERFRole
12             );
13              
14             # atoms:
15             #- N 0 0.483824 1.697569 -0.701935
16             #....
17             #- C 2 CC 3 CCC 4 CCCC
18             #vars:
19             #- CC : 1.54
20             #- CCC : 106.42
21             #- CCCC : [-81.90, 89, 09]
22              
23             sub read_yaml_atoms {
24             # this is going to be the simplest implementation for now using the code from the zmatrix reader
25             # generate a zmatrix (or zmatrices if there are scans) and push on to the atoms
26             #xyz file and generate list of Atom object
27             #issue 16 on github
28 0     0 0   my $self = shift;
29 0           my $yaml = shift;
30             #use Data::Dumper;
31             #print Dumper $yaml;
32 0           my %vars = %{$yaml->{vars}};
  0            
33 0           my @atlines = @{$yaml->{atoms}};
  0            
34 0           my @atoms;
35 0           my ( $n, $t ) = ( 0, 0 );
36              
37 0           my @scan_vars = grep {ref($vars{$_}) eq 'ARRAY'} keys (%vars) ;
  0            
38 0 0         if (@scan_vars) {
39 0           my $scan_var = pop @scan_vars;
40 0 0         carp "scanning more than one coordinate not supported; ignoring scans for $scan_vars[0]" if @scan_vars ;
41 0           my $values_rh = delete $vars{$scan_var};
42              
43 0           foreach my $value (@{$values_rh}){
  0            
44 0           $vars{$scan_var} = $value;
45 0           my @atlines = _yaml_substitute_variables(\%vars, \@atlines);
46 0           @atoms = $self->parse_zmat_atoms(\@atlines, \@atoms, $t);
47 0           $t++;
48             }
49             }
50             else {
51              
52 0           my @atlines = _yaml_substitute_variables(\%vars, \@atlines);
53 0           @atoms = $self->parse_zmat_atoms(\@atlines, \@atoms, $t);
54             }
55              
56 0           $atoms[$_]->iatom($_) foreach ( 0 .. $#atoms );
57             #use Data::Dumper;
58             #print Dumper \@atoms;
59              
60 0           return (\@atoms);
61              
62             }
63              
64             sub parse_zmat_atoms {
65 0     0 0   my $self = shift;
66 0           my $zmat = shift;
67 0           my $atoms = shift;
68 0           my $t = shift;
69 0           my @zmat = @{ $zmat };
  0            
70 0           my @atoms = @{ $atoms };
  0            
71              
72             #use Data::Dumper;
73             #print Dumper $zmat;
74              
75             # we have 5 types of extensions
76             # A. SYM 0 x y z
77             # B. SYM
78             # C. SYM i R
79             # D. SYM i R j Ang
80             # E. SYM i R j Ang k Tors
81             # we need to filter the indices (can't lose the location)
82              
83             #type A
84 0           my @iA = grep { $zmat[$_] =~ m/^\s*\w+\s+0(\s+-*\d*\.*\d*){3}/ } 0 .. $#zmat;
  0            
85 0           my @inA = singleton( 0 .. $#zmat, @iA );
86              
87             #type B
88 0           my @iB = grep { $zmat[$_] =~ m/^\s*\w+\s*$/ } @inA;
  0            
89              
90             #type C
91 0           my @iC = grep { $zmat[$_] =~ m/^\s*\w+(\s+\d+\s+\d*\.*\d*)\s*$/ } @inA;
  0            
92              
93             #type D
94 0           my @iD = grep { $zmat[$_] =~ m/^\s*\w+(\s+\d+\s+\d*\.*\d*){2}\s*$/ } @inA;
  0            
95              
96             #type E
97             my @iE = grep {
98 0           $zmat[$_] =~ m/^\s*\w+(\s+\d+\s+\d*\.*\d*){2}\s+\d+\s+-*\d*\.*\d*\s*$/
  0            
99             } @inA;
100              
101 0           my $diff = @zmat - (@iA+@iB+@iC+@iD+@iE); #scalar context
102            
103 0 0         if ($diff){
104 0           print "Lines in Z-matrix: ", scalar (@zmat), " Number of lines to be processed: ", scalar (@zmat) - $diff, "\n";
105 0           print "Lines missed: ", $diff, "\n";
106 0           print "\n\nHere is your Z-matrix:\n";
107 0           print $_ . "\n" foreach @zmat;
108 0           print "Indices of lines to be processed: ", join("\n", @iA, @iB, @iC, @iD, @iE);
109 0           croak "\nThere is something funky with your zmatrix";
110             }
111              
112 0           foreach my $ia (@iA) {
113 0           my ( $sym, $iat1, @xyz ) = split( ' ', $zmat[$ia] );
114 0 0         if ($t) {
115             #print "$ia SHITSHIT $t\n";
116             #print Dumper $atoms[$ia];
117 0           $atoms[$ia]->set_coords($t, V(@xyz));
118             } else {
119 0           $atoms[$ia] = HackaMol::Atom->new(
120             name => $sym.$ia,
121             symbol => $sym,
122             coords => [V(@xyz)]
123             );
124             }
125             }
126            
127 0           foreach my $ib (@iB) {
128 0           my $sym = $zmat[$ib];
129 0           my $a = $self->init;
130 0           $sym =~ s/^\s+|\s+$//;
131 0 0         if ($t) {
132 0           $atoms[$ib]->set_coords($t, $a);
133             } else {
134 0           $atoms[$ib] = HackaMol::Atom->new(
135             name => $sym.$ib,
136             symbol => $sym,
137             coords => [$a]
138             );
139             }
140             }
141              
142             # print Dump 'B', \@atoms;
143              
144 0           foreach my $ic (@iC) {
145 0           my ( $sym, $iat1, $R ) = split( ' ', $zmat[$ic] );
146 0           my $a = $atoms[ $iat1 - 1 ]->xyz;
147 0           my $b = $self->extend_a( $a, $R );
148 0 0         if ($t) {
149 0           $atoms[$ic]->set_coords($t, $b);
150             } else {
151 0           $atoms[$ic] = HackaMol::Atom->new(
152             name => $sym.$ic,
153             symbol => $sym,
154             coords => [$b]
155             );
156             }
157             }
158              
159             # print Dump 'C', \@atoms;
160              
161 0           foreach my $id (@iD) {
162 0           my ( $sym, $iat1, $R, $iat2, $ang ) = split( ' ', $zmat[$id] );
163 0           my $a = $atoms[ $iat1 - 1 ]->get_coords($t);
164 0           my $b = $atoms[ $iat2 - 1 ]->get_coords($t);
165 0           my $c = $self->extend_ab( $b, $a, $R, $ang );
166 0 0         if ($t) {
167 0           $atoms[$id]->set_coords($t, $c);
168             } else {
169 0           $atoms[$id] = HackaMol::Atom->new(
170             name => $sym.$id,
171             symbol => _trim($sym),
172             coords => [$c]
173             );
174             }
175             }
176              
177             # print Dump 'D', \@atoms;
178              
179 0           foreach my $ie (@iE) {
180 0           my ( $sym, $iat1, $R, $iat2, $ang, $iat3, $tor ) =
181             split( ' ', $zmat[$ie] );
182 0           my $a = $atoms[ $iat1 - 1 ]->get_coords($t);
183 0           my $b = $atoms[ $iat2 - 1 ]->get_coords($t);
184 0           my $c = $atoms[ $iat3 - 1 ]->get_coords($t);
185 0           my $d = $self->extend_abc( $c, $b, $a, $R, $ang, $tor );
186 0 0         if ($t) {
187 0           $atoms[$ie]->set_coords($t, $d);
188             } else {
189 0           $atoms[$ie] = HackaMol::Atom->new(
190             name => $sym.$ie,
191             symbol => _trim($sym),
192             coords => [$d]
193             );
194             }
195             }
196 0           return @atoms;
197             }
198              
199             sub _yaml_substitute_variables{
200 0     0     my ($var,$Zmat) = (shift,shift);
201 0           my %var = %{ $var };
  0            
202 0           my @Zmat = @{ $Zmat };
  0            
203              
204 0           foreach my $line (@Zmat){
205 0           my @vals = split (/ /, $line);
206 0 0         next unless @vals > 2;
207 0 0         $line = join(' ', $vals[0], map{ exists($var{$_}) ? $var{$_} : $_ } @vals[1 .. $#vals] );
  0            
208             }
209 0           return (@Zmat);
210             }
211              
212 11     11   28545 no Moose::Role;
  11         32  
  11         108  
213              
214             1;
215              
216             __END__
217              
218             =pod
219              
220             =head1 NAME
221              
222             HackaMol::Roles::ReadYAMLRole - Read files with molecular information
223              
224             =head1 VERSION
225              
226             version 0.051
227              
228             =head1 SYNOPSIS
229              
230             my @atoms = HackaMol->new
231             ->read_zmat_atoms("some.zmat");
232              
233             =head1 DESCRIPTION
234              
235             The HackaMol::Roles::ReadZmatRole provides read_zmat_atoms for the flexible reading of Z-matrix files.
236             It supports inline cartesian coordinates and variables as in the following example:
237              
238             N 0 -12.781 3.620 15.274
239              
240             C 0 -11.976 4.652 15.944
241              
242             C 0 -12.722 6.019 15.985
243              
244             O 0 -13.133 6.378 14.897
245              
246             C 2 CBCA 3 CBCAC 4 CBCACO
247              
248             C 5 CBCA 2 CBCAC 3 CG1CBCAC
249              
250             C 5 CBCA 2 CBCAC 3 CG2CBCAC
251              
252             CBCA = 1.54
253              
254             CBCAC = 113.4
255              
256             CBCACO = 71.85
257              
258             CG1CBCAC = 54.
259              
260             CG2CBCAC = 180.
261              
262             =head1 METHODS
263              
264             =head2 read_zmat_atoms
265              
266             One argument: the filename
267             Returns a list of HackaMol::Atom objects.
268              
269             =head1 SEE ALSO
270              
271             =over 4
272              
273             =item *
274              
275             L<HackaMol>
276              
277             =item *
278              
279             L<HackaMol::Atom>
280              
281             =item *
282              
283             L<HackaMol::Roles::MolReadRole>
284              
285             =item *
286              
287             L<Protein Data Bank|http://pdb.org>
288              
289             =back
290              
291             =head1 CONSUMES
292              
293             =over 4
294              
295             =item * L<HackaMol::Roles::NERFRole>
296              
297             =back
298              
299             =head1 AUTHOR
300              
301             Demian Riccardi <demianriccardi@gmail.com>
302              
303             =head1 COPYRIGHT AND LICENSE
304              
305             This software is copyright (c) 2017 by Demian Riccardi.
306              
307             This is free software; you can redistribute it and/or modify it under
308             the same terms as the Perl 5 programming language system itself.
309              
310             =cut