#!g:\mtapps\perl\bin #use GD::Graph; ############################# #Author = David Daycock #Date = May, 2004 ############################# &INTRO; &CHOICE; sub INTRO { print <<EOF ****************************************************** * * * * * Bath Temperature Calculation Utility * * ver. 1.0.0 * * * * by: * * David Daycock * * * * * * * ****************************************************** EOF ; } sub CHOICE { print("\n1. Predict Temperature for a given etch rate"); print("\n2. Predict Etch Rate for a given temperature"); print("\n3. Statistics on my data"); print("\n4. Information and assumptions"); print("\n5. Quit"); print("\n\nSelection: "); $pick = <STDIN>; if ($pick == 1) { &TtoER; } elsif ($pick == 2) { &ERtoT; } elsif ($pick == 3) { &STAT; } elsif ($pick == 4) { &INFO; } elsif ($pick == 5) { &QUIT; } else { print("I need a numerical answer!\n"); &CHOICE; }; } sub BASICS { print("\nYou need to input our data in x,y pairs. Press ENTER to +finish.\n"); print("If using this for Temperature and Etch Rate calcs, X should + be Temp\n"); print("and Y should be the etch rate.\n"); for ($i = 0; 1; $i++) { $numdis = $i+1; print("\nX$numdis = "); $x[$i] = <STDIN>; chomp $x[$i]; if ($x[$i] !~ m/\d/) { pop @x; last; }; #if a digit is not entered, leave the loop. print("\nY$numdis = "); $y[$i] = <STDIN>; chomp $y[$i]; } @xstore = @x; @ystore = @y; $xref = \@x; #this is a reference for later putting into r squared + functions and slope functions, etc... $yref = \@y; #remember, "perldoc perlreftut" for information on re +ferences.... } sub STAT { &BASICS; &LINorARH; my $avgX = average(@x); my $avgY = average(@y); my ($slope, $intercept, $rsquared) = linearfit($xref, $yref); if ($LINorARH == 1) { print("\n\nAVERAGE of Xs:\t\t\t$avgX\n"); print("AVERAGE of Ys:\t\t\t$avgY\n"); print("Slope of best fit line:\t\t$slope\n"); print("Intercept of best fit line:\t$intercept\n"); print("R-squared of fit:\t\t$rsquared\n"); } elsif ($LINorARH == 2) { $expA = exp($intercept); $k = -1 * $slope; print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n") +; print("A:\t\t\t$expA\n"); print("k:\t\t\t$k\n"); print("R-squared of fit:\t$rsquared\n"); } elsif ($LINorARH == 3) { $expA = exp($intercept); $k = 1 * $slope; print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\ +n"); print("A:\t\t\t$expA\n"); print("k:\t\t\t$k\n"); print("R-squared of fit:\t$rsquared\n"); } &ASK; } sub LINorARH { print("Is your data:\n"); print("1. Linear\n"); print("2. Fit to Arrhenius Equation\n"); print("3. Exponential\n"); print("Choice: "); $LINorARH = <STDIN>; chomp $LINorARH; if ($LINorARH == 2) { @x = map { 1 / $x[$_]} 0..$#x; @y = map {log $y[$_]} 0..$#y; $xref = \@x; $yref = \@y; } elsif ($LINorARH == 1) { @x = @x; @y = @y; } elsif ($LINorARH == 3) { @x = @x; @y = map {log $y[$_]} 0..$#y; $xref = \@x; $yref = \@y; } else { print("You did not enter a number!"); &LINorARH; } } sub ERtoT { &BASICS; &LINorARH; print("What is the desired etch rate: "); $er = <STDIN>; chomp($er); my ($m, $b, $rsquared) = linearfit($xref, $yref); if ($LINorARH == 1) { $temp = ($er - $b) / $m; print("\nEtch Rate at $temp deg\.C = $er\n"); } elsif ($LINorARH == 2) { $A = exp($b); $k = -1 * $m; $temp = $k / (log($A) - log($er)); print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n") +; print("Etch Rate at $temp deg\.C = $er\n"); } elsif ($LINorARH == 3) { $A = exp($b); $k = 1 * $m; $temp = (log($er) - log($A)) / $k; print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\ +n"); print("Etch Rate at $temp deg\.C = $er\n"); } &ASK; } sub TtoER { &BASICS; &LINorARH; print("At what temperature would you like to predict the etch rate +: "); $temp = <STDIN>; chomp($temp); my ($m, $b, $rsquared) = linearfit($xref, $yref); if ($LINorARH == 1) { $er = ($m * $temp) + $b; print("\nEtch Rate at $temp deg\.C = $er\n"); } elsif ($LINorARH == 2) { $A = exp($b); $k = -1 * $m; $er = $A * exp(-$k/$temp); print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n") +; print("Etch Rate at $temp deg\.C = $er\n"); } elsif ($LINorARH == 3) { $A = exp($b); $k = 1 * $m; $er = $A*exp($k * $temp); print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\ +n"); print("Etch Rate at $temp deg\.C = $er\n"); } &ASK; } sub ASK { print("\nWould you like to save your data table to a file (y): "); $savedata = <STDIN>; chomp($savedata); if ($savedata eq "y" || $savedata eq "Y") { print("\nFile name: "); $fname = <STDIN>; chomp($fname); print("\nFile $fname\.xls saved to desktop.\n"); $path = "$ENV{'HOMEDRIVE'}"."$ENV{'HOMEPATH'}"."\\"."Desktop". +"\\"; open(AFILE, ">$path"."$fname\.xls"); print AFILE ("X \(Temp\)\tY\(Etch Rate\)\n"); for ($i = 0; $i <= $#xstore; $i++) { print AFILE ("$xstore[$i] \t $ystore[$i] \n"); } close AFILE; } print("\nAre you finished (y or n): "); $quitornot = <STDIN>; chomp($quitornot); undef ($temp); undef ($A); undef ($b); undef ($m); undef ($k); undef ($LINroARH); undef ($rsquared); if ($quitornot eq "y" || $quitornot eq "Y") { &QUIT; } elsif ($quitornot eq "n" || $quitornot eq "N") { &CHOICE; } else { print ("\nThat is not an option...try again.\n"); &ASK; }; } sub INFO { print("\nAssumptions include but are not limited to:\n"); print("\nR-squared value is non-weighted.\n"); print("I can't really think of any others right now.\n\n"); &CHOICE; } sub QUIT {print("\nHope this helped! See you next time...\n");} ###################################################################### +################# #Below here are function subroutines ###################################################################### +################# sub average { #this subroutine averages the results of an array passed to it. R +eturns a single value. my $sum = 0; foreach $_ (@_) { $sum += $_; } my $avg = $sum / ($#_ + 1); return $avg; } sub linearfit { #this subroutine takes as arguments two array references containin +g linear x and y #it returns the linear best fit regression and r-squared correlati +on. #Usage is @foo = linearfit($xref, $yref) where $xref is a referenc +e to an array holding all values of #x and $yref is a reference to an array holding all values of y. +The index of x and y must be equal #in order for this to work correctly. The function returns an arr +ay in the following order: # @results = (slope of line, intercept of line, rsquared correlati +on) # in order fo this function to work, you need the sum, average and + sqr functions in the file. my @xs = @{@_[0]}; #turns a reference into an array! my @ys = @{@_[1]}; my @xsqrd = sqr(@xs); my @xy = map {$xs[$_] * $ys[$_]} 0..$#xs; my $sumX = sum(@xs); my $sumY = sum(@ys); my $sumXY = sum(@xy); my $sumXsqr = sum(@xsqrd); my $n = $#xs; my $b = (($sumY * $sumXsqr) - ($sumX * $sumXY)) / ((($n+1) * $sumX +sqr) - ($sumX * $sumX)); my $m = ((($n+1) * $sumXY) - ($sumX * $sumY)) / ((($n+1) * $sumXsq +r) - ($sumX * $sumX)); my $w; my @predY; for ($w = 0; $w <= $#xs; $w++) { $predY[$w] = ($xs[$w] * $m ) + $b; } my $yAvg = average(@ys); my $k; my @predYErr; for ($k = 0; $k <= $#predY; $k++) { $predYErr[$k] = $predY[$k] - $yAvg; } my @ssPred = sqr(@predYErr); my $l; my @Err; for ($l = 0; $l <= $#xs; $l++) { $Err[$l] = $ys[$l] - $yAvg; } my @ssTotal = sqr(@Err); my $sumSSpred = sum(@ssPred); my $sumSStotal = sum(@ssTotal); my $rsqrd; if ($sumSStotal == 0) { $rsqrd = 0; } else { $rsqrd = $sumSSpred / $sumSStotal; $rsqrd = $rsqrd * 10000; $rsqrd = int ($rsqrd); $rsqrd = $rsqrd / 10000; #this block of code gives a four sig + fig rsquared value. } my @ans = ($m, $b, $rsqrd); # @data = (@x, @predY); # my $graph = GD::Graph::points->new(400, 300); # # $graph->set # ( # x_label => 'Temperature', # y_label => 'Etch Rate', # title => 'Some simple graph', # y_max_value => 100, # y_tick_number => 100, # y_label_skip => 2 # ) or die $my_graph->error; # # my $gd = $my_graph->plot(\@data) or die $my_graph->error; # return @ans; } sub sum { #this subroutine sums the numbers passed to it. Returns a single +value. my $sum = 0; foreach my $line (@_) { $sum += $line; } return $sum; } sub sqr { #Calculates the square of any array passed to it, returns an array + with the squares. my @xs = @_; my @result = map {$xs[$_] * $xs[$_]} 0..$#xs; #multiply each line +of an array together. return @result; }

In reply to BathTemp by ~~David~~

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.