#! /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/sximodegti.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/sximodegti.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/sximodegti.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: sximodegti.pl
# Author: A. J. Sargent NASA GSFC
# $Date: 2016/04/19 16:46:05 $
# Version: 0
#
# Create a Good Time Interval (GTI) excluding dead time for each supported SXI
# mode (full window, 1/8 window, full window+burst, 1/8 window+burst,
# 1/8 window+area discrimination).  This is used for exposure map generation.
# The task uses the exposure FFF, and creates GTI(s) for all the modes found.
#
# Tool Dependencies:
# 
# Library Dependencies:
#   heacore/perl/ahlog
#   heacore/perl/ahapp
#   heacore/perl/ahgen
#   gen/lib/perl/ahfilterlib
#   POSIX 
#
# Modification History:
#

# Set up
use strict;
use warnings;

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

use POSIX; # floor()

# turn on AUTOFLUSH
$| = 1;

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

# input parameters
my $infile="";        # input sxi exposure fff file
my $outfile="";       # output sxi gti file
my $mergefile="";     # output sxi merged datactlm gti file
my $tstart;           # Start time for pointed observations [sec]
my $tstop;            # Stop time for pointed observations [sec]
my $numdclass=0;      # Output par: number of datactlm's in merged gtifile

# Keyword and miscellaneous variables
my $sorted_infile;    # Temporary file with time-sorted data
my $naxis2;           # Number of rows in input file
my $tlmin_ccd;        # Minimum value for CCD_ID column
my $tlmax_ccd;        # Maximum value for CCD_ID column
my $tnull_ccd;        # Null value for CCD_ID column
my $tlmin_seg;        # Minimum value for SEGMENT column
my $tlmax_seg;        # Maximum value for SEGMENT column
my $tnull_seg;        # Null value for SEGMENT column

my $sximodegtierror = 0;  # sximodegti exit status

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

ahapp::startup () ;

ahapp::begin_processing () ;

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

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

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

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

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

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

sub get_parameters {

  $infile     = ahapp::query_parameter("infile");
  $outfile    = ahapp::query_parameter("outfile");
  $mergefile  = ahapp::query_parameter("mergefile");
  $tstart     = ahapp::query_parameter("tstart");
  $tstop      = ahapp::query_parameter("tstop");

  return 0;

}

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

