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 )