Need help debugging Perl in Config file

Started by msandersen, May 19, 2020, 12:45:23 PM

Previous topic - Next topic

msandersen

Hi
I'm spending the evenings at home sorting my old photos using Photo Mechanic (which also uses Exiftool), and I decided to sort out some of the metadata using Exiftool directly to parse several thousands of photos, specifically to add FocalLengthIn35mmFormat where not present, and add MWG:Copyright to everything, which I notice also fixes a tag written by the camera which Photo Mechanic doesn't fix. In trying to get one thing to work, I ended up adding a bunch of other routines to learn and get something that works.
I've spent the last week racking my brain trying to make it all work, reading the forum and Perl tutorials trying to get to grips with it all to sort out the bugs, but it is difficult as there is no feedback as to why a subroutine doesn't work.

What I'm trying to achieve:
1. If a file doesn't have FocalLengthIn35mmFormat, create it and write it to the file. This would be a pass of it's own, as it is a conditional Exiftool command, like:
exiftool -if 'not $FocalLengthIn35mmFormat' '-FocalLengthIn35mmFormat<FocalLengthEquiv' -overwrite_original image.ext
where FocalLengthEquiv is a subroutine in the Config file, which I managed to get working, using data from digicamdb.com.

2. Write Copyright to all the files using MWG:Copyright with the name based on the camera body, ie one camera was only used by my wife.
exiftool '-OwnerName<BodyOwner' '-MWG:Creator<BodyOwner' '-MWG:Copyright<MyCopyRight' filename
where BodyOwner and MyCopyRight are working subroutines in the config file.

