Chemistry-OpenSMILES
view release on metacpan or search on metacpan
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
is_double_bond
is_ring_atom
is_ring_bond
is_single_bond
is_triple_bond
mirror
toggle_cistrans
valence
);
sub is_chiral($);
sub is_chiral_planar($);
sub is_chiral_tetrahedral($);
sub mirror($);
sub toggle_cistrans($);
our %normal_valence = (
B => [ 3 ],
C => [ 4 ],
N => [ 3, 5 ],
O => [ 2 ],
P => [ 3, 5 ],
S => [ 2, 4, 6 ],
F => [ 1 ],
Cl => [ 1 ],
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
return 1;
}
# Removes chiral setting from allenal, square planar, tetrahedral and trigonal bipyramidal chiral centers if deemed unimportant.
# For allenal, tetrahedral and trigonal bipyramidal arrangements when not all the neighbours are distinct.
# For square planar arrangements this means situations when all neighbours are the same.
# Chiral centers with lone pairs are left untouched.
# Returns the affected atoms.
#
# TODO: check other chiral centers
sub clean_chiral_centers($$)
{
my( $moiety, $color_sub ) = @_;
my @affected;
for my $atom ($moiety->vertices) {
next unless is_chiral_allenal( $atom ) ||
is_chiral_planar( $atom ) ||
is_chiral_tetrahedral( $atom ) ||
is_chiral_trigonal_bipyramidal( $atom );
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
}
}
delete $atom->{chirality};
push @affected, $atom;
}
return @affected;
}
sub is_aromatic($)
{
my( $atom ) = @_;
return $atom->{symbol} ne ucfirst $atom->{symbol};
}
sub is_aromatic_bond
{
my( $moiety, $a, $b ) = @_;
return $moiety->has_edge_attribute( $a, $b, 'bond' ) &&
$moiety->get_edge_attribute( $a, $b, 'bond' ) eq ':';
}
sub is_chiral($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
return exists $what->{chirality};
} else { # Graph representing moiety
return any { is_chiral( $_ ) } $what->vertices;
}
}
sub is_chiral_allenal($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
return $what->{chirality} && $what->{chirality} =~ /^\@AL[12]$/;
} else { # Graph representing moiety
return any { is_chiral_allenal( $_ ) } $what->vertices;
}
}
sub is_chiral_planar($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
return $what->{chirality} && $what->{chirality} =~ /^\@SP[123]$/;
} else { # Graph representing moiety
return any { is_chiral_planar( $_ ) } $what->vertices;
}
}
sub is_chiral_tetrahedral($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
# CAVEAT: will fail for allenal configurations of @/@@ in raw mode
return $what->{chirality} && $what->{chirality} =~ /^@@?$/;
} else { # Graph representing moiety
return any { is_chiral_tetrahedral( $_ ) } $what->vertices;
}
}
sub is_chiral_trigonal_bipyramidal($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
return $what->{chirality} && $what->{chirality} =~ /^\@TB([1-9]|1[0-9]|20)$/;
} else { # Graph representing moiety
return any { is_chiral_trigonal_bipyramidal( $_ ) } $what->vertices;
}
}
sub is_chiral_octahedral($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
return $what->{chirality} && $what->{chirality} =~ /^\@OH([1-9]|[12][0-9]|30)$/;
} else { # Graph representing moiety
return any { is_chiral_octahedral( $_ ) } $what->vertices;
}
}
sub is_cis_trans_bond
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
$moiety->get_edge_attribute( $a, $b, 'bond' ) eq '-';
}
sub is_triple_bond
{
my( $moiety, $a, $b ) = @_;
return $moiety->has_edge_attribute( $a, $b, 'bond' ) &&
$moiety->get_edge_attribute( $a, $b, 'bond' ) eq '#';
}
sub mirror($)
{
my( $what ) = @_;
if( ref $what eq 'HASH' ) { # Single atom
if( is_chiral_tetrahedral( $what ) ) {
$what->{chirality} = $what->{chirality} eq '@' ? '@@' : '@';
}
if( is_chiral_allenal( $what ) ) {
$what->{chirality} = $what->{chirality} eq '@AL1' ? '@AL2' : '@AL1';
}
# Square planar centers are not affected by mirroring, doing nothing
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
0..$#OH;
$what->{chirality} = '@OH' . ($opposite + 1);
}
} else {
for ($what->vertices) {
mirror( $_ );
}
}
}
sub toggle_cistrans($)
{
return $_[0] unless $_[0] =~ /^[\\\/]$/;
return $_[0] eq '/' ? '\\' : '/';
}
# TODO: The actual unsprouting has to happen during print.
sub _unsprout_hydrogens($)
{
my( $moiety ) = @_;
for my $atom ($moiety->vertices) {
next unless can_unsprout_hydrogen( $moiety, $atom );
my( $neighbour ) = $moiety->neighbours( $atom );
# TODO: Adjust other chiralities as well
if( is_chiral_tetrahedral $neighbour ) {
lib/Chemistry/OpenSMILES.pm view on Meta::CPAN
@{$neighbour->{chirality_neighbours}} =
grep { $_ != $atom } @{$neighbour->{chirality_neighbours}};
mirror $neighbour unless $pos % 2;
}
$neighbour->{hcount}++;
$moiety->delete_vertex( $atom );
}
}
sub valence($$)
{
my( $moiety, $atom ) = @_;
return ($atom->{hcount} ? $atom->{hcount} : 0) +
sum0 map { exists $bond_symbol_to_order{$_}
? $bond_symbol_to_order{$_}
: 1 }
map { $moiety->has_edge_attribute( $atom, $_, 'bond' )
? $moiety->get_edge_attribute( $atom, $_, 'bond' )
: 1 }
$moiety->neighbours( $atom );
}
# CAVEAT: requires output from non-raw parsing due issue similar to GH#2
sub _validate($@)
{
my( $moiety, $color_sub ) = @_;
# Identify islands of allene systems
my $allenes = _allene_graph( $moiety );
my $color_by_element = sub { $_[0]->{symbol} };
for my $atom (sort { $a->{number} <=> $b->{number} } $moiety->vertices) {
if( is_chiral_allenal($atom) ) {
( run in 0.285 second using v1.01-cache-2.11-cpan-1f129e94a17 )