#! /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/sxipipeline.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/sxipipeline.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/sxipipeline.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: sxipipeline.pl # Author: A. J. Sargent NASA GSFC # $Date: 2016/05/31 19:38:23 $ # Version: 0 # # Calibrate sxi data # # Tool Dependencies: # # Library Dependencies: # gen/lib/perl/ahlog # gen/lib/perl/ahapp # gen/lib/perl/ahgen # gen/lib/perl/ahfilterlib # gen/tasks/ahpipeline/ahpllib # # Modification History: # # Set up use strict; use warnings; use File::Find; use File::Spec::Functions; use File::Basename; use File::Copy; use File::Path; use Cwd 'abs_path'; use POSIX qw(strftime); use ahlog ; use ahapp ; use ahgen qw (:ALL) ; use ahfilterlib ; use ahpllib qw (:ALL); # turn on AUTOFLUSH $| = 1; ######################### # Variable Definitions ######################### our %Params = ( indir => "", # "Input Directory" outdir => "", # "Output Directory" steminputs => "", # "Stem for input files name" stemoutputs => "", # "Stem for output files name" instrument => "sxi", # "Which instrument" verify_input => 0, # Verify the input files before processing? attitude => "", # "Attitude file" housekeeping => "", # "Housekeeping file" extended_housekeeping=> "", # "Extended housekeeping file" makefilter => "", # "Makefilter file, comma seperated list for multiple files" orbit => "", # "Orbit file, comma seperated list for multiple files" timfile => "", # "Time file, comma seperated list for multiple files" obsgti => "", # "Time file, comma seperated list for multiple files" sxi_start => 0, # "SXI CALDB start time" ra => -999.99999, # RA of nominal pointing [deg] dec => -999.99999, # Dec of nominal pointing [deg] roll => 0, # Roll of nominal pointing [deg] optdetx => -999.99999, # SXI optical detx coordinate optdety => -999.99999, # SXI optical dety coordinate optfocx => -999.99999, # SXI optical focx coordinate optfocy => -999.99999, # SXI optical focy coordinate optskyx => -999.99999, # SXI optical skyx coordinate optskyy => -999.99999, # SXI optical skyy coordinate ra_pnt => -999.99999, # RA of sxi pointing [deg] dec_pnt => -999.99999, # Dec of sxi pointing [deg] entry_stage => 1, # exit_stage => 1, # stage1_switch => 0, # stage2_switch => 0, # stage3_switch => 0, # numerrs => 0, # ); our %files = ( attitude => "", housekeeping => "", extended_housekeeping => "", makefilter => "", orbit => "", obsgti => "", regionfile => "", event_uf => [], event_cl => [], hpix => [], fpix => [], telgti => "", exposure => "", modegti => "", seggti => "", ); our $zpatt = qr/(\.Z|\.z|\.gzip|\.GZIP|\.gz|\.GZ|\.zip\.ZIP)?/; our %patterns = ( mission => qr/ah/, sequence => qr/[0-9]{1,9}/, event_uf => qr/(sxi_[ps][0-9][0-9a-f]{8}_uf\.evt)$zpatt$/, event_cl => qr/(sxi_[ps][0-9][0-9a-f]{8}_cl\.evt)$zpatt$/, hpix => qr/(sxi_a0[0-9a-f]{8}\.hpix)$zpatt$/, fpix => qr/(sxi_[psa][0-9][0-9a-f]{8}\.fpix)$zpatt$/, exposure => qr/(sxi_a0exp\.fits)$zpatt$/, modegti => qr/(sxi_mode\.gti)$zpatt$/, telgti => qr/(sxi_tel\.gti)$zpatt$/, ); my $pipelineerror = 0; # sxipipeline exit status our @filelist_output; our @error_output; # Use this comparison function for numeric sorting. sub numerically { $a <=> $b; } ######################### # Main Code Block ######################### ahapp::startup () ; ahapp::begin_processing () ; # Reset the numerrs parameters $Params{numerrs} = 0; ahgen::run_ftool("pset","sxipipeline","numerrs=0"); $pipelineerror = get_parameters () ; unless ( $pipelineerror == 0 ) { $Params{numerrs} += 1; push @error_output, "get_parameters failed"; ahlog::ah_err "get_parameters" ; ahapp::end_processing($pipelineerror); } $pipelineerror = initialize () ; unless ( $pipelineerror == 0 ) { $Params{numerrs} += 1; push @error_output, "initialize failed"; ahlog::ah_err "initialize" ; ahapp::end_processing($pipelineerror); } $pipelineerror = do_work () ; unless ( $pipelineerror == 0 ) { $Params{numerrs} += 1; push @error_output, "do_work failed"; ahlog::ah_err "do_work" ; ahapp::end_processing($pipelineerror); } $pipelineerror = finalize () ; unless ( $pipelineerror == 0 ) { $Params{numerrs} += 1; push @error_output, "finalize failed"; ahlog::ah_err "finalize" ; ahapp::end_processing($pipelineerror); } # We're done. ahapp::end_processing($pipelineerror); ######################### # Subroutines ######################### # ------------------------------------------------------------------------------ sub get_parameters { # Run tool parameters # These are hidden, so we can check these first # input file pars # Required parameters $Params{indir} = ahapp::query_parameter("indir"); $Params{outdir} = ahapp::query_parameter("outdir"); $Params{steminputs} = ahapp::query_parameter("steminputs"); $Params{stemoutputs} = ahapp::query_parameter("stemoutputs"); $Params{entry_stage} = ahapp::query_parameter("entry_stage"); $Params{exit_stage} = ahapp::query_parameter("exit_stage"); # Before we get the rest of the parameters, check the entry # and exit stages if (CheckEntryExitStage($Params{entry_stage},$Params{exit_stage})) { return 1; } # Set up the entry and exit stage flags $Params{stage1_switch} = 0; $Params{stage2_switch} = 0; $Params{stage3_switch} = 0; if ( $Params{entry_stage} == 1 ) { $Params{stage1_switch} = 1; $Params{stage2_switch} = 1; $Params{stage3_switch} = 1; } if ( $Params{entry_stage} == 2 ) { $Params{stage2_switch} = 1; $Params{stage3_switch} = 1; } if ( $Params{entry_stage} == 3 ) { $Params{stage3_switch} = 1; } if ( $Params{exit_stage} == 1 ) { $Params{stage2_switch} = 0; $Params{stage3_switch} = 0; } if ( $Params{exit_stage} == 2 ) { $Params{stage3_switch} = 0; } # Check that we are doing something unless ( $Params{stage1_switch} or $Params{stage2_switch} or $Params{stage3_switch} ) { ahlog::ah_err "Nothing to do."; return 1; } $Params{attitude} = ahapp::query_parameter("attitude"); $Params{makefilter} = ahapp::query_parameter("makefilter"); $Params{extended_housekeeping} = ahapp::query_parameter("extended_housekeeping"); $Params{orbit} = ahapp::query_parameter("orbit"); $Params{obsgti} = ahapp::query_parameter("obsgti"); $Params{housekeeping} = ahapp::query_parameter("housekeeping"); $Params{regionfile} = ahapp::query_parameter("regionfile"); $Params{sxi_start} = ahapp::query_parameter("sxi_start"); # CALDB files $Params{leapsecfile} = ahapp::query_parameter("leapsecfile"); $Params{selectfile} = ahapp::query_parameter("selectfile"); $Params{calc_modegti} = ahapp::query_parameter("calc_modegti",1); $Params{sxi_mkflabel} = ahapp::query_parameter("sxi_mkflabel"); $Params{sxi_ehklabel} = ahapp::query_parameter("sxi_ehklabel"); $Params{sxi_evtlabel} = ahapp::query_parameter("sxi_evtlabel"); # Coordinate parameters $Params{ra} = ahapp::query_parameter("ra"); $Params{dec} = ahapp::query_parameter("dec"); $Params{roll} = ahapp::query_parameter("roll"); $Params{optdetx} = ahapp::query_parameter("optdetx"); $Params{optdety} = ahapp::query_parameter("optdety"); $Params{optfocx} = ahapp::query_parameter("optfocx"); $Params{optfocy} = ahapp::query_parameter("optfocy"); $Params{optskyx} = ahapp::query_parameter("optskyx"); $Params{optskyy} = ahapp::query_parameter("optskyy"); $Params{ra_pnt} = ahapp::query_parameter("ra_pnt"); $Params{dec_pnt} = ahapp::query_parameter("dec_pnt"); # ahapp returns cleanup as yes/no $Params{cleanup} = ahapp::query_parameter("cleanup",1); if ( $Params{stage1_switch} ) { # If we aren't calibrating events, finding tool parameters # can significantly slow down the pipeline script # CALDB files $Params{teldeffile} = ahapp::query_parameter("teldeffile"); $Params{badpixfile} = ahapp::query_parameter("badpixfile"); $Params{maskfile} = ahapp::query_parameter("maskfile"); $Params{vtevnoddfile} = ahapp::query_parameter("vtevnoddfile"); $Params{chtrailfile} = ahapp::query_parameter("chtrailfile"); $Params{ctifile} = ahapp::query_parameter("ctifile"); $Params{spthfile} = ahapp::query_parameter("spthfile"); $Params{gainfile} = ahapp::query_parameter("gainfile"); $Params{patternfile} = ahapp::query_parameter("patternfile"); $Params{calc_hotpix} = ahapp::query_parameter("calc_hotpix",1); # Shared pars $Params{timecol} = ahapp::query_parameter("timecol"); $Params{seed} = ahapp::query_parameter("seed"); # coordevt pars $Params{dattfile} = ahapp::query_parameter("dattfile"); $Params{startsys} = ahapp::query_parameter("coordevt_startsys"); $Params{stopsys} = ahapp::query_parameter("stopsys"); $Params{annaber} = ahapp::query_parameter("annaber"); $Params{followsun} = ahapp::query_parameter("followsun"); $Params{orbaber} = ahapp::query_parameter("orbaber"); $Params{attinterp} = ahapp::query_parameter("attinterp"); $Params{dattinterp} = ahapp::query_parameter("dattinterp"); $Params{attdt} = ahapp::query_parameter("attdt"); $Params{dattdt} = ahapp::query_parameter("dattdt"); $Params{chkattgap} = ahapp::query_parameter("chkattgap"); $Params{chkdattgap} = ahapp::query_parameter("chkdattgap"); $Params{attext} = ahapp::query_parameter("attext"); $Params{attcol} = ahapp::query_parameter("attcol"); $Params{attform} = ahapp::query_parameter("attform"); $Params{orbext} = ahapp::query_parameter("orbext"); $Params{orbcol} = ahapp::query_parameter("orbcol"); $Params{orbform} = ahapp::query_parameter("orbform"); $Params{coordevt_randomize} = ahapp::query_parameter("coordevt_randomize"); $Params{randsys} = ahapp::query_parameter("randsys"); $Params{randscalesys} = ahapp::query_parameter("randscalesys"); $Params{infileext} = ahapp::query_parameter("infileext"); $Params{inclfloatcol} = ahapp::query_parameter("inclfloatcol"); $Params{inclfloatskycol} = ahapp::query_parameter("inclfloatskycol"); $Params{floatcolsuffix} = ahapp::query_parameter("floatcolsuffix"); $Params{startwithfloat} = ahapp::query_parameter("startwithfloat"); $Params{blankcol} = ahapp::query_parameter("blankcol"); $Params{btnull} = ahapp::query_parameter("btnull"); $Params{itnull} = ahapp::query_parameter("itnull"); $Params{jtnull} = ahapp::query_parameter("jtnull"); $Params{ktnull} = ahapp::query_parameter("ktnull"); $Params{sbtnull} = ahapp::query_parameter("sbtnull"); $Params{uitnull} = ahapp::query_parameter("uitnull"); $Params{ujtnull} = ahapp::query_parameter("ujtnull"); # sximodegti # sxiphas $Params{colbound} = ahapp::query_parameter("colbound"); # searchflickpix $Params{chipcol} = ahapp::query_parameter("chipcol"); $Params{xcol} = ahapp::query_parameter("xcol"); $Params{ycol} = ahapp::query_parameter("ycol"); $Params{chancol} = ahapp::query_parameter("chancol"); $Params{gradecol} = ahapp::query_parameter("gradecol"); $Params{grade} = ahapp::query_parameter("grade"); $Params{n_division} = ahapp::query_parameter("n_division"); $Params{cleanimg} = ahapp::query_parameter("cleanimg"); $Params{cellsize} = ahapp::query_parameter("cellsize"); $Params{impfac} = ahapp::query_parameter("impfac"); $Params{logprob1} = ahapp::query_parameter("logprob1"); $Params{logprob2} = ahapp::query_parameter("logprob2"); $Params{iterate} = ahapp::query_parameter("iterate"); $Params{flagedge} = ahapp::query_parameter("flagedge"); $Params{bthresh} = ahapp::query_parameter("bthresh"); $Params{duration} = ahapp::query_parameter("duration"); $Params{sigma} = ahapp::query_parameter("sigma"); $Params{firstchip} = ahapp::query_parameter("firstchip"); $Params{lastchip} = ahapp::query_parameter("lastchip"); $Params{xmin} = ahapp::query_parameter("xmin"); $Params{xmax} = ahapp::query_parameter("xmax"); $Params{ymin} = ahapp::query_parameter("ymin"); $Params{ymax} = ahapp::query_parameter("ymax"); $Params{chanmin} = ahapp::query_parameter("chanmin"); $Params{chanmax} = ahapp::query_parameter("chanmax"); # sxiflagpix $Params{outbadpix} = ahapp::query_parameter("outbadpix",1); $Params{outbadimg} = ahapp::query_parameter("outbadimg",1); $Params{npixnbr} = ahapp::query_parameter("npixnbr"); $Params{nboundnbr} = ahapp::query_parameter("nboundnbr"); $Params{citrailnbr} = ahapp::query_parameter("citrailnbr"); $Params{ciprenbr} = ahapp::query_parameter("ciprenbr"); $Params{bad_status} = ahapp::query_parameter("bad_status"); $Params{copyphas} = ahapp::query_parameter("copyphas"); $Params{resetflags} = ahapp::query_parameter("resetflags"); # sxipi $Params{hkext} = ahapp::query_parameter("hkext"); $Params{hkcolstem} = ahapp::query_parameter("hkcolstem"); $Params{hkvideoid} = ahapp::query_parameter("hkvideoid"); $Params{startcol} = ahapp::query_parameter("startcol"); $Params{evnoddcor} = ahapp::query_parameter("evnoddcor"); $Params{chtrailcor} = ahapp::query_parameter("chtrailcor"); $Params{cticor} = ahapp::query_parameter("cticor"); $Params{gaincor} = ahapp::query_parameter("gaincor"); $Params{ctigrade} = ahapp::query_parameter("ctigrade"); $Params{copygrade} = ahapp::query_parameter("copygrade"); $Params{phcut} = ahapp::query_parameter("phcut"); $Params{badpixopt} = ahapp::query_parameter("badpixopt"); $Params{spthiter} = ahapp::query_parameter("spthiter"); $Params{spthcaldb} = ahapp::query_parameter("spthcaldb"); $Params{spthoffset} = ahapp::query_parameter("spthoffset"); $Params{spthslope} = ahapp::query_parameter("spthslope"); $Params{evtthre} = ahapp::query_parameter("evtthre"); $Params{negthre} = ahapp::query_parameter("negthre"); $Params{deltatime} = ahapp::query_parameter("deltatime"); $Params{debugcol} = ahapp::query_parameter("debugcol"); $Params{randomize} = ahapp::query_parameter("randomize"); } if (uc($Params{stemoutputs}) eq "DEFAULT") { $Params{stemoutputs} = $Params{steminputs}; } # Set output report name $Params{stemoutputs} =~ s/^\s+//; # Remove leading blanks $Params{stemoutputs} =~ s/\s+$//; # Remove trailing blanks # Get the stem for log files and temporary files $Params{stemreport} = ahapp::query_parameter("stemreport"); # If the report stem parameter is empty, create a new one if ( $Params{stemreport} ) { # Create temporary and log file name stems $Params{tempstem} = $Params{stemreport} . "_tmp_"; $Params{logstem} = $Params{stemreport} . "_"; } else { # Set the date string in the format YYYYMMDDTHHMMSS my $taskstart = strftime "%Y%m%dT%H%M%S", localtime ; # Create temporary and log file name stems $Params{tempstem} = "sxipipeline_" . $taskstart . "_tmp_"; $Params{logstem} = "sxipipeline_" . $taskstart . "_"; } return 0; } # ------------------------------------------------------------------------------ sub initialize { my $status=0; my $indir = $Params{indir}; my $outdir = $Params{outdir}; my $steminputs = $Params{steminputs}; my $stemoutputs = $Params{stemoutputs}; my $inst = $Params{instrument}; my $attitude = $Params{attitude}; my $makefilter = $Params{makefilter}; my $extended_housekeeping = $Params{extended_housekeeping}; my $orbit = $Params{orbit}; my $housekeeping = $Params{housekeeping}; my $obsgti = $Params{obsgti}; my $regionfile = $Params{regionfile}; # Check the input and output directories if (CheckInputDirectory($indir,$outdir)) { return 1; }; if (CheckOutputDirectory($outdir)) { return 1; }; # Find and store the list of input files @{$files{event_uf}} = FindInputFiles($indir,$steminputs , $patterns{event_uf}); @{$files{event_cl}} = FindInputFiles($indir,$steminputs , $patterns{event_cl}); @{$files{hpix}} = FindInputFiles($indir,$steminputs , $patterns{hpix}); ($files{exposure}) = FindInputFiles($indir,$steminputs , $patterns{exposure}); ($files{modegti}) = FindInputFiles($indir,$steminputs , $patterns{modegti}); ($files{telgti}) = FindInputFiles($indir,$steminputs , $patterns{telgti}); # Check the input CALDB files if ( $Params{stage1_switch} ) { # Check for file requirements if (isOptionalFileNotFound($attitude)) { return 1; } if (isOptionalFileNotFound($orbit)) { return 1; } if (isOptionalFileNotFound($housekeeping)) { return 1; } if (isRequiredFileNotFound($obsgti)) { return 1; } # Store the required input files $files{attitude} = $attitude; $files{orbit} = $orbit; $files{obsgti} = $obsgti; $files{housekeeping} = $housekeeping; if (isBadCALDBFileParameterValue($Params{teldeffile},"teldeffile")) { return 1;} if (isBadCALDBFileParameterValue($Params{badpixfile},"badpixfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{maskfile},"maskfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{vtevnoddfile},"vtevnoddfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{ctifile},"ctifile")) { return 1;} if (isBadCALDBFileParameterValue($Params{chtrailfile},"chtrailfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{spthfile},"spthfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{gainfile},"gainfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{patternfile},"patternfile")) { return 1;} if ( uc $Params{stopsys} eq "HIGHEST" and uc $files{attitude} eq "NONE" ) { ahlog::ah_info "HIGH","No input ATTITUDE file. Setting stopsys as FOC"; $Params{stopsys} = "FOC"; } if ( uc $files{orbit} eq "NONE" ) { ahlog::ah_info "HIGH","No input ORBIT file"; } if ( uc $files{housekeeping} eq "NONE" ) { ahlog::ah_info "HIGH","No input HOUSEKEEPING file. Setting evnoddcor as no"; $Params{evnoddcor} = "no"; } } if ( $Params{stage2_switch} ) { # Check for file requirements if (isRequiredFileNotFound($obsgti)) { return 1; } if (isRequiredFileNotFound($makefilter)) { return 1; } if (isRequiredFileNotFound($extended_housekeeping)) { return 1; } $files{obsgti} = $obsgti; $files{makefilter} = $makefilter; $files{extended_housekeeping} = $extended_housekeeping; if (isBadCALDBFileParameterValue($Params{leapsecfile},"leapsecfile")) { return 1;} if (isBadCALDBFileParameterValue($Params{selectfile},"selectfile")) { return 1;} if (isRequiredFileNotFound($files{makefilter})) { return 1; } if (isRequiredFileNotFound($files{extended_housekeeping})) { return 1; } } if ( $Params{stage3_switch} ) { $files{regionfile} = $regionfile; if (isOptionalFileNotFound($files{regionfile})) { return 1; } } # Search for required files for each step # Check that we found a list of unfiltered event files if ( $Params{stage1_switch} or $Params{stage2_switch} ) { unless ( @{$files{event_uf}} ) { ahlog::ah_err "Cannot find any $inst event files in $indir" ; return 1; } unless ( $files{telgti} ) { ahlog::ah_err "Cannot find any $inst telemetry GTI files in $indir" ; return 1; } } # For cleaning events, mode GTI is required # Check whether we are calculating SXI GTI from the exposure # or using an input GTI if( $Params{stage2_switch} ) { # Check that we have a valid label for SXI # If not, throw an error if ( $Params{sxi_mkflabel} !~ /#/ or $Params{sxi_ehklabel} !~ /#/ or $Params{sxi_evtlabel} !~ /#/ ) { ahlog::ah_err " *** Not a valid label for SXI. Label requires '#'."; return 1; } if($Params{calc_modegti}) { unless ( $files{exposure} ) { ahlog::ah_err "Cannot find any $inst exposure files in $indir" ; return 1; } } else { unless ( $files{modegti} ) { ahlog::ah_err "Cannot find any $inst mode GTI files in $indir" ; return 1; } } } # If creating products and not cleaning events, input cleaned # event files required if( $Params{stage3_switch} and ! $Params{stage2_switch} ) { unless ( @{$files{event_cl}} ) { ahlog::ah_err "Cannot find any $inst event files in $indir" ; return 1; } } # Print a summary of the found files if ( ahgen::getdebug ) { ahlog::ah_debug "Attitude file = $files{attitude}\n" if $files{attitude}; ahlog::ah_debug "Orbit file = $files{orbit}\n" if $files{orbit}; ahlog::ah_debug "Housekeeping file = $files{housekeeping}\n" if $files{housekeeping}; ahlog::ah_debug "GTI file = $files{obsgti}\n" if $files{obsgti}; ahlog::ah_debug "Extended housekeeping file = $files{extended_housekeeping}\n" if $files{extended_housekeeping}; ahlog::ah_debug "Makefilter file = $files{makefilter}\n" if $files{makefilter}; ahlog::ah_debug "Region file = $files{regionfile}\n" if $files{regionfile}; ahlog::ah_debug "$inst unfiltered file(s) found:" if @{$files{event_uf}}; foreach my $filename ( sort @{$files{event_uf}} ) { ahlog::ah_debug " $filename\n"; } ahlog::ah_debug "$inst hot pixel file(s) found:" if @{$files{hpix}}; foreach my $filename ( sort @{$files{hpix}} ) { ahlog::ah_debug " $filename\n"; } ahlog::ah_debug "$inst cleaned file(s) found:" if @{$files{event_cl}}; foreach my $filename ( sort @{$files{event_cl}} ) { ahlog::ah_debug " $filename\n"; } if ( defined $files{exposure} ) { ahlog::ah_debug "$inst exposure file found:"; ahlog::ah_debug " $files{exposure}\n" ; } if ( defined $files{modegti} ) { ahlog::ah_debug "$inst modegti file found:"; ahlog::ah_debug " $files{modegti}\n" ; } } # Write all parameters to this script to the log file. ah_info "HIGH", ahapp::write_parameters () ; return 0; } # ------------------------------------------------------------------------------ sub do_work { my $status = 0; if ( $Params{stage1_switch} == 1 ) { $status = CalibrateEvents(); unless ( $status == 0 ) { ahlog::ah_err "CalibrateEvents" ; return $status; } } if ( $Params{stage2_switch} == 1 ) { $status = CleanEvents(); unless ( $status == 0 ) { ahlog::ah_err "CleanEvents" ; return $status; } } if ( $Params{stage3_switch} == 1 ) { $status = CreateProducts(); unless ( $status == 0 ) { ahlog::ah_err "CreateProducts" ; return $status; } } return 0; } # ------------------------------------------------------------------------------ sub CalibrateEvents { if ( ahlog::getdebug ) { ahlog::ah_debug "\nCalibrateEvents\n"; } my @calibrated_sxi_uf_evt_files = ( ); my @calibrated_sxi_hpix_files = ( ); my @calibrated_sxi_fpix_files = ( ); my @calibrated_sxi_fpix_pfiles = ( ); my @calibrated_sxi_fpix_sfiles = ( ); my @merged_sxi_fpix_files = ( ); my $status = 0; ############# setup parameters for each tool ############# my $calc_hotpix = $Params{calc_hotpix}; my $sxi_start = $Params{sxi_start}; my $cleanup = $Params{cleanup}; # Attitude/Orbit files my $attitude = $files{attitude}; my $orbit = $files{orbit}; my $obsgti = $files{obsgti}; # SXI files my $hkfile = $files{housekeeping}; # TSTART/TSTOP my @tstart = (); my @tstop = (); my %coordevt_pars_pointing = ( teldeffile => $Params{teldeffile}, attfile => $attitude, dattfile => $Params{dattfile}, orbfile => $orbit, startsys => $Params{startsys}, stopsys => $Params{stopsys}, annaber => $Params{annaber}, followsun => $Params{followsun}, orbaber => $Params{orbaber}, attinterp => $Params{attinterp}, dattinterp => $Params{dattinterp}, attdt => $Params{attdt}, dattdt => $Params{dattdt}, chkattgap => $Params{chkattgap}, chkdattgap => $Params{chkdattgap}, attext => $Params{attext}, attcol => $Params{attcol}, attform => $Params{attform}, orbext => $Params{orbext}, orbcol => $Params{orbcol}, orbform => $Params{orbform}, randomize => $Params{coordevt_randomize}, seed => $Params{seed}, randsys => $Params{randsys}, randscalesys => $Params{randscalesys}, infileext => $Params{infileext}, timecol => $Params{timecol}, inclfloatcol => $Params{inclfloatcol}, inclfloatskycol => $Params{inclfloatskycol}, floatcolsuffix => $Params{floatcolsuffix}, startwithfloat => $Params{startwithfloat}, blankcol => $Params{blankcol}, btnull => $Params{btnull}, itnull => $Params{itnull}, jtnull => $Params{jtnull}, ktnull => $Params{ktnull}, sbtnull => $Params{sbtnull}, uitnull => $Params{uitnull}, ujtnull => $Params{ujtnull}, ra => $Params{ra}, dec => $Params{dec}, roll => 0, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, ); my %coordevt_pars_slew = %coordevt_pars_pointing; $coordevt_pars_slew{stopsys} = "FOC"; my %coordevt_pars_hpix = %coordevt_pars_pointing; $coordevt_pars_hpix{stopsys} = "DET"; $coordevt_pars_hpix{infileext} = "HOTPIX"; my %coordevt_pars_fpix = %coordevt_pars_pointing; $coordevt_pars_fpix{startsys} = "ACT"; $coordevt_pars_fpix{stopsys} = "DET"; $coordevt_pars_fpix{infileext} = "PIXELS"; my %sxiphas_pars = ( colbound => $Params{colbound}, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, ); my %sxiflagpix_pars = ( outbadpix => "NONE", outbadimg => "NONE", badpixfile => $Params{badpixfile}, maskfile => $Params{maskfile}, npixnbr => $Params{npixnbr}, nboundnbr => $Params{nboundnbr}, citrailnbr => $Params{citrailnbr}, ciprenbr => $Params{ciprenbr}, bad_status => $Params{bad_status}, copyphas => $Params{copyphas}, resetflags => $Params{resetflags}, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, ); my %sxiflagpix_pars_run2 = %sxiflagpix_pars; $sxiflagpix_pars_run2{resetflags} = "no"; my %sxipi_pars = ( hkext => $Params{hkext}, hkcolstem => $Params{hkcolstem}, hkvideoid => $Params{hkvideoid}, vtevnoddfile => $Params{vtevnoddfile}, chtrailfile => $Params{chtrailfile}, ctifile => $Params{ctifile}, spthfile => $Params{spthfile}, gainfile => $Params{gainfile}, patternfile => $Params{patternfile}, startcol => $Params{startcol}, evnoddcor => $Params{evnoddcor}, chtrailcor => $Params{chtrailcor}, cticor => $Params{cticor}, gaincor => $Params{gaincor}, ctigrade => "no", copygrade => $Params{copygrade}, phcut => $Params{phcut}, badpixopt => $Params{badpixopt}, spthiter => $Params{spthiter}, spthcaldb => $Params{spthcaldb}, spthoffset => $Params{spthoffset}, spthslope => $Params{spthslope}, evtthre => $Params{evtthre}, negthre => $Params{negthre}, deltatime => $Params{deltatime}, debugcol => $Params{debugcol}, randomize => $Params{randomize}, seed => $Params{seed}, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, ); my %sxipi_pars_run2 = %sxipi_pars; $sxipi_pars_run2{ctigrade} = $Params{ctigrade}; my %searchflickpix_pars = ( chipcol => $Params{chipcol}, xcol => $Params{xcol}, ycol => $Params{ycol}, chancol => $Params{chancol}, gradecol => $Params{gradecol}, grade => $Params{grade}, n_division => $Params{n_division}, cleanimg => $Params{cleanimg}, cellsize => $Params{cellsize}, impfac => $Params{impfac}, logprob1 => $Params{logprob1}, logprob2 => $Params{logprob2}, iterate => $Params{iterate}, flagedge => $Params{flagedge}, bthresh => $Params{bthresh}, duration => $Params{duration}, sigma => $Params{sigma}, firstchip => $Params{firstchip}, lastchip => $Params{lastchip}, xmin => $Params{xmin}, xmax => $Params{xmax}, ymin => $Params{ymin}, ymax => $Params{ymax}, chanmin => $Params{chanmin}, chanmax => $Params{chanmax}, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, ); # Find the first and the last SXI files # due to file splitting. We want to attach a GTI extension to the output # event file if there is no GTI attached to the event file. # If there is a file split, the first file in time uses the # GTIPOINT TSTART to the event file TSTOP. Each subsequent file split # uses GTIPOINT between that file's TSTART/TSTOP # The last file in time uses TSTART from the event file and TSTOP from GTIPOINT # # Example: An event file is split three times. # GTIPOINT: |----------------------------------------------| # EVENTS : |-----------|--------------|--------------| # GTI1 : |-------------| # GTI2 : |--------------| # GTI3 : |-----------------| my $first_indx; my $last_indx; my $tstart_prev=0; my $tstop_prev=0; # Find the first and last indx for SXI foreach my $evtfile ( @{$files{event_uf}} ) { my $mode = find_file_mode($evtfile); my $indx = find_file_indx($evtfile); # Skip any slew file if ( lc $mode eq "s" ) { next; } if ( $indx == 0 ) { # If the indx is 0, then there is no file split # We can ignore the first and last indx $first_indx=0; $last_indx=0; next; } my $tstart = ahgen::get_keyword($evtfile,"EVENTS","TSTART"); unless ( defined $tstart ) { ahlog::ah_out"In file '$evtfile', could not read keyword TSTART"; ahlog::ah_out"Skipping file."; next; } my $tstop = ahgen::get_keyword($evtfile,"EVENTS","TSTOP"); unless ( defined $tstop ) { ahlog::ah_out"In file '$evtfile', could not read keyword TSTOP"; ahlog::ah_out"Skipping file."; next; } if ( $tstart_prev == 0 ) { $tstart_prev = $tstart; $first_indx = $indx;} if ( $tstop_prev == 0 ) { $tstop_prev = $tstop; $last_indx = $indx; } if ( $tstart < $tstart_prev ) { $tstart_prev = $tstart; $first_indx = $indx; } if ( $tstop > $tstop_prev ) { $tstop_prev = $tstop; $last_indx = $indx; } } ############# Calibrate each sxi file ############# ahlog::ah_out "Calibrating SXI events"; foreach my $sxifile ( sort @{$files{event_uf}} ) { ############# setup input/output files ############# # Set up input and output files my $hpix = find_hpix_file($sxifile); my $sxifile_out = form_outfile_name($sxifile); my $hpix_out = uc $hpix eq "NONE" ? $hpix : form_outfile_name($hpix); my $fpix = form_fpix_file($sxifile_out); # Set up the output bad pixel file and output bad img file names if ( $Params{outbadpix} ) { $sxiflagpix_pars_run2{outbadpix} = form_bpix_file($sxifile_out); } else { $sxiflagpix_pars_run2{outbadpix} = "NONE"; } if ( $Params{outbadimg} ) { $sxiflagpix_pars_run2{outbadimg} = form_img_file($sxifile_out); } else { $sxiflagpix_pars_run2{outbadimg} = "NONE"; } my $bpix_out = $sxiflagpix_pars_run2{outbadpix}; my $bpix_img = $sxiflagpix_pars_run2{outbadimg}; # Get basenames (for temporary files) and remove the extension my $basename = basename($sxifile_out); $basename =~ s/\.evt.*$//; my $basename_hpix = basename($hpix_out); $basename_hpix =~ s/\.hpix.*$/_hpix/; my $basename_fpix = basename($fpix); $basename_fpix =~ s/\.fpix.*$/_fpix/; # Determine the file index for this sxi file my $indx = find_file_indx($sxifile_out); # Skip the file if there are no events my $naxis2 = ahgen::get_keyword($sxifile,"EVENTS","NAXIS2"); unless ( defined $naxis2 ) { ahlog::ah_out"In file '$sxifile', could not read keyword NAXIS2"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (NAXIS2 not defined)"; $Params{numerrs} += 1; next; } unless ( $naxis2 ) { ahlog::ah_out"No events found in file '$sxifile'"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (NAXIS2=0)"; $Params{numerrs} += 1; next; } # read keywords TSTART, TSTOP, DATE-OBS, and OBSMODE my $tstart = ahgen::get_keyword($sxifile,"EVENTS","TSTART"); unless ( defined $tstart ) { ahlog::ah_out"In file '$sxifile', could not read keyword TSTART"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (TSTART not defined)"; $Params{numerrs} += 1; next; } my $tstop = ahgen::get_keyword($sxifile,"EVENTS","TSTOP"); unless ( defined $tstop ) { ahlog::ah_out"In file '$sxifile', could not read keyword TSTOP"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (TSTOP not defined)"; $Params{numerrs} += 1; next; } my $dateobs = ahgen::get_keyword($sxifile,"EVENTS","DATE-OBS"); unless ( defined $dateobs ) { ahlog::ah_out"In file '$sxifile', could not read keyword DATE-OBS"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (DATE-OBS not defined)"; $Params{numerrs} += 1; next; } my $obsmode = ahgen::get_keyword($sxifile,"EVENTS","OBS_MODE"); unless ( defined $obsmode ) { ahlog::ah_out"In file '$sxifile', could not read keyword OBS_MODE"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (OBS_MODE not defined)"; $Params{numerrs} += 1; next; } my $detnam = ahgen::get_keyword($sxifile,"EVENTS","DETNAM"); if(ahgen::get_error_flag()) { ahlog::ah_err "Could not get DETNAM keyword from $sxifile"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (DETNAM not defined)"; $Params{numerrs} += 1; next; } my $datamode = ahgen::get_keyword($sxifile,"EVENTS","DATAMODE"); unless ( defined $datamode ) { ahlog::ah_out"In file '$sxifile', could not read keyword DATAMODE"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile (DATAMODE not defined)"; $Params{numerrs} += 1; next; } # Save the tstart and tstop regardless of mode push @tstart, $tstart; push @tstop, $tstop; ahlog::ah_debug "Input File : $sxifile"; ahlog::ah_debug "Input hpix File : $hpix"; ahlog::ah_debug "Output File : $sxifile_out"; ahlog::ah_debug "Output hpix File : $hpix_out" unless $calc_hotpix; ahlog::ah_debug "Output fpix File : $fpix"; ahlog::ah_debug "tstart : $tstart"; ahlog::ah_debug "tstop : $tstop"; ahlog::ah_debug "dateobs: : $dateobs"; ahlog::ah_debug "obsmode: : $obsmode"; # can this file ($sxifile) be processed with the caldb files? if ( $tstop < $sxi_start ) { ahlog::ah_out"SXI input file $sxifile occurs before CALDB (sxi_start)"; ahlog::ah_out"SXI input file $sxifile will NOT be re-calibrated"; push @error_output, "Skipped file: $sxifile (sxi_start occurs before CALDB)"; $Params{numerrs} += 1; next; } ahlog::ah_out "Calibrating SXI file $sxifile"; my $tmpfile = ""; # Copy the infile(s) to the output file(s) if (copyFITSFile($sxifile,$sxifile_out)) { return 1; } if ( uc $hpix_out ne "NONE" ) { if(copyFITSFile($hpix,$hpix_out)) { return 1; } } # Perform coordevt calculation on hotpix file if( uc $hpix ne "NONE" ) { ahlog::ah_out "Running coordevt on file $hpix_out"; $tmpfile = $Params{tempstem} . $basename_hpix . "_coordevt.hpix"; ahapp::add_temp_file($tmpfile); $coordevt_pars_hpix{logfile} = $Params{logstem} . $basename_hpix . "_coordevt.log"; $status = run_coordevt($hpix_out,$tmpfile,\%coordevt_pars_hpix); if ( $status ) { ahlog::ah_err "coordevt failed"; return 1; } if(copyFITSFile($tmpfile,$hpix_out)) { return 1; } } else { # Use the input hpix file if not calculating coordinates $hpix_out = $hpix; } # COORDEVT (events) ahlog::ah_out "Running coordevt on file $sxifile_out"; my %coordevt_pars; if( uc $obsmode eq "POINTING" ) { %coordevt_pars = %coordevt_pars_pointing; } else { %coordevt_pars = %coordevt_pars_slew; } $tmpfile = $Params{tempstem} . $basename . "_coordevt.evt"; ahapp::add_temp_file($tmpfile); $coordevt_pars{logfile} = $Params{logstem} . $basename . "_coordevt.log"; $status = ahpllib::run_coordevt($sxifile_out,$tmpfile,\%coordevt_pars); if ( $status ) { ahlog::ah_err "coordevt failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # SXIPHAS ahlog::ah_out "Running sxiphas on file $sxifile_out"; $tmpfile = $Params{tempstem} . $basename . "_sxiphas.evt"; ahapp::add_temp_file($tmpfile); $sxiphas_pars{logfile} = $Params{logstem} . $basename . "_sxiphas.log"; $status = run_sxiphas($sxifile_out,$tmpfile,\%sxiphas_pars); if ( $status ) { ahlog::ah_err "sxiphas failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # SXIFLAGPIX (1) ahlog::ah_out "Running sxiflagpix (1) on file $sxifile_out"; $tmpfile = $Params{tempstem} . $basename . "_sxiflagpix_1.evt"; ahapp::add_temp_file($tmpfile); $sxiflagpix_pars{logfile} = $Params{logstem} . $basename . "_sxiflagpix_1.log"; $status = run_sxiflagpix($sxifile_out,$tmpfile,$hpix_out,"NONE",\%sxiflagpix_pars); if ( $status ) { ahlog::ah_err "sxiflagpix failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # SXIPI (1) ahlog::ah_out "Running sxipi (1) on file $sxifile_out"; $tmpfile = $Params{tempstem} . $basename . "_sxipi_1.evt"; ahapp::add_temp_file($tmpfile); $sxipi_pars{logfile} = $Params{logstem} . $basename . "_sxipi_1.log"; $status = run_sxipi($sxifile_out,$tmpfile,$hkfile,\%sxipi_pars); if ( $status ) { ahlog::ah_err "sxipi failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # SXIPI (2) ahlog::ah_out "Running sxipi (2) on file $sxifile_out"; $tmpfile = $Params{tempstem} . $basename . "_sxipi_2.evt"; ahapp::add_temp_file($tmpfile); $sxipi_pars_run2{logfile} = $Params{logstem} . $basename . "_sxipi_2.log"; $status = run_sxipi($sxifile_out,$tmpfile,$hkfile,\%sxipi_pars_run2); if ( $status ) { ahlog::ah_err "sxipi failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # Extract events and find flickering pixels ahlog::ah_out "Extracting STATUS[1]==b0 from $sxifile_out"; my $sxifile_fl = $Params{tempstem} . $basename . "_filtered.evt"; ahapp::add_temp_file($sxifile_fl); $status = run_ftselect($sxifile_out,"EVENTS",$sxifile_fl,"STATUS[1]==b0"); if ( $status ) { ahlog::ah_out "No events to create flickering pixels file."; } # SEARCHFLICKPIX ahlog::ah_out "Running searchflickpix on file $sxifile_fl"; $searchflickpix_pars{logfile} = $Params{logstem} . $basename_fpix . "_searchflickpix.log"; $status = run_searchflickpix($sxifile_fl,$fpix,\%searchflickpix_pars); if ( $status ) { ahlog::ah_err "searchflickpix failed"; return 1; } # COORDEVT (flickering pixels) ahlog::ah_out "Running coordevt on file $fpix"; $tmpfile = $Params{tempstem} . $basename_fpix . "_coordevt.fpix"; ahapp::add_temp_file($tmpfile); $coordevt_pars_fpix{logfile} = $Params{logstem} . $basename_fpix . "_coordevt.log"; $status = run_coordevt($fpix,$tmpfile,\%coordevt_pars_fpix); if ( $status ) { ahlog::ah_err "coordevt failed"; return 1; } if(copyFITSFile($tmpfile,$fpix)) { return 1; } # SXIFLAGPIX (2) ahlog::ah_out "Running sxiflagpix (2) on file $sxifile_out"; $tmpfile = $Params{tempstem} . $basename . "_sxiflagpix_2.evt"; ahapp::add_temp_file($tmpfile); $sxiflagpix_pars_run2{logfile} = $Params{logstem} . $basename . "_sxiflagpix_2.log"; $status = run_sxiflagpix($sxifile_out,$tmpfile,$hpix_out,$fpix,\%sxiflagpix_pars_run2); if ( $status ) { ahlog::ah_err "sxiflagpix failed"; return 1; } if(copyFITSFile($tmpfile,$sxifile_out)) { return 1; } # Attach GTI due to file splitting if there is no GTI already attached. # We want to attach a GTI extension to the output # event file if there is no GTI attached to the event file. # If there is a file split, the first file in time uses the # GTIPOINT TSTART to the event file TSTOP. Each subsequent file split # uses GTIPOINT between that file's TSTART/TSTOP # The last file in time uses TSTART from the event file and TSTOP from GTIPOINT # # Example: An event file is split three times. # GTIPOINT: |----------------------------------------------| # EVENTS : |-----------|--------------|--------------| # GTI1 : |-------------| # GTI2 : |--------------| # GTI3 : |-----------------| if ( ! ahgen::check_hdu_exists($sxifile,"GTI") ) { ahlog::ah_out "Attaching GTI to file $sxifile_out"; # Get the GTI for this file split (mode and slew) # We want to make sure that the first STOP is greater than TSTART of the events # and that the last START is less than TSTOP of the events my $cutgti = $Params{tempstem} . $basename . "_split.gti"; ahapp::add_temp_file($cutgti); my $gtiext = ""; if ( uc $obsmode eq 'SLEW' ) { $gtiext = "GTISLEW"; # Attach updated GTI to SFFa # No GTI attached to sff, expanded, recgain $status = copy_hdu($obsgti,"GTISLEW][col #EXTNAME=\"GTI\"", $sxifile_out); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } else { # Attach the GTI to the reconstructed event file if ( $indx == 0 ) { # Attach directly the GTIPOINT if there is no file splitting # Change the extension name from GTIPOINT to GTI $status = copy_hdu($obsgti,"GTIPOINT][col #EXTNAME=\"GTI\"", $sxifile_out); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } else { # Get the GTI for this file split # We want to make sure that the first STOP is greater than TSTART of the events # and that the last START is less than TSTOP of the events if ( $indx == $first_indx ) { # Bound the GTIPOINT to the tstop of the event file $status = copy_hdu($obsgti,"GTIPOINT][START<$tstop][col #EXTNAME=\"GTI\"", $cutgti); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } elsif ( $indx == $last_indx ) { # Bound the GTIPOINT to the tstart of the event file $status = copy_hdu($obsgti,"GTIPOINT][STOP>$tstart][col #EXTNAME=\"GTI\"", $cutgti); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } else { # Bound the GTIPOINT to the tstart/tstop of the event file $status = copy_hdu($obsgti,"GTIPOINT][STOP>$tstart&&START<$tstop][col #EXTNAME=\"GTI\"",$cutgti); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } my $lastrow = ahgen::get_keyword($cutgti,"GTI","NAXIS2"); unless ( defined $lastrow ) { ahlog::ah_out"In file '$cutgti\[GTI]', could not read keyword NAXIS2"; ahlog::ah_out"Skipping file."; push @error_output, "Error in file: $sxifile (Could not append GTI)"; $Params{numerrs} += 1; next; } # If the indx is not the first, use the TSTART of GTIPOINT # Otherwise use the TSTART of the event file if ( $indx != $first_indx ) { # Make sure that the first START == TSTART $status = ahgen::run_ftool('ftedit', "infile=$cutgti\[GTI]","column=START", "row=1","value=$tstart"); if ($status) { ahlog::ah_err "ftedit failed."; return $status; } # Update TSTART and TSTOP keywords to match GTI file ahgen::set_keyword( $cutgti, "GTI", 'TSTART' , $tstart ) ; } # If the indx is not the last, use the TSTOP of GTIPOINT if ( $indx != $last_indx ) { # Make sure that the last STOP == TSTOP $status = ahgen::run_ftool('ftedit',"infile=$cutgti\[GTI]","column=STOP", "row=$lastrow","value=$tstop"); if ($status) { ahlog::ah_err "ftedit failed."; return $status; } # Update TSTART and TSTOP keywords to match GTI file ahgen::set_keyword( $cutgti, "GTI", 'TSTOP' , $tstop ) ; } # Attach updated GTI to SFFa # No GTI attached to sff, expanded, recgain $status = copy_hdu($cutgti,"GTI", $sxifile_out); if ($status) { ahlog::ah_err "ftcopy failed."; return $status; } } } # end attach GTI } # end if GTI extension exists # Update the INSTRUME, DETNAM, DATAMODE keywords in the GTI extension ahgen::set_keyword( $sxifile_out , "GTI", 'INSTRUME' , "SXI" ) ; ahgen::set_keyword( $sxifile_out , "GTI", 'DETNAM' , $detnam ) ; ahgen::set_keyword( $sxifile_out , "GTI", 'DATAMODE' , $datamode ) ; # Set the coordinate keywords in the output SXI event file push @calibrated_sxi_uf_evt_files, $sxifile_out; push( @filelist_output, $sxifile_out ); push @calibrated_sxi_fpix_files, $fpix; if ( uc $hpix_out ne "NONE" ) { push @calibrated_sxi_hpix_files, $hpix_out; push( @filelist_output, $hpix_out ); } if ( $Params{outbadpix} ) { push( @filelist_output, $bpix_out ); } } # end loop over each sxi file ahlog::ah_debug "End of SXI Event calibration"; # Save lists of newly calibrated '_uf.evt', '.hpix' and '.fpix' files @{$files{event_uf}} = @calibrated_sxi_uf_evt_files; @{$files{hpix}} = @calibrated_sxi_hpix_files; @{$files{fpix}} = @calibrated_sxi_fpix_files; # Empty the fpix file array @calibrated_sxi_fpix_files = (); my $tstart_obs = ( sort numerically @tstart )[ 0 ]; my $tstop_obs = ( sort numerically @tstop )[ -1 ]; ahlog::ah_out "Merging pointing and slew flickering pixel files"; # Merge the pointing and slew flickering pixel files foreach my $fpix_p ( @{$files{fpix}} ) { # skip any slew files if( $fpix_p =~ /sxi_s/ ) { next; } # Set up the input/output file names my $fpix_s = $fpix_p; $fpix_s =~ s/sxi_p/sxi_s/g; my $fpix = $fpix_p; $fpix =~ s/sxi_p/sxi_a/g; my $pixels = $fpix . ".pixels"; # Mark files for deletion ahapp::add_temp_file($pixels); ahapp::add_temp_file($fpix_p); # Merge the EVENTS extensions and sort by TIME $status = merge_slew_and_pointing($fpix_s,$fpix_p,$fpix,"EVENTS","TIME"); if ( $status ) { ahlog::ah_err "merge fpix failed"; return 1; } # Merge the PIXELS extensions and sort by START then STOP $status = merge_slew_and_pointing($fpix_s,$fpix_p,$pixels,"PIXELS","START STOP"); if ( $status ) { ahlog::ah_err "merge fpix failed"; return 1; } # Append the PIXELS extension to the output file $status = ahgen::run_ftool("ftappend",$pixels."[PIXELS]",$fpix); unlink $pixels; # Just delete the pixels file here if ( $status ) { ahlog::ah_err "ftappend failed"; return 1; } # Update the TSTART/TSTOP keywords to include slew and pipeline ahgen::set_keyword($fpix,"EVENTS","TSTART",$tstart_obs); ahgen::set_keyword($fpix,"EVENTS","TSTOP",$tstop_obs); ahgen::set_keyword($fpix,"PIXELS","TSTART",$tstart_obs); ahgen::set_keyword($fpix,"PIXELS","TSTOP",$tstop_obs); push( @filelist_output, $fpix ); # Save the merged flickering pixel files push @calibrated_sxi_fpix_files, $fpix; } ahlog::ah_debug "End of SXI flickering pixel merge"; # Save lists of newly merged '.fpix' files @{$files{fpix}} = @calibrated_sxi_fpix_files; if ( ahlog::getdebug ) { ahlog::ah_debug "\nEnd CalibrateEvents\n"; } return 0; } # ------------------------------------------------------------------------------ sub CleanEvents { if ( ahlog::getdebug ) { ahlog::ah_debug "\nCleanEvents\n"; } my $status = 0; my $exposure = $files{exposure}; my $telgti = $files{telgti}; my $modegti = $files{modegti}; my $makefilter = $files{makefilter}; my $ehk = $files{extended_housekeeping}; my $obsgti = $files{obsgti}; my $select = $Params{selectfile}; my $leapsecfile = $Params{leapsecfile}; my $outdir = $Params{outdir}; my $stemoutputs = $Params{stemoutputs}; my $instrument = $Params{instrument}; my $mkflabel = $Params{sxi_mkflabel}; my $ehklabel = $Params{sxi_ehklabel}; my $evtlabel = $Params{sxi_evtlabel}; my $seggti = ""; my @calibrated_sxi_cl_evt_files = ( ); # Check that we have good GTI from pointing and attitude GTI if ( ! has_good_time( $obsgti, "GTIPOINT" ) ) { ahlog::ah_out "$obsgti\[GTIPOINT] has no GTI. Cannot clean SXI Data."; return 1; } if ( ! has_good_time( $obsgti, "GTIATT" ) ) { ahlog::ah_out "$obsgti\[GTIATT] has no GTI. Cannot clean SXI Data."; return 1; } # Check that we have good GTI from telemetry saturation GTI if ( ! has_good_time( $telgti, "GTITEL" ) ) { ahlog::ah_out "$telgti\[GTITEL] has no GTI. Cannot clean SXI Data."; return 1; } if($Params{calc_modegti}) { $seggti = catfile($outdir , $stemoutputs . "sxi_seg.gti"); $modegti = catfile($outdir , $stemoutputs . "sxi_mode.gti"); # Read the TSTART, TSTOP keywords from the exposure file my $tstart = ahgen::get_keyword($obsgti,"GTIOBS","TSTART"); unless ( defined $tstart ) { ahlog::ah_out"In file '$obsgti', could not read keyword TSTART"; push @error_output, "In file: $obsgti (TSTART not defined)"; return 1; } my $tstop = ahgen::get_keyword($obsgti,"GTIOBS","TSTOP"); unless ( defined $tstop ) { ahlog::ah_out"In file '$obsgti', could not read keyword TSTOP"; push @error_output, "In file: $obsgti (TSTOP not defined)"; return 1; } # Run the sximodegti script my $logfile = $Params{logstem} . "sximodegti.log"; $status = run_sximodegti($exposure,$seggti,$modegti,{ tstart => $tstart, tstop => $tstop, clobber => "yes", logfile => $logfile, }); if ( $status ) { ahlog::ah_err "sximodegti failed"; return 1; } # Write the coordinate keywords to the output GTI files push( @filelist_output, $seggti ); push( @filelist_output, $modegti ); } foreach my $sxifile ( sort @{$files{event_uf}} ) { my @ingtis = (); my $sxifile_out = form_cleaned_file_name($sxifile); my $detnam = get_keyword( $sxifile, "EVENTS", "DETNAM" ); my $basename = basename($sxifile); $basename =~ s/\.evt.*$//; unless ( defined $detnam ) { ahlog::ah_out"In file '$sxifile', could not read keyword DETNAM"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile_out (DETNAM not defined)"; $Params{numerrs} += 1; next; } my $dataclass = get_keyword( $sxifile, "EVENTS", "DATACTLM" ); unless ( defined $dataclass ) { ahlog::ah_out"In file '$sxifile', could not read keyword DATACTLM"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile_out (DATACTLM not defined)"; $Params{numerrs} += 1; next; } my $datamode = get_keyword( $sxifile, "EVENTS", "DATAMODE" ); unless ( defined $datamode ) { ahlog::ah_out"In file '$sxifile', could not read keyword DATAMODE"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile_out (DATAMODE not defined)"; $Params{numerrs} += 1; next; } my $obsmode = ahgen::get_keyword( $sxifile,"EVENTS","OBS_MODE"); unless ( defined $obsmode ) { ahlog::ah_out"In file '$sxifile', could not read keyword OBS_MODE"; ahlog::ah_out"Skipping file."; push @error_output, "Skipped file: $sxifile_out (OBS_MODE not defined)"; $Params{numerrs} += 1; next; } # Skip any slew event files if ( uc $obsmode eq "SLEW" ) { next; } # Check that we have good GTI from pointing GTI unless ( ahgen::check_hdu_exists($modegti, "GTI_$dataclass" ) ) { ahlog::ah_out "No GTI_$dataclass extension in $modegti. Cannot clean SXI Data for $sxifile."; push @error_output, "Skipped file: $sxifile_out (Extension GTI_$dataclass does not exist in $modegti)"; $Params{numerrs} += 1; next; } if ( ! has_good_time( $modegti, "GTI_$dataclass" ) ) { ahlog::ah_out "$modegti\[GTI_$dataclass] has no GTI. Cannot clean SXI Data for $sxifile."; push @error_output, "Skipped file: $sxifile_out (Extension GTI_$dataclass has no GTI)"; $Params{numerrs} += 1; next; } # Form the label from the DETNAM and DATAMODE my $windowmode = get_sxi_mode( $detnam, $datamode ); if ( $windowmode eq "" ) { ahlog::ah_info "HIGH", "Not a valid mode for file $sxifile."; ahlog::ah_info "HIGH", " DETNAM : $detnam"; ahlog::ah_info "HIGH", " DATAMODE : $datamode"; push @error_output, "Skipped file: $sxifile_out (Not a valid mode ($detnam, $datamode))"; $Params{numerrs} += 1; next; } my $label_mode = $detnam . $windowmode; my $mkflabel_mode = $mkflabel; my $ehklabel_mode = $ehklabel; my $evtlabel_mode = $evtlabel; $mkflabel_mode =~ s/#/$label_mode/; $ehklabel_mode =~ s/#/$label_mode/; $evtlabel_mode =~ s/#/$label_mode/; ahlog::ah_debug "Input File : $sxifile"; ahlog::ah_debug "Output File : $sxifile_out"; ahlog::ah_debug "Detnam : $detnam"; ahlog::ah_debug "Datamode : $datamode"; ahlog::ah_debug "MKF Label : $mkflabel_mode"; ahlog::ah_debug "EHK Label : $ehklabel_mode"; ahlog::ah_debug "Event Label : $evtlabel_mode"; # Verify that we have good GTI if ( ! has_good_time( $sxifile, "GTI" ) ) { ahlog::ah_out "$sxifile\[GTI] has no GTI. Cannot clean SXI Data."; push @error_output, "Skipped file: $sxifile_out (No GTI)"; $Params{numerrs} += 1; next; } # MKF/EHK depend on DETNAM/WINDOW my $gtimkf = $Params{tempstem} . lc $mkflabel_mode . "_mkf.gti"; my $gtiehk = $Params{tempstem} . lc $ehklabel_mode . "_ehk.gti"; my $logfile = ""; ahapp::add_temp_file ( $gtimkf ); ahapp::add_temp_file ( $gtiehk ); if ( ! -e $gtimkf ) { # Create the MKF GTI file $logfile = $Params{logstem} . lc $mkflabel_mode . "_mkf_ahgtigen.log"; $status = create_gti(infile => $makefilter, outfile => $gtimkf, selectfile => $select, instrume => $instrument, label => $mkflabel_mode, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, logfile => $logfile, ); if ( $status ) { ahlog::ah_err "ahgtigen failed for SXI MKF: $gtimkf"; push @error_output, "Skipped file: $sxifile_out (ahgtigen failed)"; $Params{numerrs} += 1; next; } if ( ! has_good_time( $gtimkf, "GTI" ) ) { ahlog::ah_out "$gtimkf\[GTI] has no GTI from MKF."; push @error_output, "Skipped file: $sxifile_out (No GTIMKF found)"; $Params{numerrs} += 1; next; } } if ( ! -e $gtiehk ) { # Create the EHK GTI file $logfile = $Params{logstem} . lc $ehklabel_mode . "_ehk_ahgtigen.log"; $status = create_gti(infile => $ehk, outfile => $gtiehk, selectfile => $select, instrume => $instrument, label => $ehklabel_mode, clobber => $ahapp::clobber ? "yes" : "no" , chatter => $ahapp::chatter, logfile => $logfile, ); if ( $status ) { ahlog::ah_err "ahgtigen failed for SXI EHK: $gtiehk"; push @error_output, "Skipped file: $sxifile_out (ahgtigen failed)"; $Params{numerrs} += 1; next; } if ( ! has_good_time( $gtiehk, "GTI" ) ) { ahlog::ah_err "$gtiehk\[GTI] has no GTI from SXI EHK."; push @error_output, "Skipped file: $sxifile_out (No GTIEHK found)"; $Params{numerrs} += 1; next; } } ahlog::ah_out "Cleaning events in $sxifile"; # Load the GTI files into parameter push @ingtis, $sxifile . "[GTI]"; push @ingtis, $obsgti . "[GTIPOINT]"; push @ingtis, $obsgti . "[GTIATT]"; push @ingtis, $telgti . "[GTITEL]"; push @ingtis, $modegti . "[GTI_$dataclass]"; push @ingtis, $gtimkf . "[GTI]"; push @ingtis, $gtiehk . "[GTI]"; # Merge the GTI and screen events $logfile = $Params{logstem} . $basename . "_ahscreen.log"; $status = screen_events(infile => $sxifile, outfile => $sxifile_out, gtifile => join(",",@ingtis), upkeyword => "yes", cpkeyword => "yes", leapsecfile => $leapsecfile, selectfile => $select, label => $evtlabel_mode, clobber => "yes", chatter => $ahapp::chatter, logfile => $logfile, ); if ( $status ) { ahlog::ah_err "ahscreen failed. Skipping $sxifile_out."; push @error_output, "Skipped file: $sxifile_out (ahscreen failed)"; $Params{numerrs} += 1; unlink $sxifile_out; next; } if ( ! has_good_time( $sxifile_out, "GTI" ) ) { ahlog::ah_out "$sxifile_out has no GTI. Skipping $sxifile_out."; push @error_output, "Skipped file: $sxifile_out (Screened all events)"; $Params{numerrs} += 1; unlink $sxifile_out; next; } push( @filelist_output, $sxifile_out ); push @calibrated_sxi_cl_evt_files, $sxifile_out; } # end loop over unfiltered files # Save lists of newly calibrated '_uf.evt', '.hpix' and '.fpix' files @{$files{event_cl}} = @calibrated_sxi_cl_evt_files; if ( ahlog::getdebug ) { ahlog::ah_debug "\nEnd ScreenEvents\n"; } return 0; } # ------------------------------------------------------------------------------ sub CreateProducts { if ( ahlog::getdebug ) { ahlog::ah_debug "\nCreateProducts\n"; } my $status = 0; my $region = $files{regionfile}; my $instrument = $Params{instrument}; foreach my $sxifile ( sort @{$files{event_cl}} ) { # Calculate the output file names my $pha = $sxifile; $pha =~ s/_cl.evt/_src.pha/; my $img = $sxifile; $img =~ s/_cl.evt/_src.img/; my $lc = $sxifile; $lc =~ s/_cl.evt/_src.lc/; # Run the extractor to create spectra, lightcurves and images $status = extract(infile => $sxifile, phafile => $pha, imgfile => $img, lcfile => $lc, region => $region, type => $instrument, ); if ( $status ) { ahlog::ah_err "extractor failed"; return 1; } # +++ Create gif images } if ( ahlog::getdebug ) { ahlog::ah_debug "\nEnd CreateProducts\n"; } return 0; } # ------------------------------------------------------------------------------ sub finalize { my $status = 0; my $inst = $Params{instrument}; # Print list of output files calibrated or cleaned, and any products created if ( $Params{stage1_switch} ) { ahlog::ah_debug "$inst event file(s) calibrated:" if @{$files{event_uf}}; foreach my $filename ( sort @{$files{event_uf}} ) { ahlog::ah_debug " $filename\n"; } if ( $Params{calc_hotpix} ) { ahlog::ah_debug "$inst hot pixel file(s) calibrated:" if @{$files{hpix}}; foreach my $filename ( sort @{$files{hpix}} ) { ahlog::ah_debug " $filename\n"; } } ahlog::ah_debug "$inst flickering pixel file(s) created:" if @{$files{fpix}}; foreach my $filename ( sort @{$files{fpix}} ) { ahlog::ah_debug " $filename\n"; } } if ( $Params{stage2_switch} ) { ahlog::ah_debug "$inst file(s) screened:" if @{$files{event_cl}}; foreach my $filename ( sort @{$files{event_cl}} ) { ahlog::ah_debug " $filename\n"; } } if ( $Params{stage3_switch} ) { } # Check each file @filelist_output = sort( @filelist_output ); my $prev = 'nonesuch'; my @filelist_output_unique = grep( $_ ne $prev && ( ( $prev ) = $_ ), @filelist_output ); foreach my $infile ( @filelist_output_unique ) { ahlog::ah_debug "\nStamping ahpipeline parameters on file $infile\n" ; ## Open file and count number of HDU's (Headers) my $hdutotal = ahgen::get_total_hdu($infile); # Loop on HDUs and write the coordinate keywords for ( my $i1 = 0 ; $i1 < $hdutotal ; $i1++ ) { add_coord_keys($infile,$i1); } ## Update the CHECKSUM and DATASUM keywords $status = update_checksum_and_verify($infile); unless ( $status ) { ahlog::ah_err "verify failed for $infile"; return $status; } } ahgen::run_ftool("pset","sxipipeline","numerrs=$Params{numerrs}"); # Print the errors found from the pipeline if ( $Params{numerrs} ) { ahlog::ah_out "SXIPIPELINE had the following errors/warnings:"; foreach my $errlog ( @error_output ) { ahlog::ah_out " $errlog"; } } return 0; } # ------------------------------------------------------------------------------ sub form_outfile_name { my $infile = shift; my $outdir = $Params{outdir}; my $steminputs = $Params{steminputs}; my $stemoutputs = $Params{stemoutputs}; my $zpatt = qr/(\.Z|\.z|\.gzip|\.GZIP|\.gz|\.GZ|\.zip\.ZIP)?/; my $outfile = ""; # Get the basename of the input file and calculate the output file name # Using the outdir and stemoutputs parameters my $basename = basename($infile); my ($filebase) = $basename =~ /$steminputs(.*)/; # Strip off any 'zip' pattern $filebase =~ s/$zpatt$//; $outfile = catfile($outdir , $stemoutputs . $filebase); return $outfile ; } # ------------------------------------------------------------------------------ sub form_cleaned_file_name { my $infile = shift; my $outdir = $Params{outdir}; my $steminputs = $Params{steminputs}; my $stemoutputs = $Params{stemoutputs}; my $outfile = ""; # Get the basename of the input file and calculate the output file name # Using the outdir and stemoutputs parameters my $basename = basename($infile); my ($filebase) = $basename =~ /$steminputs(.*)/; # Strip off any 'zip' pattern $filebase =~ s/$zpatt$//; $outfile = catfile($outdir , $stemoutputs . $filebase); $outfile =~ s/_uf/_cl/g; return $outfile ; } # ------------------------------------------------------------------------------ sub get_dataclass_from_filename { my $sxifile = shift; my $dataclass = ""; # Parse the dataclass from the input event file name ($dataclass) = $sxifile =~ qr/sxi_[ps][0-9]([0-9a-z]{8})_[a-z]{2}\.evt$zpatt$/, return $dataclass; } # ------------------------------------------------------------------------------ sub find_hpix_file { my $sxifile = shift; my $notfound = "NONE"; my $dataclass = get_dataclass_from_filename($sxifile); # Find the corresponding hot pixel file by searching # through the input hot pixel files and finding # a corresponding dataclass foreach my $hpix ( @{$files{hpix}} ) { if ( $hpix =~ qr/(sxi_a0$dataclass\.hpix)$zpatt$/ ) { return $hpix; } } return $notfound; } # ------------------------------------------------------------------------------ sub form_fpix_file { my $sxifile = shift; my $fpix = $sxifile; # Form the fpix file name using the input event file name $fpix =~ s/_uf\.evt/\.fpix/; $fpix =~ s/$zpatt$//; return $fpix; } # ------------------------------------------------------------------------------ sub form_bpix_file { my $sxifile = shift; my $bpix = $sxifile; # Form the fpix file name using the input event file name $bpix =~ s/_uf\.evt/\.bpix/; $bpix =~ s/$zpatt$//; return $bpix; } # ------------------------------------------------------------------------------ sub form_img_file { my $sxifile = shift; my $img = $sxifile; # Form the fpix file name using the input event file name $img =~ s/_uf\.evt/\.bimg/; $img =~ s/$zpatt$//; return $img; } # ------------------------------------------------------------------------------ sub find_file_mode { my $evtfile = shift; my ($mode) = $evtfile =~ /sxi_([ps])[0-9][0-9a-f]{8}_uf\.evt$zpatt$/; return $mode; } # ------------------------------------------------------------------------------ sub find_file_indx { my $evtfile = shift; my ($indx) = $evtfile =~ /sxi_[ps]([0-9])[0-9a-f]{8}_uf\.evt$zpatt$/; return $indx; } # ------------------------------------------------------------------------------ sub get_sxi_mode { my $detnam = shift; my $datamode = shift; my $mode = ""; # Calculate the window mode if(uc $detnam eq "CCD" and uc $datamode eq "WINDOW1" ) { $mode = "W1"; } elsif(uc $detnam eq "CCD34" and uc $datamode eq "WINDOW1" ) { $mode = "WF"; } elsif(uc $detnam eq "CCD12" and ( uc $datamode eq "WINDOW2" or uc $datamode eq "WINDOW1BURST" or uc $datamode eq "WINDOW2BURST" ) ) { $mode = "WA"; } else { ahlog::ah_err "Not a valid WINDOW mode"; } return $mode; } # ------------------------------------------------------------------------------ sub add_coord_keys { my $infile = shift; my $ext = shift; my $ra = $Params{ra}; my $dec = $Params{dec}; my $roll = $Params{roll}; my $ra_pnt = $Params{ra_pnt}; my $dec_pnt = $Params{dec_pnt}; my $optdetx = $Params{optdetx}; my $optdety = $Params{optdety}; my $optfocx = $Params{optfocx}; my $optfocy = $Params{optfocy}; my $optskyx = $Params{optskyx}; my $optskyy = $Params{optskyy}; # Set the nominal pointing keywords if ( $ra >= 0. and $ra <= 360. ) { ahgen::set_keyword($infile,$ext,"RA_NOM",$ra,'Nominal aspect point R.A.') } if ( $dec >= -90. and $dec <= 90. ) { ahgen::set_keyword($infile,$ext,"DEC_NOM",$dec,'Nominal aspect point Dec') } if ( $roll != 0 ) { ahgen::set_keyword($infile,$ext,"PA_NOM",$roll,'Nominal aspect point Roll' ) } if ( $ra_pnt >= 0. and $ra_pnt <= 360. ) { ahgen::set_keyword($infile,$ext,"RA_PNT",$ra_pnt,'Pointing RA') } if ( $dec_pnt >= -90. and $dec_pnt <= 90. ) { ahgen::set_keyword($infile,$ext,"DEC_PNT",$dec_pnt,'Pointing DEC'); } # Set the optical coordinates # +++ Not sure of the ranges of these if ( $optdetx != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTDETX",$optdetx,'Optical axis DETX'); } if ( $optdety != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTDETY",$optdety,'Optical axis DETY') } if ( $optfocx != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTFOCX",$optfocx,'Optical axis FOCX' ) } if ( $optfocy != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTFOCY",$optfocy,'Optical axis FOCY' ) } if ( $optskyx != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTSKYX",$optskyx,'Optical axis SKYX') } if ( $optskyy != -999.99999 ) { ahgen::set_keyword($infile,$ext,"OPTSKYY",$optskyy,'Optical axis SKYY') } return 0; } # ------------------------------------------------------------------------------