#! /bin/sh
# This is the LHEA perl script: /cvmfs/extras-fp7.egi.eu/extras/heasoft/hitomi/x86_64-unknown-linux-gnu-libc2.19-0/bin/sxspixgti.pl
# The purpose of this special block is to make this script work with
# the user's local perl, regardless of where that perl is installed.
# The variable LHEAPERL is set by the initialization script to
# point to the local perl installation.
#-------------------------------------------------------------------------------
eval '
if [ "x$LHEAPERL" = x ]; then
  echo "Please run standard LHEA initialization before attempting to run /cvmfs/extras-fp7.egi.eu/extras/heasoft/hitomi/x86_64-unknown-linux-gnu-libc2.19-0/bin/sxspixgti.pl."
  exit 3
elif [ "$LHEAPERL" = noperl ]; then
  echo "During LHEA initialization, no acceptable version of Perl was found."
  echo "Cannot execute script /cvmfs/extras-fp7.egi.eu/extras/heasoft/hitomi/x86_64-unknown-linux-gnu-libc2.19-0/bin/sxspixgti.pl."
  exit 3
elif [ `$LHEAPERL -v < /dev/null 2> /dev/null | grep -ic "perl"` -eq 0 ]; then
  echo "LHEAPERL variable does not point to a usable perl."
  exit 3
else
  # Force Perl into 32-bit mode (to match the binaries) if necessary:
  if [ "x$HD_BUILD_ARCH_32_BIT" = xyes ]; then
    if [ `$LHEAPERL -V 2> /dev/null | grep -ic "USE_64_BIT"` -ne 0 ]; then
      VERSIONER_PERL_PREFER_32_BIT=yes
      export VERSIONER_PERL_PREFER_32_BIT
    fi
  fi
  exec $LHEAPERL -x $0 ${1+"$@"}
fi
'
if(0);
# Do not delete anything above this comment from an installed LHEA script!
#-------------------------------------------------------------------------------
#!/usr/bin/perl
#
# File name: sxspixgti.pl
# Author: A. J. Sargent NASA GSFC
# $Date: 2016/05/31 18:10:57 $
# Version: 0
#
# Run ahgtigen and create 36 extension GTI file for sxs pixels. 
# Create additional GTI file with one extension and columns START, STOP, PIXEL
#
# Tool Dependencies:
# 
# Library Dependencies:
#   gen/lib/perl/ahlog
#   gen/lib/perl/ahapp
#   gen/lib/perl/ahgen
#
# Modification History:
#

# Set up
use strict;
use warnings;

use ahlog ;
use ahapp ;
use ahgen qw (:ALL) ;
use ahfilterlib ;

# turn on AUTOFLUSH
$| = 1;

#########################
# Variable Definitions 
#########################

my $mkffile="";       # input mkf file 
my $outfile="";       # output sxs gti file
my $outpixfile="";    # output sxs merged gti file
my $label="";         # label for ahgtigen
my $gtilost="";       # GTI lost file
my $gtifile="";       # GTI file to merge
my $teldef="";        # teldef file for coordevt

my $gtiexpr;
my $mergegti;
my $upkeyword;
my $leapsecfile;
my $selectfile;
my $instarts;
my $instops;
my $time;
my $outstart;
my $outstop;
my $prefr;
my $postfr;

my $calc_mkf=0;       # Boolean to process MKF file
my $calc_gtilost=0;   # Boolean to process GTI lost 

my $sxspixgtierror = 0;  # sxspipeline exit status

#########################
#  Main Code Block 
#########################

ahapp::startup () ;

ahapp::begin_processing () ;

$sxspixgtierror = get_parameters () ;
unless ( $sxspixgtierror == 0 ) {
  ah_info "HIGH", ahapp::write_parameters () ;  
  ahlog::ah_err "get_parameters" ;
  ahapp::end_processing($sxspixgtierror);
}

