<commit_before>#!/usr/bin/perl -T

=head1 NAME

B<PhysicoChemical_Descriptor>

=head1 DESCRIPTION

A CGI service for calculation of physicochemical properties of a given 
amino acid sequence.

=head1 USAGE

http://imgt.org/pc_descriptor/properties.pl?sequence="SEQUENCE"

=head1 EXAMPLE

http://imgt.org/pc_descriptor/properties.pl?sequence=RWMDR

=head1 DEPENDENCIES

-the Perl interpreter, >= 5.10

-CGI, >= 3.63 (Perl module)

-DBD::SQLite, >= 1.37 (Perl module)

-DBI, >= 1.622 (Perl module)

=head1 LIMITATIONS

There is a limit of no more than 400 amino acids per sequence.

=head1 AUTHORS

-Dimitrios - <NAME> <<<EMAIL>>>

-<NAME> <<<EMAIL>>>

-<NAME> <<<EMAIL>>>

=head1 LICENSE

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
<a href="http://www.gnu.org/licenses/agpl.html" style="text-decoration:none">GNU Affero General Public License</a> for more details.

=cut

use strict;
use warnings;

use feature qw(say switch);

use CGI;
use DBI;
use utf8;

our $VERSION = 'v1.01';

my $cgi = CGI->new;
print $cgi->header;

my $sequence = $cgi->param('sequence');
my $advanced = $cgi->param('advanced');

# Remove single and double quotes in the sequence, if any. #
$sequence =~ s/["|']//g;

# Connect to the amino acids database. #
my $dbh = DBI->connect( 'dbi:SQLite:../amino_acids.db', q{}, q{} );

# Stuff to be printed at the end of the page. #
my $bottom_info = << 'ENDHTML';
<hr/><sub>
This tool was primarily developed by <NAME>, <NAME> and <a href='mailto:<EMAIL>' style="text-decoration:none"><NAME></a> 
from the <a href='http://www.bioacademy.gr/bioinformatics/' style="text-decoration:none">Bioinformatics and Medical Informatics Research Group</a> of the<br>
<a href='http://www.bioacademy.gr/?lang=en' style="text-decoration:none">Biomedical Research Foundation, Academy of Athens, Greece</a> 
in collaboration with <a href="http://www.imgt.org/" style="text-decoration:none">IMGT®, the international ImMunoGeneTics information system®</a>,<br>
<a href='http://www.imgt.org/IMGTinformation/LIGM.html' style="text-decoration:none">Laboratoire d'ImmunoGénétique Moléculaire</a> of the 
<a href='http://www.igh.cnrs.fr/EN/index.php' style="text-decoration:none">Institut de Génétique Humaine, CNRS (UPR 1142), Montpellier, France</a>.
<br><br>
The <a href='https://github.com/dgkontopoulos/PhysicoChemical_Descriptor' style="text-decoration:none">source code</a> is freely available under the 
<a href='http://www.gnu.org/licenses/agpl.html' style="text-decoration:none">GNU Affero GPL</a>.
</sub>
ENDHTML

if ( $sequence =~ /^\s*$/ )    # Reject empty sequences. #
{
    print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );

    # Header and error message. #
    print << "ENDHTML";
<center>
<table cols=2 width='100%' >
<tr>

<td align=left nowrap valign=middle width='70%'>
<font size='+3' color='#000099'><b>WELCOME</font>
<font size='+2' color='#000099'><br>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>No sequence was entered!</font>
</center>
ENDHTML
}
elsif ( $sequence =~ /^[A|R|N|D|C|E|Q|G|H|I|L|K|M|F|P|S|T|W|Y|V]+$/i )
{

    # Reject sequences that are larger than 400 amino acids. #
    if ( length $sequence > 400 )
    {
        print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );
        print << "ENDHTML";
<center>
<table cols=2 width="100%" >
<tr>

<td align=left nowrap valign=middle width="70%">
<font size="+3" color="#000099"><b>WELCOME</b></font>
<font size='+2' color="#000099"><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>
</font></td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>Currently there is a limit of 400 amino acids per sequence!</font>
</center>
ENDHTML
        print $bottom_info . $cgi->end_html;
        exit;
    }

    print << "END_HEADER";
