Download

package EPICSources;
use strict;
use English;
use Carp;
use vars qw(@ISA $VERSION $name $author $date $version @instList $numberOfStreams);
@ISA = qw(Module);
use ModuleResources;
use ModuleUtil;

$name    = __PACKAGE__;
$VERSION = '0.15';
$version = $VERSION;
$author  = 'Anja Schroeder,Ian Stewart,Duncan John Fyfe, Duncan Law-Green';
$date    = '2012-11-07';

#
# ChangeLog
# =========
#
#
# version 0.15 - 2014-02-28 (EOP)
# ------------
# 
# + Following the recommendation in the SAS Users Guide and SAS threads, MOS
#   spectral products should be created after applying #XMMEA_EM flag
#   filtering. 
#   NOTE: These flag masks are applied the same in EPICSourceProducts.pm
#
# version 0.14 - 2012-03-15 DLG
# ------------
#
# + esources mintotalcts 100. 
#
# version 0.14 - 2012-03-15 DLG
# ------------
#
# + esources mintotalcts 300. Again.
#
# version 0.13 - 2012-03-13 DLG
# ------------
# 
# + try reverting esources mintotalcts to 500 to avoid xspec spectral extraction failures
#
# version 0.12 - 2012-01-19 DLG
# ------------
#
# + Added Attitude GTI filtering to $specExpression and $timeExpression to
#   propagate to SSP spectra and time series
#
# version 0.11 - 2012-01-19 DLG
# ------------
#
# + Altered mintotalcts in esources from 500 to 300 to test optimised
#   faint source extraction
#
# version 0.10 - 2009-09-14 DLG
# ------------
#
# + Added test for MOS W6 and PN SW modes. Exclude these from SSP generation.
#
# version 0.09 - 2006-08-11 DJF
# ------------
#
# + Added a test  for PN CCD in low gain mode.  Exclude PN exposures where some CCDs are in low gain mode.
#
# version 0.08 - 2006-03-03 ACS
# ------------
# + A couple of corrections to the perl code introduced by the changes the day before.
#
# version 0.07 - 2006-03-02 ACS
# ------------
# + Added determination of minimum TSTART and maximum TSTOP of all valid exposures
#   and inserted them into each filtered event list for light curves
# + Commented out selection by data mode ..Prime.. since FU imaging event lists
#   did not get filtered event lists. 
#
# version 0.06 - 2005-12-02 IMS
# ------------
# + Now really added --setflags=yes (d'oh!!)
#
# version 0.05 - 2005-12-01 IMS
# ------------
# + Added --setflags=yes to esources call. This sets the SPECTRA and TSERIES flag columns of the srcmatch list to T for those sources selected for SSPs.
#
# version 0.04 - 2005-11-29 IMS
# ------------
# + Changed the flag mask selections to those agreed upon.
#
# version 0.03 - 2005-10-14 IMS
# ------------
# + Shortened the content string for the SSP source list
#
# version 0.02 - 2005-09-08 RGW
# ------------
#
# + exit gracefully if required source list doesn't exist
#
# version 0.01 - 2005-06-09 IMS
# ------------
#
# + First draft - ported from ACS script.
#

# Declare instruments of interest
@instList = qw(all);

# Number of Streams
sub numberOfStreams
{
    return 1;
}

# Rules evaluated to determine when this modules can run.
sub evaluateRules
{
    # If upstream module has been ignored, so if this one
    return ignore()
      if ignored(
        module => 'SrcMerge'
        , instrument => 'all'
        , stream => 1
      );

    #
    return start()
      if complete(
        module => 'SrcMerge'
        , instrument => 'all'
        , stream => 1
      )
}