$sxspixgtierror = initialize () ;
unless ( $sxspixgtierror == 0 ) {
  ah_info "HIGH", ahapp::write_parameters () ;   
  ahlog::ah_err "initialize" ;
  ahapp::end_processing($sxspixgtierror);
}

$sxspixgtierror = do_work () ;
unless ( $sxspixgtierror == 0 ) {
  ahlog::ah_err "do_work" ;
  ahapp::end_processing($sxspixgtierror);
}

$sxspixgtierror = finalize () ;
unless ( $sxspixgtierror == 0 ) {
  ahlog::ah_err "finalize" ;
  ahapp::end_processing($sxspixgtierror);
}

# We're done.
ahapp::end_processing($sxspixgtierror);


#########################
# Subroutines
#########################

sub get_parameters {

  $mkffile     = ahapp::query_parameter("mkffile");
  $outfile     = ahapp::query_parameter("outfile");
  $outpixfile  = ahapp::query_parameter("outpixfile");
  $label       = ahapp::query_parameter("label");
  $gtilost     = ahapp::query_parameter("gtilost");
  $gtifile     = ahapp::query_parameter("gtifile");

  # ahgtigen parameters
  $gtiexpr         = ahapp::query_parameter("gtiexpr");
  $mergegti        = ahapp::query_parameter("mergegti");
  $upkeyword       = ahapp::query_parameter("upkeyword");
  $leapsecfile     = ahapp::query_parameter("leapsecfile");
  $selectfile      = ahapp::query_parameter("selectfile");
  $instarts        = ahapp::query_parameter("instarts");
  $instops         = ahapp::query_parameter("instops");
  $time            = ahapp::query_parameter("time");
  $outstart        = ahapp::query_parameter("outstart");
  $outstop         = ahapp::query_parameter("outstop");
  $prefr           = ahapp::query_parameter("prefr");
  $postfr          = ahapp::query_parameter("postfr");

  $teldef      = ahapp::query_parameter("teldeffile");

  return 0;

}

# ------------------------------------------------------------------------------

sub initialize {

  my $status = 0;
  
  # We need to check that we at least have one input
  # mkf or gti lost file. If they are both missing 
  # there is nothing to do.
  if ( ! isFileNone($mkffile)  ) {
    $calc_mkf = 1;
  }
  if ( ! isFileNone($gtilost)  ) {
    $calc_gtilost = 1;
  }

  if ( $calc_mkf == 0 and $calc_gtilost == 0 ) {
    ahlog::ah_err "No valid input files. Need an MKF and/or a GTI lost file";
    return 1;
  }

  # Input file checking
  # Check for MKF/ahgtigen file requirements
  if ( $calc_mkf ) {
    if (isRequiredFileNotFound($mkffile)) { return 1; }
    # Make sure we have a selection file
    if (isBadCALDBFileParameterValue($selectfile,"selectfile")) { return 1; }
    # Make sure label has ## marks
    if ( $label !~ /[#]{2}/) {
      ahlog::ah_err "Missing ## from label parameter";
      return 1;
    }
  } else {
    $label = "none";
    $selectfile = "none";
  }
  # Check for gti lost file requirements
  if ( $calc_gtilost ) {
    if (isRequiredFileNotFound($gtilost)) { return 1; }
    # Verify EXTNAME = GTILOST and DETNAM = PIXEL 
    my $extname = ahgen::get_keyword($gtilost,1,"EXTNAME");
    if( ahgen::get_error_flag ) {
      ahlog::ah_err "EXTNAME keyword not defined in $gtilost"; return ahgen::get_error_flag;
    }
    if ( uc $extname ne "GTILOST" ) {
      ahlog::ah_err "Extension must be GTILOST for GTI lost file (EXTNAME=$extname)";
      return 1;
    }
    my $detnam = ahgen::get_keyword($gtilost,1,"DETNAM");
    if( ahgen::get_error_flag ) {
      ahlog::ah_err "DETNAM keyword not defined in $gtilost"; return ahgen::get_error_flag;
    }
    if ( uc $detnam ne "PIXEL" ) {
      ahlog::ah_err "DETNAM must be PIXEL for GTI lost file (DETNAM=$detnam)";
      return 1;
    }
  }
  if (isOptionalFileNotFound($gtifile)) { return 1; }

  # Check if output files exist
  if (removeOutputFileIfClobbering($outfile,$ahapp::clobber)) { return 1; }
  if (removeOutputFileIfClobbering($outpixfile,$ahapp::clobber)) { return 1; }

  # Write all parameters to this script to the log file.
  ah_info "HIGH", ahapp::write_parameters () ;                 

  return 0;

}

# ------------------------------------------------------------------------------

sub do_work {

  my $pixlist  = "ftmerge.txt";
  my $pixlistoff  = "ftmerge_off.txt";
  my $tmpmerge = "ftmerge.out";
  my $tmpmergeoff = "ftmergeoff.out";
  my $pixlist_expr="";
  my $pixlist_expr_off="";
  my $extlost = "";
  my $extlostpix = "";
  my $status = 0;

  ahapp::add_temp_file($pixlist);
  ahapp::add_temp_file($pixlistoff);
  ahapp::add_temp_file($tmpmerge);
  ahapp::add_temp_file($tmpmergeoff);

  if ( $calc_gtilost ) {
    $extlostpix = "GTIPIX";
    $extlost = "GTIPIXEL";
  } else {
    $extlostpix = "GTIPIXL";
    $extlost = "GTIPIXELL";
  }

  # Run tool ahgtigen 36 times
  # Copy keywords to each extension
  foreach my $ipix (0..35) {

    my $pixnn  = sprintf('%02i',$ipix);
    my $extname= "$extlostpix$pixnn";
    my $extnameoff= "$extlostpix" . $pixnn . "OFF";
    my $detnam = "PIX$pixnn";
    (my $label_pix = $label ) =~ s/[#]{2}/sprintf('%02d',$ipix)/e;
    my $pixgti = "pix$pixnn.gti";
    my $pixgtioff = "pix$pixnn\_off.gti";
    my $pixgtilostoff = "pix$pixnn\_lostoff.gti";
    my @gtilist = ();
    ahapp::add_temp_file($pixgti);
    ahapp::add_temp_file($pixgtioff);
    ahapp::add_temp_file($pixgtilostoff);

    # Add the general GTI file to the list of GTI to merge
    if ( ! isFileNone($gtifile) ) { push @gtilist, $gtifile; }

    # Extract current pixel and run GTI invert
    if ( $calc_gtilost ) {
      # Run gtiinvert
      $status = run_gtiinvert ( $gtilost . "[1][PIXEL==$ipix]", $pixgtilostoff, "GTI", {}) ;
      if ( $status ) { ahlog::ah_err "gtiinvert failed"; return $status; }
      push @gtilist, $pixgtilostoff . "[GTI]";
    }

    if ( @gtilist > 1 or $calc_mkf ) {
      my $gtilist = join ",", @gtilist;
      if ( @gtilist == 0 ) { $gtilist = "none"; }
      # Run ahgtigen and create Pixel GTI with corresponding label
      $status = run_ftool("ahgtigen","infile=$mkffile","outfile=$pixgti","gtifile=$gtilist",
                          "gtiexpr=$gtiexpr","mergegti=$mergegti","cpkeyword=none",
                          "upkeyword=$upkeyword","leapsecfile=$leapsecfile",
                          "instrume=SXS","selectfile=$selectfile","label=$label_pix",
                          "instarts=$instarts","instops=$instops","time=$time",
                          "outstart=$outstart","outstop=$outstop","prefr=$prefr","postfr=$postfr",
                          "chatter=0");
      if ( $status ) { ahlog::ah_err "ahgtigen failed"; return $status; }
      # Update the extension name and copy to output file
      if (set_keyword($pixgti,"GTI","EXTNAME",$extname)) { return 1; }
      if (set_keyword($pixgti,$extname,"DETNAM",$detnam)) { return 1; }
      # Run gtiinvert
      $status = run_gtiinvert ( $pixgti . "[$extname]", $pixgtioff, $extnameoff, {}) ;
      if ( $status ) { ahlog::ah_err "gtiinvert failed"; return $status; }
    } else {
      # We still want to create the same output files as if ahgtigen was run
      # Copy the GTI lost (off) to the GTIPIXnn extension
      if (ahgen::copy_hdu($pixgtilostoff,"GTI][col #EXTNAME=\"$extname\";START;STOP;",$pixgti)) { return 1; }
      # Copy the GTI lost (on) to the GTIPIXnnOFF extension
      if (ahgen::copy_hdu($gtilost,"1][col #EXTNAME=\"$extnameoff\";START;STOP;PIXEL;][PIXEL==$ipix",$pixgtioff)) { return 1; }
    }

    if (ahgen::copy_hdu($pixgti,$extname,$outfile)) { return 1; }

    # ftcalc fails if there are zero rows when adding a new column
    # Regardless, zero row files are unnecessary
    # Get number of rows in GTI files
    # read the NAXIS2 keyword for fine GTI
    my $naxis2 = ahgen::get_keyword($pixgti,$extname,"NAXIS2");
    if( ahgen::get_error_flag ) {
      ahlog::ah_err "NAXIS2 keyword not defined in $pixgti"; return ahgen::get_error_flag;
    }
    if ($naxis2) {
      # Add a pixel column to the GTI file
      $status = ahgen::run_ftool("ftcalc",$pixgti."[$extname]",$pixgti,"PIXEL",$ipix,"tform=1B","clobber=yes");
      if ( $status ) { ahlog::ah_err "ftcalc failed"; return $status; }
      # build a list of files to merge
      $pixlist_expr .= $pixgti."[$extname]\n";
    }

    my $naxis2_off = ahgen::get_keyword($pixgtioff,$extnameoff,"NAXIS2");
    if( ahgen::get_error_flag ) {
      ahlog::ah_err "NAXIS2 keyword not defined in $pixgti"; return ahgen::get_error_flag;
    }
    if ($naxis2_off) {
      # Add a pixel column to the inverted GTI file
      $status = ahgen::run_ftool("ftcalc",$pixgtioff."[$extnameoff]",$pixgtioff,"PIXEL",$ipix,"tform=1B","clobber=yes");
      if ( $status ) { ahlog::ah_err "ftcalc failed"; return $status; }
      # build a list of files to merge
      $pixlist_expr_off .= $pixgtioff."[$extnameoff]\n";
    }

    # Write the sxspixgti parameters to the output file
    ahapp::write_parameters ($outfile,$extname) ;                 

  } # end loop on pixel

  # Create text file to merge pixel lists
  # +++ 2016-02-19 AS: What to do if input list is empty?
  
  # Set a file to copy keywords from
  my $keyfile = "";
  my $keyext = "";
  if ( $calc_mkf ) { $keyfile = $mkffile; $keyext="FILTER"}
  else { $keyfile = $gtilost; $keyext = "1";}

  # Create the column description file
  my $gtiempty="empty.gti";
  my $cdfile="gti.cdf";
  my $dtfile="gti.dat";
  ahapp::add_temp_file($gtiempty);
  ahapp::add_temp_file($cdfile);
  ahapp::add_temp_file($dtfile);
  open CDFILE, ">", $cdfile;
  print CDFILE "START 1D sec\n";
  print CDFILE "STOP 1D sec\n";
  print CDFILE "PIXEL 1B\n";
  close CDFILE;
  # Print to the data file
  open DTFILE, ">", $dtfile;
  close DTFILE;

  # Create a minimum empty GTI file in case no GTI were created
  # Run ftcreate and append to the output file
  $status = ahgen::run_ftool("ftcreate","cdfile=$cdfile","datafile=$dtfile",
                             "outfile=$gtiempty","extname=GTI",
                             "clobber=yes");
  if($status) { ahlog::ah_err "Error running ftcreate for GTI"; return $status; }

  open SXSPIXMG, ">", $pixlist;
  print SXSPIXMG $gtiempty . "[GTI]\n";
  print SXSPIXMG $pixlist_expr;
  close SXSPIXMG;

  # Merge the selected files
  $status = ahgen::run_ftool("ftmerge","\@$pixlist",$tmpmerge,"copyall=no","skipbadfile=no");
  if ( $status ) { ahlog::ah_err "ftmerge failed"; return $status; }

  # Update the output extension name
  if (set_keyword($tmpmerge,"1","EXTNAME","$extlost")) { return 1; }

  # Sort the output file by START time, STOP time then PIXEL
  my $coordevt = $tmpmerge . ".coordevt";
  ahapp::add_temp_file($coordevt);
  $status = ahgen::run_ftool("ftsort",$tmpmerge."[$extlost]",$coordevt,"START,STOP,PIXEL");
  if ( $status ) { ahlog::ah_err "ftsort failed"; return $status; }

  if (ahfilterlib::copy_keywords($keyfile,"$keyext][col -TSTART;-TSTOP",$coordevt,"$extlost","gti","all")) { return 1; }
  $status = ahgen::set_keyword($coordevt,"$extlost","INSTRUME","SXS");
  if($status) { ahlog::ah_err "Error updating INSTRUME keyword for $extlost"; return $status; }
  $status = ahgen::set_keyword($coordevt,"$extlost","DETNAM","PIXEL");
  if($status) { ahlog::ah_err "Error updating DETNAM keyword for $extlost"; return $status; }
  $status = ahgen::run_ftool("coordevt",$coordevt,$outpixfile,$teldef,"stopsys=FOC","infileext=$extlost");
  if ( $status ) { ahlog::ah_err "coordevt failed"; return $status; }

  my $pixel_rows = ahgen::get_keyword($outpixfile,"$extlost","NAXIS2");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "NAXIS2 keyword not defined in $outpixfile"; return ahgen::get_error_flag;
  }

  # Update the TSTART and TSTOP keyword values
  my @startcol  = ahgen::read_column($outpixfile,"$extlost","START",1);
  my @stopcol   = ahgen::read_column($outpixfile,"$extlost","STOP",$pixel_rows);

  if ( @startcol ) {
    my $tstart  = ( @startcol )[0];
    $status = ahgen::set_keyword($outpixfile,"$extlost","TSTART",$tstart);
    if($status) { ahlog::ah_err "Error updating TSTART keyword for $extlost"; return $status; }
  }
  if ( @stopcol ) {
    my $tstop   = ( @stopcol )[-1];
    $status = ahgen::set_keyword($outpixfile,"$extlost","TSTOP",$tstop);
    if($status) { ahlog::ah_err "Error updating TSTOP keyword for $extlost"; return $status; }
  }

  # Delete the tmp file
  unlink $tmpmerge;

  # Create text file to merge pixel lists
  open SXSPIXMG, ">", $pixlist;
  print SXSPIXMG $gtiempty . "[GTI]\n";
  print SXSPIXMG $pixlist_expr_off;
  close SXSPIXMG;

  # Merge the selected files
  $status = ahgen::run_ftool("ftmerge","\@$pixlist",$tmpmerge,"copyall=no","skipbadfile=no");
  if ( $status ) { ahlog::ah_err "ftmerge failed"; return $status; }

  # Update the output extension name
  if (set_keyword($tmpmerge,"1","EXTNAME","${extlost}OFF")) { return 1; }

  $coordevt = $tmpmergeoff . ".coordevt";
  ahapp::add_temp_file($coordevt);

  # Sort the output file by START time, STOP time then PIXEL
  $status = ahgen::run_ftool("ftsort",$tmpmerge."[${extlost}OFF]",$coordevt,"START,STOP,PIXEL");
  if ( $status ) { ahlog::ah_err "ftsort failed"; return $status; }

  if (ahfilterlib::copy_keywords($keyfile,"$keyext][col -TSTART;-TSTOP",$coordevt,"${extlost}OFF","gti","all")) { return 1; }
  $status = ahgen::set_keyword($coordevt,"${extlost}OFF","INSTRUME","SXS");
  if($status) { ahlog::ah_err "Error updating INSTRUME keyword for ${extlost}OFF"; return $status; }
  $status = ahgen::set_keyword($coordevt,"${extlost}OFF","DETNAM","PIXEL");

  if($status) { ahlog::ah_err "Error updating DETNAM keyword for ${extlost}OFF"; return $status; }
  # Run coordevt to calculate PIXEL -> FOC
  $status = ahgen::run_ftool("coordevt",$coordevt,$tmpmergeoff,$teldef,"stopsys=FOC","infileext=${extlost}OFF");
  if ( $status ) { ahlog::ah_err "coordevt failed"; return $status; }
  if (ahgen::copy_hdu($tmpmergeoff,"${extlost}OFF",$outpixfile)) { return 1; }

  my $pixeloff_rows = ahgen::get_keyword($outpixfile,"${extlost}OFF","NAXIS2");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "NAXIS2 keyword not defined in $outpixfile"; return ahgen::get_error_flag;
  }

  # Update the TSTART and TSTOP keyword values
  my @startcol_off  = ahgen::read_column($outpixfile,"${extlost}OFF","START",1);
  my @stopcol_off   = ahgen::read_column($outpixfile,"${extlost}OFF","STOP",$pixeloff_rows);

  if ( @startcol_off ) {
    my $tstart  = ( @startcol_off )[0];
    # Have to do this after copying the keywords from primary header
    $status = ahgen::set_keyword($outpixfile,"${extlost}OFF","TSTART",$tstart);
    if($status) { ahlog::ah_err "Error updating TSTART keyword for ${extlost}OFF"; return $status; }
  }
  if ( @stopcol_off ) {
    my $tstop   = ( @stopcol_off )[-1];
    $status = ahgen::set_keyword($outpixfile,"${extlost}OFF","TSTOP",$tstop);
    if($status) { ahlog::ah_err "Error updating TSTOP keyword for ${extlost}OFF"; return $status; }
  }

  # Write the sxspixgti parameters to the output file
  ahapp::write_parameters ($outpixfile,"${extlost}") ;
  ahapp::write_parameters ($outpixfile,"${extlost}OFF") ;



  return 0;

}

