File Coverage

blib/lib/HackaMol/Dihedral.pm
Criterion Covered Total %
statement 41 41 100.0
branch n/a
condition n/a
subroutine 14 14 100.0
pod 4 4 100.0
total 59 59 100.0


line stmt bran cond sub pod time code
1             package HackaMol::Dihedral;
2             $HackaMol::Dihedral::VERSION = '0.051';
3             #ABSTRACT: Dihedral Angle class for HackaMol
4 12     12   997 use 5.008;
  12         51  
5 12     12   83 use Moose;
  12         29  
  12         109  
6 12     12   88745 use namespace::autoclean;
  12         35  
  12         134  
7 12     12   1353 use Carp;
  12         36  
  12         1003  
8 12     12   91 use Math::Trig;
  12         28  
  12         2542  
9 12     12   114 use MooseX::StrictConstructor;
  12         43  
  12         125  
10             #use MooseX::Storage;
11             #with Storage( 'io' => 'StorableFile' ),
12             with 'HackaMol::Roles::NameRole', 'HackaMol::Roles::AtomGroupRole';
13              
14             has $_ => (
15             is => 'rw',
16             isa => 'Num',
17             default => 0,
18             lazy => 1,
19             clearer => "clear_$_",
20             ) foreach qw(dihe_fc dihe_dphase dihe_eq dihe_mult);
21              
22             sub dihe_deg {
23 144     144 1 108608 my $self = shift;
24 144         5400 my @atoms = $self->all_atoms;
25 144         535 return ( $atoms[0]->dihedral_deg( $atoms[1], $atoms[2], $atoms[3] ) );
26             }
27              
28             sub dihe_rad {
29 2     2 1 3 my $self = shift;
30 2         68 my @atoms = $self->all_atoms;
31 2         16 return ( $atoms[0]->dihedral_rad( $atoms[1], $atoms[2], $atoms[3] ) );
32             }
33              
34             has 'improper_dihe_efunc' => (
35             is => 'rw',
36             isa => 'CodeRef',
37             builder => "_build_improper_dihe_efunc",
38             lazy => 1,
39             );
40              
41             sub _build_improper_dihe_efunc {
42             my $subref = sub {
43 2     2   5 my $dihedral = shift;
44 2         5 my $val = ( $dihedral->dihe_deg - $dihedral->dihe_eq )**2;
45 2         52 return ( $dihedral->dihe_fc * $val );
46 1     1   5 };
47 1         28 return ($subref);
48             }
49              
50             has 'torsion_efunc' => (
51             is => 'rw',
52             isa => 'CodeRef',
53             builder => "_build_torsion_efunc",
54             lazy => 1,
55             );
56              
57             sub _build_torsion_efunc {
58             my $subref = sub {
59 2     2   5 my $dihedral = shift;
60 2         53 my $val =
61             1 +
62             cos( $dihedral->dihe_mult * $dihedral->dihe_rad -
63             $dihedral->dihe_dphase );
64 2         62 return ( $dihedral->dihe_fc * $val );
65 1     1   7 };
66 1         28 return ($subref);
67             }
68              
69             sub torsion_energy {
70 3     3 1 7 my $self = shift;
71 3         6 my $energy = &{ $self->torsion_efunc }( $self, @_ );
  3         87  
72 3         35 return ($energy);
73             }
74              
75             sub improper_dihe_energy {
76 3     3 1 552 my $self = shift;
77 3         7 my $energy = &{ $self->improper_dihe_efunc }( $self, @_ );
  3         91  
78 3         27 return ($energy);
79             }
80              
81             __PACKAGE__->meta->make_immutable;
82              
83             1;
84              
85             __END__
86              
87             =pod
88              
89             =head1 NAME
90              
91             HackaMol::Dihedral - Dihedral Angle class for HackaMol
92              
93             =head1 VERSION
94              
95             version 0.051
96              
97             =head1 SYNOPSIS
98              
99             use HackaMol::Atom;
100             use HackaMol::Dihedral;
101              
102             my ($atom1,$atom4) = map {
103             Atom->new(
104             name => "C".($_+1),
105             charges => [0],
106             coords => [ V( $_, $_, 0) ],
107             Z => 6,
108             )} (-1, 1);
109            
110             my ($atom2,$atom3) = map {
111             Atom->new(
112             name => "S".($_+1),
113             charges => [0],
114             coords => [ V( $_, 0, 0) ],
115             Z => 16,
116             )} (-1, 1);
117            
118             my $dihe = HackaMol::Dihedral->new(name=>'disulfide',
119             atoms=>[$atom1,$atom2,$atom3,$atom4]);
120            
121             my $pdihe = sprintf(
122             "Dihedral: %s, angle: %.2f\n"
123             $dihe->name,
124             $dihe->dihe_deg,
125             );
126            
127             print $pdihe;
128            
129             my $COM_atom = HackaMol::Atom->new(
130             name => "X".$_->name."X",
131             coords => [ $dihe->COM ],
132             Z => 1,
133             );
134              
135             =head1 DESCRIPTION
136              
137             The HackaMol Dihedral class provides a set of methods and attributes for working
138             with three connections between four atoms. Like the L<HackaMol::Bond> and
139             L<HackaMol::Angle> classes, the Dihedral class consumes the
140             L<HackaMol::AtomGroupRole>
141             providing methods to determine the center of mass, total charge, etc.
142             (see AtomGroupRole). A $dihedral containing (atom1,atom2,atom3,atom4) produces
143             the angle ($dihedral->dihe_deg) between the planes containing (atom1, atom2,
144             atom3) and (atom2, atom3, atom4).
145              
146             The Dihedral class also provides attributes and methods to set parameters and
147             functions to measure energy. The energy methods call on CodeRef attributes that
148             the user may define. See descriptions below.
149              
150             =head1 METHODS
151              
152             =head2 dihe_deg
153              
154             no arguments. returns the angle (degrees) between the planes containing
155             (atom1,atom2,atom3) and (atom2, atom3, atom4).
156              
157             =head2 dihe_rad
158              
159             no arguments. returns the angle (radians) between the planes containing
160             (atom1,atom2,atom3) and (atom2, atom3, atom4).
161              
162             =head2 improper_dihe_energy
163              
164             arguments, as many as you want. Calculates energy using the
165             improper_dihe_efunc described below, if the attribute, dihe_fc > 0.
166             The improper_dihe_energy method calls the improper_dihe_efunc as follows:
167              
168             my $energy = &{$self->improper_dihe_efunc}($self,@_);
169              
170             which will pass $self and that in @_ array to improper_dihe_efunc, which, similar to the Bond and Angle classes, can be redefined. torsion_energy is analogous.
171              
172             =head2 torsion_energy
173              
174             analogous to improper_dihe_energy
175              
176             =head1 ATTRIBUTES
177              
178             =head2 atoms
179              
180             isa ArrayRef[Atom] that is lazy with public ARRAY traits provided by the
181             AtomGroupRole (see documentation for more details).
182              
183             =head2 name
184              
185             isa Str that is lazy and rw. useful for labeling, bookkeeping...
186              
187             =head2 dihe_dphase
188              
189             isa Num that is lazy and rw. default = 0. phase shift for torsion potentials.
190              
191             =head2 dihe_mult
192              
193             isa Num that is lazy and rw. default = 0. multiplicity for torsion potentials.
194              
195             =head2 dihe_fc
196              
197             isa Num that is lazy and rw. default = 0. force constant for harmonic bond potentials.
198              
199             =head2 dihe_eq
200              
201             isa Num that is lazy and rw. default = 0. Equilibrium dihedral angle.
202              
203             =head2 improper_dihe_efunc
204              
205             isa CodeRef that is lazy and rw. default uses builder to generate a
206             harmonic potential for the improper_dihedral and a torsion potential.
207              
208             =head2 torsion_efunc
209              
210             analogous to improper_dihe_efunc
211              
212             =head1 SEE ALSO
213              
214             =over 4
215              
216             =item *
217              
218             L<HackaMol::AtomGroupRole>
219              
220             =item *
221              
222             L<Chemistry::Bond>
223              
224             =item *
225              
226             L<HackaMol::Angle>
227              
228             =back
229              
230             =head1 EXTENDS
231              
232             =over 4
233              
234             =item * L<Moose::Object>
235              
236             =back
237              
238             =head1 CONSUMES
239              
240             =over 4
241              
242             =item * L<HackaMol::Roles::AtomGroupRole>
243              
244             =item * L<HackaMol::Roles::NameRole>
245              
246             =item * L<HackaMol::Roles::NameRole|HackaMol::Roles::AtomGroupRole>
247              
248             =back
249              
250             =head1 AUTHOR
251              
252             Demian Riccardi <demianriccardi@gmail.com>
253              
254             =head1 COPYRIGHT AND LICENSE
255              
256             This software is copyright (c) 2017 by Demian Riccardi.
257              
258             This is free software; you can redistribute it and/or modify it under
259             the same terms as the Perl 5 programming language system itself.
260              
261             =cut