The problem is the stretch goal I set myself: In Photo Mechanic, it shows the now deprecated Category and Supplementary Category fields, so I use it for noting camera settings just for convenience (using PM's metadata variables). While this is not necessary, I wanted to see if I could do it in Exiftool. Category is easy, it is a standard field. But the Supplementary Category field is an unordered list, and I thought I could pass an array to Exiftool, but I can't make it work, I've tried all sorts of variations. This is a Nice To Have just because I started it and would like to know what I'm doing wrong.
The subroutine is called SuppCat, and is trying to set 3 unordered list items, which I can do manually in Exiftool with 3 -SupplementalCategory+="something", but I can't pass the data to it, or get the routine working, there is no feedback on the command line.
Part of the data I wanted to put in is Angle of View which I'd calculate, with a fallback to FOV, a composite tag provided by Exiftool. This routine I can't get to work either.
In the routine SensorDiagonal, I tried to use an array with camera models as keys, but I could't get it to work, so I went back to a series of If-Else statements.

The last thing I put on the back burner was I thought it could be interesting to put some of the values from digicamdb as well as calculated Angle of View into the file under XMP:Exif. I made a preliminary attempt which is not working, but the config file examples are mind bending, as is some of the forum posts on the subject.

Routines that work:
CropFactor
SensorDiagonal (with compromise)
BodyOwner
MyCopyRight
FocalLengthEquiv

Not working:
AngleOfView
SuppCat (inc how to pass 3 values to Exiftool commandline).
Attempt at creating XMP tags.

The config file is a bit messy with commented out experiments and Print statements for debugging.
# %Image::ExifTool::XMP::exif' => {
#    SensorWidth => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    SensorHeight => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    SensorDiagonal => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    CropFactor => { Writable => 'rational', Groups => { 2 => 'Camera' } },
#    AngleOfView => { Writable => 'rational', Groups => { 2 => 'Camera' } },
#},
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        CropFactor => {
        Require => {
                0 => 'Make',
                1 => 'Model',
                2 => 'ScaleFactor35efl',
            },
            ValueConv => q{
            my $make = $val[0];
            my $model = $val[1];
            my $CropFactor;
            print(">>CropFactor<<\n");
if ($model eq "Canon PowerShot S2 IS") {
$CropFactor = 6.02;
# print("Canon Powershot\n");
}
elsif ($model eq "FinePix S1000fd") {
$CropFactor = 5.62;
# print("Fuji Finepix\n");
}
elsif (($make eq "PENTAX Corporation") or ($make eq "FUJIFILM")) {
$CropFactor = 1.53; # all Pentax or Fuji models APS-C
# print("Pentax\n");
}
elsif ($make eq "Canon") {
$CropFactor = 1.6; # all other Canon models APS-C
# print("Canon\n");
}
else {
$CropFactor = sprintf("%.2f",$val[2]); # Exiftool calculated cropfactor
print("Default to ScaleFactor35efl for >".$model." (".$make.")<\n");
}
print("Model: ".$model."\nCropfactor: ".$CropFactor."\n\n");
return($CropFactor);
},
       
        },
        SensorDiagonal => {
        # https://www.digicamdb.com/
        # https://www.dxomark.com/Cameras/
        Require => {
                0 => 'Model',
            },
            ValueConv => q{
            my $model = $val[0];
            print(">>>SensorDiagonal<<<\n");
            my $Diag;
            # Compact cameras with small sensors like the Finepix 1/2.3" or Powershot 1/2.5" don't have detailed sensor specs published.
            # my %SensorDiagonal('Canon PowerShot S2 IS' => 7.19,
            # 'FinePix S1000fd' => 7.70,
            # 'PENTAX K100D Super' => 28.26,
            # 'X-T20' => 28.29,
            # 'Canon EOS Kiss X5' => 26.82,
            # 'Canon EOS 60D' => 26.82,
            # 'Canon EOS 80D' => 27.04
            # );
            # print(">Array<\nModel: ".$model."\nDiagonal: ".%SensorDiagonal."\n\n");
            # if ($SensorDiagonal[$val[0]]) {
            # print($SensorDiagonal[$val[0]]." match\n\n");
            # return $SensorDiagonal[$val[0]];
            # }
            # else {  print("Undefined diagonal\n\n");
            #     return undef;
            # }
if ($model eq "Canon PowerShot S2 IS") {
$Diag = 7.19; # https://www.digicamdb.com/specs/canon_powershot-s2-is/
# print("Canon Powershot diag: ".$Diag."\n");
}
elsif ($model eq "FinePix S1000fd") {
$Diag = 7.70; # https://www.digicamdb.com/specs/fujifilm_finepix-s1000fd/
# print("Fuji Finepix diag: ".$Diag."\n");
}
elsif ($model eq "PENTAX K100D Super") {
$Diag = 28.26; # https://www.digicamdb.com/specs/pentax_k100d-super/
# print("Pentax diag: ".$Diag."\n");
}
elsif ($model eq "X-T20") {
$Diag = 28.29; # https://www.digicamdb.com/specs/fujifilm_x-t20/
# print("Fuji diag: ".$Diag."\n");
}
elsif ($model eq "Canon EOS Kiss X5" or $model eq "Canon EOS 60D") {
$Diag = 26.82;
# print("Canon diag: ".$Diag."\n");
}
elsif ($model eq "Canon EOS 80D") {
$Diag = 27.04;
# print($model." sensor diagonal: ".$Diag."\n\n");
}
else {
print("Undefined diagonal\n\n");
return undef;
}
print("Model: ".$model."\nDiagonal: ".$Diag."\n\n");
return($Diag);
},
        },
        BodyOwner => { # If Canon PowerShot S2, Jane's camera.
Require => 'Model',
ValueConv => q{
if ($val[0] eq 'Canon PowerShot S2 IS') { return "Jane Balke Andersen"; }
return PrintConv => "Martin Stær Andersen";
},
},
MyCopyRight => {
Require => {
0 => 'CreateDate',
1 => 'BodyOwner',
},
ValueConv => '"Photo ©".substr($val[0],0,4)." ".$prt[1]',
},
        FocalLengthEquiv => {
          Require => {
                0 => 'FocalLength',
                1 => 'CropFactor',
            },
            ValueConv => q{
            my $focalLength = sprintf("%.0f", $val[0] * $val[1]);
            print(">>FocalLengthEquiv<<\nFocal Length: ".$val[0]."\nFocal length (35mm Equivalent): ".$focalLength."\n\n");
            return $focalLength;
            },
            # PrintConv => 'sprintf("%.1f",$val)',
        },
    AngleOfView => {
        # Description => 'Angle of View',
        # Notes => q{
        #     Calculated on the diagonal of the sensor size.
        # },
        Require => {
            0 => 'FocalLength',
            1 => 'CropFactor',
        },
        Desire => {
            2 => 'SensorDiagonal',
        },
# ref https://www.kenrockwell.com/tech/angle-of-view.htm
#     https://en.wikipedia.org/wiki/Angle_of_view
# ValueConv => 'rad2deg(2*atan2(43.27, 2*$val[0]*$val[1]));
        ValueConv => q{
                use strict;
                use warnings;
                print(">>Angle Of View<<\n");
        my $AoV;
        if (defined $Val[2]) { 
        # Angle of View = 2 * arctan (sensor size/(focal length * 2)) * 180/Pi
        $AoV = rad2deg(2*atan2($val[2],2*$val[0]));
        print("SensorDiagonal defined: ".$val[2]."\nAngle of View: ".$AoV."\n\n");
        } else {
        # Default; Full-frame sensor 36x24mm, diagonal 43.27mm
$AoV = rad2deg(2*atan2(43.27, 2*$val[0]*$val[1]));
        print("SensorDiagonal undefined: FF 43.27mm used.\nAngle of View: ".$AoV."\n\n");
}
            return $AoV;
            },
        },
SuppCat => { # Supplemental Category
Require => {
                0 => 'FocalLength',
                1 => 'FocalLengthEquiv',
                2 => 'ShutterSpeed',
                3 => 'Aperture',
                4 => 'FOV',
                5 => 'ISO',
                6 => 'ExposureCompensation',
                7 => 'Model',
            },
            # Ex: 27.6mm (166mm) 1/1000sec f/4.5 12.4 deg FoV,
# ISO: 50 Exp.Comp: -0.33,
# Canon PowerShot S2 IS
ValueConv => q{
    my @Suppcat;
    $SuppCat[0] = $val[0]."mm (".$val[1]."mm) ".$prt[2]."sec f/".$val[3]." ".$prt[4]." FOV";
    $SuppCat[1] = "ISO: ".$val[5]." Exp.Comp: ".sprintf("%.1f", $val[6]);
    $SuppCat[2] = ($val[7] eq "X-T20" ? "Fuji ".$val[7] : $val[7]);
   
# my @SuppCat = ($val[0]."mm (".$val[1]."mm) ".$prt[2]."sec f/".$val[3]." ".$prt[4]." FOV",
# "ISO: ".$val[5]." Exp.Comp: ".sprintf("%.1f", $val[6]),
# ($val[7] eq "X-T20" ? "Fuji ".$val[7] : $val[7]));
print(@SuppCat);
print("0: ".$SuppCat[0]."\n1: ".$SuppCat[1]."\n2: ".$SuppCat[2]."\n\n");
# return @SuppCat;
return $SuppCat[0];
    },
        #   ValueConv => '$val[0]."mm (".$val[1]."mm) ".$prt[2]."sec f/".$val[3]." ".$prt[4]." FOV\nISO: ".$val[5]." Exp.Comp: ".sprintf("%.1f", $val[6])."\n".($val[7] eq "X-T20" ? "Fuji ".$val[7] : $val[7])',
},
    }, # end Composite
); # end Userdefined
# A special 'Lenses' list can be defined to give priority to specific lenses
# in the logic to determine a lens model for the Composite:LensID tag
@Image::ExifTool::UserDefined::Lenses = (
'Sigma 18-35mm f/1.8 DC HSM',
'Sigma 50-150 f/2.8 APO DC HSM',
'Sigma 8-16mm f/4.5-5.6 DC HSM',
    'Sigma 18-50mm f/3.5-5.6 DC',
    'Tamron 17-50mm f/2.8 Di II A16',
);
1; # end

StarGeek

For your SuppCat tag, you are declaring
my @Suppcat;
but it should be
my @SuppCat;

And for the return, you want to return a reference to the array, not the array itself
return \@SuppCat;

Here's the output I get after those changes
C:\>exiftool -config test.config -g1 -a -s -SuppCat "Y:\Pictures\Camera_Pictures\Camera-Unsorted\More_Unsorted\SDCC\2013\Day_2-07-19\2013-07-19_16.32.54.Nef"
>>CropFactor<<
Default to ScaleFactor35efl for >NIKON D5100 (NIKON CORPORATION)<
Model: NIKON D5100
Cropfactor: 1.50

>>FocalLengthEquiv<<
Focal Length: 66
Focal length (35mm Equivalent): 99

66mm (99mm) 1/60sec f/7.1 20.1 deg (1.00 m) FOVISO: 800 Exp.Comp: 0.0NIKON D51000: 66mm (99mm) 1/60sec f/7.1 20.1 deg (1.00 m) FOV
1: ISO: 800 Exp.Comp: 0.0
2: NIKON D5100

---- Composite ----
SuppCat                         : 66mm (99mm) 1/60sec f/7.1 20.1 deg (1.00 m) FOV, ISO: 800 Exp.Comp: 0.0, NIKON D5100


