#!/usr/bin/perl  -Tw

$ENV{PATH} = "/bin/:/usr/bin/:/usr/local/bin/";
$ENV{ENV} = "";

use strict;

#######################################################################
#                      Set Up The Varaibles                           #
#######################################################################

my    (     
       $TempFile,        
       $Library,        # the cgi-lib.pl
       $Author,
       $Source, 
       $This_File,
       $IntroMessage,
       %form_input,       # The cgi & readparse data
       $Data_Set,        
       $Data_Spaced,        
       $DataSource,        
       $Template,        
       $Stats,        
       $StatsProg,        
       $ThisFile,        
       $perlwarn,        
       $MR_Bar,        
       $MR_Data,        
       $UCLX,        
       $UCLMR,        
       $LCLX,        
       $LLX,        
       $ULX,        
       $ULMR,        
       $Mean,        
       $result,        
       $Sd,        
       $Seed,        
       $Process,
       $X_Chart,
       $MR_Chart,
       @DataArray,      
      );

$StatsProg ="/usr/local/bin/stats"; 
$TempFile = "/tmp/Tmp$$";
$Author = "<a href=http://mug.sys.virginia.edu/~drf5n>David Forrest</a>";
$Source = "<a href=/cgi-scripts/plot.pl>Source Code</a>";
$ThisFile="/cgi-bin/plot.pl";
$Library= "./cgi-lib.pl";

#$CritProg ="/usr/local/bin/probdist"; 

$Template= "     |              .              |     "; 

require $Library;
require "/var/lib/httpd/cgi-bin/drf-lib.pl";


#######################################################################
#                       Print http Header.                            #
#######################################################################

# First tell Perl to bypass the buffer.  Then, print out the HTTP
# header. We'll output this quickly so that we
# will be able to do some of our debugging from the web and so that in
# the case of a bogged down server, we won't get timed-out. 
  $! = 1;


print &PrintHeader;
print &HtmlTop ("Shewhart Individuals SPC Chart") ;

&ReadParse (\%form_input); 

#print &PrintVariables (\%form_input);

$Seed =  $$;
$DataSource = $form_input{'Data'};

unless (defined $DataSource){$DataSource ="Clear";}
$_ = $DataSource;

SWITCH: {
        if (/AR1:([-\d,\.]+)/ ) { $Data_Set=`arma -p$1 -n1000 -s$Seed`;
                 $Process="AR(p) p=($1) Z=iid(0,1)";
            last SWITCH; }
        if (/ARMA\(([-\d,\.]+):([-\d\.,]+)\)/ ) { 
                 $Data_Set  =`arma -p$1 -q$2 -n1000 -s$Seed`;
                 $Process   ="ARMA(p,q) p=($1) q=($2) Z=iid(0,1)";
            last SWITCH; }
        if ($DataSource eq "Clear") { $Data_Set="0.3 2 4.5 4";
                 $Process="Demo Data";
                 last SWITCH; }
        if ($DataSource eq "My Data") { $Data_Set= $form_input{'DataSet'};
                 $Process="Your Data";
                 last SWITCH; }
        $Data_Set= $form_input{'DataSet'};
        $Process="Your Data";
    }



$perlwarn = $^W;
$^W=0;

if ($Data_Set =~ /^([-eE.,\s\d\n]+)$/) {     
        $Data_Set = $1;                  
    } else {
        $Process="Corrupt Data";
        $Data_Set="0.3 2 4.5 4";
    }

$^W = $perlwarn;
	#$Data_set =~s/^\s*(.*?)\s*$/$1/g;
	$Data_Set =~ s/([-eE\.\d]+)[\s,]+/$1 \n/g;

if (defined $Data_Set ){
    $Data_Set =~ s/([\r]+)//g;           # Remove the Carriage Returns
    $Data_Set =~ s/ *([\n]+) */\0/g;         # Change the newlines into nulls
    $Data_Set =~ s/([\s]+)/ /g;          # Remove the extra space
    $Data_Set =~ s/ *([\0]+) */\n/g;         # Change all the nulls back to \n
    chomp $Data_Set;                     #Remove trailing newline

    $Data_Spaced = $Data_Set;
    $Data_Spaced =~ s/\n/ /g;
}

open (Temp_File, ">$TempFile") || die "Can't open $TempFile";
print Temp_File "$Data_Set";
close (Temp_File);


$Stats =`$StatsProg <$TempFile`; 

$result= `$StatsProg mean sd <$TempFile`;
($Mean,  $Sd) = split (/\s+/,$result);

unlink $TempFile;

($MR_Bar, $MR_Data) = &Calculate_MR ("$Data_Set ");

$UCLX = $Mean + 2.66 * $MR_Bar;
$LCLX = $Mean - 2.66 * $MR_Bar;
$ULX = $Mean + 3.32 * $MR_Bar;
$LLX = $Mean - 3.32 * $MR_Bar;
$UCLMR = 3.627* $MR_Bar;
$ULMR = 3.627*1.25* $MR_Bar;
     
