package ImageMerge;
use strict;
use English;
use Carp;
use vars
qw(@ISA $VERSION $name $author $date $version @instList $numberOfStreams);
@ISA = qw(Module);
use ModuleResources;
# Declare identity, version, author, date, etc.
$name = __PACKAGE__;
$VERSION = '2.19';
$version = $VERSION;
$author = 'Dean Hinshaw,Duncan John Fyfe,Ian Stewart,Eduardo Ojero,Ed Chapin,Jose Vicente Perea';
$date = '2014-04-21';
#
# ChangeLog
# =========
#
# Version 2.19 - 2014-04-21 (JVP)
# ------------
# + Fix typo in line 560 replace '=' by '=>'
#
# Version 2.18 - 2014-04-21 (JVP&EOP)
# ------------
# + Added new parameters attfile and minexptime to etruecolor execution call.
# New etrucolor was included in xcolorcod-1.28 (xmmsas_20140415_1130).
# SPR 7201.
#
# Version 2.17 - 2014-03-06 (EOP)
# ------------
#
# + implotrgb is now run always without srclisttab regardless of mlList existence.
#
# Version 2.16 - 2014-02-20 (EOP)
# ------------
#
# + Call implotrgb to produce an annotated image in PPM format.
# The PPM plot is generated with a special PGPLOT 5.2.2 driver hacked
# to render RGB plots. Then, a PNG file is obtained by means of the
# well known tool 'convert' from ImageMagick.
#
# Version 2.15 - 2014-01-22 (EC)
# ------------
#
# + Call etruecolor to make 3-colour images (PPS SCR #7166)
#
# Version 2.14 - 2014-01-18 (EC)
# ------------
#
# + Rules modified to handle mosaics
#
# Version 2.13 - 2013-06-11 (EC)
# ------------
#
# + Merge changes from SOC version.
#
# version 2.12.1 - 2011-08-09 EOP
# --------------
#
# + GIF replaced by PNG to avoid seg. fault on 64-bit
#
# version 2.12 - 2006-02-21 DJF
# ------------
#
# + Now derive list of images to emosaic from lists saved by earlier modules.
# This is so emosaic preserves input image keywords. these are lost if
# imweightadd output images are used.
#
# version 2.11 - 2005-11-24 IMS
# ------------
# + Makes use of new parameter --forceuniformkwds of emosaic.
#
# version 2.10 - 2005-11-14 IMS
# ------------
# + Needed to add band => 8 for most of the emosaic outputs.
#
# version 2.09 - 2005-11-14 IMS
# ------------
#
# + Added all-source DS9 region product.
# + Deleted some obsolete code (or rather DJF did in one of the previous 2 versions).
# + Implemented DJF's shortened intermediate file names.
#
# version 2.08 - 2005-11-10 DJF
# ------------
#
# + Failure of implot of EPIC_OBSERVATION_BACKGROUND_MAP was not terminating
# module. return exception() added.
#
# version 2.07 - 2005-11-09 DJF
# ------------
#
# + info statement to say how many merged images , background maps and exposure maps were found for merging.
# This will help debug the case where one or more lists are empty.
#
# version 2.06 - 2005-11-02 IMS
# ------------
#
# + Input images to emosaic changed from the exposure-level images to the 'merged' images used for source detection. This has meant some fairly major code rearrangement - images and exp maps are now sought in the same way bkg maps have been from version 2.03.
# + Following on from this: delete the requirement that input images must have flare gtis and be full-frame mode.
#
# version 2.05 - 2005-10-14 IMS
# ------------
#
# + Added 'complete' to the list of methods called from ModuleResources.
#
# version 2.04 - 2005-10-07 RGW
# ------------
#
# + use the correct content keyword when looking for the epic
# observation ML source list
#
# version 2.03 - 2005-09-20 IMS
# ------------
#
# + Now also makes a mosaic (though without source overlays) of the band 8 background maps. (Note that band 8 bkg maps were not made before ExpDetect v2.04).
#
# version 2.02 - 2005-08-16 RGW
# ------------
#
# + fixed bug calling addattribute
# + changed to use the EPIC product images, not intermediate files
#
# version 2.01 - 2005-07-27 IMS
# ------------
#
# + @instList changed from 'all' to 'epic'.
# + Test on completion of ExpDetect added to evaluateRules.
# + FITS and PNG images are now also made of the mosaiced exposure maps.
# + Source circles added to PNG images.
#
# version 2.00 - 2005-05-09 DJF
# ------------
#
# + Add explicit perl module headers. Previously these were supplied
# at compile time. This will make debugging and extending the modules
# through additional perl libraries easier.
#
# + Code layout made more uniform with perltidy
# + Standerdized date format (ccyy-mm-dd)
# + Standerdized author list to use comma separator
# + Make use of perl $VERSION magic. Now $Version = version = ''
#
# Version 1.17 - 2004-01-14 (DJF)
# ------------
#
# + Really change dependance on MakeImage to MakeMOSImage and MakePNImage this time
#
# Version 1.16 - 2004-01-14 (DJF)
# ------------
#
# + Changed dependance on MakeImage to MakeMOSImage and MakePNImage
#
# Version 1.15 - 2003-12-09 (DJF)
# ------------
#
# + Adapted doCommand to use anonymous lists for list parameters
# + Changed final addattribute to avoid looping over it.
#
# Version 1.14 - 2002-13-11 (DJF)
# ------------
#
# + implot parameter changes. Merged plotfile/Device
#
# Version 1.13 - 2002-12-11 (DJF)
# ------------
#
# + Change implot parameter withsrclistset to withsrclisttab (SAS 5.4)
#
# Version 1.12 - 2001-05-31 (DH)
# ------------
#
# + More sophisticated selection of images. Now use only
# full frame images with flare gti files. Still defaults
# to using everything if no images pass the selection.
#
# Version 1.11 - 2001-05-11 (DH)
# ------------
#
# + Add double quotes to value string in addattribute.
# Needed because parameters are now lists.
#
# Version 1.10 - 2001-03-16 (DH)
# ------------
#
# + Print out version number in performAction() for
# tracking purposes.
#
# Version 1.09 - 2001-01-31 (DH)
# ------------
#
# + Bug fixes for version 1.08
#
# Version 1.08 - 2001-01-31 (DH)
# ------------
#
# + Use as input special created images, which
# results in only the MOS fov being included.
#
# Version 1.07 - 2001-01-10 (DH)
# ------------
#
# + Add ignore rule.
#
# Version 1.06 - 2000-12-15 (DH)
# ------------
#
# + First production version.
#
# Declare list of instruments this module is interested in
@instList = qw(epic);
# Number of streams
sub numberOfStreams
{
return 1;
}
# Rules method
sub evaluateRules
{
return ignore()
if ( allIgnored( module => 'MakeMOSImage' )
&& allIgnored( module => 'MakePNImage' ) );
start()
if ( allComplete( module => 'MakeMOSImage' )
&& allComplete( module => 'MakePNImage' )
&& complete(
module => 'ExpDetect',
, instrument => 'epic',
, stream => 1
) );
}
# Action method
sub performAction
{
info("Module version number: $version");
# get all band 8 images, exp maps and bkg maps.
info("Searching for components...");
my @fullImages;
foreach my $fullImages ( findFile(class => 'intermediate'
, content => 'raw image list'
, band => 8
)){
push @fullImages , readASCIIFile( name => $fullImages );
}
chomp(@fullImages);
my @fullMaps;
foreach my $fullMaps ( findFile(class => 'intermediate'
, content => 'exposure map list'
, band => 8
)){
push @fullMaps , readASCIIFile( name => $fullMaps );
}
chomp(@fullMaps);
my @bkgImList;
foreach my $bkgImList ( findFile(class => 'intermediate'
, content => 'background map list'
, band => 8
)){
push @bkgImList , readASCIIFile( name => $bkgImList );
}
chomp(@bkgImList);
info('Found: '. scalar(@fullImages) .' merged images , '. scalar(@fullMaps) .' exposure maps and '. scalar(@bkgImList) .' background maps' );
return success() unless (@fullImages && @fullMaps && @bkgImList);
# Got inputs, now make mosaic image
my $fitsMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION IMAGE'
);
doCommand(
'emosaic', imagesets => [@fullImages]
, mosaicedset => $fitsMosaic
, withexposure => 'N'
, forceuniformkwds => 'yes'
)
or return exception();
# Now also make mosaic of exposure maps
my $expmapFitsMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION EXPOSURE MAP'
);
doCommand(
'emosaic', imagesets => [@fullMaps]
, mosaicedset => $expmapFitsMosaic
, withexposure => 'N'
, forceuniformkwds => 'yes'
)
or return exception();
# Now also make mosaic of background maps
my $bkgmapFitsMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION BACKGROUND MAP'
);
doCommand(
'emosaic', imagesets => [@bkgImList]
, mosaicedset => $bkgmapFitsMosaic
, withexposure => 'N'
, forceuniformkwds => 'yes'
)
or return exception();
# Copy some keywords, as emosaic doesn't do this at the moment
my @keywords = (
'INSTRUME', 'BAND', 'DATAMODE', 'TELESCOP'
, 'OBS_ID', 'DATE-OBS', 'DATE-END', 'OBJECT'
, 'OBSERVER'
);
my @types = (
'string', 'integer', 'string', 'string', 'string', 'string'
, 'string', 'string', 'string'
);
my @strvalues = ( 'EPIC' );
my @intvalues=(8);
my @no=('no') x 9;
foreach ( @keywords[ 2 .. 8 ] )
{
push(
@strvalues
, (
hasFITSKeyword(
file => $fullImages[0]
, extension => 1
, keyword => $_
)
)
? readFITSKeyword(
file => $fullImages[0]
, extension => 1
, keyword => $_
)
: 'UNDEFINED'
);
}
doCommand(
'addattribute', set => $fitsMosaic
, attributename => [@keywords]
, attributetype => [@types]
, stringvalue => [@strvalues]
, integervalue => [@intvalues]
)
or return exception();
doCommand(
'addattribute', set => $expmapFitsMosaic
, attributename => [@keywords]
, attributetype => [@types]
, stringvalue => [@strvalues]
, integervalue => [@intvalues]
)
or return exception();
doCommand(
'addattribute', set => $bkgmapFitsMosaic
, attributename => [@keywords]
, attributetype => [@types]
, stringvalue => [@strvalues]
, integervalue => [@intvalues]
)
or return exception();
# Make graphics images:
my $gifMosaic = newFile(
class => 'intermediate'
, instrument => 'epic'
, band => 8
, content => 'IMAGE'
, 'format' => 'GIF'
);
my $pngMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION IMAGE'
, 'format' => 'PNG'
);
my $expmapGifMosaic = newFile(
class => 'intermediate'
, instrument => 'epic'
, band => 8
, content => 'EXPOSURE MAP'
, 'format' => 'GIF'
);
my $expmapPngMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION EXPOSURE MAP'
, 'format' => 'PNG'
);
my $bkgmapGifMosaic = newFile(
class => 'intermediate'
, instrument => 'epic'
, band => 8
, content => 'BACKGROUND MAP'
, format => 'GIF'
);
my $bkgmapPngMosaic = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC OBSERVATION BACKGROUND MAP'
, format => 'PNG'
);
my $ds9SrcRegions = newFile(
class => 'product'
, instrument => 'epic'
, content => 'EPIC SOURCE DS9 REGIONS'
, format => 'ASCII'
);
my $mlList = findFile(
class => 'product'
, instrument => thisInstrument
, content => 'EPIC observation ml source list'
);
if (fileExists( file => $mlList ))
{
my $tempSrcSet = newFile(
class => 'intermediate'
, content => 'Temporary source list'
);
doCommand(
'implot', set => $fitsMosaic
, device => "$pngMosaic/PNG"
, withsrclisttab => 'yes'
, srclisttab => $mlList.':SRCLIST'
, expression => 'ID_BAND==0 && ID_INST==0'
, tempset => $tempSrcSet
)
or return exception();
doCommand(
'implot', set => $expmapFitsMosaic
, device => "$expmapPngMosaic/PNG"
, withsrclisttab => 'yes'
, srclisttab => $mlList.':SRCLIST'
, expression => 'ID_BAND==0 && ID_INST==0'
, tempset => $tempSrcSet
)
or return exception();
doCommand(
'implot', set => $bkgmapFitsMosaic
, device => "$bkgmapPngMosaic/PNG"
, withsrclisttab => 'yes'
, srclisttab => $mlList.':SRCLIST'
, expression => 'ID_BAND==0 && ID_INST==0'
, tempset => $tempSrcSet
)
or return exception();
doCommand(
'slconv'
, srclisttab => "${mlList}:SRCLIST"
, expression => 'ID_BAND==0 && ID_INST==0'
, radiusexpression => 'RATE'
, radiusstyle => 'auto'
, withlabels => 'no'
, colour => 'green'
, outputstyle => 'ds9'
, outfilestyle => 'whole'
, outfile => $ds9SrcRegions
)
or return exception();
}
else
{
info("Source list not found - thus can't add source overlays to png images.");
doCommand(
'implot', set => $fitsMosaic
, device => "$pngMosaic/PNG"
, withsrclisttab => 'no'
)
or return exception();
doCommand(
'implot', set => $expmapFitsMosaic
, device => "$expmapPngMosaic/PNG"
, withsrclisttab => 'no'
)
or return exception();
doCommand(
'implot', set => $bkgmapFitsMosaic
, device => "$bkgmapPngMosaic/PNG"
, withsrclisttab => 'no'
)
or return exception();
}
# GIFtoPNG(
# source => $gifMosaic
# , destination => $pngMosaic
# )
# or return exception();
# GIFtoPNG(
# source => $expmapGifMosaic
# , destination => $expmapPngMosaic
# )
# or return exception();
# GIFtoPNG(
# source => $bkgmapGifMosaic
# , destination => $bkgmapPngMosaic
# )
# or return exception();
# Now we're going to make the threecolor image
my @filteredfiles8 = findFile(class => 'intermediate'
, band => 8
, content => 'image event list'
);
my @filteredlist8;
foreach my $file (@filteredfiles8) {
push @filteredlist8, "${file}:EVENTS";
}
my $rgbfileFits = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC THREECOLOUR IMAGE'
, format => 'FITS'
);
my $ppmfile = newFile(
class => 'intermediate'
, instrument => 'epic'
, band => 8
, content => 'EPIC THREECOLOUR IMAGE'
, format => 'PPM'
);
# Find spacecraft attitude file
my $attFile=findFile(
class => 'product'
, instrument => 'all'
, content => 'Attitude time series'
, required => 'true'
);
doCommand('etruecolor'
, tablelist => \@filteredlist8
, ppmfile => $ppmfile
, fileset => $rgbfileFits
, attfile => $attFile
, minexptime => 500
) or return exception();
# if (fileExists( file => $mlList )){
# doCommand('implotrgb'
# , set => $rgbfileFits
# , device => "$ppmfile/PPM"
# , withsrclisttab => 'yes'
# , srclisttab => $mlList.':SRCLIST'
# , expression => 'ID_BAND==0 && ID_INST==0'
# ) or return exception();
# } else {
doCommand('implotrgb'
, set => $rgbfileFits
, device => "$ppmfile/PPM"
, withsrclisttab => 'no'
) or return exception();
# }
my $pngfile = newFile(
class => 'product'
, instrument => 'epic'
, band => 8
, content => 'EPIC THREECOLOUR IMAGE'
, format => 'PNG'
);
doCommand("convert '$ppmfile' '$pngfile'") or return exception();
return success();
}
1;