package Util::Catalog; ############################################################################## # # DESCRIPTION: This class is useful for generating catalogs of files. # DESCRIPTION: Calling the "make" method will create a FITS output catalog # DESCRIPTION: with the standard format. The genral user does not need # DESCRIPTION: to worry about any of the other methods. # DESCRIPTION: # DESCRIPTION: Certain catalog information is accumulated in the class data. # DESCRIPTION: This makes it more efficient to generate more than one catalog # DESCRIPTION: containing identical files. # DESCRIPTION: It also allows the "all_files" and "fits_files" methods to # DESCRIPTION: give lists # DESCRIPTION: of files in the union of all catalogs created so far. # DESCRIPTION: # DESCRIPTION: Sub-classes may change the format of the catalog file # DESCRIPTION: by overriding some of the methods. The Util::HTMLcatalog class # DESCRIPTION: does this. # # HISTORY # HISTORY: $Log: Catalog.pm,v $ # HISTORY: Revision 1.2 2006/08/01 20:35:34 apsop # HISTORY: Add in CVS history indicator. # HISTORY: # HISTORY: # HISTORY: 2005-05-27 # HISTORY: Add capability a file type to have more than one file class # HISTORY: # # VERSION: 1.0 # ############################################################################## use Util::Stool; use strict; my $FILENAME; my $LOG; my $isFITS; my $HEADER_TEMPLATE; my $KEYWORD_TEMPLATE; my %SIZE; my %FORMAT; my %FILES_OF_TYPE; my %ALL_FILES; my %FITS_FILES; my %FUTURE_FILES; #################################### # initialize some of the class data #################################### sub BEGIN { ##################################### # initialize variables ##################################### %SIZE=(); %FORMAT=(); %FILES_OF_TYPE=(); %ALL_FILES=(); %FITS_FILES=(); #################################################### # text for header template file #################################################### $HEADER_TEMPLATE ="FILENAME 64A\n"; $HEADER_TEMPLATE.="FORMAT 16A\n"; $HEADER_TEMPLATE.="TYPE 32A\n"; $HEADER_TEMPLATE.="FILECLAS 32A\n"; $HEADER_TEMPLATE.="DESCRIP 64A\n"; $HEADER_TEMPLATE.="FILESIZE 1J kilobytes\n"; $HEADER_TEMPLATE.="ARCHSIZE 1J kilobytes\n"; $HEADER_TEMPLATE.="CHECKSUM 1J\n"; $HEADER_TEMPLATE.="GZIP_CRC 8A\n"; } ######################### # constructor ######################### sub new { #(catalog_type) my $proto = shift; my $class = ref($proto) || $proto; ####################################### # be sure we are initialized ####################################### unless( $FILENAME) { print STDERR "Util::Catalog not initialized properly"; exit 1; } ##################################### # initialize some variables ##################################### my $self={}; $self->{CAT_TYPE}=shift; $self->{CAT_NAME}=$FILENAME->get($self->{CAT_TYPE}); $self->{DATA}=""; ######################################################### # put references to these variables in $self so that they # can be accessed by sub-classes ######################################################### $self->{FILENAME}=$FILENAME; $self->{LOG}=$LOG; $self->{HEADER_TEMPLATE}=\$HEADER_TEMPLATE; $self->{KEYWORD_TEMPLATE}=\$KEYWORD_TEMPLATE; $self->{SIZE}=\%SIZE; $self->{FORMAT}=\%FORMAT; $self->{FILES_OF_TYPE}=\%FILES_OF_TYPE; $self->{ALL_FILES}=\%ALL_FILES; $self->{FITS_FILES}=\%FITS_FILES; $self->{FUTURE_FILES}=\%FUTURE_FILES; bless($self,$class); return $self; } ################################### # ACCESSORS: ################################### ############################################################## # set or return the filename generator object for this class ############################################################## sub filename { my $self=shift; if(@_) { ##################################### # we are setting the filename object ##################################### $FILENAME=shift; ###################################################### # text for keywords template file ###################################################### my $origin=$FILENAME->procpar()->read("origin"); my $seq =$FILENAME->sequence(); my $ver =$FILENAME->version(); $KEYWORD_TEMPLATE ="ORIGIN=$origin / Place this file was created\n"; $LOG=$FILENAME->log(); } # end if setting FILENAME object return $FILENAME; } ######################################################################### # set the files which we should not expect to exist yet when we # are making the catalog. ######################################################################### sub future_files { #(type=>format, type=>format...) my $self=shift; %FUTURE_FILES=@_; my $type; foreach $type (keys %FUTURE_FILES ) { $FORMAT{$FILENAME->get($type)}=$FUTURE_FILES{$type}; $SIZE{$FILENAME->get($type)}=0; } } ############################################################# # returns a list of all FITS format files appearing in all # catalogs created so far. ############################################################# sub fits_files { my $self=shift; return keys %FITS_FILES; } ############################################################# # returns a list of all files appearing in all # catalogs created so far. ############################################################# sub all_files { my $self=shift; return keys %ALL_FILES; } ################### # METHODS: ################### ###################################################### # determine the format (FITS, ASCII, etc.) of a file. ###################################################### sub format { my $self=shift; my $file=shift; ###################################################### # determine the file format if we don't know it already ###################################################### unless( $FORMAT{$file} ) { ###################################################### # create the isFITS tool if it doesn't already exist ###################################################### unless($isFITS) { $isFITS=Util::Stool->new("isFITS") ->verbose(0) } ###################### # determine the format ###################### $FORMAT{$file}=$isFITS->command_line($file) ->run() ->stdout(); chomp($FORMAT{$file}); } ############################ # return the file size ############################ return $FORMAT{$file}; } # end of format method ############################################# # determine the size of a file in kilobytes ############################################# sub size { my $self=shift; my $file=shift; ###################################################### # calculate the file size if we don't know it already ###################################################### unless( defined $SIZE{$file} ) { $SIZE{$file}=int((-s $file)/1024+.5); } ############################ # return the file size ############################ return $SIZE{$file}; } # end of size method ###################################### # add a file to the catalog ###################################### sub add_file { my $self=shift; my $file=shift; my $type=shift; my $classes=shift; my $description=shift; #print "file=|$file| type=|$type| class=|$class| desc=|$description|\n"; my $format=$self->format($file); my $size =$self->size($file); $ALL_FILES{$file}=$type; if($format eq 'FITS' ) { $FITS_FILES{$file}=$type } foreach my $class (@$classes){ $self->{DATA}.="$file $format $type $class '$description' "; $self->{DATA}.="$size 0 0 'ffffffff'\n"; } } ####################################### # return all the files of a given type ####################################### sub files_of_type { my $self=shift; my $type=shift; unless($FILES_OF_TYPE{$type} ) { ############################################# # need to determine the files for this type ############################################ if($FUTURE_FILES{$type}) { ########################################## # the file of this type may not exist yet ########################################## my $file=$FILENAME->get($type); if( -f $file && ! $SIZE{file} ) { ########################################## # the file has been created already # but has zero size, so set its size as # unknown so it will be determined later ########################################## $SIZE{$file}=undef; } $FILES_OF_TYPE{$type}=[$file]; } else { ###################################################### # only add the files of this type which already exist ###################################################### $FILES_OF_TYPE{$type}=[]; foreach ($FILENAME->any($type)) { if(-f ) {push @{$FILES_OF_TYPE{$type}}, ($_) } } } # end if files should exist already } # end if we needed to determine the files for this type return @{$FILES_OF_TYPE{$type}}; } ################################################### # add all the files of a given type to the catalog ################################################### sub add_type { my $self=shift; my $type=shift; my $description=$FILENAME->description($type); my $classes =$FILENAME->class($self->{CAT_TYPE},$type); my $file; foreach $file ($self->files_of_type($type) ) { $self->add_file($file,$type,$classes,$description); } } ######################################################### # add all the files of all the file types to the catalog ######################################################### sub fill { my $self=shift; my $type; foreach $type ($FILENAME->types($self->{CAT_TYPE}) ) { $self->add_type($type); } } ############################################################### # actually write the catalog file ############################################################### sub close { my $self=shift; ################################## # create the template files ################################## my $header_template="$self->{CAT_TYPE}_header_template.tmp"; open HEADER, ">$header_template"; print HEADER $HEADER_TEMPLATE; close HEADER; my $keyword_template="$self->{CAT_TYPE}_keyword_template.tmp"; open KEYWORD, ">$keyword_template"; print KEYWORD $KEYWORD_TEMPLATE; close KEYWORD; my $data_template="$self->{CAT_TYPE}_data_template.tmp"; open DATA, ">$data_template"; print DATA $self->{DATA}; close DATA; ################################################################# # run fcreate - destroy it explicitly to be sure the parfile is # not hanging around later when we look for leftover files ################################################################# unlink $self->{CAT_NAME}; Util::Ftool->new("fcreate") ->params({outfile => $self->{CAT_NAME}, datafile => $data_template, cdfile => $header_template, headfile => $keyword_template, tbltype => "binary", nskip => 0, nrows => 0, history => "no", morehdr => 0, extname => "CATALOG", clobber => "yes" }) ->run() ->DESTROY(); ################################# # clean up the temporary files ################################# unlink $data_template; unlink $header_template; unlink $keyword_template; } # end of close method ######################################## # fill and close the catalog ######################################## sub make { my $self=shift; $LOG->entry("Creating $self->{CAT_NAME}"); $self->fill(); $self->close(); return $self; } ########################################################### # add the name of the catalog to the parfile ########################################################### sub register_in_parfile { my $self=shift; my $param=shift || $self->{CAT_TYPE}; $FILENAME->jobpar()->set({$param=>$self->{CAT_NAME}}); } 1;