
package cal_pipe2;

require Exporter;

@ISA      = qw(Exporter);
@EXPORT   = qw(cal_occultation);

use strict;

sub cal_occultation {

  # Get arguments passed from cal_pipe2.pm
  my ($file, $hv, $c) = @_;
  my %head_vals = %$hv;
  my %cmds = %$c;

  my ($ir_state, $vis_state, $ir_power_state, $vis_power_state, $line);
  my ($core_item_type, $power_state_flag, $smpl, $bnd, $ln, $core_name);
  my ($instrument_mode_id, $file2, $path, $file2_nopath, $fileCM, $temp);
  my ($file_nopath, $ff, $cmd, $sat, $ir_exp, $vis_exp);
  my ($start_sample, $start_line, $sampling_mode, $ir_sampling_mode);
  my ($vis_sampling_mode, $key, $background_sampling_mode);
  my ($vis_back_samp_mode, $ir_back_samp_mode, $gain_mode);
  my ($vis_gain_mode, $ir_gain_mode, $dsp1, $dsp2, $dsp3, $dsp4);
  my ($doperf, $doflat, $do_specific_energy, $garbage, $spkfil);
  my ($vissm, $vres, $vexp, $dovisdark, $fib, $sef, $ssf);
  my ($compressor_id, $compid);

  my $caldir = $ENV{caldir};
  my $idldir = $ENV{IDL_DIR};

  $ir_state = $head_vals{ir_power_state} eq "ON";

  # Find the core cube name.
  ($path,$file_nopath) = $file =~ /(.*\/)(.*)/;
  ($core_name) = $file =~ /.*\/[A-Z,a-z]*([_\d]*).*/;
  print("cube core_name = $core_name\n");

  # Run 'cube_prep' on the cube.
  $file2 = $path . $core_name;
  ($path,$file2_nopath) = $file2 =~ /(.*\/)(.*)/;
  $fileCM = $path . "CM_" . $file2_nopath . ".cub";

  # cube_prep adds calibration keyword/values pairs to the header,
  # looks up and translates the back plane data, and swaps bytes if
  # needed.  It also sets CORE_NULL values from -8192 to -32768.
  if ($head_vals{core_item_type} eq "SUN_INTEGER") {
    # Swap bytes.
    $cmd = "$ENV{caldir}/software/bin/cube_prep $file $fileCM s\n";
    print ("$cmd");
    system ("$cmd");
  } elsif ($head_vals{core_item_type} eq "PC_INTEGER") {
    # Don't swap bytes.
    $cmd = "$ENV{caldir}/software/bin/cube_prep $file $fileCM\n";
    print ("$cmd");
    system ("$cmd");
  } else {
    print("cube core_item_type is strange, skipping...\n");
    next;
  }

  # If the compressor was turned off, we need to subtract
  # the background values from the cube.
  $temp = "tempcb.cub";
  $garbage = "garbage_data";
  $compid  = $head_vals{"compressor_id"};
  print("compid = $compid\n");
  if ($compid == 'N/A') {
    $cmd = "$ENV{caldir}/software/bin/ir_bg_sub $fileCM $temp\n";
    print("$cmd");
    system("$cmd");
    system("mv $temp $fileCM");

  }

  # Run 'mark_saturated' on the 'CM_' file.  This program adds
  # the background back into each pixel and checks to see if
  # it is greater than or equal to 4095.  If it is, it marks it
  # as saturated (pixel value set to -32765).
  $temp = "tempcb.cub";
  $garbage = "garbage_data";
  $sat  = $cmds{"mark_saturated"};
  if ($sat eq "yes") {
    $cmd = "$ENV{caldir}/software/bin/mark_saturated $fileCM $temp\n";
    print("$cmd");
    system("$cmd");
    system("mv $temp $fileCM");

    # Update the header to show that this step has been run.
    $cmd = "labels from=$fileCM" .
	   "  list=SUMMARY" .
	   "  dest=FILE" .
	   "  listfile=listfile" .
	   "  grpnam=CALIBRATION" .
	   "  keyword=SET_SATURATED" .
	   "  keyvalue=YES" .
	   "  keytype=STRING";
    system($cmd);
    system("rm listfile.lis");
  }

  # Transpose the cube to make some things run faster.
  $cmd = "transpose from=$fileCM to=$temp order=BSQ\n";
  print("$cmd");
  system($cmd);
  system("mv $temp $fileCM");

  # Flat field the IR cube then flat field the VIS cube (if wanted).
  my $doirflat = $cmds{"ir_flat_field"};
  if ($doirflat eq "yes") {
    if ($ir_state) {
      print("flat_ir2 $fileCM $temp head_vals\n");
      flat_ir2 ($fileCM, $temp, %head_vals);
      system("mv $temp $fileCM");
    }
  }

  # This step removes the performance model, divides by the exposure time,
  # and then converts the resulting electrons/second to ergs/sec/spectel.
  my $to_specific_energy = $cmds{"to_specific_energy"};
  if ($to_specific_energy eq "yes") {
    print("specific_energy $fileCM $temp head_vals\n");
    specific_energy($fileCM, $temp, %head_vals);
    system("mv $temp $fileCM");

    # Change CORE_NAME to SPECIFIC_ENERGY and CORE_UNIT to ERGS_PER_SECOND
    $cmd = "labels from=$fileCM" .
	   " list=NONE" .
	   " dest=FILE" .
	   " listfile=listfile" .
	   " objtyp=QUBE" .
	   " keyword=CORE_NAME" .
	   " keyvalue=SPECIFIC_ENERGY" .
	   " keytype=LITERAL";
    print("$cmd\n");
    system($cmd);
    system("rm listfile.lis");

    $cmd = "labels" .
	   " from=$fileCM" .
	   " list=NONE" .
	   " dest=FILE" .
	   " listfile=listfile" .
	   " objtyp=QUBE" .
	   " keyword=CORE_UNIT" .
	   " keyvalue=ERGS_PER_SECOND" .
	   " keytype=LITERAL";
    print("$cmd\n");
    system($cmd);
    system("rm listfile.lis");
  }

  system("rm $fileCM" . ".tmp\n");

  # Make sure we copy the timing backplanes from the original
  # cube back onto the output cube here.  The backplanes were
  # lost during execution of FX or RATIO or somewhere.
  # we must swap the bytes of the original cube into a temp cube first.
  my $tempcube = "TempCub.cub";
  $cmd = "$ENV{caldir}/software/bin/cube_prep $file $tempcube s\n";
  print ("$cmd");
  system ("$cmd");

  # bandcopy
  $cmd = "bandcopy" .
   " from=$tempcube" .
   " sfrom='\"::\"'" .
   " to=$fileCM" .
   " iband=0" .
   " oband=0" .
   " ibcknam=SLICE_TIME_SECONDS" .
   " obcknam=SLICE_TIME_SECONDS";
  print("$cmd\n");
  system($cmd);

  $cmd = "bandcopy" .
   " from=$tempcube" .
   " sfrom='\"::\"'" .
   " to=$fileCM" .
   " iband=0" .
   " oband=0" .
   " ibcknam=SLICE_TIME_TICKS" .
   " obcknam=SLICE_TIME_TICKS";
  print("$cmd\n");
  system($cmd);

  system("rm $tempcube\n");

  # Transpose the cube back to BIL.
  $cmd = "transpose from=$fileCM to=$temp order=BIL\n";
  print("$cmd");
  system($cmd);
  system("mv $temp $fileCM");

}   # end of subroutine.
