Friday, January 4, 2013

Data file conversion script

It's been a while since I have posted anything to this blog. In my memory the last use of Perl for work was a file parser that did a coordinate transform on one of the fields. I think it's some of the more complicated regular expression applications I have made so far.

The file takes defectivity data generated by an Orbotech display circuit scanner and converts it to a format that is compatible with a TNP laser tool. With the TNP laser we can move to the defective coordinates found by the Orbotech and attempt to salvage the circuit using laser ablation.



# Orbotech_to_TNP_Converter_20111121.pl
#
# Jovan Trujillo
# Arizona State University
# 11/21/2011
#
# This script formats an Orbotech file for use with the TNP Laser system.
#

use strict;

if ($#ARGV != 0) {
print "ARGV = ", $#ARGV, "\n";
print "Usage: Orbotech_to_TNP_Converter_20111121.pl \n";
exit(1);
}

my $rootPath = $ARGV[0];
my @lotList;
my @dataFile;
my $dataLine;
my $tempPath;

# Generate list of subfolders
opendir DIR, $rootPath or die "Couldn't open dir $rootPath: $!\n";
my @folders = readdir DIR;
closedir DIR;

foreach (@folders) {
if (-d $rootPath . "\\" . $_) {
if ($_ eq ".") {}
elsif($_ eq "..") {}
else {
push(@lotList, $_);
}
}
}

my %lotHash = ();
my $currentLot;

#Generate list of lot folders
foreach (@lotList) {
$tempPath = $rootPath . "\\" . $_;
$currentLot = $_;
opendir DIR, $tempPath or die "Couldn't open dir $tempPath: $!\n";
@folders = readdir DIR;
closedir DIR;
# Generate list of process folders
foreach (@folders) {
if (-d $tempPath . "\\" . $_) {
if ($_ eq ".") {}
elsif($_ eq "..") {}
else {
push(@{$lotHash{$currentLot}}, $_);
}
}
}
}

my $lot = "NULL";
my $process_step = "NULL";
my $data_file = "NULL";
my $panel_type = "";
my $panel_id = "";
my $operator_id = "";
my $scan_status = "";
my $queue = "";
my $go_repeats = "";
my $nogo_repeats = "";
my $num_repeats = "";
my $image_file_prefix = "";
my $slot_no = "";
my $glass_size_X = "";
my $glass_size_Y = "";
my $board_center_X = "";
my $board_center_Y = "";
my $panel_status = "NOT CLASSIFIED";
my $align_targets = "";
my $num_defects = "";
my $rep_no = "NULL";
my $X_coord = "NULL";
my $Y_coord = "NULL";
my $size = "NULL";
my $retype = "NULL";
my $type = "NULL";
my $cell_zone = "NULL";
my $size_X = "NULL";
my $size_Y = "NULL";
my $class = "NULL";
my $imagesuffix = "NULL";
my $row_cell_num = "NULL";
my $col_cell_num = "NULL";
my $i = 0;
my $output_file;
my @defect_list;
my $defect_string;

@folders = ();
for my $key (keys %lotHash) {
for ($i=0; $i <= $#{$lotHash{$key}}; $i++) {
$tempPath = $rootPath . "\\" . $key . "\\" . $lotHash{$key}[$i];
$lot = $key;
$process_step = $lotHash{$key}[$i];
opendir DIR, $tempPath or die "Couldn't open dir $tempPath: $!\n";
@folders = readdir DIR;
closedir DIR;
# Open each data file and parse for valid Orbotech Data
foreach (@folders) {
$tempPath = $rootPath . "\\" . $key . "\\" . $lotHash{$key}[$i] . "\\" . $_;
$data_file = $_;
open(DATA, "<$tempPath");

# Open report output file
$output_file = "TNP_" . $data_file;
$tempPath = $rootPath . "\\" . $key . "\\" . $lotHash{$key}[$i] . "\\" . $output_file;
open (REPORT, ">$tempPath") or die "Could not open $tempPath: $!\n";

@dataFile = ;
foreach $dataLine (@dataFile) {
# print "dataLine: $dataLine\n";
if ($dataLine =~ /panel_type\s*=\s*"([\w\s]*)"/) {
$panel_type = $1;
}
if ($dataLine =~ /panel_id\s*=\s*"([\w\s]*)"/) {
$panel_id = $1;
}
if ($dataLine =~ /operator_id\s*=\s*"([\w\s]*)"/) {
$operator_id = $1;
}
if ($dataLine =~ /queue\s*=\s*"([\w\s]*)"/) {
$queue = $1;
}
if ($dataLine =~ /scan_status\s*=\s*"([\w\s]*)"/) {
$scan_status = $1;
}
if ($dataLine =~ /go_repeats\s*=\s*"([\w\s]*)"/) {
$go_repeats = $1;
}
if ($dataLine =~ /nogo_repeats\s*=\s*"([\w\s]*)"/) {
$nogo_repeats = $1;
}
if ($dataLine =~ /image_file_prefix\s*=\s*"([\w\s\.]*)"/) {
$image_file_prefix = $1;
}
if ($dataLine =~ /slot_no\s*=\s*([\d\.\-]*)/) {
$slot_no = $1;
}
if ($dataLine =~ /num_repeats\s*=\s*([\d\.\-]*)/) {
$num_repeats = $1;
}
if ($dataLine =~ /glass_size.x\s*=\s*([\d\.\-]*)/) {
$glass_size_X = $1;
}
if ($dataLine =~ /glass_size.y\s*=\s*([\d\.\-]*)/) {
$glass_size_Y = $1;
}
if ($dataLine =~ /board_center.x\s*=\s*([\d\.\-]*)/) {
$board_center_X = $1;
}
if ($dataLine =~ /board_center.y\s*=\s*([\d\.\-]*)/) {
$board_center_Y = $1;
}
if ($dataLine =~ /panel_status\s*=\s*"([\w\s]*)"/) {
$panel_status = $1;
}
if ($dataLine =~ /align_targets\s*=\s*\(([\d\.\-]*)\s*([\d\.\-]*)\)\s*\(([\d\.\-]*)\s*([\d\.\-]*)\)\s*\(([\d\.\-]*)\s*([\d\.\-]*)\)\s*\(([\d\.\-]*)\s*([\d\.\-]*)\)/ ) {
$align_targets = "(" . $2 . " " . -$1 . ")(" . $4 . " " . -$3 . ")(" . $6 . " " . -$5 . ")(" . $8 . " " . -$7 . ")";
}
if ($dataLine =~ /num_defects\s*=\s*([\d\.\-]*)/) {
$num_defects = $1;
}
if ($dataLine =~ /([\d\.\-]*)\s*,\s*([\d\.\-]*)\s*,\s*([\d\.\-]*)\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\[\]\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*"*([\w\+\-\.]*)"*\s*,\s*([\d\.]*)\s*,\s*([\d\.]*),?/) {
$rep_no = $1;
$X_coord = $3;
$Y_coord = -$2;
$size = $4;
$retype = $5;
$type = $6;
$cell_zone = $7;
$size_X = $8;
$size_Y = $9;
$class = $10;
$imagesuffix = $11;
$row_cell_num = $12;
$col_cell_num = $13;
$defect_string = $rep_no . ", " . $X_coord . ", " . $Y_coord . ", \"" . $size . "\", \"" . $retype . "\", \"" . $type . "\", \"" . $cell_zone . "\", \"" . $size_X . "\", \"" . $size_Y . "\", \"" . $class . "\", \"" . $imagesuffix . "\", " . $row_cell_num . ", " . $col_cell_num . ", \n";
push(@defect_list, $defect_string);
}
}
print REPORT "panel_type =\"$panel_type\"\n";
print REPORT "panel_id =\"$panel_id\"\n";
print REPORT "operator_id =\"$operator_id\"\n";
print REPORT "queue =\"$queue\"\n";
print REPORT "scan_status =\"$scan_status\"\n";
print REPORT "go_repeats =\"$go_repeats\"\n";
print REPORT "nogo_repeats =\"$nogo_repeats\"\n";
print REPORT "image_file_prefix =\"$image_file_prefix\"\n";
print REPORT "slot_no =$slot_no\n";
print REPORT "num_repeats =$num_repeats\n";
print REPORT "glass_size.x =$glass_size_X\n";
print REPORT "glass_size.y =$glass_size_Y\n";
print REPORT "board_center.x =$board_center_X\n";
print REPORT "board_center.y =$board_center_Y\n";
print REPORT "panel_status =\"$panel_status\"\n";
print REPORT "align_targets =$align_targets\n";
print REPORT "num_defects =$num_defects\n";
print REPORT "defect_list =\"#Rep no. X coord. Y coord. Size-X Size-Y Class ImageSuffix Row_Cell_Num Col_Cell_Num\"\n";
foreach (@defect_list) {
print REPORT $_;
}
$panel_type = "";
$panel_id = "";
$operator_id = "";
$queue = "";
$scan_status = "";
$go_repeats = "";
$nogo_repeats = "";
$image_file_prefix = "";
$slot_no = "";
$num_repeats = "";
$glass_size_X = "";
$glass_size_Y = "";
$board_center_X = "";
$board_center_Y = "";
$panel_status = "NOT CLASSIFIED";
$align_targets = "";
$num_defects = "";
@defect_list = ();
close(DATA);
close(REPORT);
}
@folders = ();
}
}
print "Data conversion complete!\n";