# ------------------------------------------------------------------------------

sub finalize {

  my $status = 0;

  # Verify output files
  $status = update_checksum_and_verify($outfile);
  unless ( $status ) { ahlog::ah_err "verify failed for $outfile"; return $status; }
  $status = update_checksum_and_verify($outpixfile);
  unless ( $status ) { ahlog::ah_err "verify failed for $outpixfile"; return $status; }

  return 0;
  
}

# ------------------------------------------------------------------------------

sub run_gtiinvert {

  my $infile=shift;
  my $outfile=shift;
  my $outgti=shift;
  my %gtiinvert_pars=%{shift()};

  my $toolname="gtiinvert";
  my $tmpoutfile=formTemporaryFileName($outfile,$toolname);

  my @params = (
    ['infile'       , $infile],
    ['outfile'      , $tmpoutfile],
    ['outext'       , $outgti],
  );
  my @ordered_pars = qw( margingti tstart tstop dt );
  foreach my $par (@ordered_pars) {
    if(defined $gtiinvert_pars{$par}) { push @params, [$par, $gtiinvert_pars{$par}]; }
  }

  if (runTool($toolname,\@params)) { return 1; }
  if (copyOrMoveFileBasedOnCleanup($tmpoutfile, $outfile, $ahapp::cleanup)) { return 1; }

  return 0;
  
}

# ------------------------------------------------------------------------------
