#!/usr/bin/perl # Anvil 2 FORM2 # # This scripts takes a .anvil file as an arugment # and converts it to the .form2 file format. # # Chris Osborn # cosborn@ldc.upenn.edu # # FORM Project, Linguistic Data Consortium # University of Pennsylvania # # http://www.ldc.upenn.edu/Projects/FORM/ # use Graph; print "\n"; #all hashes,maps,etc $labelMap{"Dimension X"} = "X"; $labelMap{"Dimension Y"} = "Y"; $labelMap{"Dimension Z"} = "Z"; $labelMap{"Upper arm lift"} = "Lift"; $labelMap{"Forearm orientation"} = "Forearm"; $labelMap{"Handshape group"} = "Group"; $labelMap{"Handshape letter"} = "Letter"; $labelMap{"Wrist bend: up and down"} = "UpDown"; $labelMap{"Wrist bend: side to side"} = "SideSide"; $labelMap{"Excursionduration"} = "Duration"; $labelMap{"Tension"} = "Tension"; $labelMap{"Effort"} = "Effort"; $liftValMap[1] = 0; $liftValMap[2] = 22.5; $liftValMap[3] = 45; $liftValMap[4] = 67.5; $liftValMap[5] = 90; $liftValMap[6] = 112.5; $liftValMap[7] = 135; $liftValMap[8] = 157.5; $liftValMap[9] = 180; #change these $foreValMap[1] = -90; $foreValMap[2] = -45; $foreValMap[3] = 0; $foreValMap[4] = 45; $foreValMap[5] = 90; $foreValMap[6] = 90; $foreValMap[7] = 90; $shapeValMap{"NS"} = 0; $shapeValMap{"0A"} = 1; $shapeValMap{"0B"} = 2; $shapeValMap{"0C"} = 3; $shapeValMap{"0D"} = 4; $shapeValMap{"0E"} = 5; $shapeValMap{"0F"} = 6; $shapeValMap{"1A"} = 7; $shapeValMap{"1B"} = 8; $shapeValMap{"1C"} = 9; $shapeValMap{"1D"} = 10; $shapeValMap{"1E"} = 11; $shapeValMap{"1F"} = 12; $shapeValMap{"1G"} = 13; $shapeValMap{"1H"} = 14; $shapeValMap{"2A"} = 15; $shapeValMap{"2B"} = 16; $shapeValMap{"2C"} = 17; $shapeValMap{"2D"} = 18; $shapeValMap{"2E"} = 19; $shapeValMap{"2F"} = 20; $shapeValMap{"2G"} = 21; $shapeValMap{"2H"} = 22; $shapeValMap{"2I"} = 23; $shapeValMap{"2J"} = 24; $shapeValMap{"2K"} = 25; $shapeValMap{"3A"} = 26; $shapeValMap{"3B"} = 27; $shapeValMap{"3C"} = 28; $shapeValMap{"3D"} = 29; $shapeValMap{"3E"} = 30; $shapeValMap{"3F"} = 31; $shapeValMap{"4A"} = 32; $shapeValMap{"5A"} = 33; $shapeValMap{"5B"} = 34; $shapeValMap{"5C"} = 35; $shapeValMap{"5D"} = 36; $shapeValMap{"5E"} = 37; $shapeValMap{"5F"} = 38; $shapeValMap{"5G"} = 39; $shapeValMap{"5H"} = 40; $shapeValMap{"5I"} = 41; $shapeValMap{"5J"} = 42; $shapeValMap{"6A"} = 43; $shapeValMap{"6B"} = 44; $shapeValMap{"6C"} = 45; $shapeValMap{"6D"} = 46; $shapeValMap{"6E"} = 47; $shapeValMap{"6F"} = 48; $shapeValMap{"6G"} = 49; $shapeValMap{"6H"} = 50; $shapeValMap{"6I"} = 51; $upDownValMap[1] = 85; $upDownValMap[2] = 42.5; $upDownValMap[3] = 0; $upDownValMap[4] = -42.5; $upDownValMap[5] = -85; $sideSideValMap[1] = 22.5; $sideSideValMap[2] = 0; $sideSideValMap[3] = -22.5; $sideSideValMap[4] = -45; $timeFormat = "%.3f"; ### This is to easily adjust the time-stamp tolerance. $fps = 29.97; $spf = 1/$fps; $interFlag = 1; ### interpolation parameter, 0=off, 1(default)=on $lastFrame = 0; $firstRFrame = 100000; $firstLFrame = 100000; #general rounding function sub round { $_[0] > 0 ? int $_[0] + 0.5 : int $_[0] - 0.5 } ### one-dimensional interpolation function ### args: int $tS ($_[0]), int $tE ($_[1]), real $valS ($_[2]), real $valE ($_[3]) ### return: list of interpolated values from $valS to $valE with size $tE-$tS sub interpolate{ my $tS = $_[0]; my $tE = $_[1]; my $valS = $_[2]; my $valE = $_[3]; my $timeDiff = $tE - $tS; my $valDiff = $valE - $valS; my $valInc = $valDiff/$timeDiff; for(my $i=1; $i<=$timeDiff; $i++){ $valArray[$i-1] = $valS + ($valInc*$i); } return @valArray; } for(my $i=0; $i<$#ARGV; $i++){ if($ARGV[$i] =~ /-\w/){ $ARGV[$i] =~ s/-//; $paraName = $ARGV[$i]; $paraVal = $ARGV[$i+1]; ARG: { if($paraName =~ /f/){ if($paraVal !~ /^[\d.]*?$/){ print "Invalid frame rate.\n"; $paraCounter = $paraCounter+2; $fFlag = 1; }else{ $fps = $paraVal; $spf = 1/$fps; $paraCounter = $paraCounter+2; $fFlag = 1; } last ARG; } if($paraName =~ /n/){ $interFlag = 0; $paraCounter++; last ARG; } print "-$ARGV[$i] is an invalid parameter.\n"; $paraCounter++; } }else{ if($fFlag == 0){ if($ARGV[$i] !~ /.anvil/){ print "$ARGV[$i] is an invalid parameter.\n"; $paraCounter++; } }else{ $fFlag = 0; } } } for(my $i=0; $i<$paraCounter; $i++){ shift(@ARGV); } ### This reads in the files and create the annotation graphs for each annotator. $graphCounter = 0; foreach $file (@ARGV){ open (FILE, "./$file"); $fileName = $file; $fileName =~ s/.anvil//g; $noIName = "$fileName"."NoI.form2"; $IName = "$fileName".".form2"; $graphCounter++; $annotationGraph{$graphCounter} = Graph->new(); while () { $line = $_; if ($line =~ /Right/){$armFlag = 0} if ($line =~ /Left/){$armFlag = 1} ### The following extracts the trackname, which will be part of the edge name if ($line =~ /track name/) { ($trackName) = ($line =~ /track name="(.*?)"/); $trackName =~ s/ //g; ($highLevel,$midLevel,$lowLevel) = (split(/\./, $trackName)); } ### This sets the nodes if ($line =~ //); $start = sprintf("$timeFormat",$start); $end = sprintf("$timeFormat",$end); if($armFlag == 0){ if($start < $firstRFrame){ $firstRFrame = $start; $firstRFrameEnd = $end; } $tempEnd = $end-1; if($tempEnd > $lastRFrame){$lastRFrame = $tempEnd;} } if($armFlag == 1){ if($start < $firstLFrame){ $firstLFrame = $start; $firstLFrameEnd = $end; } if($tempEnd > $lastRFrame){$lastRFrame = $tempEnd;} } $annotationGraph{$graphCounter}->add_edge( "$start", "$end"); if ($trackName =~ /duration/){ $attribute = "Excursionduration"; $value = "NA"; $totalAttribute = "$trackName" . "::$attribute" . "::$start" . "::$end"; $annotationGraph{$graphCounter}->set_attribute($totalAttribute,$start,$end,$value); } } ### This sets the names of the edges if ($line =~ /(.*?)set_attribute($totalAttribute,$start,$end,$value); } } close (FILE); } ### This creates the labeled-edge hashes for each file $arcCounter = 0; if($lastRFrame > $lastLFrame){$lastFrame = $lastRFrame;} else{$lastFrame = $lastLFrame;} $frames = ($lastFrame - $firstFrame)*$fps; $firstRFrame = round($firstRFrame*$fps); $firstLFrame = round($firstLFrame*$fps); $lastRFrame = round($lastRFrame*$fps); $lastLFrame = round($lastRFrame*$fps); $boundHash{"firstRFrame"} = $firstRFrame; $boundHash{"firstLFrame"} = $firstLFrame; $boundHash{"lastRFrame"} = $lastRFrame; $boundHash{"lastLFrame"} = $lastLFrame; foreach $graph (keys %annotationGraph){ my $u, $v; my @vertices = sort {$a <=> $b} $annotationGraph{$graph}->vertices; foreach $u (@vertices){ my @successors = $annotationGraph{$graph}->successors($u); undef %singular; foreach $v (@successors){ if (!$singular{$v}){ $singular{$v} = 1; %attributes = $annotationGraph{$graph}->get_attributes($u, $v); foreach $totalAttribute (sort keys %attributes){ $arcKey = "$u" . "::$v" . "::$totalAttribute" . "::$attributes{$totalAttribute}"; ($armName, $track, $label, $tStart, $tEnd) = ($totalAttribute =~ /^(.*?)\.(.*?)::(.*?)::(.*?)::(.*?)$/); if($armName =~ /Right/){$hand = "R";} else{$hand = "L";} if ($track =~ /UpperArm\.Movement/){$moveFlag = 0} #following data is for UpperArm Movement track if ($track =~ /Forearm\.Movement/){$moveFlag = 1} #following data is for Forearm Movement track if ($track =~ /HandandWrist\.Movement/){$moveFlag = 2} #following data is for HandAndWrist Movement track $label = $labelMap{$label}; if($label =~ /\w/){ if($label =~ /Effort/){ if($moveFlag == 0){$move = "Arm"} elsif($moveFlag == 1){$move = "Fore"} elsif($moveFlag == 2){$move = "Hand"} } else{$move = ""} $label = "$hand"."$move"."$label"; my $val = $attributes{$totalAttribute}; ($num) = ($val =~ /^(\d).*?$/); $frameStamp = round($tStart*$fps); $frameEnd = round($tEnd*$fps); $fDiff = $frameEnd - $frameStamp; if($label =~ /Duration/){ $labelHash{$label}{$frameStamp} = 0; $labelHash{$label}{$frameEnd-1} = 1; }else{ if($label !~ /Letter/){$tempVal = $num;}else{$tempVal = $val;} if($fDiff > 1){ for(my $i=$frameStamp; $i<$frameEnd; $i++){$labelHash{$label}{$i} = $tempVal;} }else{$labelHash{$label}{$frameStamp} = $tempVal;} } } $arcCounter++; $graphList[$graph]{$arcKey}++; } } } } } #-------------------------------- #interpolation #-------------------------------- @labelArray = ("X","Y","Z","Lift","Forearm","SideSide","UpDown"); @armArray = ("R","L"); if($interFlag == 1){ foreach $arm (@armArray){ foreach my $name (@labelArray){ $lastLabel = "$arm"."$name"; $lastHash{$lastLabel} = ""; } my $firstFrameLabel = 'first'."$arm".'Frame'; my $lastFrameLabel = 'last'."$arm".'Frame'; for(my $i=$boundHash{$firstFrameLabel}; $i<$boundHash{$lastFrameLabel}; $i++){ $durationLabel = "$arm"."Duration"; if($labelHash{$durationLabel}{$i} eq 0){ foreach my $name (@labelArray){ $lastLabel = "$arm"."$name"; $lastHash{$lastLabel} = ""; $lasttSHash{$lastLabel} = ""; } } foreach my $name (@labelArray){ $labelName = "$arm"."$name"; $tempHash{$labelName} = $labelHash{"$labelName"}{$i}; if($labelName =~ /Lift/){$tempHash{$labelName} = $liftValMap[$tempHash{$labelName}];} elsif($labelName =~ /Forearm/){$tempHash{$labelName} = $foreValMap[$tempHash{$labelName}];} elsif($labelName =~ /SideSide/){$tempHash{$labelName} = $sideSideValMap[$tempHash{$labelName}];} elsif($labelName =~ /UpDown/){$tempHash{$labelName} = $upDownValMap[$tempHash{$labelName}];} if(($tempHash{$labelName} ne "") && ($lastHash{$labelName} ne "")){ $ArrHash{$labelName} = [interpolate($lasttSHash{$labelName}, $i, $lastHash{$labelName}, $tempHash{$labelName})]; for(my $j=$lasttSHash{$labelName}; $j<$i; $j++){ $temp2 = $ArrHash{$labelName}[$j-$lasttSHash{$labelName}]; $labelHash{$labelName}{$j+1} = $temp2; } }else{$labelHash{$labelName}{$i} = $tempHash{$labelName};} if($tempHash{$labelName} ne ""){ $lastHash{$labelName} = $tempHash{$labelName}; $lasttSHash{$labelName} = $i; } } } } } if($interFlag == 1){ open(OUT, ">./$IName"); print OUT "#$IName\n\n"; }else{ open(OUT, ">./$noIName"); print OUT "#$noIName\n\n"; } foreach $arm (@armArray){ if($arm =~ /R/){print OUT "#Right Hand\n#------------\n";} else{print OUT "#Left Hand\n#------------\n";} $gestureFlag = 0; my $firstFrameLabel = 'first'."$arm".'Frame'; my $lastFrameLabel = 'last'."$arm".'Frame'; $xLabel = "$arm"."X"; $yLabel = "$arm"."Y"; $zLabel = "$arm"."Z"; $liftLabel = "$arm"."Lift"; $foreLabel = "$arm"."Forearm"; $shapeLabel = "$arm"."Shape"; $groupLabel = "$arm"."Group"; $letterLabel = "$arm"."Letter"; $sideSideLabel = "$arm"."SideSide"; $upDownLabel = "$arm"."UpDown"; $effortLabel = "$arm"."ArmEffort"; $tensionLabel = "$arm"."Tension"; for(my $i=$boundHash{$firstFrameLabel}; $i<$boundHash{$lastFrameLabel}; $i++){ $durationLabel = "$arm"."Duration"; $tempDuration = $labelHash{$durationLabel}{$i}; if($tempDuration eq 0){$gestureFlag = 1;} if($gestureFlag eq 1){ $tempX = $labelHash{$xLabel}{$i}; $tempY = $labelHash{$yLabel}{$i}; $tempZ = $labelHash{$zLabel}{$i}; $tempLift = $labelHash{$liftLabel}{$i}; $tempForearm = $labelHash{$foreLabel}{$i}; $tempGroup = $labelHash{$groupLabel}{$i}; $tempLetter = $labelHash{$letterLabel}{$i}; $tempShape = $shapeValMap{"$tempGroup"."$tempLetter"}; $tempSideSide = $labelHash{$sideSideLabel}{$i}; $tempUpDown = $labelHash{$upDownLabel}{$i}; $tempTension = $labelHash{$tensionLabel}{$i}; $tempEffort = $labelHash{$effortLabel}{$i}; if($interFlag eq 0){ if($tempX ne ""){$tempX = sprintf("$timeFormat",$tempX);} if($tempY ne ""){$tempY = sprintf("$timeFormat",$tempY);} if($tempZ ne ""){$tempZ = sprintf("$timeFormat",$tempZ);} if($tempLift ne ""){$tempLift = sprintf("$timeFormat",$liftValMap[$tempLift]);} if($tempForearm ne ""){$tempForearm = sprintf("$timeFormat",$foreValMap[$tempForearm]);} if($tempSideSide ne ""){$tempSideSide = sprintf("$timeFormat",$sideSideValMap[$tempSideSide]);} if($tempUpDown ne ""){$tempUpDown = sprintf("$timeFormat",$upDownValMap[$tempUpDown]);} }else{ if($tempX ne ""){$tempX = sprintf("$timeFormat",$tempX);} if($tempY ne ""){$tempY = sprintf("$timeFormat",$tempY);} if($tempZ ne ""){$tempZ = sprintf("$timeFormat",$tempZ);} if($tempLift ne ""){$tempLift = sprintf("$timeFormat",$tempLift);} if($tempForearm ne ""){$tempForearm = sprintf("$timeFormat",$tempForearm);} if($tempSideSide ne ""){$tempSideSide = sprintf("$timeFormat",$tempSideSide);} if($tempUpDown ne ""){$tempUpDown = sprintf("$timeFormat",$tempUpDown);} } if($tempShape eq ""){$tempShape = 0;} if($tempTension eq ""){$tempTension = 0;} if($tempEffort eq ""){$tempEffort = 0;} if($tempDuration eq 1){ if($tempX ne ""){$tempX = sprintf("$timeFormat",$tempX);} if($tempY ne ""){$tempY = sprintf("$timeFormat",$tempY);} if($tempZ ne ""){$tempZ = sprintf("$timeFormat",$tempZ);} if($tempLift ne ""){$tempLift = sprintf("$timeFormat",$liftValMap[$tempLift]);} if($tempForearm ne ""){$tempForearm = sprintf("$timeFormat",$foreValMap[$tempForearm]);} if($tempSideSide ne ""){$tempSideSide = sprintf("$timeFormat",$sideSideValMap[$tempSideSide]);} if($tempUpDown ne ""){$tempUpDown = sprintf("$timeFormat",$upDownValMap[$tempUpDown]);} } print OUT "$i,$tempX,$tempY,$tempZ,$tempLift,$tempForearm,$tempShape,$tempSideSide,$tempUpDown,$tempEffort,$tempTension\n"; if($tempDuration eq 1){ print OUT "#---end of gesture---\n"; $gestureFlag = 0; } } } } close(OUT); if($interFlag == 0){print "Done, output in $noIName\n\n";} else{print "Done, output in $fileName.form2\n\n";}