Chemistry-Reaction
view release on metacpan or search on metacpan
lib/Chemistry/Reaction.pm view on Meta::CPAN
0/3 (creation of a triple bond)
An explicit chemical reaction $react can be forward or reverse applied
once to a molecule $mol at the first subgraph of $mol found which is
isomorphic to the substrate or product of $react:
my $subst = $react->substrate;
if ($subst->match($mol)) {
$react->forward($mol, $subst->atom_map);
}
Also, an explicit chemical reaction $react can be forward or reverse
applied once to a molecule $mol at each subgraph of $mol which is
isomorphic to the substrate or product of $react:
my $subst = $react->substrate;
my @products;
while ($subst->match($mol)) {
my $new_mol = $mol->clone; # start from a fresh molecule
my @map = $subst->atom_map;
# translate atom map to the clone
my @m = map { $new_mol->by_id($_->id) } @map;
$react->forward($new_mol, @m);
push @products, $new_mol;
}
Furthermore, an explicit chemical reaction $react can be forward or
reverse applied as long as possible to a molecule $mol at the first
subgraph of $mol found which is isomorphic to the substrate or product
of $react:
my $subst = $react->substrate;
while ($subst->match($mol)) {
$react->forward($mol, $subst->atom_map);
}
=cut
use 5.006;
use strict;
use warnings;
use base qw(Chemistry::Pattern);
=head1 METHODS
=over 4
=item Chemistry::Reaction->new($subst, $prod, \%map)
Create a new Reaction object that describes the transformation of the
$subst substrate into the $prod product, according to the %map mapping
of substrate atoms to product atoms.
=cut
sub new {
my ($class, $substrate, $product, $mapping, %args) = @_;
die sprintf(
"$class substrate and product must coincide on atoms (%s ne %s)\n",
$substrate->formula, $product->formula)
if $substrate->formula ne $product->formula;
my $order1 = 0;
foreach my $bond ($substrate->bonds) {
$order1 += $bond->order;
}
my $order2 = 0;
foreach my $bond ($product->bonds) {
$order2 += $bond->order;
}
die "$class substrate and product must coincide on total bond order\n"
if $order1 != $order2;
foreach my $atom ($substrate->atoms) {
die sprintf(
"$class substrate and product must coincide on atom symbols "
."(%s ne %s)\n", $atom->symbol, $mapping->{$atom}->symbol)
if $atom->symbol ne $mapping->{$atom}->symbol;
}
foreach my $atom ($product->atoms) {
$atom->attr("reaction/mapped", 1);
}
foreach my $atom ($substrate->atoms) {
$mapping->{$atom}->attr("reaction/mapped", 0);
}
foreach my $atom ($product->atoms) {
die "$class atom mapping must be bijective\n"
if $atom->attr("reaction/mapped");
}
# the substrate of the reaction is cloned in order to isolate all
# changes to bond orders from the given $substrate
my $self = $substrate->clone;
bless $self, ref $class || $class;
$self->$_($args{$_}) for (keys %args);
# the $mapping array gives the product atom which each substrate
# atom is mapped to, and the %unmapping hash gives back the
# substrate atom which each product atom is mapped to
my %unmapping;
foreach my $a1 (keys %$mapping) {
my $a2 = ${$mapping}{$a1};
$unmapping{$a2} = $a1;
}
# the %bonds hash gives an array of substrate and product bond
# orders for each pair of atoms which are bonded in substrate or in
# the product of the reaction
# first of all, set $bonds{$a1}{$a2} to an array containing only the
# substrate bond order, for each pair of atoms $a1 and $a2 which are
# bonded in the substrate
my %bonds;
foreach my $bond ($self->bonds) {
my @atoms = $bond->atoms;
@atoms[0,1] = @atoms[1,0] unless $atoms[0] lt $atoms[1];
$bonds{$atoms[0]}{$atoms[1]} = [$bond->order];
( run in 1.528 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )