# -*-perl-*-
=head1 NAME
_CORRECT_NONLINEARITY_ -- Corrects the raw data for detector
non-linearity.
=head1 DESCRIPTION
This primitive is used to correct UIST frames for non-linearity. It
only operates on data taken after 20070501.
UIST's detector is non-linear in different ways depending on the
waveform used and the observed count.
For non-thermal data, the correction factor is:
y = ( 1.7929E-14 * x^3 ) - ( 1.9544E-10 * x^2 ) + ( 6.5558E-6 * x ) + 0.98657
for data where the counts are between 750 and 20000 ADUs.
For thermal data, the correction factors are:
y = ( 3.6058E-27 * x^6 ) - (4.1373E-22* x^5) + ( 1.8632E-17 * x^4 ) - ( 4.1209E-13 * x^3 ) +
( 4.762E-9 * x^2 ) - ( 2.353E-5 * x ) + 1.0294
for data where the counts are between 890 and 36000 ADUs.
This correction factor is multiplied by the observed count to obtain
the corrected value in each pixel.
=head1 NOTES
=over 4
=item *
This primitive is suitable for UIST in imaging mode.
=back
=head1 AUTHORS
Brad Cavanagh <b.cavanagh@jach.hawaii.edu>
=head1 COPYRIGHT
Copyright (C) 2007 Science and Technology Facilities Council. All
Rights Reserved.
=cut
# Only run if the UT date is after 20070501 and we haven't corrected
# yet.
if( $Frm->hdr( "ORACTIME" ) > 20070501 && ! defined( $Frm->uhdr( "NONLINEARITY_CORRECTED" ) ) ) {
# Set the filenames.
my( $in, $out ) = $Frm->inout( "_nl" );
# Check the waveform. If it's thermal, then we have to use a separate
# set of correction equations.
my $waveform = $Frm->hdr( "WAVEFORM" );
if( $waveform =~ /thermal/i ) {
orac_print "Applying thermal non-linearity corrections.\n";
# Thermal waveform.
my $lo1 = 890;
my $hi1 = 36000;
# Threshold the first batch into a temporary file.
my $tmp1 = new ORAC::TempFile;
my $tmp1file = $tmp1->file;
my $params = "in=$in out=$tmp1file thrlo=$lo1 thrhi=$hi1 newlo=bad newhi=bad";
$Mon{'kappa_mon'}->obeyw( "thresh", "$params" );
# Run MATHS.
my $tmp2 = new ORAC::TempFile;
my $tmp2file = $tmp2->file;
$params = "exp='IA*(1.0*(3.6058E-27*IA**6)-(4.1373E-22*IA**5)+(1.8632E-17*IA**4)-(4.1209E-13*IA**3)+(4.762E-9*IA**2)-(2.353E-5*IA)+1.0294)' out=$tmp2file ia=$tmp1file";
$Mon{'kappa_mon'}->obeyw( "maths", "$params" );
# Paste them onto the input file.
$params = "in=$in p1=$tmp2file out=$out";
$Mon{'kappa_mon'}->obeyw( "paste", "$params" );
} else {
orac_print "Applying non-thermal non-linearity corrections.\n";
# Non-thermal waveform.
my $lo = 750;
my $hi = 20000;
# Threshold into a temporary file.
my $tmp1 = new ORAC::TempFile;
my $tmp1file = $tmp1->file;
my $params = "in=$in out=$tmp1file thrlo=$lo thrhi=$hi newlo=bad newhi=bad";
$Mon{'kappa_mon'}->obeyw( "thresh", "$params" );
# Run MATHS on the thresholded file.
my $tmp2 = new ORAC::TempFile;
my $tmp2file = $tmp2->file;
$params = "exp='IA*((1.7929E-14*IA**3)-(1.9544E-10*IA**2)+(6.5558E-6*IA)+0.98657)' out=$tmp2file ia=$tmp1file";
$Mon{'kappa_mon'}->obeyw( "maths", "$params" );
# Paste this output onto the input file. The bad pixels in the
# linearity-corrected file will allow the base image's pixels to
# come through.
$params = "in=$in p1=$tmp2file out=$out";
$Mon{'kappa_mon'}->obeyw( "paste", "$params" );
}
# Report to the user.
orac_print "$in to $out: Detector non-linearity corrected.\n";
# Update the frame object.
$Frm->uhdr( "NONLINEARITY_CORRECTED", 1 );
$Frm->file( $out );
# Display, if necessary.
_DISPLAY_FRAME_IMAGE_
# Tidy-up output.
orac_print "\n";
}