Package invocations :: Package cu2 :: Module cu2jpeg
[hide private]

Source Code for Module invocations.cu2.cu2jpeg

  1  #! /usr/bin/env python 
  2  #------------------------------------------------------------------------------ 
  3  #$Id: cu2jpeg.py 7582 2010-10-01 11:22:55Z EckhardSutorius $ 
  4  """ 
  5     Make JPEGS of pixel data. This will make compressed images for all pixel 
  6     data in the input transfer log. 
  7   
  8     @author: E. Sutorius 
  9     @org:    WFAU, IfA, University of Edinburgh 
 10   
 11     @newfield contributors: Contributors, Contributors (Alphabetical Order) 
 12     @contributors: R.S. Collins 
 13   
 14     @requires: PyFITS 
 15  """ 
 16  #------------------------------------------------------------------------------ 
 17  import getopt 
 18  import math 
 19  import os 
 20  import re 
 21  import shutil 
 22  import sys 
 23   
 24  from   wsatools.DbConnect.IngIngester import IngestLogger as Logger 
 25  import wsatools.FitsUtils                 as fits 
 26  import wsatools.jpeg                      as jpeg 
 27  from   wsatools.Logger                import ForLoopMonitor 
 28  from   wsatools.SystemConstants       import SystemConstants 
 29  import wsatools.Utilities                 as utils 
 30  #------------------------------------------------------------------------------ 
 31  # Constants 
 32  contrast = 0.25  #: Greyscale contrast: structures: 0.25; smooth: 1.042 
 33  quality = 90     #: JPEG quality (0-100). 
 34  scrunch = 2      #: Pixel super bin size in rebinning process. 
 35  re_datevers = re.compile(r'((\d{8})_v(\d)(.{0,1}\d+))') 
 36  #------------------------------------------------------------------------------ 
 37   