<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>PC Descriptor || &#39;$sequence&#39;</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Mono' rel='stylesheet' type='text/css'>
</head>
<body>
END_HEADER

    my $input_seq = $sequence;

    # Change line after every 50 characters. #
    $input_seq =~ s/(\w{50})/$1<br>&nbsp;/g;

    # Header, input sequence. #
    print << "ENDHTML";
<center>
<table cols=2 width='100%' >
<tr>

<td align=left nowrap valign=middle width='70%'>
<font size='+3' color='#000099'><b>WELCOME</b></font>
<font size='+2' color='#000099'><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>

<td align=right valign=top width='30%'>
<a href='http://www.imgt.org'><img src='http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png' alt='IMGT'></a>
</td>
</tr>
</table>
</center>
<hr/>
<font face='Ubuntu Mono, Courier New'>Input sequence:<br><b>&nbsp;$input_seq</b>
</font><br><br>
ENDHTML

    # Check if we're using the advanced interface. #
    if ( $advanced != 1 )
    {
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>The following table displays calculations of various physicochemical properties
of the input sequence.
<br>Clicking on property codes (first column) will show their description.
<br>To use the advanced interface, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1' style='text-decoration:none'>here</a>.
<br><br><center>
ENDHTML

        # List the available properties. #
        my @properties = qw(
          Hydro_IMGT  Vol_IMGT ASA     b_rotR CASA_pos CASA_neg E
          E_sol       E_strain E_tor   E_vdw  logP_o_w logS     PEOE_PC_pos
          PEOE_PC_neg Vdw_area Vdw_vol VSA    Weight
        );

        create_results_table( \@properties, $sequence );

        # Properties Codebook. #
        codebook( \@properties );
    }
    elsif ($advanced == 1
        && $cgi->param('proceed') )    # Advanced interface, show results. #
    {

        # Advanced interface text. #
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>
This is the advanced interface of the tool. To go back to the simple interface (calculating only default properties), click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence' style='text-decoration:none'>here</a>.
<br>To reselect properties to be computed, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1' style='text-decoration:none'>here</a>.
</font><br><br>
ENDHTML

        # Get a list of parameters and try to find selected properties. #
        my @parameters = $cgi->param;

        for ( 0 .. $#parameters )
        {
            if (   $parameters[$_] eq 'sequence'
                or $parameters[$_] eq 'advanced'
                or $parameters[$_] eq 'proceed' )
            {
                undef $parameters[$_];
            }
        }

        @parameters = grep { defined } @parameters;

        # If no properties were found, exit. #
        if ( $#parameters == -1 )
        {
            print << 'ENDHTML';
<center><font face='Ubuntu Mono, Courier New' size='+1'>
<b>ERROR!</b><br>
No properties have been selected!<br>
Please <a href='javascript:history.go(-1)'>go back</a> and select some properties to be computed.</font>
</center><br>
ENDHTML
            print $bottom_info . $cgi->end_html;
            exit;
        }

        my @properties;
        foreach my $element (@parameters)
        {

            # Substitute illegal characters. #
            $element = string_reformat( $element, 'for_sql' );

            # Query to check if a table exists with that name. #
            my $select_text = << 'END_SQL';
Select name from sqlite_master where type='table' and name = ?;
END_SQL
            my $db_sel = $dbh->prepare($select_text);

            # Bind variable to avoid sql injection attack. #
            $db_sel->execute($element);
            my $result = $db_sel->fetchall_arrayref;

            if ( $result->[0]->[0] )
            {
                push @properties, $result->[0]->[0];
            }
        }

        # If no valid properties were found, exit. #
        if ( $#properties == -1 )
        {
            print << 'ENDHTML';
<center><font face='Ubuntu Mono, Courier New' size='+1'>
<b>ERROR!</b><br>
No properties have been selected!<br>
Please <a href='javascript:history.go(-1)'>go back</a> and select some properties to be computed.</font>
</center><br>
ENDHTML
            print $bottom_info . $cgi->end_html;
            exit;
        }

        print '<center>';
        create_results_table( \@properties, $sequence );
        print '</center><br><font face="Ubuntu Mono, Courier New">';

        # Properties Codebook. #
        codebook( \@properties );
    }
    elsif ( $advanced == 1 )    # Advanced interface, specify parameters. #
    {

        # Advanced interface text and beginning the form #
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>
This is the advanced interface of the tool. To go back to the simple interface, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence' style='text-decoration:none'>here</a>.
<br>Otherwise, please select the physicochemical properties to compute for the input sequence.
<br>To download the complete Properties Codebook, click
<a href='http://tinyurl.com/pc-descriptor-codebook' style='text-decoration:none'>here</a>.
</font>

<form id = 'submit' method = 'post'
action=http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1>

<input type=hidden name='sequence' value='$sequence'>
<input type=hidden name='advanced' value='1'>
<input type=hidden name='proceed' value='1'>
ENDHTML

        my ( $tables, $categories, $colors ) = get_available_properties();

        # Get and list the available properties. #
        say '<center><table cellspacing = "5"><tr>';
        for ( 0 .. @{$tables} - 1 )
        {
            if ( $_ % 8 == 0 )
            {
                say '</tr><tr></tr><tr></tr><tr>';
            }

            # Create checkbuttons. #
            print << "ENDHTML";
<td><font face='Ubuntu Mono, Courier New' size='2' 
color = '$colors->{$categories->{$tables->[$_]}}'>
<input type=checkbox name='$tables->[$_]' value='1'>$tables->[$_]
</font></td><td></td>
ENDHTML
        }

        # Create the submit button. #
        print << 'ENDHTML';
</table><br>
<input id='submit' type='submit' value=' Submit '></form></center><br>
<font face="Ubuntu Mono, Courier New">
ENDHTML

        say << 'ENDHTML';
<center>
<table frame = 'box'><tr bgcolor='#FAFAD2'><td></td>
<td><center><b>LEGEND</b></td><td></td></tr><tr>
ENDHTML

        # Legend table. #
        my $legend_counter = 0;
        foreach ( keys %{$colors} )
        {
            if ( $legend_counter == 3 )
            {
                say '</tr><tr>';
                $legend_counter = 0;
            }
            say << "ENDHTML";
<td><center>
<font face='Ubuntu Mono, Courier New' size='2' 
color = '$colors->{$_}'>$_</font>
</center></td>
ENDHTML
            $legend_counter++;
        }
        say '</center></td></tr></table></center></br>';
    }
}
else    # Handle any non-protein sequences. #
{
    print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );

    # Header and error. #
    print << "ENDHTML";
<center>
<table cols=2 width="100%" >
<tr>

<td align=left nowrap valign=middle width="70%">
<font size="+3" color="#000099"><b>WELCOME</b></font>
<font size='+2' color="#000099"><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>
</font></td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>This does not look like an amino acid sequence!</font>
</center>
ENDHTML
}

# Print bottom text and details. #
print $bottom_info . $cgi->end_html;

#############################################
# S   U   B   R   O   U   T   I   N   E   S #
#############################################

# Add units to properties, where available. #
sub add_units
{
    my ($property) = @_;

    for ($property)
    {
        $property .= '<sub>(g/mol)</sub>' when 'Weight';<commit_msg>Fixed problems only appearing in Internet Explorer (>_>): border around linked image and misaligned table cells.<commit_after>#!/usr/bin/perl -T

=head1 NAME

B<PhysicoChemical_Descriptor>

=head1 DESCRIPTION

A CGI service for calculation of physicochemical properties of a given 
amino acid sequence.

=head1 USAGE

http://imgt.org/pc_descriptor/properties.pl?sequence="SEQUENCE"

=head1 EXAMPLE

http://imgt.org/pc_descriptor/properties.pl?sequence=RWMDR

=head1 DEPENDENCIES

-the Perl interpreter, >= 5.10

-CGI, >= 3.63 (Perl module)

-DBD::SQLite, >= 1.37 (Perl module)

-DBI, >= 1.622 (Perl module)

=head1 LIMITATIONS

There is a limit of no more than 400 amino acids per sequence.

=head1 AUTHORS

-Dimitrios - <NAME> <<<EMAIL>>>

-<NAME> <<<EMAIL>>>

-<NAME> <<<EMAIL>>>

=head1 LICENSE

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
<a href="http://www.gnu.org/licenses/agpl.html" style="text-decoration:none">GNU Affero General Public License</a> for more details.

=cut

use strict;
use warnings;

use feature qw(say switch);

use CGI;
use DBI;
use utf8;

our $VERSION = 'v1.01';

my $cgi = CGI->new;
print $cgi->header;

my $sequence = $cgi->param('sequence');
my $advanced = $cgi->param('advanced');

# Remove single and double quotes in the sequence, if any. #
$sequence =~ s/["|']//g;

# Connect to the amino acids database. #
my $dbh = DBI->connect( 'dbi:SQLite:../amino_acids.db', q{}, q{} );

# Stuff to be printed at the end of the page. #
my $bottom_info = << 'ENDHTML';
<hr/><sub>
This tool was primarily developed by <NAME>, <NAME> and <a href='mailto:<EMAIL>' style="text-decoration:none"><NAME></a> 
from the <a href='http://www.bioacademy.gr/bioinformatics/' style="text-decoration:none">Bioinformatics and Medical Informatics Research Group</a> of the<br>
<a href='http://www.bioacademy.gr/?lang=en' style="text-decoration:none">Biomedical Research Foundation, Academy of Athens, Greece</a> 
in collaboration with <a href="http://www.imgt.org/" style="text-decoration:none">IMGT®, the international ImMunoGeneTics information system®</a>,<br>
<a href='http://www.imgt.org/IMGTinformation/LIGM.html' style="text-decoration:none">Laboratoire d'ImmunoGénétique Moléculaire</a> of the 
<a href='http://www.igh.cnrs.fr/EN/index.php' style="text-decoration:none">Institut de Génétique Humaine, CNRS (UPR 1142), Montpellier, France</a>.
<br><br>
The <a href='https://github.com/dgkontopoulos/PhysicoChemical_Descriptor' style="text-decoration:none">source code</a> is freely available under the 
<a href='http://www.gnu.org/licenses/agpl.html' style="text-decoration:none">GNU Affero GPL</a>.
</sub>
ENDHTML

if ( $sequence =~ /^\s*$/ )    # Reject empty sequences. #
{
    print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );

    # Header and error message. #
    print << "ENDHTML";
<center>
<table cols=2 width='100%' >
<tr>

<td align=left nowrap valign=middle width='70%'>
<font size='+3' color='#000099'><b>WELCOME</font>
<font size='+2' color='#000099'><br>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img style="border:none;" src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>No sequence was entered!</font>
</center>
ENDHTML
}
elsif ( $sequence =~ /^[A|R|N|D|C|E|Q|G|H|I|L|K|M|F|P|S|T|W|Y|V]+$/i )
{

    # Reject sequences that are larger than 400 amino acids. #
    if ( length $sequence > 400 )
    {
        print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );
        print << "ENDHTML";
<center>
<table cols=2 width="100%" >
<tr>

<td align=left nowrap valign=middle width="70%">
<font size="+3" color="#000099"><b>WELCOME</b></font>
<font size='+2' color="#000099"><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>
</font></td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img style="border:none;" src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>Currently there is a limit of 400 amino acids per sequence!</font>
</center>
ENDHTML
        print $bottom_info . $cgi->end_html;
        exit;
    }

    print << "END_HEADER";
<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>PC Descriptor || &#39;$sequence&#39;</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Mono' rel='stylesheet' type='text/css'>
</head>
<body>
END_HEADER

    my $input_seq = $sequence;

    # Change line after every 50 characters. #
    $input_seq =~ s/(\w{50})/$1<br>&nbsp;/g;

    # Header, input sequence. #
    print << "ENDHTML";
<center>
<table cols=2 width='100%' >
<tr>

<td align=left nowrap valign=middle width='70%'>
<font size='+3' color='#000099'><b>WELCOME</b></font>
<font size='+2' color='#000099'><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>

<td align=right valign=top width='30%'>
<a href='http://www.imgt.org'><img style="border:none;" src='http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png' alt='IMGT'></a>
</td>
</tr>
</table>
</center>
<hr/>
<font face='Ubuntu Mono, Courier New'>Input sequence:<br><b>&nbsp;$input_seq</b>
</font><br><br>
ENDHTML

    # Check if we're using the advanced interface. #
    if ( $advanced != 1 )
    {
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>The following table displays calculations of various physicochemical properties
of the input sequence.
<br>Clicking on property codes (first column) will show their description.
<br>To use the advanced interface, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1' style='text-decoration:none'>here</a>.
<br><br><center>
ENDHTML

        # List the available properties. #
        my @properties = qw(
          Hydro_IMGT  Vol_IMGT ASA     b_rotR CASA_pos CASA_neg E
          E_sol       E_strain E_tor   E_vdw  logP_o_w logS     PEOE_PC_pos
          PEOE_PC_neg Vdw_area Vdw_vol VSA    Weight
        );

        create_results_table( \@properties, $sequence );

        # Properties Codebook. #
        codebook( \@properties );
    }
    elsif ($advanced == 1
        && $cgi->param('proceed') )    # Advanced interface, show results. #
    {

        # Advanced interface text. #
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>
This is the advanced interface of the tool. To go back to the simple interface (calculating only default properties), click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence' style='text-decoration:none'>here</a>.
<br>To reselect properties to be computed, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1' style='text-decoration:none'>here</a>.
</font><br><br>
ENDHTML

        # Get a list of parameters and try to find selected properties. #
        my @parameters = $cgi->param;

        for ( 0 .. $#parameters )
        {
            if (   $parameters[$_] eq 'sequence'
                or $parameters[$_] eq 'advanced'
                or $parameters[$_] eq 'proceed' )
            {
                undef $parameters[$_];
            }
        }

        @parameters = grep { defined } @parameters;

        # If no properties were found, exit. #
        if ( $#parameters == -1 )
        {
            print << 'ENDHTML';
<center><font face='Ubuntu Mono, Courier New' size='+1'>
<b>ERROR!</b><br>
No properties have been selected!<br>
Please <a href='javascript:history.go(-1)'>go back</a> and select some properties to be computed.</font>
</center><br>
ENDHTML
            print $bottom_info . $cgi->end_html;
            exit;
        }

        my @properties;
        foreach my $element (@parameters)
        {

            # Substitute illegal characters. #
            $element = string_reformat( $element, 'for_sql' );

            # Query to check if a table exists with that name. #
            my $select_text = << 'END_SQL';
Select name from sqlite_master where type='table' and name = ?;
END_SQL
            my $db_sel = $dbh->prepare($select_text);

            # Bind variable to avoid sql injection attack. #
            $db_sel->execute($element);
            my $result = $db_sel->fetchall_arrayref;

            if ( $result->[0]->[0] )
            {
                push @properties, $result->[0]->[0];
            }
        }

        # If no valid properties were found, exit. #
        if ( $#properties == -1 )
        {
            print << 'ENDHTML';
<center><font face='Ubuntu Mono, Courier New' size='+1'>
<b>ERROR!</b><br>
No properties have been selected!<br>
Please <a href='javascript:history.go(-1)'>go back</a> and select some properties to be computed.</font>
</center><br>
ENDHTML
            print $bottom_info . $cgi->end_html;
            exit;
        }

        print '<center>';
        create_results_table( \@properties, $sequence );
        print '</center><br><font face="Ubuntu Mono, Courier New">';

        # Properties Codebook. #
        codebook( \@properties );
    }
    elsif ( $advanced == 1 )    # Advanced interface, specify parameters. #
    {

        # Advanced interface text and beginning the form #
        print << "ENDHTML";
<font face='Ubuntu Mono, Courier New'>
This is the advanced interface of the tool. To go back to the simple interface, click
<a href='http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence' style='text-decoration:none'>here</a>.
<br>Otherwise, please select the physicochemical properties to compute for the input sequence.
<br>To download the complete Properties Codebook, click
<a href='http://tinyurl.com/pc-descriptor-codebook' style='text-decoration:none'>here</a>.
</font>

<form id = 'submit' method = 'post'
action=http://imgt.org/pc_descriptor/properties.pl?sequence=$sequence&advanced=1>

<input type=hidden name='sequence' value='$sequence'>
<input type=hidden name='advanced' value='1'>
<input type=hidden name='proceed' value='1'>
ENDHTML

        my ( $tables, $categories, $colors ) = get_available_properties();

        # Get and list the available properties. #
        say '<center><table cellspacing = "5"><tr>';
        for ( 0 .. @{$tables} - 1 )
        {
            if ( $_ % 8 == 0 )
            {
                say '</tr><tr></tr><tr></tr><tr>';
            }

            # Create checkbuttons. #
            print << "ENDHTML";
<td align="left"><font face='Ubuntu Mono, Courier New' size='2'
color = '$colors->{$categories->{$tables->[$_]}}'>
<input type=checkbox name='$tables->[$_]' value='1'>$tables->[$_]
</font></td><td></td>
ENDHTML
        }

        # Create the submit button. #
        print << 'ENDHTML';
</table><br>
<input id='submit' type='submit' value=' Submit '></form></center><br>
<font face="Ubuntu Mono, Courier New">
ENDHTML

        say << 'ENDHTML';
<center>
<table frame = 'box'><tr bgcolor='#FAFAD2'><td></td>
<td><center><b>LEGEND</b></td><td></td></tr><tr>
ENDHTML

        # Legend table. #
        my $legend_counter = 0;
        foreach ( keys %{$colors} )
        {
            if ( $legend_counter == 3 )
            {
                say '</tr><tr>';
                $legend_counter = 0;
            }
            say << "ENDHTML";
<td><center>
<font face='Ubuntu Mono, Courier New' size='2' 
color = '$colors->{$_}'>$_</font>
</center></td>
ENDHTML
            $legend_counter++;
        }
        say '</center></td></tr></table></center></br>';
    }
}
else    # Handle any non-protein sequences. #
{
    print $cgi->start_html( -title => 'PC Descriptor || ERROR!' );

    # Header and error. #
    print << "ENDHTML";
<center>
<table cols=2 width="100%" >
<tr>

<td align=left nowrap valign=middle width="70%">
<font size="+3" color="#000099"><b>WELCOME</b></font>
<font size='+2' color="#000099"><br><b>to PhysicoChemical Descriptor<sup><small>($VERSION)</small></sup>!</b></font>
</td>
</font></td>

<td align=right valign=top width="30%">
<a href="http://www.imgt.org"><img style="border:none;" src="http://imgt.org/IMGT_vquest/share/textes/images/logoIMGT.png" alt="IMGT"></a>
</td>
</tr>
</table>
<hr/>
<font face="Ubuntu Mono, Courier New"><b>ERROR!</b><br>This does not look like an amino acid sequence!</font>
</center>
ENDHTML
}

# Print bottom text and details. #
print $bottom_info . $cgi->end_html;

#############################################
# S   U   B   R   O   U   T   I   N   E   S #
#############################################

# Add units to properties, where available. #
sub add_units
{
    my ($property) = @_;

    for ($property)
    {
        $property .= '<sub>(g/mol)</sub>' when 'Weight';
{'fraction_non_alphanumeric': 0.17817062643095746, 'fraction_numerical': 0.013962391622565027, 'mean_word_length': 3.419306684358932, 'pattern_counts': {'":': 0, '<': 651, '<?xml version=': 0, '>': 659, 'https://': 2, 'lorem ipsum': 0, 'www.': 26, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6567062', 'n_tokens_mistral': 9358, 'n_tokens_neox': 8722, 'n_words': 2266}