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