Util::EventFileList (version $)


package Util::EventFileList;
##############################################################################
#
# DESCRIPTION: This class handles a list of event files. In particular 
# DESCRIPTION: it allows grouping the files with common keywords, and 
# DESCRIPTION: allows merging event files, properly handling the GTI 
# DESCRIPTION: extensions, etc.
#
# HISTORY
# HISTORY: $Log: EventFileList.pm,v $
# HISTORY: Revision 1.3  2014/02/27 07:01:06  apsop
# HISTORY: VERSION header now shows CVS Revision
# HISTORY:
# HISTORY: Revision 1.2  2006/08/01 20:35:34  apsop
# HISTORY: Add in CVS history indicator.
# HISTORY:
# HISTORY: 1.0 -> 1.1 2000-08-09
# HISTORY: Now reads NAXIS2 in the first extension to get the number of events.
# HISTORY: Added merge_gtis method
#
# VERSION: $Revision: 1.3 $
#
##############################################################################

use Util::FITSlist;
use Util::Stool;
@ISA=("Util::FITSlist");

use strict;


############################
# constructor
############################
sub new { #(file1, file2 ...)
    my $self=shift;
   
    ###########################################
    # inherit the generic FITSlist constructor
    ###########################################
    $self=$self->SUPER::new(@_);

    ######################################
    # initialize NEVENTS to a null value
    ######################################
    $self->{NEVENTS}=-1;

    return $self;

} # end of constructor

#################
# ACCESSORS:
#################

##################################################
# access the total number of events in all the files
##################################################
sub nevents {
    my $self=shift;
    if(@_) { 
        #######################################
        # set the value and return that number
        #######################################
        $self->{NEVENTS}=shift;
        return $self->{NEVENTS};

    } else {
        ########################################################
        # we are querying and not setting the number of events
        ########################################################
        if($self->{NEVENTS} < 0 ) {
            ##################################################
            # nevents is currently undefined so calculate it
            ##################################################
            my $ext=$self->get_extension();
            $self->extension(1);
            $self->{NEVENTS} = $self->sum_keywords("NAXIS2");
            $self->extension($ext);

        } # end if calculating NEVENTS


    return $self->{NEVENTS};

    } # end if not setting NEVENTS

} # end of nevents method


#################
# METHODS:
#################

#############################################################################
#############################################################################
# divide the files in the list into a set of sublists, grouping
# files with specified keys together. This is basicly an interface
# to the group_event_files STOOL.
# The first argument is a file listing the keywords to be considered.
# The second optional argument is the minimum number of events per group.
#############################################################################
sub group {
    my $self=shift;
    my $key_list=shift;
    my $min_events=shift || 0;

    ###############################################################
    # write the files to a temporary list.
    # we oughtta change the syntax of group_event_files for this
    ###############################################################
    my $list="event_file_group_list.tmp";
    open LIST, ">$list";
    foreach ($self->files_with_ext() ) {
        print LIST "$_\n";
    }
    close LIST;

    #############################################
    # run group_event_files
    #############################################
    my $text=Util::Stool->new("group_event_files")
                        ->command_line($list, $key_list)
                        ->run()
                        ->stdout();

    ##############################################
    # parse the output from group_event_files and
    # add create a new list object for each
    # group of files with the same keywords
    ##############################################
    my @result=();
    my $group;
    my @files=("dummy");
    for($group=1; @files= ($text =~ /^$group\s(\S+)\s\d+$/gm); $group++ ) {

        ###################################################
        # create a new list for the current group of files
        ###################################################
        my $list=Util::EventFileList->new(@files);

        ###################################################
        # get the total number of events from the
        # group_event_files output and set this value in
        # the list
        ###################################################
        my ($nevents) = $text =~ /^$group\s\S+\s(\d+)$/m;
        $list->nevents($nevents);

        ###########################################
        # add the new list to the vector of lists 
        # which we will return
        ###########################################
        push @result, ($list);
     

    }

    ########################
    # cleanup temporary file
    ########################
    unlink $list;

    return (@result);

} # end of group method
    
#############################################################################
#############################################################################
# merge the files in the list into a single FITS file with the given name
# This is basicly just an interface to the cmerge STOOL
# Note this overrides the generic Util::FITSlist merge method 
# which uses the fmerge FTOOL.
#############################################################################
sub merge {
    my $self=shift;
    my $merged_file=shift;

    unlink $merged_file;

    my $cmerge=Util::Stool->new("cmerge")
                          ->command_line("$merged_file",$self->as_param() )
                          ->run();

    if($cmerge->had_error() ) { return undef        }
    else                      { return $merged_file }

} # end of merge method

#############################################################################
#############################################################################
# merge the GTIs from all the event files in the list.
# If there is more than one event file in the list the result it sorted in time
# and a new file with the suggested name is created.
# If there is only one file in the list, nothing is done and the name of
# the original file is returned.
# if the list is empty, returns nothing.
#############################################################################
sub merge_gtis {
    my $self=shift;
    my $merged=shift;

    #############################################
    # return nothing if there are no files
    #############################################
    unless($self->files()) {return }

    ############################################
    # just return if we only have one file
    ############################################
    if($self->files() == 1 ) { return $self->file() }

    #################################################
    # get the GTI extension name from the first file
    #################################################
    my $extname=Util::FITSfile->new($self->file(),2)
                              ->keyword("EXTNAME");

    ###################################################
    # merge the GTIs using the merge method from the
    # FITSlist superclass
    ###################################################
    my $ext=$self->get_extension();

    $self->extension(2)
         ->SUPER::merge($merged,$extname);

    $self->extension($ext);

    #################################################
    # sort the GTIs into time order
    #################################################
    Util::FITSfile->new($merged,$extname)
                  ->cols("START")
                  ->sort();

    return $merged;

} # end of merge_gtis method



1;