For AngleOfView, you are using $Val instead of $val.  Additionally, you are calling rad2deg which I think is part of the Math::Trig module, which isn't included in exiftool as far as I can tell.  But a quick google search came up with this Perl Cookbook page which has a short subroutine you can just drop in.  So add this to the top of your config
sub rad2deg {
my $radians = shift;
return ($radians / PI) * 180;
}
%Image::ExifTool::UserDefined = (


Unfortunately, my test image returns an Illegal division by zero error when running AngleOfView, so there may be additional problems in that tag or the SensorDiagonal/CropFactor tags you call from it.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

msandersen

#2
Thanks StarGeek.
I've been playing around with it some more today with fresh eyes; trying to learn this stuff at 2-3am in the morning doesn't necessarily make for a clear mind.
The thing with the reference I didn't know, the sort of thing I was looking for.
I managed to make things work without the arrays, but I will give your way a go as I want to understand. I missed the spelling mistake, the sort of thing you do when your eyes are tired.
I downloaded BBEdit and have been going through the file with it's help in matching parentheses.
I am in the process of testing on a folder of test images from various cameras and phones before letting loose on the actual files; there are several thousands to do, eventually tens of thousands, no time to eff up.

I used values plucked from digicamdb, if not in the list it defaults to a part of the code which I think wasn't working. In my case, it will just be iPhone photos.
The other part with getting the Supplemental Categories into the command line and written to file I found out had to be firstly with it being specifically xml-photoshop:SupplementaryCategories and with me missing the string in the -sep command (caught that from re-reading the FAQ), and the string ", " (comma-space) not working in an Args file. It didn't work when swapping for ==, so I just put it in the command line, and that made it work.

Edit: There's still a problem in my logic; SuppCat fails if any of the variables aren't available, because they are Required, and hence the supplemental categories aren't set. Need more testing and rejigging, but the routines themselves at least are working, with Copyright info and FocalLengthin35mmFormat set, and that's the critical part.
There's a problem with the Composite ISO returning a wrong value for files of one camera or not present on another, but while getting exif:ISO fixes it for them, the files which have ISO don't have exif:ISO, so will have to tweak.
Edit 3: I think I fixed the issue with ISO and Exposure Compensation by moving them to the Desire section and including both exif:ISO and ISO and testing for exif:ISO being set, otherwise using the composite ISO. A bit more testing.

The problem with AngleOfView once I took out the Perl section, was seemingly because it didn't recognise rad2deg() as you said or Pi, which I found on documents for the Perl::Maths page (I was searching for how to use atan2, which I think is part of the Trig module). There was no error message to let me know, I don't know how to debug it other than with Print statements.

The relevant code I went with in AngleOfView (similar to FOV frankly, but with my values) reads:
ValueConv => '(defined $val[2] ? 2*atan2($val[2], 2*$val[0])*(180/3.14159) : 2*atan2(43.27, 2*$val[0]*$val[1])*(180/3.14159))',
PrintConv => 'sprintf("%.1f",$val)." deg"',

which checks if SensorDiagonal is set ($val[2] is set to undef if not in my list, ie iphones), and chooses which formula to use.

The methodology I've gone with is first parsing separate exiftool commands to fix up Tamron and Sigma lens definitions, then I will run
exiftool -if 'not $FocalLengthIn35mmFormat' '-FocalLengthIn35mmFormat<FocalLengthEquiv' -r -overwrite_original /folder/path/
to fix up FocalLengthIn35mmFormat conditionally of it not existing already; again, often Tamron or Sigma lenses, other native lenses embed it, as well as iPhone pics.

Then I will run
exiftool -@ /path/to/argsfile.args -sep ", "  /folder/path
where the Args file reads
-OwnerName<BodyOwner
-xmp:CaptionWriter<BodyOwner
-MWG:Creator<BodyOwner
-MWG:Copyright<MyCopyRight
-xmp:Category=Categoryname
-XMP-photoshop:SupplementalCategories<SuppCat
-CreatorCity=Sydney
-CreatorRegion=NSW
-CreatorCountry=Australia
-CreatorPostalCode=2016
-CreatorWorkEmail=xxxxxxx@tpg.com.au
#[CSTR]-CreatorAddress=Instagram: \n@jam_project\n@jam_packed_photography
-DigitalSourceType=http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture
-overwrite_original
-m # Ignore minor errors
-r # Recursive

and from there I have a lot of batchwork in Photo Mechanic with keywording and using variables to add cations, locations and such. That will be the bulk of it, these Exiftool passes will help.

My revised Config file, still a bit messy, currently reads:
# %Image::ExifTool::XMP::exif' => {
#    SensorWidth => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    SensorHeight => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    SensorDiagonal => { Writable => 'int16u', Groups => { 2 => 'Camera' } },
#    CropFactor => { Writable => 'rational', Groups => { 2 => 'Camera' } },
#    AngleOfView => { Writable => 'rational', Groups => { 2 => 'Camera' } },
#},
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        CropFactor => {
        Require => {
                0 => 'Make',
                1 => 'Model',
                2 => 'ScaleFactor35efl',
            },
            ValueConv => q{
            my $make = $val[0];
            my $model = $val[1];
            my $CropFactor;
            # print(">>CropFactor<<\n");
if ($model eq "Canon PowerShot S2 IS") {
$CropFactor = 6.02;
# print("Canon Powershot\n");
}
elsif ($model eq "FinePix S1000fd") {
$CropFactor = 5.62;
# print("Fuji Finepix\n");
}
elsif (($make eq "PENTAX Corporation") or ($make eq "FUJIFILM")) {
$CropFactor = 1.53; # all Pentax or Fuji models APS-C
# print("Pentax\n");
}
elsif ($make eq "Canon") {
$CropFactor = 1.6; # all other Canon models APS-C
# print("Canon\n");
}
else {
$CropFactor = sprintf("%.2f",$val[2]); # Exiftool calculated cropfactor
# print("Default to ScaleFactor35efl for >".$model." (".$make.")<\n");
}
# print("Model: ".$model."\nCropfactor: ".$CropFactor."\n\n");
return($CropFactor);
},
       
        },
        SensorDiagonal => {
        # https://www.digicamdb.com/
        # https://www.dxomark.com/Cameras/
        Require => {
                0 => 'Model',
            },
            ValueConv => q{
            my $model = $val[0];
            # print(">>>SensorDiagonal<<<\n");
            my $Diag;
            # Compact cameras with small sensors like the Finepix 1/2.3" or Powershot 1/2.5" don't have detailed sensor specs published.
            # my %SensorDiagonal('Canon PowerShot S2 IS' => 7.19,
            # 'FinePix S1000fd' => 7.70,
            # 'PENTAX K100D Super' => 28.26,
            # 'X-T20' => 28.29,
            # 'Canon EOS Kiss X5' => 26.82,
            # 'Canon EOS 60D' => 26.82,
            # 'Canon EOS 80D' => 27.04
            # );
            # print(">Array<\nModel: ".$model."\nDiagonal: ".%SensorDiagonal."\n\n");
            # if ($SensorDiagonal[$val[0]]) {
            # print($SensorDiagonal[$val[0]]." match\n\n");
            # return $SensorDiagonal[$val[0]];
            # }
            # else {  print("Undefined diagonal\n\n");
            #     return undef;
            # }
if ($model eq "Canon PowerShot S2 IS") {
$Diag = 7.19; # https://www.digicamdb.com/specs/canon_powershot-s2-is/
# print("Canon Powershot diag: ".$Diag."\n");
}
elsif ($model eq "FinePix S1000fd") {
$Diag = 7.70; # https://www.digicamdb.com/specs/fujifilm_finepix-s1000fd/
# print("Fuji Finepix diag: ".$Diag."\n");
}
elsif ($model eq "PENTAX K100D Super") {
$Diag = 28.26; # https://www.digicamdb.com/specs/pentax_k100d-super/
# print("Pentax diag: ".$Diag."\n");
}
elsif ($model eq "X-T20") {
$Diag = 28.29; # https://www.digicamdb.com/specs/fujifilm_x-t20/
# print("Fuji diag: ".$Diag."\n");
}
elsif ($model eq "Canon EOS Kiss X5" or $model eq "Canon EOS 60D") {
$Diag = 26.82;
# print("Canon diag: ".$Diag."\n");
}
elsif ($model eq "Canon EOS 80D") {
$Diag = 27.04;
# print($model." sensor diagonal: ".$Diag."\n\n");
}
else {
# print("Undefined diagonal\n\n");
return undef;
}
# print("Model: ".$model."\nDiagonal: ".$Diag."\n\n");
return($Diag);
},
        },
        BodyOwner => { # If Canon PowerShot S2, Jane's camera.
Require => 'Model',
ValueConv => q{
if ($val[0] eq 'Canon PowerShot S2 IS') { return "Jane Balke Andersen"; }
return PrintConv => "Martin Stær Andersen";
},
},
MyCopyRight => {
Require => {
0 => 'CreateDate',
1 => 'BodyOwner',
},
ValueConv => '"Photo ©".substr($val[0],0,4)." ".$prt[1]',
},
        FocalLengthEquiv => {
          Require => {
                0 => 'FocalLength',
                1 => 'CropFactor',
            },
            ValueConv => q{
            my $focalLength = sprintf("%.0f", $val[0] * $val[1]);
            # print(">>FocalLengthEquiv<<\nFocal Length: ".$val[0]."\nFocal length (35mm Equivalent): ".$focalLength."\n\n");
            return $focalLength;
            },
            # PrintConv => 'sprintf("%.1f",$val)',
        },
    AngleOfView => {
        Description => 'Angle of View',
        Notes => q{
            Calculated on the diagonal of the sensor size.
        },
        Require => {
                0 => 'FocalLength',
                1 => 'CropFactor',
        },
        Desire => {
            2 => 'SensorDiagonal',
        },
# ref https://www.kenrockwell.com/tech/angle-of-view.htm
#     https://en.wikipedia.org/wiki/Angle_of_view
# Full-frame sensor: 36x24mm, diagonal 43.27mm
            # Angle of View = 2 * arctan (sensor size/(focal length * 2)) * 180/Pi
ValueConv => '(defined $val[2] ? 2*atan2($val[2], 2*$val[0])*(180/3.14159) : 2*atan2(43.27, 2*$val[0]*$val[1])*(180/3.14159))',
PrintConv => 'sprintf("%.1f",$val)." deg"',
        # ValueConv => q{
        #       use strict;
        #        use warnings;
        #        print(">>Angle Of View<<\n");
        # my $AoV;
        # if (defined $Val[2]) { 
        # # Angle of View = 2 * arctan (sensor size/(focal length * 2)) * 180/Pi
        # $AoV = rad2deg(2*atan2($val[2],2*$val[0]));
        # print("SensorDiagonal defined: ".$val[2]."\nAngle of View: ".$AoV."\n\n");
        # } else {
        # # Default; Full-frame sensor 36x24mm, diagonal 43.27mm
# $AoV = rad2deg(2*atan2(43.27, 2*$val[0]*$val[1]));
        # print("SensorDiagonal undefined: FF 43.27mm used.\nAngle of View: ".$AoV."\n\n");
# }
        #    return $AoV;
        #    },
        },
SuppCat => { # '-XMP-Photoshop:SupplementalCategories<SuppCat' -sep ", "
Require => {
                0 => 'FocalLength',
                1 => 'FocalLengthEquiv',
                2 => 'ExposureTime',
                3 => 'Aperture',
                4 => 'AngleOfView',
                5 => 'Model',
            },
        Desire => {
            6 => 'exif:ISO',
            7 => 'ISO',
                8 => 'ExposureCompensation',
        },
            # Example:
            # 27.6mm (166mm) 1/1000sec f/4.5 12.4 deg FoV,
# ISO: 50 Exp.Comp: -0.33,
# Canon PowerShot S2 IS
            ValueConv => '$val[0]."mm (".$val[1]."mm)   ".$prt[2]."sec   f/".$val[3]."   AoV: ".$prt[4].", ISO: ".(defined($val[6]) ? $val[6] : $val[7])."   Exp.Comp: ".sprintf("%.1f", $val[8]).", ".($val[5] eq "X-T20" or $val[5] eq "FinePix S1000fd" ? "Fuji ".$val[5] : $val[5])',
# ValueConv => q{
# my @SuppCat = ($val[0]."mm (".$val[1]."mm)   ".$prt[2]."sec   f/".$val[3]."   AoV: ".$prt[4],
# "ISO: ".$val[6]."   Exp.Comp: ".sprintf("%.1f", $val[8]),
# ($val[5] eq "X-T20" or $val[5] eq "FinePix S1000fd" ? "Fuji ".$val[5] : $val[5]));
# print("0: ".$SuppCat[0]."\n1: ".$SuppCat[1]."\n2: ".$SuppCat[2]."\n");
# Return \@SuppCat;
# },
},
    }, # end Composite
); # end Userdefined
# A special 'Lenses' list can be defined to give priority to specific lenses
# in the logic to determine a lens model for the Composite:LensID tag
@Image::ExifTool::UserDefined::Lenses = (
'Sigma 18-35mm f/1.8 DC HSM',
'Sigma 50-150 f/2.8 APO DC HSM',
'Sigma 8-16mm f/4.5-5.6 DC HSM',
    'Sigma 18-50mm f/3.5-5.6 DC',
    'Tamron 17-50mm f/2.8 Di II A16',
);
1; # end

once I finish testing, I might clean it up a little, it won't really matter as long as it works effectively. I want to see if I can get the Array method working after your fix, just because.

Edit 2
set up a Test args file
# exiftool -@ /path/to/Exiftool-testoutput.args -sep ", " -d %Y  /path/to/test/filename.ext
-s
-a
-G
-Make
-Model
-LensID
-LensMake
-LensModel
-Lens
-xmp:Lens
-LensInfo
-MaxApertureValue
-ApertureValue
-FNumber
-ShutterSpeed
-ExposureTime
-ISO
-exif:ISO
-CropFactor
-SensorDiagonal
-ScaleFactor35efl
-FocalLength
-FOV
-AngleOfView
-focalLength35efl
-focallengthin35mmformat
-FocalLengthEquiv
-BodyOwner
-OwnerName
-CreateDate
-MyCopyRight
-Copyright
-CopyrightNotice
-xmp:Rights
-iptc:By-Line
-XMP-photoshop:SupplementalCategories
-SuppCat