Chemistry-InternalCoords
view release on metacpan or search on metacpan
InternalCoords.pm view on Meta::CPAN
package Chemistry::InternalCoords;
$VERSION = '0.18';
# $Id: InternalCoords.pm,v 1.6 2004/09/24 20:48:23 itubert Exp $
use 5.006;
use strict;
use warnings;
use Math::VectorReal qw(:all);
use Carp;
use overload '""' => "stringify", fallback => 1;
use Scalar::Util 'weaken';
use Math::Trig 'deg2rad';
=head1 NAME
Chemistry::InternalCoords - Represent the position of an atom using internal
coordinates and convert it to Cartesian coordinates.
=head1 SYNOPSIS
use Chemistry::InternalCoords;
# ... have a molecule in $mol
my $atom = $mol->new_atom;
# create an internal coordinate object for $atom
# with respect to atoms with indices 4, 3, and 2.
my $ic = Chemistry::InternalCoords->new(
$atom, 4, 1.1, 3, 109.5, 2, 180.0
);
# can also use atom object references instead of indices
($atom4, $atom3, $atom2) = $mol->atoms(4,3,2);
my $ic = Chemistry::InternalCoords->new(
$atom, $atom4, 1.1, $atom3, 109.5, $atom2, 180.0
);
# calculate the Cartesian coordinates for
# the atom from the internal coordinates
my $vector = $ic->cartesians;
# calculate and set permanently the Cartesian coordinates
# for the atom from the internal coordinates
my $vector = $ic->add_cartesians;
# same as $atom->coords($ic->cartesians);
# dump as string
print $ic;
# same as print $ic->stringify;
=head1 DESCRIPTION
This module implements an object class for representing internal coordinates
and provides methods for converting them to Cartesian coordinates.
For generating an internal coordinate representation (aka a Z-matrix) of a
molecule from its Cartesian coordinates, see the
L<Chemistry::InternalCoords::Builder> module.
This module is part of the PerlMol project, L<http://www.perlmol.org/>.
=head1 METHODS
=over
=item my $ic = Chemistry::InternalCoords->new($atom, $len_ref, $len_val,
$ang_ref, $ang_val, $dih_ref, $dih_val)
Create a new internal coordinate object. $atom is the atom to which the
coordinates apply. $len_ref, $ang_ref, and $dih_ref are either atom references
or atom indices and are used to specify the distance, angle, and dihedral that
are used to define the current position. $len_val, $ang_val, and $dih_val are
the values of the distance, angle, and dihedral. The angle and the dihedral are
expected to be in degrees.
For example,
my $ic = Chemistry::InternalCoords->new(
$atom, 4, 1.1, 3, 109.5, 2, 180.0
);
means that $atom is 1.1 distance units from atom 4, the angle $atom-4-3 is
109.5 degrees, and the dihedral $atom-4-3-2 is 180.0 degrees.
The first three atoms in the molecule don't need all the internal coordinates:
the first atom doesn't need anything (except for the atom reference $atom)
because it will always be placed at the origin; the second atom only needs
a distance, and it will be placed on the X axis; the third atom needs a
distance and an angle, and it will be placed on the XY plane.
=cut
sub new {
my $class = shift;
my $atom = shift;
my $self = bless {
atom => $atom,
len_ref => shift, len_val => shift,
ang_ref => shift, ang_val => shift,
dih_ref => shift, dih_val => shift,
}, ref $class || $class;
weaken($self->{atom}); # to avoid memory leaks
for (@$self{qw(len_ref ang_ref dih_ref)}) {
if ($_ and not ref) {
$_ = $atom->parent->atoms($_);
}
}
$self;
}
=item my ($atom, $distance) = $ic->distance
Return the atom reference and distance value contained in the
Chemistry::InternalCoords object.
=cut
sub distance {
my ($self) = @_;
($self->{len_ref}, $self->{len_val});
}
=item my ($atom, $angle) = $ic->angle
Return the atom reference and angle value contained in the
Chemistry::InternalCoords object.
=cut
sub angle {
my ($self) = @_;
($self->{ang_ref}, $self->{ang_val});
}
=item my ($atom, $dihedral) = $ic->dihedral
Return the atom reference and dihedral value contained in the
Chemistry::InternalCoords object.
=cut
sub dihedral {
my ($self) = @_;
($self->{dih_ref}, $self->{dih_val});
}
=item my $vector = $ic->cartesians
Calculate the Cartesian coordinates from an internal coordinate object.
Returns a Math::VectorReal object. Note that the Cartesian coordinates of the
atoms referenced by the $ic object should already be calculated.
=cut
sub cartesians {
my ($self) = @_;
#print "cartesians\n";
unless ($self->{len_ref}) { # origin
return vector(0, 0, 0);
( run in 2.159 seconds using v1.01-cache-2.11-cpan-364913b4093 )