sub initialize {

  my $tstart_expo;
  my $tstop_expo;
  my $status = 0;

  # Input file checking
  if (isRequiredFileNotFound($infile)) { return 1; }

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

  # clone the input file to the output file
  $sorted_infile = formTemporaryFileName((parse_file_name($infile))[0],"ftsort");
  ahapp::add_temp_file($sorted_infile);
  if (copyFITSFile($infile,$sorted_infile)) { return 1; }

  # Get the INSTRUME keyword from the exposure FFF file
  my $instrume = ahgen::get_keyword($sorted_infile,"EXPOSURE","INSTRUME");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "INSTRUME keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  if(lc $instrume ne "sxi") {
    ahlog::ah_err "INSTRUME keyword should be SXI, not $instrume"; return 1;
  }

  # a. Open exposure file
  # b. Sort exposure data by TIME.
  $status = ahgen::run_ftool("ftsort",$sorted_infile."[EXPOSURE]",$sorted_infile,"TIME","clobber=yes");
  if ( $status ) { ahlog::ah_err "ftsort failed"; return $status; }

  # Read keywords from input exposure file
  ahlog::ah_info "HIGH", "Reading input exposure file $sorted_infile";
  $naxis2 = ahgen::get_keyword($sorted_infile,"EXPOSURE","NAXIS2");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "NAXIS2 keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tstart_expo = ahgen::get_keyword($sorted_infile,"EXPOSURE","TSTART");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TSTART keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tstop_expo = ahgen::get_keyword($sorted_infile,"EXPOSURE","TSTOP");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TSTOP keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }

  # If the TSTART->TSTOP interval from the exposure file does not fully contain
  # the tstart->tstop interval, # then we cannot make a complete GTI
  # We should use the exposure TSTART and/or TSTOP
  if ( $tstart_expo > $tstart ) {
    ahlog::ah_out " *** Exposure file TSTART must begin before parameter tstart";
    ahlog::ah_out "Using $infile TSTART.";
    $tstart = $tstart_expo;
  } 
  if ( $tstop_expo < $tstop ) {
    ahlog::ah_out " *** Exposure file TSTOP must end after parameter tstop";
    ahlog::ah_out "Using $infile TSTOP.";
    $tstop = $tstop_expo;
  }

  # Read TLMIN,TLMAX,TNULL for CCD_ID,SEGMENT
  my $ccdnum = ahgen::get_column_num($sorted_infile,"EXPOSURE","CCD_ID");
  unless ($ccdnum) { ahlog::ah_err "Could not find column CCD_ID in $infile"; return 1;}
  my $segnum = ahgen::get_column_num($sorted_infile,"EXPOSURE","SEGMENT");
  unless ($segnum) { ahlog::ah_err "Could not find column SEGMENT in $infile"; return 1;}
  $tlmin_ccd = ahgen::get_keyword($sorted_infile,"EXPOSURE","TLMIN$ccdnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TLMIN$ccdnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tlmax_ccd = ahgen::get_keyword($sorted_infile,"EXPOSURE","TLMAX$ccdnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TLMAX$ccdnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tnull_ccd = ahgen::get_keyword($sorted_infile,"EXPOSURE","TNULL$ccdnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TNULL$ccdnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tlmin_seg = ahgen::get_keyword($sorted_infile,"EXPOSURE","TLMIN$segnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TLMIN$segnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tlmax_seg = ahgen::get_keyword($sorted_infile,"EXPOSURE","TLMAX$segnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TLMAX$segnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }
  $tnull_seg = ahgen::get_keyword($sorted_infile,"EXPOSURE","TNULL$segnum");
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "TLMIN$segnum keyword not defined in $sorted_infile"; return ahgen::get_error_flag;
  }

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

  return 0;

}

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

sub do_work {

  my $time_previous=0;
  my $framenum_previous=0;

  # Frame storage variables
  # Initialize hashes indexed by extension number to hold the CCD_ID,
  # SEGMENT, DATACTLM, etc. to which that extension corresponds.
  # These will be searched for each exposure row
  # to figure out where to put the GTI entry
  my $extnum=0;         # number of extensions
  my %GTI_hdfiles;      # list of header definition files for each GTI extension, for ftcreate
  my %GTI_dtfiles;      # list of data files for each GTI extension, for ftcreate
  my %GTI_datactlms;    # DATACTLM for each GTI extension
  my %GTI_ccdids;       # CCD_ID for each GTI extension
  my %GTI_segments;     # SEGMENT for each GTI extension
  my %GTI_detnams;      # DETNAM for each GTI extension
  my %GTI_datamodes;    # DATAMODE for each GTI extension
  my %GTI_numframes;    # Number of frames for each GTI extension
  my %GTI_tstart;       # TSTART for each GTI extension
  my %GTI_tstop;        # TSTOP for each GTI extension
  
  # The DATACLASS column is being changed to DATACTLM, but this tool
  # still needs to work with old data.  Set up an if-block here to get data
  # from the DATACTLM column if it exists, otherwise get it from the DATACLASS
  # column
  my $datactlm_col="DATACTLM";
  my $colnum = ahgen::get_column_num($sorted_infile,"EXPOSURE","DATACTLM");
  if ($colnum == 0) {
    $datactlm_col="DATACLASS";
    ahlog::ah_debug "DATACTLM column not found; using DATACLASS column";
  }
  
  # Counters
  my $num_rows_previous=0;
  my $num_bad_time=0.;
  my $num_bad_ccdid=0;
  my $num_bad_segment=0;
  my $num_bad_frametype=0;
  my $num_bad_datamode=0;
  my $num_bad_detnam=0;

  my @row_present = ();

  my $status = 0;

  # Initialize the row_present array. This stores the number of rows of each
  # CCD_ID+SEGMENT combination that are present in the current group
  # (should be all ones when we're done reading the group of rows
  push @row_present, 0 foreach (0..7);

  # For each row in TIME-sorted exposure file
  # Read following columns:
  #   TIME
  #   CCD_ID
  #   SEGMENT
  #   DATACTLM or DATACLASS
  #   FRAMENUM (integer counting the frames, unique for each set of 8 segments)
  #   FRAMETYPE (0=event data, 1=rframe data, 2=iframe data, 3=dframe data) (?)
  #   DETNAM (CCD, CCD12, CCD34)
  #   DATAMODE (WINDOW1, WINDOW1BURST, WINDOW2, WINDOW2BURST)
  #   ADOU0ENA (0=off, 1=on but only allowed for CCD_ID=1, SEGMENT=1)
  ahlog::ah_info "LOW", "Reading $naxis2 rows from $infile";
  my @time      = ahgen::read_column($sorted_infile,"EXPOSURE","TIME");
  if($naxis2 != @time      ) { ahlog::ah_err "Error reading TIME column in $sorted_infile"; return 1; }
  my @ccd_id    = ahgen::read_column($sorted_infile,"EXPOSURE","CCD_ID");
  if($naxis2 != @ccd_id    ) { ahlog::ah_err "Error reading CCD_ID column in $sorted_infile"; return 1; }
  my @segment   = ahgen::read_column($sorted_infile,"EXPOSURE","SEGMENT");
  if($naxis2 != @segment   ) { ahlog::ah_err "Error reading SEGMENT column in $sorted_infile"; return 1; }
  my @datactlm = ahgen::read_column($sorted_infile,"EXPOSURE",$datactlm_col);
  if($naxis2 != @datactlm ) { ahlog::ah_err "Error reading DATACTLM column in $sorted_infile"; return 1; }
  my @framenum  = ahgen::read_column($sorted_infile,"EXPOSURE","FRAMENUM");
  if($naxis2 != @framenum  ) { ahlog::ah_err "Error reading FRAMENUM column in $sorted_infile"; return 1; }
  my @frametype = ahgen::read_column($sorted_infile,"EXPOSURE","FRAMETYPE");
  if($naxis2 != @frametype ) { ahlog::ah_err "Error reading FRAMETYPE column in $sorted_infile"; return 1; }
  my @detnam    = ahgen::read_column($sorted_infile,"EXPOSURE","DETNAM");
  if($naxis2 != @detnam    ) { ahlog::ah_err "Error reading DETNAM column in $sorted_infile"; return 1; }
  my @datamode  = ahgen::read_column($sorted_infile,"EXPOSURE","DATAMODE");
  if($naxis2 != @datamode  ) { ahlog::ah_err "Error reading DATAMODE column in $sorted_infile"; return 1; }
  # Check for any errors
  if( ahgen::get_error_flag ) {
    ahlog::ah_err "Error reading columns in $sorted_infile"; 
    return ahgen::get_error_flag;
  }

  # Loop through exposure rows
  foreach my $irow (1..$naxis2) {
    my $time_row      = $time[$irow-1];
    my $ccd_id_row    = $ccd_id[$irow-1];
    my $segment_row   = $segment[$irow-1];
    my $datactlm_row  = sprintf("%lx", $datactlm[$irow-1]); # convert to hex (string) from long int 
    my $framenum_row  = $framenum[$irow-1];
    my $frametype_row = $frametype[$irow-1];
    my $detnam_row    = $detnam[$irow-1];
    my $datamode_row  = $datamode[$irow-1];

    # Timing variables
    my $timedel=0;
    my $timtranb=0;
    my $timtrana=0;
    my $expdeadb=0;
    my $expdeada=0;
    my $flushimb=0;
    my $lastdead=0;
    my $lastdel=0;
    my $nomexpo=0;
    my $timepixr=0;

    my $num_windows=0;
    my $subcycletime=0;
    my $extratime=0;

    my @start_time=();
    my @stop_time=();

    ahlog::ah_debug "Reading row $irow of $naxis2 from $sorted_infile:";
    ahlog::ah_debug "  TIME      : $time_row";
    ahlog::ah_debug "  CCD_ID    : $ccd_id_row";
    ahlog::ah_debug "  SEGMENT   : $segment_row";
    ahlog::ah_debug "  DATACTLM : h$datactlm_row";
    ahlog::ah_debug "  FRAMENUM  : $framenum_row";
    ahlog::ah_debug "  FRAMETYPE : $frametype_row";
    ahlog::ah_debug "  DETNAM    : $detnam_row";
    ahlog::ah_debug "  DATAMODE  : $datamode_row";

    # Skip any row that has a NULL value for time
    if( $time_row eq "NULL" ) { 
      ahlog::ah_info "LOW", "Row $irow: TIME is NULL, skipping."; 
      $num_bad_time++;
      next; 
    }

    # If TIME is before the start of pointed observations, skip this row
    # Assumes TIME is in order (sorted in initialize)
    if($time_row < $tstart) { next; }

    # If TIME is after the end of pointed observations, we're done reading
    # Assumes TIME is in order (sorted in initialize)
    if($time_row > $tstop) { 
      ahlog::ah_info "LOW", "Row $irow: TIME is later than $tstop, finished reading exposure file.";
      last; 
    }

    # Check if frametype is event data (skip rframe, iframe, dframe data).
    if ( $frametype_row != 0 ) {
      ahlog::ah_info "LOW", "Row $irow: FRAMETYPE is not event data, skipping. (FRAMETYPE=$frametype_row)";
      $num_bad_frametype++;
      next;
    }

    # if CCD_ID or SEGMENT are out of range, skip this row
    if( $ccd_id_row < $tlmin_ccd or
        $ccd_id_row > $tlmax_ccd or
        $ccd_id_row == $tnull_ccd ) {
      ahlog::ah_info "LOW", "Row $irow: CCD_ID is out of range, skipping. (CCD_ID=$ccd_id_row)";
      $num_bad_ccdid++;
      next;
    }
    if( $segment_row < $tlmin_seg or
        $segment_row > $tlmax_seg or
        $segment_row == $tnull_seg ) {
      ahlog::ah_info "LOW", "Row $irow: SEGMENT is out of range, skipping.(SEGMENT=$segment_row)";
      $num_bad_segment++;
      next;
    }

    # Check if this row is in a supported mode. If not, go to the next row with
    # a notification.
    # These are the possible combinations:
    # CCD_ID  SEG   DETNAM   DATAMODE     ADOU0ENA
    # 0       0     CCD      WINDOW1      0
    # 0       1     CCD      WINDOW1      0
    # 0       0     CCD12    WINDOW2      0
    # 0       1     CCD12    WINDOW2      0
    # 0       0     CCD12    WINDOW1BURST 0
    # 0       1     CCD12    WINDOW1BURST 0
    # 0       0     CCD12    WINDOW2BURST 0
    # 0       1     CCD12    WINDOW2BURST 0
    # 1       0     CCD      WINDOW1      0
    # 1       1     CCD      WINDOW1      0
    # 1       0     CCD12    WINDOW2      0
    # 1       1     CCD12    WINDOW2      0
    # 1       1     CCD12    WINDOW2      1  only allowed ADOU0ENA==1
    # 1       0     CCD12    WINDOW1BURST 0
    # 1       1     CCD12    WINDOW1BURST 0
    # 1       0     CCD12    WINDOW2BURST 0
    # 1       1     CCD12    WINDOW2BURST 0
    # 2       0     CCD      WINDOW1      0
    # 2       1     CCD      WINDOW1      0
    # 2       0     CCD34    WINDOW1      0
    # 2       1     CCD34    WINDOW1      0
    # 3       0     CCD      WINDOW1      0
    # 3       1     CCD      WINDOW1      0
    # 3       0     CCD34    WINDOW1      0
    # 3       1     CCD34    WINDOW1      0

    # The following 'if' statments check whether this is an allowed
    # combination according to the table above.

    # For each allowed CCD_ID, check various allowed combinations
    if( $ccd_id_row==0 or $ccd_id_row==1 ) {
      # Check CCD_ID = 0 or CCD_ID = 1
      if( uc $detnam_row eq "CCD" ) {
        # Check DETNAM = 'CCD'
        if( uc $datamode_row ne "WINDOW1" ) {
          # 'WINDOW1' must be used for 'CCD'
          ahlog::ah_info "LOW", "Row $irow: DATAMODE is not supported for GTI, skipping. (DATAMODE=$datamode_row)";
          $num_bad_datamode++;
          next;
        } else { 
          # Row is a supported datactlm
          ahlog::ah_info "LOW", "Row $irow: Found DATACTLM $datactlm_row";
        }
      } elsif ( uc $detnam_row eq "CCD12" ) {
        # Check DETNAM = 'CCD12' for CCD_ID = 0, 1
        if( uc $datamode_row ne "WINDOW2" and 
            uc $datamode_row ne "WINDOW1BURST" and
            uc $datamode_row ne "WINDOW2BURST" ) {
          # 'CCD12' must have one of these three DATAMODEs
          ahlog::ah_info "LOW", "Row $irow: DATAMODE is not supported for GTI, skipping. (DATAMODE=$datamode_row)";
          $num_bad_datamode++;
          next;
        } else { 
          # Row is a supported datactlm
          ahlog::ah_info "LOW", "Row $irow: Found DATACTLM $datactlm_row";
        }
      } else {
        ahlog::ah_info "LOW", "Row $irow: DETNAM is not supported for GTI, skipping. (DETNAM=$detnam_row)";
        $num_bad_detnam++;
        next;
      }
      # end if CCD_ID = 0,1
    } elsif( $ccd_id_row==2 or $ccd_id_row==3 ) {
      # Check CCD_ID = 2 or CCD_ID = 3
      #if( uc $detnam_row ne "CCD" or 
      if( uc $detnam_row ne "CCD" and
          uc $detnam_row ne "CCD34" ) {
        # CCD_ID 2, 3 must be DETNAM = 'CCD' or 'CCD34'
        ahlog::ah_info "LOW", "Row $irow: DETNAM is not supported for GTI, skipping. (DETNAM=$detnam_row)";
        $num_bad_detnam++;
        next;
      } elsif ( uc $datamode_row ne "WINDOW1" ) {
        # CCD_ID 2, 3 must be DATAMODE = 'WINDOW1'
        ahlog::ah_info "LOW", "Row $irow: DATAMODE is not supported for GTI, skipping. (DATAMODE=$datamode_row)";
        $num_bad_datamode++;
        next;
      } else {
        # Row is a supported DATACTLM
        ahlog::ah_info "LOW", "Row $irow: Found DATACTLM $datactlm_row";
      }
    } else {
      # CCD_ID is wrong
      ahlog::ah_info "LOW", "Row $irow: CCD_ID is not supported for GTI, skipping. (CCD_ID=$ccd_id_row)";
      $num_bad_ccdid++;
      next;
    } # end if CCD_ID

    # Figure out which GTI extension to use for the combination of
    # CCD_ID, SEGMENT, DATACTLM
    my $gtiext = -1; # $gtiext is the extension of the current GTI
    foreach my $gti_ii (1..$extnum) {
      next unless ($ccd_id_row == $GTI_ccdids{$gti_ii});
      next unless ($segment_row == $GTI_segments{$gti_ii});
      next unless ($datactlm_row eq $GTI_datactlms{$gti_ii});
      $gtiext = $gti_ii;
      last;
    }

    # If the GTI extension for this CCD_ID+SEGMENT+DATACTLM doesn't exist yet, create it
    if ( $gtiext == -1 ) {

      # increment number of GTI extensions
      $extnum++;

      # Calculate temporary header and datafile names
      # Remove header and data files if they exist
      my $hdfile="gti_CCD$ccd_id_row\_SEG$segment_row\_DATACTLM$datactlm_row\.hdr";
      my $dtfile="gti_CCD$ccd_id_row\_SEG$segment_row\_DATACTLM$datactlm_row\.dat";
      ahapp::add_temp_file($hdfile); unlink $hdfile;
      ahapp::add_temp_file($dtfile); unlink $dtfile;

      $status = createGTIExtension($ccd_id_row,$segment_row,$datactlm_row,
                                   $detnam_row,$datamode_row,$hdfile);
      if($status) { 
        ahlog::ah_err "Row $irow: Could not create GTI extension for CCD_ID $ccd_id_row, SEGMENT $segment_row, DATACTLM $datactlm_row."; 
        return 1;
      }
      ahlog::ah_info "HIGH", "Created GTI extension for CCD_ID $ccd_id_row, SEGMENT $segment_row, DATACTLM $datactlm_row, ext $extnum.";

      # Populate the hash and arrays with the correct values for this GTI extension
      $gtiext = $extnum;
      $GTI_hdfiles{$gtiext} = $hdfile;
      $GTI_dtfiles{$gtiext} = $dtfile;
      $GTI_ccdids{$gtiext} = $ccd_id_row;
      $GTI_segments{$gtiext} = $segment_row;
      $GTI_datactlms{$gtiext} = $datactlm_row;
      $GTI_detnams{$gtiext} = $detnam_row;
      $GTI_datamodes{$gtiext} = $datamode_row;
      $GTI_numframes{$gtiext} = 0;
      # Set TSTART and TSTOP for this extension; TSTART will not be changed, TSTOP will be 
      # changed as we encounter new exposure rows.
      $GTI_tstart{$gtiext} = $time_row;
      $GTI_tstop{$gtiext} = $time_row;
    }

    # Get the timing  parameters for this DATAMODE
    $status = getTimingParams($datamode_row,
                              \$timedel,\$timtranb,\$timtrana,\$expdeadb,
                              \$expdeada,\$flushimb,\$lastdead,\$lastdel,
                              \$nomexpo,\$timepixr);
    if($status) { 
      ahlog::ah_err "Row $irow: Tried to get timing parameters for unrecognized DATAMODE $datamode_row."; 
      return 1;
    }

    # From ahtime.cxx, here is a description of how to translate frame timing parameters
    # for event data in a given mode.
    #   TIME in exposure file as at the beginning of a frame
    #   TIME in events file in the center of the TIMEDEL window as shown below
    # We need to set START and STOP to beginning and end of TIMEDEL window
    #
    # The SXI instrument operates in fixed-length time cycles given by the
    # keyword, NOMEXPO (i.e. 4s).  The total cycle is further divided into
    # subcycles based on the DATAMODE keyword.  A subcycle is divided in the
    # following way:
    #
    # [---EXPDEADB---|---TIMTRANB----|---FLUSHIMB----|====TIMEDEL====|---TIMTRANA----|---EXPDEADA---]
    #
    # where events are only recorded during the TIMEDEL interval.  While the
    # number of sub-cycles depends on the DATAMODE keyword, it can also be
    # calculated by dividing the total cycle time (NOMEXPO) by the subcycle
    # time illustrated above.  The time assigned to events is within the
    # TIMEDEL interval based on the TIMEPIXR keyword.  For TIMEPIXR=0.5, the
    # time is assigned at the halfway point in the interval as shown below:
    # 
    # [---EXPDEADB---|---TIMTRANB----|---FLUSHIMB----|====TIMEDEL====|---TIMTRANA----|---EXPDEADA---]
    # |----------------SUBCYCLE TIME SHIFT-------------------->
    #
    # The total time shift from the beginning of SEQ_START_TIME is the subcycle
    # time shift shown above plus the total time of all subcycles prior to the
    # active subcycle:
    #
    #  time shift = SUBCYCLE_SHIFT + (icycle * SUBCYCLE_TIME)
    #
    # where SUBCYCLE_SHIFT = EXPDEADB+TIMTRANB+FLUSHIMB+(TIMEPIXR*TIMEDEL), 
    #       SUBCYCLE_TIME = EXPDEADB+TIMTRANB+FLUSHIMB+TIMEDEL+TIMTRANA+EXPDEADA,
    # and icycle ranges from 0 to NEXP-1, where NEXP is the number of
    # nexposures in one complete cycle (e.g. 4s).
    #
    # The SUBCYCLE_SHIFT is constant for all subcycles except the last where
    # TIMEDEL and EXPDEADA can be extended.  For time assignment, the adjusted
    # EXPDEADA can be ignored since it occurs after the exposure window, but
    # an additional shift is needed based on the final TIMEDEL size:
    #
    #  ADJLASTTIME = TIMEPIXR * (LASTDEL - TIMEDEL)
    #
    # In the last subcycle, this value must be added to the time shift.
    #
    # TIMEDEL     / [s] Integration time
    # TIMTRANB    / [s] Transfer time before exposure
    # TIMTRANA    / [s] Transfer time after exposure
    # EXPDEADB    / [s] Deadtime before exposure
    # EXPDEADA    / [s] Deadtime after exposure
    # FLUSHIMB    / [s] Flush out time
    # LASTDEAD    / [s] Last Deadtime after exposure
    # LASTDEL     / [s] Last Integration time in exposure
    # NOMEXPO     / [s] period of seq start time
    # TIMEPIXR    / Bintime start=0 middle=0.5 end=1

    # for time assignment, the above keyword values can be reduced to the following:
    #  - subcycletime: total time of a single subcycle
    #  - num_windows: number of windows (subcycles) in full exposure cycle
    #  - extratime: extra time at the end of the last subcycle
    $subcycletime = $expdeadb+$timtranb+$flushimb+$timedel+$expdeada+$timtrana;
    if ( $lastdel > 0. ) {
      $extratime = ($lastdead-$expdeada)+($lastdel-$timedel);
    } else {
      $extratime = 0.;
    }
    
    # How many GTI windows per exposure frame?
    if( uc $datamode_row eq "WINDOW1" or
        uc $datamode_row eq "WINDOW1BURST" ) {
        # in full window (with or without burst), there is 1 GTI
        # entry per exposure row
        $num_windows = 1;
    } elsif ( uc $datamode_row eq "WINDOW2" or
              uc $datamode_row eq "WINDOW2BURST" ) {
        # in 1/8 window (with or without burst), there are 8 GTI
        # entries per exposure row
        $num_windows = 8;
    }

    # Set START and STOP times for GTI extension
    for (my $gti_ii=0;$gti_ii<$num_windows;$gti_ii++) {
      # START of GTI entry should be at beginning of TIMEDEL window above
      $start_time[$gti_ii] = $time_row+$subcycletime*$gti_ii+$expdeadb+$timtranb+$flushimb;
      # STOP of GTI entry should be at end of TIMEDEL window above
      $stop_time[$gti_ii] = $start_time[$gti_ii] + $timedel;
    } # end for gti_ii loop 

    # Last window for 1/8 window has a slightly longer exposure time
    # Add it here
    $stop_time[$num_windows-1] += $extratime;

    # Write START STOP FRAMENUM columns to proper GTI file extension
    for (my $gti_ii=0;$gti_ii<$num_windows;$gti_ii++) {
      my $dtfile = $GTI_dtfiles{$gtiext};
      my $start = $start_time[$gti_ii];
      my $stop = $stop_time[$gti_ii];
      $status = writeGTIRow($dtfile,$start,$stop,$framenum_row);
      if($status) { 
        ahlog::ah_err "Row $irow: Could not write to GTI extension: $gtiext."; 
        return 1;
      }
    }

    # Set extension TSTOP to the TIME of this row plus the nominal frame exposure time
    $GTI_tstop{$gtiext} = $time_row + $nomexpo;
    
    # Increment the number of (good) frames hash for this GTI extension
    $GTI_numframes{$gtiext}++;

    # Keep track of how many rows in this TIME group
    if ( $time_row == $time_previous ) {
      # We're still in a new group of 8 segments
      # Increment the array that keeps track of which CCD_ID+SEGMENT
      # combination we have encountered in the group of 8
      $row_present[$ccd_id_row*2+$segment_row]++;
    } else {
      # We're in a new group of 8 segments
      if ( $time_previous == 0 ) {
        # We're at the first row, so move on
        $row_present[$ccd_id_row*2+$segment_row]++;
        $time_previous = $time_row;
        $framenum_previous = $framenum_row;
      } else {
        # We're done with the group, so check it
        # Check for each CCD_ID+SEGMENT combination to see if we have
        # 1 of each of the 8
        for (my $ii=0;$ii<8;$ii++) {
          if( $row_present[$ii] < 1 ) {
            my $ccd_id_frame = floor($ii/2);
            my $segment_frame = $ii%2;
            ahlog::ah_info "HIGH", "Exposure row for frame $framenum_previous, " .
                                   "CCD_ID $ccd_id_frame, SEGMENT $segment_frame " .
                                   "is missing.";
          } elsif ( $row_present[$ii] > 1 ) {
            my $ndups = $row_present[$ii];
            my $ccd_id_frame = floor($ii/2);
            my $segment_frame = $ii%2;
            ahlog::ah_info "HIGH", "Exposure row for frame $framenum_previous, " .
                                   "CCD_ID $ccd_id_frame, SEGMENT $segment_frame " .
                                   "is duplicated $ndups times.";
          }
        } # end CCD_ID+SEGMENT combo
        # Re-initialize row_present array to zeroes, then increment
        # the current CCD_ID+SEGMENT
        for (my $ii=0;$ii<8;$ii++) { $row_present[$ii]=0; }
        $row_present[$ccd_id_row*2+$segment_row]++;
        $time_previous = $time_row;
        $framenum_previous = $framenum_row;
      } # end if time_previous
    } # end if time
  } # end of row loop

  # We're done with the final group, so we have to check it here
  # Check for each CCD_ID+SEGMENT combination to see if we have
  # 1 of each of the 8
  for (my $ii=0;$ii<8;$ii++) {
    if ( $row_present[$ii] < 1 ) {
      my $ccd_id_frame = floor($ii/2);
      my $segment_frame = $ii%2;
      ahlog::ah_info "HIGH", "Exposure row for frame $framenum_previous, " .
                             "CCD_ID $ccd_id_frame, SEGMENT $segment_frame " .
                             "is missing.";
    } elsif ( $row_present[$ii] > 1 ) {
      my $ndups = $row_present[$ii];
      my $ccd_id_frame = floor($ii/2);
      my $segment_frame = $ii%2;
      ahlog::ah_info "HIGH", "Exposure row for frame $framenum_previous, " .
                             "CCD_ID $ccd_id_frame, SEGMENT $segment_frame " .
                             "is duplicated $ndups times.";
    }
  } # End CCD_ID+SEGMENT combo

  # End of loop through exposure

  # Write number of frames into header of each GTI extension and print it
  unless($extnum) { ahlog::ah_err "  No GTI extension found.\n"; return 1; }
  ahlog::ah_info "HIGH", "Found the following numbers of GTI extensions: $extnum";

  # Create the column description file
  my $cdfile="gti.cdf";
  ahapp::add_temp_file($cdfile);
  open CDFILE, ">", $cdfile;
  print CDFILE "START 1D s\n";
  print CDFILE "STOP 1D s\n";
  print CDFILE "FRAMENUM 1J\n";
  close CDFILE;

  my %gti_dclass;
  my %tstart_dclass;
  my %tstop_dclass;

  # Create  GTI file for each frame
  foreach my $gti_ii (1..$extnum) {
    my $gtifile = "gti_$gti_ii\.tmp";
    my $hdfile = $GTI_hdfiles{$gti_ii};
    my $dtfile = $GTI_dtfiles{$gti_ii};
    my $numframes = $GTI_numframes{$gti_ii};
    my $tstart_gti = $GTI_tstart{$gti_ii};
    my $tstop_gti = $GTI_tstop{$gti_ii};
    my $datactlm = $GTI_datactlms{$gti_ii};
    my $ccd_id = $GTI_ccdids{$gti_ii};
    my $segment = $GTI_segments{$gti_ii};
    my $extname = "GTI_SEG" . (2*$ccd_id+$segment) . $datactlm;

    ahapp::add_temp_file($gtifile);

    # Add the NUMFRAMES keyword to the header file
    open HDFILE, ">>", $hdfile;
    print HDFILE "NUMFRAMS = $numframes\n";
    close HDFILE;

    # Run ftcreate and append to the output file
    $status = ahgen::run_ftool("ftcreate","cdfile=$cdfile","datafile=$dtfile",
                               "outfile=$gtifile","headfile=$hdfile","extname=$extname",
                               "clobber=yes");
    if($status) { ahlog::ah_err "Error running ftcreate for GTI $gti_ii"; return $status; }

    # Copy keywords from the primary extension to the output GTI extension
    # This is likely to change. 
    # Need to watch out for overwriting the DETNAM and DATAMODE keywords
    $status = ahfilterlib::copy_keywords((parse_file_name($infile))[0],"0",$gtifile,$extname,"GTI","all");
    if($status) { ahlog::ah_err "Error copying keywords from $infile to $gti_ii"; return $status; }

    # Update the TSTART and TSTOP keyword values
    # Have to do this after copying the keywords from primary header
    $status = ahgen::set_keyword($gtifile,$extname,"TSTART",$tstart_gti);
    if($status) { ahlog::ah_err "Error updating TSTART keyword for GTI $gti_ii"; return $status; }
    $status = ahgen::set_keyword($gtifile,$extname,"TSTOP",$tstop_gti);
    if($status) { ahlog::ah_err "Error updating TSTOP keyword for GTI $gti_ii"; return $status; }

    # Write the sximodegti parameters to the output GTI file
    ahapp::write_parameters ($gtifile,$extname) ;                 

    # Copy the new GTI file to the output file
    $status = ahgen::copy_hdu($gtifile,$extname,$outfile);
    if($status) { ahlog::ah_err "Error copying HDU for GTI $gti_ii to $outfile"; return $status; }

    ahlog::ah_info "HIGH", "  Ext $gti_ii: $numframes frames found.";
    ahlog::ah_info "LOW", "  Ext $gti_ii: TSTART = $tstart_gti.";
    ahlog::ah_info "LOW", "  Ext $gti_ii: TSTOP  = $tstop_gti.";

    # Create an array to push GTI files into for merging
    unless ( exists $gti_dclass{$datactlm} ) { $gti_dclass{$datactlm} = (); }
    unless ( exists $tstart_dclass{$datactlm} ) { $tstart_dclass{$datactlm} = $tstart_gti; }
    unless ( exists $tstop_dclass{$datactlm} ) { $tstop_dclass{$datactlm} = $tstop_gti; }
    push @{$gti_dclass{$datactlm}}, $gtifile;
    if( $tstart_dclass{$datactlm} > $tstart_gti ) { $tstart_dclass{$datactlm} = $tstart_gti; }
    if( $tstop_dclass{$datactlm} < $tstop_gti ) { $tstop_dclass{$datactlm} = $tstop_gti; }

  }
  
  # Create a keyfile to not copy the CCD_ID and SEGMENT keywords
  my $keyfil = "keyfil.txt";
  open KYFILE, ">", $keyfil;
  print KYFILE "!CCD_ID\n";
  print KYFILE "!SEGMENT\n";
  print KYFILE "!ADOU0ENA\n";
  print KYFILE "!EXTNAME\n";
  close KYFILE;
  ahapp::add_temp_file($keyfil);
  
  # Merge the GTI files
  foreach my $datactlm ( sort keys %gti_dclass ) {
    my %mgtime_pars;
    my $gtifile = "merge_DATACTLM$datactlm.gti";
    my $tstart_gti = $tstart_dclass{$datactlm};
    my $tstop_gti = $tstop_dclass{$datactlm};
    my @gtifiles = @{$gti_dclass{$datactlm}};
    my $extname = "GTI_$datactlm";
    ahapp::add_temp_file($gtifile);

    # Increment the output numdclass parameter
    $numdclass++;

    # Merge GTI files with matching DATACLAS
    if( ahfilterlib::merge_gti(\@gtifiles,$gtifile,"AND",$extname,\%mgtime_pars) ) {
      ahlog::ah_err "Error merging GTI files" ;
      return ahgen::get_error_flag;
    } 

    # Copy keywords from the first GTI file in the datactlm.
    # Do not copy the CCD_ID or SEGMENT
    $status = ahgen::run_ftool("cphead",$gtifiles[0]."[1]",$gtifile."[$extname]","keyfil=$keyfil","comment=no","history=no");
    if($status) { ahlog::ah_err "Error copying keywords from $gtifile to $mergefile"; return $status; }

    # Have to do this after copying the keywords from primary header
    $status = ahgen::set_keyword($gtifile,$extname,"TSTART",$tstart_gti);
    if($status) { ahlog::ah_err "Error updating TSTART keyword for GTI $gtifile"; return $status; }
    $status = ahgen::set_keyword($gtifile,$extname,"TSTOP",$tstop_gti);
    if($status) { ahlog::ah_err "Error updating TSTOP keyword for GTI $gtifile"; return $status; }

    # Copy the new GTI file to the output file
    $status = ahgen::copy_hdu($gtifile,$extname,$mergefile);
    if($status) { ahlog::ah_err "Error copying HDU for GTI $gtifile to $mergefile"; return $status; }

  }

  # Print the counters to the log file
  ahlog::ah_info "LOW", "Number of datactlmes            : $numdclass";
  ahlog::ah_info "LOW", "Number of frames excluded:";
  ahlog::ah_info "LOW", "  With TIME = NULL              : $num_bad_time";
  ahlog::ah_info "LOW", "  With CCD_ID out of range      : $num_bad_ccdid";
  ahlog::ah_info "LOW", "  With SEGMENT out of range     : $num_bad_segment";
  ahlog::ah_info "LOW", "  With FRAMETYPE not events     : $num_bad_frametype";
  ahlog::ah_info "LOW", "  With DETNAM not supported     : $num_bad_detnam";
  ahlog::ah_info "LOW", "  With DATAMODE not supported   : $num_bad_datamode";

  return 0;

} 

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

sub finalize {

  my $status = 0;

  # Verify output file
  # Files will fail verification due to having all extensions named GTI
  $status = update_checksum_and_verify($outfile);
  unless ($status) { ahlog::ah_err "File $outfile failed ftverify"; return $status; }
  $status = update_checksum_and_verify($mergefile);
  unless ($status) { ahlog::ah_err "File $mergefile failed ftverify"; return $status; }

  # Set the output parameter numdclass
  ahgen::run_ftool("pset","sximodegti","numdclass=$numdclass");

  return 0;
  
}

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

# 
# Description: 
#
# Create a GTI Header file in the output GTI file for the combination of:
# CCD_ID, SEGMENT, DETNAM, DATAMODE, ADOU0ENA
#
# Parameters:
# [in] ccd_id      (0,1,2,3)
# [in] segment     (0: AB, 1: CD (Segment ID))
# [in] datactlm    DataClass identifier 
# [in] detnam      Detector subsystem (CCD, CCD12, CCD34)
# [in] datamode    (WINDOW1, WINDOW1BURST, WINDOW2, WINDOW2BURST)
# [in] hdfile      File of header keywords 
# [out] status     Return 0 for successful creation of merged event file
#
sub createGTIExtension ($$$$$$$) {

  my $ccd_id = shift;
  my $segment = shift;
  my $datactlm = shift;
  my $detnam = shift;
  my $datamode = shift;
  my $hdfile = shift;

  my $timedel=0;
  my $timtranb=0;
  my $timtrana=0;
  my $expdeadb=0;
  my $expdeada=0;
  my $flushimb=0;
  my $lastdead=0;
  my $lastdel=0;
  my $nomexpo=0;
  my $timepixr=0;

  my $status = 0;

  # Get the timing parameters so we can write them to keywords
  $status = getTimingParams($datamode,
                            \$timedel,\$timtranb,\$timtrana,\$expdeadb,
                            \$expdeada,\$flushimb,\$lastdead,\$lastdel,
                            \$nomexpo,\$timepixr);
  if($status) { 
    ahlog::ah_err "createGTIExtension: Tried to get timing parameters for unrecognized DATAMODE $datamode."; 
    return 1;
  }

  # Write the keywords to the header description file
  open HDFILE, ">", $hdfile;
  print HDFILE "HDUCLASS = OGIP / format conforms to OGIP/GSFC conventions\n";
  print HDFILE "HDUCLAS1 = GTI / Extension contains Good Time Intervals\n";
  print HDFILE "CCD_ID = $ccd_id / 0: CCD1, 1: CCD2, 2: CCD3, 3: CCD4\n";
  print HDFILE "SEGMENT = $segment / 0: AB, 1: CD (Segment ID)\n";
  print HDFILE "DETNAM = $detnam / CCD:all, CCD12: CCD1+2, CCD34: CCD3+4\n";
  print HDFILE "DATAMODE = $datamode / (WINDOW1, WINDOW1BURST, WINDOW2, WINDOW2BURST)\n";
  print HDFILE "DATACLAS = '$datactlm' / Code to ID all instrument settings\n";
  print HDFILE "TIMEDEL = $timedel / [s] Integration time\n";
  print HDFILE "TIMTRANB = $timtranb / [s] Transfer time before exposure\n";
  print HDFILE "TIMTRANA = $timtrana / [s] Transfer time after exposure\n";
  print HDFILE "EXPDEADB = $expdeadb / [s] Deadtime before exposure\n";
  print HDFILE "EXPDEADA = $expdeada / [s] Deadtime after exposure\n";
  print HDFILE "FLUSHIMB = $flushimb / [s] Flush out time\n";
  print HDFILE "LASTDEAD = $lastdead / [s] Last Deadtime after exposure\n";
  print HDFILE "LASTDEL = $lastdel / [s] Last Integration time in exposure\n";
  print HDFILE "NOMEXPO = $nomexpo / [s] period of seq start time\n";
  print HDFILE "TIMEPIXR = $timepixr / Bintime start=0 middle=0.5 end=1\n";
  close HDFILE;

  return 0;

}

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

# 
# Description: 
#
# Return the frame timing parameters for a given DATAMODE
#
# Parameters:
# [in]  datamode    Datamode for specified row
# [out] timedel     Integration time [s]
# [out] timtranb    Transfer time before exposure [s]
# [out] timtrana    Transfer time after exposure [s]
# [out] expdeadb    Deadtime before exposure [s]
# [out] expdeada    Deadtime after exposure [s]
# [out] flushimb    Flush out time [s]
# [out] lastdead    Last deadtime after exposure [s]
# [out] lastdel     Last integration time in exposure [s]
# [out] nomexpo     Period of seq start time [s]
# [out] timpixr     Bin time start=0 middle=0.5 end=1
# [out] status      Return 0 for success
#
sub getTimingParams ($$$$$$$$$$$) {
  
  my $datamode = shift;
  my $timedel  = shift;
  my $timtranb = shift;
  my $timtrana = shift;
  my $expdeadb = shift;
  my $expdeada = shift;
  my $flushimb = shift;
  my $lastdead = shift;
  my $lastdel  = shift;
  my $nomexpo  = shift;
  my $timpixr  = shift;

  my $status = 0;

  # 2015-11-04: Values were taken from Hayashida-san table, given in
  # v0.26 of SXI instrument document.
  # Note that TIMEPIXR should be 0., not 0.5 as initially written to the FFF files
  if( uc $datamode eq "WINDOW1" ) {
    $$timedel  = 3.963136;
    $$timtranb = 0.036864;
    $$timtrana = 0.;
    $$expdeadb = 0.;
    $$expdeada = 0.;
    $$flushimb = 0.;
    $$lastdead = 0.;
    $$lastdel  = 0.;
    $$nomexpo  = 4.;
    $$timpixr  = 0.;
  } elsif( uc $datamode eq "WINDOW1BURST" ) {
    $$timedel  = 1.9395648;
    $$timtranb = 0.;
    $$timtrana = 0.036864;
    $$expdeadb = 1.9865664;
    $$expdeada = 0.0001408;
    $$flushimb = 0.036864;
    $$lastdead = 0.;
    $$lastdel  = 0.;
    $$nomexpo  = 4.;
    $$timpixr  = 0.;
  } elsif( uc $datamode eq "WINDOW2" ) {
    $$timedel  = 0.4631184;
    $$timtranb = 0.036864;
    $$timtrana = 0.;
    $$expdeadb = 0.;
    $$expdeada = 0.;
    $$flushimb = 0.;
    $$lastdead = 0.;
    $$lastdel  = 0.4632592;
    $$nomexpo  = 4.;
    $$timpixr  = 0.;
  } elsif( uc $datamode eq "WINDOW2BURST" ) {
    $$timedel  = 0.0605952;
    $$timtranb = 0.;
    $$timtrana = 0.036864;
    $$expdeadb = 0.3633408;
    $$expdeada = 0.0023184;
    $$flushimb = 0.036864;
    $$lastdead = 0.0024592;
    $$lastdel  = 0.0605952;
    $$nomexpo  = 4.;
    $$timpixr  = 0.;
  } else {
    # unrecognized DATAMODE
    return 1;
  }

  return 0;

}

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

# 
# Description: 
#
# Write to the data description file 
#
# Parameters:
# [in] dtfile      ASCII file to write the row information to
# [in] start       START column value
# [in] stop        STOP column value
# [in] framenum    FRAMENUM column value
# [out] status     Return 0 for successful creation of merged event file
#
sub writeGTIRow ($$$$) {

  my $dtfile = shift;
  my $start = shift;
  my $stop = shift;
  my $framenum = shift;

  # Print to the data file
  open DTFILE, ">>", $dtfile;
  print DTFILE "$start $stop $framenum\n";
  close DTFILE;

  return 0;
}

# ------------------------------------------------------------------------------
#
# $Log: sximodegti.pl,v $
# Revision 1.16  2016/04/19 16:46:05  klrutkow
# changed DATACLASS to DATACTLM column (but include capability to still work with DATACLASS)
#
# Revision 1.15  2016/03/28 06:54:09  klrutkow
# removed area discrimination dependence
#
# Revision 1.14  2016/03/24 18:03:32  mdutka
# addressing items listed in issue #610
#
# Revision 1.13  2016/01/28 14:58:14  asargent
# Sorted keys alphabetically to maintain order in the output files.
#
# Revision 1.12  2015/12/31 22:28:39  asargent
# Removed re-writing of GTI extension name from sximodegti if there is only one GTI file to be morged (this is now done in the ahfilterlib module)
#
# Revision 1.11  2015/12/09 16:05:10  asargent
# Use exposure file TSTART/TSTOP if parameter tstart/tstop are out of range.
#
# Revision 1.10  2015/12/04 22:14:55  asargent
# Updated output file extension names. Added HDUCLASS and HDUCLAS1 to header keyword list.
#
# Revision 1.9  2015/12/04 20:02:19  asargent
# Remove copying of ADOU0ENA keyword from condensed GTI file.
#
# Revision 1.8  2015/12/04 15:21:11  asargent
# Updated cphead keyfil to not append
#
# Revision 1.7  2015/12/04 03:08:10  asargent
# Added new output parameter counting total number of gti dataclasses. Merged dataclasses into single gti
#
# Revision 1.6  2015/11/24 15:25:56  asargent
# Update TSTART/TSTOP to be the first start/last stop in the GTI extension.
#
#
