#!/usr/local/bin/perl -w

use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard);
use diagnostics;
#Brian O'Meara 23 Feb. 2006
#http://www.brianomeara.info
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 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
#    GNU General Public License for more details.

#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


print header;
print start_html("ModelPartition");
print '<span style="font-family: times new roman,times,serif;">';
print 'This is a cgi script to generate batch files for partitioned dataset
analyses in MrBayes. You can then use methods such as those in <a href="http://ist-socrates.berkeley.edu/~brandley/pubs/Brandley_et_al_2005_SB.pdf">Brandley et al., 2005</a> to decide which partitions to use. Note that the default values may not be best for you (especially temperature, which can dramatically affect convergence). I hope you find this useful (but no guarantees on performance) -- let me know at bcomeara_AT_ucdavis.edu if you have any suggestions or questions.<br>
<br></span><span style="font-family: monospace;">';
$step=param('step');
$datafilename=param('datafilename');
$ngen=param('ngen');
$nchain=param('nchain');
$temperature=param('temperature');
$burnin=param('burnin');
$charsetstring=param('charsetstring');
$partitionname=param('partitionname');
if ($step!~m/[0-9]/) {
    print '<form method="post"
action="http://www.brianomeara.info/cgi-bin/modelpartition.cgi">
<b>Search settings</b>:<br>
<div style="margin-left: 40px;">Data file name: <input class="post" style="width: 200px;" name="datafilename" size="100"
maxlength="100" value="" type="text"><br>
</div>
<div style="margin-left: 40px;">Num generations: <input class="post" style="width: 200px;" name="ngen" size="100"
maxlength="100" value="1000000" type="text"><br>
Num chains: <input class="post" style="width: 200px;" name="nchain" size="100"
maxlength="100" value="4" type="text"><br>
Temp: <input class="post" style="width: 200px;" name="temperature" size="100"
maxlength="100" value=".05" type="text"><br>
Burnin for sump: <input class="post" style="width: 200px;" name="burnin" size="100"
maxlength="100" value="250000" type="text"> <br>
Set of <span style="font-weight: bold;">nonoverlapping</span> charsets
(paste here, no line feeds, <b>semicolon</b> after each set). Example:<br>
<div style="margin-left: 40px;">coifirsts; coiseconds; coithirds;
ef1exon; ef1intron<br>
<input class="post" style="width: 700px;" name="charsetstring" size="1000"
maxlength="1000" value="" type="text"><br>
</div>
</div>';
print '<input type="hidden" name="step" value="2">';
    print '<input value="Input your data" type="submit"></small></form>';
}
elsif  ($step=~m/2/){
@chararray=split(/\s*;+\s*/,$charsetstring,); #so kills spaces, too.
$numberofcharsets=scalar @chararray;
@divisionarray=('excluded');
    print '<form method="post"
action="http://www.brianomeara.info/cgi-bin/modelpartition.cgi">';
print 'Partition name: <input class="post" style="width: 200px;" name="partitionname" size="1000"
maxlength="1000" value="" type="text"><br>';
print '<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
cellspacing="2"><tbody><tr><td style="vertical-align: top;"><br>
</td><td style="vertical-align: top;">Charset Name<br>
</td><td style="vertical-align: top;">In division number<br></td></tr>';
    for ($charsetnum=1;$charsetnum<=$numberofcharsets;$charsetnum++) {
        push(@divisionarray,"$charsetnum"); #since we can only select to be the same division or different from previous ones.
         print '<tr><td style="vertical-align: top;">'."$charsetnum".'</td>';
         print '<td style="vertical-align: top;">'."$chararray[$charsetnum-1]".'</td>';
         print '<td style="vertical-align: top;">';
         print popup_menu(-name=>"divCharSet$charsetnum",-values=>[@divisionarray],-default=>'excluded');
         print '</td></tr>';
    }
    print '</tr></tbody>';
print '<input type="hidden" name="datafilename" value="'."$datafilename".'">';
print '<input type="hidden" name="charsetstring" value="'."$charsetstring".'">';
print '<input type="hidden" name="burnin" value="'."$burnin".'">';
print '<input type="hidden" name="temperature" value="'."$temperature".'">';
print '<input type="hidden" name="nchain" value="'."$nchain".'">';
print '<input type="hidden" name="ngen" value="'."$ngen".'">';
print '<input type="hidden" name="step" value="3">';

    print '<input value="Input your choices" type="submit"></small></form>';
}
elsif  ($step=~m/3/){
print '<form method="post" action="http://www.brianomeara.info/cgi-bin/modelpartition.cgi">';
    @chararray=split(/\s*;+\s*/,$charsetstring,); #so kills spaces, too.
    $numberofcharsets=scalar @chararray;
    @partitionarray=();
    for ($charsetnum=1;$charsetnum<=$numberofcharsets;$charsetnum++) {
        $partitionassignment=param("divCharSet$charsetnum");
        print '<input type="hidden" name='."divCharSet$charsetnum".' value='."$partitionassignment".'>';
        if ($partitionassignment=~m/[0-9]/) {
            $place=$charsetnum-1;
            $partitionarray[$partitionassignment].=" $chararray[$place]";
        }
    }
    $numberofpartitions=(scalar @partitionarray)-1;
        print '<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
cellspacing="2"><tbody><tr><td style="vertical-align: top;">Division #
</td><td style="vertical-align: top;">Included Charsets</td><td>Model</td></tr>';
@models=('nst=1 rates=equal','nst=1 rates=gamma','nst=1 rates=propinv', 'nst=1 rates=adgamma', 'nst=1 rates=invgamma', 'nst=2 rates=equal','nst=2 rates=gamma','nst=2 rates=propinv', 'nst=2 rates=adgamma', 'nst=2 rates=invgamma','nst=6 rates=equal','nst=6 rates=gamma','nst=6 rates=propinv', 'nst=6 rates=adgamma', 'nst=6 rates=invgamma');
    for ($partitionnumber=1;$partitionnumber<=$numberofpartitions;$partitionnumber++) {
        print '<tr><td>'."$partitionnumber".'</td><td>'."$partitionarray[$partitionnumber]".'</td><td>';
        print popup_menu(-name=>"partModel$partitionnumber",-values=>[@ models],-default=>'nst=1 rates=equal');
        print '</td></tr>';
    }
    print '</tbody>';
    
    print '<input type="hidden" name="datafilename" value="'."$datafilename".'">';
print '<input type="hidden" name="charsetstring" value="'."$charsetstring".'">';
print '<input type="hidden" name="burnin" value="'."$burnin".'">';
print '<input type="hidden" name="temperature" value="'."$temperature".'">';
print '<input type="hidden" name="nchain" value="'."$nchain".'">';
print '<input type="hidden" name="ngen" value="'."$ngen".'">';
print '<input type="hidden" name="partitionname" value="'."$partitionname".'">';
print '<input type="hidden" name="step" value="4">';

    print '<input value="Input your choices" type="submit"></small></form>';
}
elsif  ($step=~m/4/){
print '<form method="post" action="http://www.brianomeara.info/cgi-bin/modelpartition.cgi">';

    print '<b>Use the following as a stand alone file, or delete the nexus and execute line and append it to your data file:</b><br>';
    print '<p>#nexus<br>begin mrbayes;<br>execute '."$datafilename".';<br>log start filename='."$partitionname".'.log append;<br>';
    
    @chararray=split(/\s*;+\s*/,$charsetstring,); #so kills spaces, too.
    $numberofcharsets=scalar @chararray;
    @partitionarray=();
    for ($charsetnum=1;$charsetnum<=$numberofcharsets;$charsetnum++) {
        $partitionassignment=param("divCharSet$charsetnum");
        if ($partitionassignment=~m/[0-9]/) {
            $place=$charsetnum-1;
            $partitionarray[$partitionassignment].=" $chararray[$place]";
        }
    }
    @partitionmodelarray=();

    $numberofpartitions=scalar @partitionarray;
    $numberofpartitions--;
    print 'partition '."$partitionname".' = '."$numberofpartitions".': ';
    for ($partitionnumber=1;$partitionnumber<=$numberofpartitions;$partitionnumber++) {
        $place=$partitionnumber-1;
        $partitionmodelarray[$place]=param("partModel$partitionnumber");
        print " $partitionarray[$partitionnumber]";
        if ($partitionnumber<$numberofpartitions) {
            print ',';
        }
        else {
            print ';<br>';
        }
    }
    print 'set partition = '."$partitionname".';<br>';
    for ($partitionnumber=1;$partitionnumber<=$numberofpartitions;$partitionnumber++) {
        $place=$partitionnumber-1;
        print 'lset applyto=('."$partitionnumber".') '."$partitionmodelarray[$place]".';<br>';
    }
    print 'unlink statefreq=(all) revmat=(all) shape=(all) pinvar=(all) tratio=(all);<br>prset applyto=(all) ratepr=variable;<br>showmodel;<br>';
    print 'mcmc ngen='."$ngen".' nchains='."$nchain".' temp='."$temperature".' burnin='."$burnin".' filename = '."$partitionname".'.out;<br>';
    print 'sump burnin='."$burnin".';<br>sumt burnin='."$burnin".';<br>quit;<br>';
        print '<input type="hidden" name="datafilename" value="'."$datafilename".'">';
print '<input type="hidden" name="charsetstring" value="'."$charsetstring".'">';
print '<input type="hidden" name="burnin" value="'."$burnin".'">';
print '<input type="hidden" name="temperature" value="'."$temperature".'">';
print '<input type="hidden" name="nchain" value="'."$nchain".'">';
print '<input type="hidden" name="ngen" value="'."$ngen".'">';
print '<input type="hidden" name="step" value="2">';

    print '<p><input value="Next partition" type="submit"></small></form>';
}

print end_html;