# The guts of the module
sub performAction
{
    info("Module version number: $version");

# First fetch list of all suitable EPIC event lists (imaging, not cal. closed)
#
    my (@eventListSets, $content, $timeExpression, $specExpression);
    my (@filteventListSets, $tlmin, $tlmax, @tmin, @tmax, @tmpmin, @tmpmax);

# get attitude GTI file
    
    my $attGTIFile = findFile(
			      class => 'intermediate'
			      , instrument => 'all'
			      , content => 'Attitude GTI'
			      );

# add attitde GTI filtering if file exists
    
    my $attGTIExpr = "";
    $attGTIExpr = "&>I($attGTIFile,TIME)" if $attGTIFile;

    foreach my $inst ( "emos1", "emos2", "epn" )
    {
        if ($inst eq 'epn')
        {
            $content= "EPIC PN imaging mode event list";
            $timeExpression
#              ="((PATTERN<=4)&&((FLAG & 0x2fb002c)==0)"
              ="((PATTERN<=4)&&((FLAG & 0xfffffef)==0)"
              ."&&(PI>=200)&&(PI<=12000))"
	      .$attGTIExpr;
            $specExpression
              ="((PATTERN<=4)&&(FLAG==0)&&(PI>=200)&&(PI<=12000))"
	      .$attGTIExpr;
        } 
		else # mos
        {
            $content= "EPIC MOS imaging mode event list";
            $timeExpression
#              ="((PATTERN<=12)&&((FLAG & 0x766b0000)==0)"
              ="((PATTERN<=12)&&((FLAG & 0x766ba000)==0)"
              ."&&(PI>=200)&&(PI<=12000))"
	      .$attGTIExpr;
#            $specExpression = $timeExpression;
            $specExpression
#              ="((PATTERN<=12)&&((FLAG & 0xfffffeff)==0)"
             ="((PATTERN<=12)&&((FLAG & 0x766ba000)==0)"
              ."&&(PI>=200)&&(PI<=12000))"
	      .$attGTIExpr;
        }

        foreach my $exp_id ( listExposures( instrument => $inst ) )
        {
            # Find imaging event file for this exposure
            my $evFile=findFile(
                class => 'product'
                , instrument => $inst
                , exp_id => $exp_id
                , content => $content
            );
            next if (! $evFile );

			if ($inst eq 'epn') 
                            ## Select EPIC PN
			{
			    my $lowgain = {};
			    
			    ## Exclude PN CCD low gain mode from SSP generation
			    if (my @lowgain = ModuleUtil::pnLowGainWarn($evFile , $lowgain) )
			    {
				info( 'Some CCD in low gain mode :' , join (' ,' , @lowgain) );
				info( 'Excluding this exposure from source detection.' );
				next;	
			    }
			    
			    ## Exclude PN SW mode from SSP generation
			    my $submode = readFITSKeyword(
							  file => $evFile
							  , extension => 'EVENTS'
							  , keyword => 'SUBMODE'
							  );

                            # EC (14 Nov 2013): don't skip, at request of PR
			    #if ($submode =~ /PrimeSmallWindow/) {
			    #	info ( 'PN PrimeSmallWindow mode detected: excluding from SSP. ');
			    #	next;
			    #}
			   
			    
			} else {
			    ## Select EPIC MOS

			    ## Exclude MOS W6 mode from SSP generation
			    my $submode = readFITSKeyword(
							  file => $evFile
							  , extension => 'EVENTS'
							  , keyword => 'SUBMODE'
							  );
			    if ($submode =~ /PrimePartialW6/) {
				info ( 'MOS PrimePartialW6 mode detected: excluding from SSP. ');
				next;
			    }
			}

			
            # Check instrument filter

            my $filter = getExposureProperty(
                instrument => $inst
                , exp_id => $exp_id
                , name => 'filter'
            );
            next if $filter =~ /Cal/;

	    # Derive Tstart and Tstop times for time series

            $tlmin = readFITSKeyword(
                file => $evFile
                , extension => 'EVENTS'
                , keyword => 'TSTART'
            );

            $tlmax = readFITSKeyword(
                file => $evFile
                , extension => 'EVENTS'
                , keyword => 'TSTOP'
            );

            # Add to lists
            push @eventListSets, $evFile;
            push @tmin, $tlmin;
            push @tmax, $tlmax;

            my $forTimeFilteredEvList = newFile(
                class => 'intermediate'
                , instrument => $inst
                , exp_id => $exp_id
                , content => 'Event list for light curves'
            );
            doCommand(
                'evselect'
                , table => "${evFile}:EVENTS"
                , keepfilteroutput => 'yes'
                , withfilteredset => 'yes'
                , filteredset => $forTimeFilteredEvList
                , writedss => 'yes'
                , updateexposure => 'yes'
                , expression => $timeExpression
                , destruct => 'yes'
              )
              or return exception();

            push @filteventListSets, $forTimeFilteredEvList;

            my $forSpecFilteredEvList = newFile(
                class => 'intermediate'
                , instrument => $inst
                , exp_id => $exp_id
                , content => 'Event list for spectra'
            );
            doCommand(
                'evselect'
                , table => "${evFile}:EVENTS"
                , keepfilteroutput => 'yes'
                , withfilteredset => 'yes'
                , filteredset => $forSpecFilteredEvList
                , writedss => 'yes'
                , updateexposure => 'yes'
                , expression => $specExpression
                , destruct => 'yes'
              )
              or return exception();
        } # end loop over $exp_id
    } # end loop over $inst

    # Return immediately if there are no suitable exposures.
    unless (@eventListSets)
    {
        info("No suitable exposures found");
        return success();
    }

    # Determine min and max of all tstart and tstop times

    @tmpmin = sort(@tmin);
    @tmpmax = sort(@tmax);
    my $tminall = $tmpmin[0];
    my $tmaxall = $tmpmax[$#tmpmax];

    # Add TLMIN1 and TLMAX1 keywords

	doCommand('addattribute'
		,set => [ @filteventListSets ]
		,attributename => [qw(EVENTS:TLMIN1 EVENTS:TLMAX1)]
		,attributetype => ['real ' , 'real']
		,realvalue => [ $tminall , $tmaxall ]
		,attributecomment => [ 'Time series start' , 'Time series stop' ]
	);
# Generate Source list:

    my $srcmatchSrcFile = findFile(
        class => 'product'
        , instrument => 'epic'
        , content => 'EPIC summary source list'
        , format => 'FITS'
    );
    return success() unless $srcmatchSrcFile;

    my $sspSrcFile = newFile(
        class => 'intermediate'
        , instrument => 'epic'
#        , content => 'Source list for source-specific products'
        , content => 'SSP source list'
    );
    doCommand(
	      'esources'
	      , eventsets => [@eventListSets]
	      , srctab => "${srcmatchSrcFile}:SRCLIST"
	      , outsrcset => $sspSrcFile
	      , mintotalcts => 100
	      , mindetml => 15
	      , minmaskfrac => 0.5
	      , numhexchar => 3
	      , setflags => 'yes'
	      )
	or return exception();

    return success();
}
1;