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;