Friday, March 22, 2024

If you don't use it you lose it.

It's been a while since I needed to write some data processing scripts. And boy am I rusty! Here is the script I wrote to average out 40 samples per data point on a wafer map, and outputting the results in an Excel spreadsheet. 

#!perl
# processResistivityMap.pl
# Take 40-pt Kelvin Resistivity Data and generate single resistivity per location on wafer.
# Works with one data file at a time representing the wafer map.
# Jovan Trujillo
# Advanced Electronics and Photonics Core Facility
# Arizona State University
# 3/20/2024
# Changelog
# v1.0 - Use last point in 40-pt data file for resistivity map output.
# v1.1 - Added k correction factor to analysis() subroutine.
# v1.2 - Parse X,Y,Z and Temperature from file.

use Modern::Perl;
use File::Find;
use Switch;
use Excel::Writer::XLSX;
our $Excelbook;
our $Excelsheet;
our $row;
our $col;

sub main {
    if ($#ARGV != 1) {
        print "Usage: perl processResistivityMap.pl path-to-data-file output-file-name\n";
    } else {
       
        # ControlPanel will provide interface for Excel Macros embedded into the data collected into this spreadsheet. Will be useful for generating the plots I want, unless PDL can do it more efficiently for me.
        # Need to write some chart making macros in Excel and export the VBA as a binary. The Excel::Writer::XLSX module has a program to help me do that.
        # From the command line.
        my $file = shift @ARGV;
        my $outputName = shift @ARGV;
        $Excelbook = Excel::Writer::XLSX->new($outputName);
                die "Problems creating new Excel file: $!" unless defined $Excelbook;
        $Excelsheet = $Excelbook->add_worksheet('Summary');
        $row = 0;
        $col = 0;
       
        $Excelsheet->write($row,0,"X (um)");
    
        $Excelsheet->write($row,1,"Y (um)");
    
        $Excelsheet->write($row,2,"Z (um)");
    
        $Excelsheet->write($row,3,"T (deg C.");
    
        $Excelsheet->write($row,4,"R (Ohms/sq)");
        $row = $row + 1;
       
        print "\n\nSearching for resistivity data in: " . $file . "\n\n";
        &process_file($file);
        $Excelbook->close();
    }
}

sub process_file {
    #print "filepath: " . $File::Find::name . "\n";
    my $filepath = shift @_;
    my $sampleNum;
    my $wafer;
    my $lotName;
    #my $Excelbook = shift @_;
    
    #my $filename;
    #print "filename: $filename\n";
    if ( -f $filepath) {
        # print " This is a file : $filename \n";
        &analysis($filepath);
    } else {
        # Keep looking for valid data files.
        say "Not a valid file path\n";
    }
}

sub analysis() {
    my $filepath = shift @_;
    #my $filename = shift @_;
    #my $sampleNum = shift @_;
    #my $wafer = shift @_;
    #my $lotName = shift @_;
    #my $Excelbook = shift @_;
    my $DI;
    my $DV;
    my $AV;
    my $CV;
    
    my $Vdiff;
    my $Temperature;
    my $Resistivity=0.0;
    my $count=0;
    my $sum=0;
    my $k = 1;
    my $x;
    my $y;
    my $z;
    
    open DATA, "<$filepath" or die "Error opening file $filepath: $!\n";
    #$header = <DATA>;
    
    while (my $line = <DATA>) {
        # We skip the first 10 points of resistivity data and average out the rest. Or try just the last point. Want to see which
        # analysis will give us the best uniformity.
        if ( $line =~  /\(([\d.]+),([\d.]+),([\d.]+)\)\s*([\d.]+)C\s*/ ) {
            say "\nFound coordinates\n";
            if ($count > 0) {
                print "Average Resistance = " . $sum/$count . "\n";
                $Excelsheet->write($row,4,$sum/$count);
                $sum = 0;
                $count = 0;
                $row = $row + 1;
            }
            $x = $1;
            $y = $2;
            $z = $3;
            $Temperature = $4;
            say "x = $x";
            say "y = $y";
            say "z = $z";
            say "Temperature = $Temperature";
            $Excelsheet->write($row,0,$x);
            $Excelsheet->write($row,1,$y);
            $Excelsheet->write($row,2,$z);
            $Excelsheet->write($row,3,$Temperature);
           
           
        } else {
            if ($line =~ /C|Resistivity|Inf|^\s*$/) {
                #say "Found header line. Skipping it.";
            } else {
                #say "Reading data from: $line";
                ($DI,$DV,$CV,$AV,$Resistivity) = split(/\t\s*/,$line,5);
                # say "DI = $DI";
                # say "DV = $DV";
                # say "CV = $CV";
                # say "AV = $AV";
                #say "Resistivity = $Resistivity";
                $sum = $sum + $Resistivity;
                $count = $count + 1;
               
            }
        }
    }
    
    if ($count > 0) {
        print "Average Resistance = " . $sum/$count . "\n";
        $Excelsheet->write($row,4,$sum/$count);
        $sum = 0;
        $count = 0;
        $row = $row + 1;
    }

    # Save data to Excel Workbook
    #Columns are:
    # 0 - x
    # 1 - y
    # 2 - z
    # 3 - temperature
    # 4 - resistivity
    
    say "All done!";
    close(DATA);
}


    
    

&main();
1;

I had trouble remembering my regex syntax, and the data input file had some sneaky spaces in places that took me a while to see. But in the end I got it to work, after an afternoon and a morning working on it.