38 -def createThumbnailImage(fileName, compName, cu2Path, dateVersStr):
39 """ 40 Creates a JPEG thumbnail image of the given FITS file. 41 42 @param fileName: Full path to the FITS file. 43 @type fileName: str 44 @param compName: Full path for the JPEG thumbnail image. 45 @type compName: str 46 @param cu2Path: Path to the CU2 directory. 47 @type cu2Path: str 48 @param dateVersStr: Date-version string of the processed file batch. 49 @type dateVersStr: str 50 51 """ 52 fitsFile = fits.open(fileName) 53 54 # Just want arrays with 2D image data 55 arrays = [hduNo for hduNo, hdu in enumerate(fitsFile) 56 if hdu.header["NAXIS"] is 2 and 57 (hdu.header.has_key("SIMPLE") 58 or hdu.header.get("XTENSION") == "IMAGE" 59 or hdu.header.get("XTENSION") == "BINTABLE" and 60 hdu.header.has_key("ZIMAGE"))] 61 62 # Dictionary mapping HDU number to compressed image filename 63 compMap = dict((str(arrayNum + 1), 64 compName + "_%s.jpg" % fitsFile[arrayNum].header["CAMNUM"]) 65 for arrayNum in arrays) 66 67 # Determine co-ordinate system and rotation 68 coordsFileName = "coords-%s.tbl" % dateVersStr 69 if "TAN" in fitsFile[1].header["CTYPE1"]: 70 shutil.copy2(os.path.join(cu2Path, "skycoords.tbl"), 71 os.path.join(cu2Path, coordsFileName)) 72 rotation = math.pi 73 else: # ZPN 74 shutil.copy2(os.path.join(cu2Path, "earthcoords.tbl"), 75 os.path.join(cu2Path, coordsFileName)) 76 rotation = 0.0 77 78 # Mosaic images split into parts don't receive a N-E overlay 79 isOverlay = not any(part in fileName for part in ["_p1_", "_p2_", "_p3_"]) 80 81 Logger.setEchoOff() 82 try: 83 Logger.addMessage("MEF = %s %r" % (fileName, arrays)) 84 85 # Make the JPEGs 86 info = jpeg.mef2jpeg(mef=fileName, coordfile=coordsFileName, 87 scrunch=scrunch, quality=quality, 88 contrast=contrast, hdumap=compMap, 89 neoverlay=isOverlay, theta=rotation) 90 91 # Parse output info from the jpeg module 92 for hdu in info: 93 Logger.addMessage(compMap[hdu] + " %s %s %s" % info[hdu]) 94 finally: 95 Logger.setEchoOn()
96 97 #------------------------------------------------------------------------------ 98
99 -def main(argv):
100 '''Make JPEGS of pixel data. This will make compressed images for all 101 pixel data in the input transfer log. 102 103 curator is a string identifying the archive curation scientist 104 that instigated this invocation; 105 xferlog is the filename of the logged successful file transfers 106 from the data processing centre. 107 outpath path where products/jpgs is created 108 comment is a string for the archive curation scientist to 109 supply an optional note for recording in the curation 110 history; 111 ''' 112 113 # read the arguments 114 try: 115 opts, args = getopt.getopt(argv[1:], "o:", ["outpath="]) 116 117 except getopt.GetoptError: 118 # print help information and exit: 119 print argv 120 print "usage: cu2jpeg.py [-o/--outpath path] curator xferlog comment" 121 raise SystemExit 122 123 jpgPath = None 124 for o, a in opts: 125 if o in ("-o", "--outpath"): 126 jpgPath = a 127 128 if len(args) != 3: 129 print argv 130 print "usage: cu2jpeg.py [-o/--outpath path] curator xferlog comment" 131 raise SystemExit 132 133 _curator = args[0] 134 xferlog = args[1] 135 _comment = args[2] 136 137 # @@TODO: Remove WSA hard-wire with a command-line option or parse existing 138 sysc = SystemConstants("WSA") 139 140 # The CU identification number of this script: 141 cuNum = 2 142 cu2Path = os.path.join(sysc.curationCodePath(), "invocations/cu2") 143 curPath = os.curdir 144 os.chdir(cu2Path) 145 146 Logger.addMessage("Running Curation Use case %s on %s" % (cuNum, xferlog)) 147 try: 148 dateVersStr = re_datevers.search(xferlog).group() 149 except AttributeError: 150 dateVersStr = "99991231_v0" 151 152 # produce the compressed images first 153 xferlines = utils.ParsedFile(xferlog).readlines() 154 progress = ForLoopMonitor(xferlines) 155 for filename in xferlines: 156 inDisk, outDir = os.path.split(os.path.dirname(filename)) 157 158 if jpgPath: 159 outDisk = jpgPath 160 elif sysc.testOutputPath() in inDisk: 161 outDisk = sysc.testOutputPath() 162 else: 163 outDisk = utils.getNextDisk(sysc) 164 165 outPath = os.path.join(outDisk, sysc.compressImDir, outDir) 166 utils.ensureDirExist(outPath) 167 168 compName = os.path.join(outPath, 169 os.path.splitext(os.path.basename(filename))[0]) 170 171 # @@TODO: This exception trap could be made more precise if the 172 # TypeError etc. were tested on the exact line where they are expected 173 # and a NotFITSError or MissingKeywordError were then thrown to be 174 # caught here. 175 try: 176 createThumbnailImage(filename, compName, cu2Path, dateVersStr) 177 except IndexError: 178 Logger.addMessage(filename +" missing required keywords. Skipping") 179 except TypeError: 180 # If HDU info came from a FITS file, the TypeError exception would 181 # not be thrown 182 Logger.addMessage(filename +" probably not FITS. Skipping") 183 except KeyError: 184 for i in range(1,5): 185 shutil.copy("noImage.jpg", compName + "_%s.jpg" % i) 186 187 progress.testForOutput() 188 189 # Create a log file name to hold the verbose record for this invocation: 190 191 logPathName = os.path.join(cu2Path, "tmplog%s_%s.log" % (cuNum, 192 os.path.splitext(os.path.basename(xferlog))[0])) 193 counter = 0 194 while os.path.exists(logPathName): 195 counter += 1 196 logPathName = \ 197 ''.join(logPathName.partition(".log")[0:2]) + str(counter) 198 199 Logger.dump(file(logPathName, 'w')) 200 os.chdir(curPath)
201 202 #------------------------------------------------------------------------------ 203 204 if __name__ == '__main__': 205 main(sys.argv) 206 207 #------------------------------------------------------------------------------ 208 # Change log: 209 # 210 # 11-Aug-2004, ETWS: Refactoring to implement latest changes to the 211 # data model along the lines of CU3 212 # 27-Jan-2005, ETWS: Refactored using pyfits instead of xheader 213 # 16-Feb-2005, ETWS: changed jpg directory name to the same as the 214 # input fits directory name (ie. observing date) 215 # 11-Apr-2005, ETWS: Included default image for files with fits key 216 # errors in their header. 217 # fixed the NextCuEventId DB update 218 # 6-May-2005, ETWS: Included os.umask setting to utils.checkDirExist, 219 # so mode will be set correctly 220 # 27-May-2005, ETWS: included cuNum in getNextCurationEventID 221 # 26-Sep-2005, RSC: now uses utils.checkDirExist instead of local function 222 # 17-Nov-2005, ETWS: Restricted output to disks on khufu; 223 # removed MultiframeID lookup, run 224 # helpers/CreateMfIdJpegList.py after CU2 has finished. 225 # 6-Jan-2006, ETWS: included xferlog name in screen output 226 # 29-Mar-2006, JB: Changed disklist to use all available disks constant 227 # 2-May-2006, RSC: Renamed checkDirExist() to ensureDirExist() 228 # 5-Jul-2006, RSC: * Removed obsolete function write_comp_logfile() 229 # * Obviated need for "from wsatools import *" statement 230 # 10-Jul-2006, RSC: Replaced string module functions with str() equivalents as 231 # the string module with be obsoleted in Python 3.0 232 # 25-Jul-2006, ETWS: Included production of mosaic jpegs 233 # 7-Sep-2006, ETWS: Fixed bug in CTYPE test 234 # 6-Mar-2007, RSC: Moved JPEG constants to here from SystemConstants. 235 # Moved getImageArrays() to here from deprecated Metadata. 236 # 12-Mar-2007, ETWS: Fixed unfinished renaming. 237 # 01-May-2007, ETWS: Updated for use with CU0 238 # 11-May-2007, ETWS: Better catching of missing keyword error. 239 # 10-Jul-2007, ETWS: Updated for use with test cases. 240 # 8-Jan-2008, ETWS: Excluded excludedRaidFileSystem from jpgdisklist. 241 # 24-Jan-2008, ETWS: Enhanced tmplog file naming. 242 # 29-Jan-2008, ETWS: Included contrast in asinh scaling. 243 # 27-May-2008, RSC: Updated to use ZIMAGE instead of EXTNAME FITS keywords. 244 # 1-Aug-2008, ETWS: Pass coordsFileName to C code to allow running on 245 # multiple processors simultaneously 246