$X_Chart= &TextGraph ($Template, 
                 $LLX,
                 $ULX,
                 "*",
                 (split /\n/,$Data_Set));
 
$MR_Chart= &TextGraph("|   .        |    ",
                  0,
                  $ULMR,
                  "*",
                  (split /\n/,$MR_Data));

#######################################################################
#                      Crank out the HTML for the form,               #
#######################################################################

# output the data input form and statistics in one table,
# Then the charts in the next

print "<table border=1><tr><td>";		# new Tables
&STATS_Form;
print <<_EOT_;
<a href=#about>About This Program<a></td>
<td><h3>Summary Statistics</h3>
<pre>$Stats</pre>
</td> <td>
<APPLET codebase="/java/class/" code="Histogram.class"
    width=200
    height=300>
    <PARAM name=data value=" $Data_Spaced ">
    <PARAM name=title value="Histogram">
</APPLET>
</td>
</tr></table>

<h1>Shewhart Individuals X-MR Charts on $Process</h1>
<table border = 1> 
<tr valign=top>
<td>X Chart<br>LCLX=$LCLX<br> Mean=$Mean<br>UCLX=$UCLX </td>
<td>X Data </td>
<td>MR </td>
<td>MR Chart MR_Bar=$MR_Bar <br> UCLMR=$UCLMR </td>
</tr>

<tr valign=top>
<td>     <pre>$X_Chart</pre> </td>
<td>     <pre>$Data_Set</pre> </td>
<td><br> <pre>$MR_Data</pre> </td>
<td><br> <pre>$MR_Chart</pre> </td>
</tr>

</table>
<h1><a name="about">About this program</h1></a>
$Source written by $Author in 1997 at 
<a href=http://www.sys.virginia.edu/>UVA Systems Engineering</a>
(<a href="http://www.sys.virginia.edu/outside/Statistics.html">See</a>)<br>
This 
<a href="$ThisFile">Demo</a>
uses <a href="http://www.perl.com/">Perl</a><a name=junk $]>, Unix,
<a href="http://www.bio.cam.ac.uk/cgi-lib/">cgi-lib.pl</a>,
and <a href="ftp://archive.cis.ohio-state.edu/pub/stat/">| Stat</a> 
to provide a quick no-software method of using SPC Charts
<p> Please enter your comma-delimited or white space delimited data into
the box and hit "Plot Data".  If you'd like you can choose one of the data
generators to make up 1000 points of random data. 
<p> The AR processes are auto-regressive with the current data point 
<pre>X[t] = p * X[t-1] + Z[t]</pre>
<p>While you might think this page to be utterly lacking in aesthetics, my plan was
to allow you to choose your own colors and text styles.  If you hate the 
background color or text style you see, you don't have to put up with it, 
change it in your browser.  I've made the page as fast and as generic as I could
in order to build a useful tool.

_EOT_


print &footer ("Goodbye");
print &HtmlBot;





sub STATS_Form {
print <<_EOT_;
<FORM METHOD="POST" ACTION=
"plot.pl"
><table border=1>
<tr><th>Variable</th><th>Value</th><th>Examples</th></tr>
<tr><td>Data Set</td><td><textarea name="DataSet" cols=10 rows=10 >$Data_Set</textarea></td><td>0.1,0.2</td></tr>
</table>
<SELECT NAME=Data>
<OPTION DEFAULT>My Data
<OPTION>Clear
<OPTION>AR1:-1
<OPTION>AR1:-0.9
<OPTION>AR1:-0.7
<OPTION>AR1:-0.5
<OPTION>AR1:-0.3
<OPTION>AR1:-0.1
<OPTION>AR1:.0
<OPTION>AR1:.1
<OPTION>AR1:.3
<OPTION>AR1:.5
<OPTION>AR1:.7
<OPTION>AR1:.9
<OPTION>AR1:1.0
<OPTION>ARMA(.7,.3:-.4,-.3,-.2)
</SELECT>
<input type=submit Value="Plot Chart">
</FORM>

_EOT_
}

#######################################################################
#            Calculate_MR                                               
#######################################################################

#   ($MR_Bar, $MR_String) = &Calculate_MR ($Data);

# Reads the argument list & finds the average difference between adjacents
# Untested with bad data
# 
# Returns 1x10^6 for a single data point
#

sub Calculate_MR {
    chomp;	
    my ($Data) = @_;
    my ($MR_Count,
           $MR_Sum,
           $X_Last, 
           $X_Remaining, 
           $X, 
	   $MR,
           $MR_Bar,
           $MR_String,
     );
    
    $MR_Count = 0;
    $MR_Sum = 0;
    $MR_String = "";
    ($X_Last, $X_Remaining) = (split "\n", $Data, 2);
    foreach $X (split "\n", $X_Remaining){
        $MR_Count++;
        $MR = abs ($X - $X_Last);
        $MR_Sum += $MR;
        $MR_String  .= sprintf("%7f\n",$MR); 
        $X_Last = $X;
    }
    $MR_Bar = ( $MR_Count >0 ? ($MR_Sum / $MR_Count): 1e6);
    return ($MR_Bar, $MR_String); 
}



