function READ_AMIE, filename, lbl, noshift = noshift, $ orientation = orientation, silent = silent, nodummy = nodummy ;+ ; $Log: READ_AMIE.PRO,v $ ; Revision 1.3 2010/03/30 11:57:40 bgrieger ; Check if the keyword SAMPLE_BIT_MASK is actually present in the label, and ; only if so, try to apply the bit mask. This has become necessary as we do ; now use a SCALING_FACTOR instead of the SAMPLE_BIT_MASK. ; ; Revision 1.2 2008/01/30 11:33:37 bgrieger ; If the SAMPLE_TYPE of the second object (the image) is ; PC_REAL, create and return a fltarr instead of a lonarr. ; Modified Files: ; READ_AMIE.PRO ; ; Revision 1.1 2008/01/10 18:42:38 smartinez ; 2008 Jan 10 sm First version added to the PSA/MISSIONS/SM1/ repository ; ; Revision 1.6 2007/12/05 09:43:58 bgrieger ; Extended the case of correcting a byte mismatch to full frame images. ; Modified Files: ; READ_AMIE.PRO ; ; Revision 1.5 2007/06/19 11:15:53 bgrieger ; Added nodummy keyword. ; Modified Files: ; READ_AMIE.PRO ; ; Revision 1.4 2007/06/19 10:39:49 bgrieger ; Added passing through of the /SILENT option. ; Modified Files: ; AMIE_COMBINE.PRO READ_AMIE.PRO ; ; Revision 1.3 2007/06/13 17:10:16 bgrieger ; AMIE_COMBINE: ; ; V1.5 - 2007 Jun 13, 18h00m, bg - Do not assume anymore that the filter ; ; number is character number 7 in the file ; ; name, but use stregex to get its position ; ; - Deleted a few lines which were commented ; ; out anyway. ; ; ; READ_AMIE: ; ; 2007 Jun 13, V1.7, bg: Treat DATA_QUALITY_ID=-1 by first calling HEADPDS and not ; ; calling READPDS if this is the case. Otherwise non existing ; ; data would cause an error. ; ; ; Modified Files: ; AMIE_COMBINE.PRO READ_AMIE.PRO ; ; Revision 1.2 2007/06/04 16:43:41 bgrieger ; ; 2007 Jun 04, V1.6, bg: Added correction of an erroneous exchange of LINES and ; ; LINE_SAMPLES which is present in the PDS headers of some image ; ; files. ; Modified Files: ; READ_AMIE.PRO ; ; Revision 1.1 2007/05/25 14:24:25 smartine ; 2007.05.25, SM: Added AMIE_COMBINE.PRO and READ_AMIE.PRO ; ; Revision 1.3 2007/05/25 11:20:10 dkoschny ; Added the $Log: READ_AMIE.PRO,v $ ; Added the Revision 1.3 2010/03/30 11:57:40 bgrieger ; Added the Check if the keyword SAMPLE_BIT_MASK is actually present in the label, and ; Added the only if so, try to apply the bit mask. This has become necessary as we do ; Added the now use a SCALING_FACTOR instead of the SAMPLE_BIT_MASK. ; Added the ; Added the Revision 1.2 2008/01/30 11:33:37 bgrieger ; Added the If the SAMPLE_TYPE of the second object (the image) is ; Added the PC_REAL, create and return a fltarr instead of a lonarr. ; Added the Modified Files: ; Added the READ_AMIE.PRO ; Added the ; Added the Revision 1.1 2008/01/10 18:42:38 smartinez ; Added the 2008 Jan 10 sm First version added to the PSA/MISSIONS/SM1/ repository ; Added the ; Added the Revision 1.6 2007/12/05 09:43:58 bgrieger ; Added the Extended the case of correcting a byte mismatch to full frame images. ; Added the Modified Files: ; Added the READ_AMIE.PRO ; Added the ; Added the Revision 1.5 2007/06/19 11:15:53 bgrieger ; Added the Added nodummy keyword. ; Added the Modified Files: ; Added the READ_AMIE.PRO ; Added the ; Added the Revision 1.4 2007/06/19 10:39:49 bgrieger ; Added the Added passing through of the /SILENT option. ; Added the Modified Files: ; Added the AMIE_COMBINE.PRO READ_AMIE.PRO ; Added the ; Added the Revision 1.3 2007/06/13 17:10:16 bgrieger ; Added the AMIE_COMBINE: ; Added the ; V1.5 - 2007 Jun 13, 18h00m, bg - Do not assume anymore that the filter ; Added the ; number is character number 7 in the file ; Added the ; name, but use stregex to get its position ; Added the ; - Deleted a few lines which were commented ; Added the ; out anyway. ; Added the ; ; Added the READ_AMIE: ; Added the ; 2007 Jun 13, V1.7, bg: Treat DATA_QUALITY_ID=-1 by first calling HEADPDS and not ; Added the ; calling READPDS if this is the case. Otherwise non existing ; Added the ; data would cause an error. ; Added the ; ; Added the Modified Files: ; Added the AMIE_COMBINE.PRO READ_AMIE.PRO ; Added the ; Added the Revision 1.2 2007/06/04 16:43:41 bgrieger ; Added the ; 2007 Jun 04, V1.6, bg: Added correction of an erroneous exchange of LINES and ; Added the ; LINE_SAMPLES which is present in the PDS headers of some image ; Added the ; files. ; Added the Modified Files: ; Added the READ_AMIE.PRO ; Added the ; Added the Revision 1.1 2007/05/25 14:24:25 smartine ; Added the 2007.05.25, SM: Added AMIE_COMBINE.PRO and READ_AMIE.PRO ; Added the keyword ; ; ; NAME: ; READ_AMIE ; ; PURPOSE: ; Reads an AMIE label and image file into an 'image' array and 'label' array. ; ; CATEGORY: ; AMIE STANDARD routines ; ; CALLING SEQUENCE: ; image = READ_AMIE (filename, label) ; ; INPUTS: ; file name of input file. ; ; OPTIONAL INPUT PARAMETERS: ; noshift: Used only when reading images in the old '*.mmi' format. ; The pixels in the image are stored in the upper 10 bit of ; 2 byte, i.e. to properly display them they have to be bit-shifted ; down by 6 byte. If NOSHIFT is not set, this shift will be ; performed. If NOSHIFT is set to one, the shift will be ; supressed. ; ; orientiation: This flag specifies the orientation READ_AMIE will read images. ; Options are: 'CCD_FRAME', 'REAL_WORLD'. If this keyword is not ; present, 'REAL_WORLD' will be used. ; See also S1-AMI-RSSD-TN-001/1d, Figure 11. ; ; CCD_FRAME will give the following orientation: ; ; y ^ ; CCD | ; | ; | ; | ; +-------> x ; CCD ; ; REAL_WORLD will give the following orientation: ; ; +-------> x ; | CCD ; | ; | ; | ; v ; y ; CCD ; ; This view corresponds to what an observer would see if he sat ; on the spacecraft with his feet mounted on the side plane of ; Smart-1 just as AMIE, looking in the direction of the line of ; sight of the camera. ; ; nodummy: When an image file is present, but does not contain image data ; (DATA_QUALITY_ID=-1), by default a dummy image is created and ; returned. This behaviour can be switched off by passing a ; nonzero value to nodummy. Then just the scalar value -nodummy is ; returned, e.g., providing /nodummy (which means nodummy=1), the ; scalar value -1 is returned. ; ; OUTPUTS: ; image: a structure containing the browse image and the full image: ; image.images: the number of images, LONG value ; image.image0: a 128 x 128 array containing an 8 bit downsampled image (BYTE) ; image.image1: a LONG array containing the image, the size depends ; on the filter the AMIE data file contains. ; COMMON BLOCKS: ; None. ; ; SIDE EFFECTS: ; Hopefully none. ; ; RESTRICTIONS: ; No restrictions ; ; EXAMPLE: ; The following program will read all AMIE images in a directory selected ; with dialog_pickfile. It will display the first image, wait for one ; second, then go to the next image, etc. ; ; ============================================= ; pro read_all_AMIE ; ; ;select a directory ; directory = dialog_pickfile (/dir) ; ;read in all file names ; filelist = file_search (directory, '*.img') ; print, filelist ; ; ;loop through all files and display them ; window, xsize = 512, ysize = 512 ; for i = 0, n_elements (filelist) - 1 do begin ; image = READ_AMIE (filelist (i)) ; tvscl, image.image1 ; wait, 1.0 ; endfor ; ; end ;pro ; ============================================= ; ; MODIFICATION HISTORY: ; ; 2003 Oct 13, V0.9: function adapted from the read_AMIEw procedure ; 2003 Oct 24, V1.0: possibility not to shift the bits with a keyword ; 2004 Mar 26, V1.1: minor updates and extense commenting ; 2005 Sep 06, V1.2, dvk: replaced image.image1 with image.image for new tag names ; 2005 Sep 26, V1.3, dvk: update to be compatible new PDS routine READPDS and ; doing some cleaning up, added documentation. Added a ; rotate (image, 2) to get the image into the 'real' ; orientation. ; 2007 May 16, V1.4, dvk: Updated the rotation after discussion with ; Bj"orn. Introduced the keyword 'orientation'. ; 2007 May 21, V1.5, bg: Added shifting of the most significant ; byte of each pixel by one pixel to compensate ; errors in the PDS headers of the current image ; files, cf. S1-AMIE-RSSD-RP-007. If the errors ; in the file headers are corrected, READ_AMIE ; should still run correctly without changes. ; 2007 Jun 04, V1.6, bg: Added correction of an erroneous exchange of LINES and ; LINE_SAMPLES which is present in the PDS headers of some image ; files. ; 2007 Jun 13, V1.7, bg: Treat DATA_QUALITY_ID=-1 by first calling HEADPDS and not ; calling READPDS if this is the case. Otherwise non existing ; data would cause an error. ; 2007 Jun 19, V1.8, bg: Added passing the silent option to READPDS routines. ; Added the 'nodummy' keyword. ; 2007 Dec 05, V1.9, bg: Extended the case of correcting a byte mismatch ; (cf. V1.5) to full frame images in order to correctly ; read old laboratory master flat fields. ; 2008 Jan 30, V1.10, bg: If the SAMPLE_TYPE of the second object (the image) is ; PC_REAL, create and return a fltarr instead of a lonarr ;- ;---------------------------------------------------------------------------------------- ;sets the keywords and perform some testing ;---------------------------------------------------------------------------------------- if keyword_set (noshift) then shft = 0 else shft = 1 if keyword_set (orientation) then orientation = orientation else $ orientation = 'REAL_WORLD' if (orientation NE 'REAL_WORLD') and (orientation NE 'CCD_FRAME') then $ message, '[ERROR] Wrong value for keyword "ORIENTATION"' if keyword_set (silent) then silent = silent else silent = 0 if keyword_set (nodummy) then nodummy = nodummy else nodummy = 0 ;---------------------------------------------------------------------------------------- ;Check if image file exists. If it doesn't returns -1 ;---------------------------------------------------------------------------------------- fileexists = file_test (filename) if fileexists NE 1 then begin message, '[ERROR] no file selected' return, -1 endif ;---------------------------------------------------------------------------------------- ;determine the extension which was actually used ;---------------------------------------------------------------------------------------- extension = str_sep (filename, '.') extension = extension (n_elements (extension) - 1) extension = strlowcase (extension) ;---------------------------------------------------------------------------------------- ;reads the image depending on the extension ;---------------------------------------------------------------------------------------- case extension of 'img': begin ;extension is 'img', read data label by calling HEADPDS lbl = HEADPDS (filename, silent=silent) data_quality_id = pdspar( lbl, 'DATA_QUALITY_ID' ) if data_quality_id eq -1 then begin if nodummy eq 0 then begin ;create dummy image structure and return without calling readpds sizes = pdspar( lbl, 'LINE_SAMPLES' ) xsize = sizes[1] sizes = pdspar( lbl, 'LINES' ) ysize = sizes[1] image = create_struct ('objects', 2, 'image0', $ bytarr (128, 128), 'image1', lonarr (xsize, ysize)) image.objects = 2 image.image0 = 0 image.image0[32:64,56:64]= 128 image.image0[80:88,32:96]= 128 image.image0[72:96,32:40]= 128 image.image0[72:88,88:96]= 128 image.image1 = 0 a=xsize/2-96 b=ysize/2-32 image.image1[32+a:64+a,56+b:64+b]= 512 image.image1[80+a:88+a,32+b:96+b]= 512 image.image1[72+a:96+a,32+b:40+b]= 512 image.image1[72+a:88+a,88+b:96+b]= 512 return, image endif else return, -nodummy endif ; read image data ;For some strange reason the READPDS routine as of V4.1.1 creates a very ;strange structure. We reform this structure to be compatible with the ;prevous version, namely we return image.image1 (for the actual image) ;and image.image0 (browse_image). temp = READPDS (filename, silent=silent) ;get the image size of the actual image, needed for creating the structure ;of the right size xsize = (size (temp.browse_image.image))(1) ysize = (size (temp.browse_image.image))(2) ; Correct for an erroneous exchange of LINES and LINE_SAMPLES in some PDS ; headers. ; Before and after the image is reformed, it has to be flipped in order to ; match the sequence of pixels in the original file with the order of pixels ; in the array as stored by IDL. filter = pdspar( lbl, 'FILTER_NAME' ) if strpos( filter, '_Y' ) ne -1 then begin if xsize ne 512 or ysize ne 256 then begin if xsize eq 256 and ysize eq 512 then begin xsize = 512 ysize = 256 temp.browse_image.image = rotate( rotate( reform( $ rotate( rotate( temp.browse_image.image, 1 ), 4 ), xsize, ysize ), 1 ), 4 ) print, 'Exchanged xsize and ysize.' endif else begin print, 'Dimensions not valid:' print, 'filter =', filter print, 'xsize =', xsize print, 'ysize =', ysize stop endelse endif endif if strpos( filter, '_X' ) ne -1 then begin if xsize ne 256 or ysize ne 512 then begin if xsize eq 512 and ysize eq 256 then begin xsize = 256 ysize = 512 temp.browse_image.image = rotate( rotate( reform( $ rotate( rotate( temp.browse_image.image, 1 ), 4 ), xsize, ysize ), 1 ), 4 ) print, 'Exchanged xsize and ysize.' endif else begin print, 'Dimensions not valid:' print, 'filter =', filter print, 'xsize =', xsize print, 'ysize =', ysize stop endelse endif endif ;create new image structure and fill it with data sample_type = pdspar( lbl, 'SAMPLE_TYPE', count = stcount ) if sample_type[1] eq 'PC_REAL' then begin print, 'READ_AMIE: SAMPLE_TYPE is PC_REAL, creating FLTARR for image.' image = create_struct ('objects', 2, 'image0', $ bytarr (128, 128), 'image1', fltarr (xsize, ysize)) endif else begin image = create_struct ('objects', 2, 'image0', $ bytarr (128, 128), 'image1', lonarr (xsize, ysize)) endelse image.objects = 2 image.image0 = temp.browse_image.browse_image image.image1 = temp.browse_image.image ; Begin of shifting of bytes to compensate errors in the PDS headers ; of the currently available image files (2007-May-21). The most ; significant byte of each pixel has to be shifted to the preceeding ; pixel, while the least significant has to stay where it is. See ; S1-AMIE-RSSD-RP-007 for a detailed description of the error. object = pdspar( lbl, 'OBJECT', count = ocount ) if ocount ne stcount then begin print, 'Number of OBJECT labels is', ocount print, 'Number of SMAPLE_TYPE labels is', stcount print, 'Cannot match.' stop endif for icount = 0, ocount-1 do begin if object[ icount ] eq 'IMAGE' then break endfor if icount eq ocount then begin print, 'No object IMAGE found.' stop endif if strpos( sample_type[ icount ], 'MSB' ) ne -1 then begin pointer = pdspar( lbl, '^IMAGE' ) if pointer eq '36864 ' or pointer eq '53248 ' then begin ; Now we do the shift. The image is ; defined as long (4 byte) integer. On ; little-endian systems, the byte ; order is ; LSB, MSB, 0, 0 ; On big-endian systems, the byte ; order is ; 0, 0, MSB, LSB ; If we count the 4 bytes of a pixel ; value as 0-3, we may just shift byte 1 ; and 2 without the need to know on ; which architecture we are. bytes = bytarr( 4, xsize, ysize ) bytes = byte( image.image1, 0, 4, xsize, ysize ) for ibyte = 1, 2 do begin for iy = ysize-1, 0, -1 do begin for ix = 0, xsize-2 do begin bytes( ibyte, ix, iy ) = bytes( ibyte, ix+1, iy ) endfor if iy gt 0 then begin bytes( ibyte, xsize-1, iy ) = bytes( ibyte, 0, iy-1 ) endif else begin ; The MSB of the very last pixel has ; not been returned by READPDS. We set ; it to the mean of the two adjacent pixels: bytes( ibyte, xsize-1, 0 ) = 0.5 * $ ( bytes( ibyte, xsize-2, 0 ) + bytes( ibyte, xsize-1, 1 ) ) endelse endfor endfor for ix = 0, xsize-1 do begin for iy = 0, ysize-1 do begin image.image1[ ix, iy ] = bytes[ 0, ix, iy ] + $ bytes[ 1, ix, iy ] * 65536 / 256 + $ bytes[ 2, ix, iy ] * 65536 / 256 + $ bytes[ 3, ix, iy ] ; Multiplication by 65536/256 instead ; of just multiplication by 256 to ; prevent automatic type conversation to signed ; short int. endfor endfor endif endif ; End of shifting of bytes. ;check whether the image needs to be bitshifted (only for old versions, ;we used the bit mask in a wrong way, it has been replaced by a scaling ;factor, which is handled by readpds) sample_bit_mask = PDSPAR (lbl, 'SAMPLE_BIT_MASK') ; print, size( sample_bit_mask, /DIMENSIONS ) if size( sample_bit_mask, /DIMENSIONS ) GT 0 then begin ; print, "bit shift" if sample_bit_mask (1) EQ '"2#1111111111000000#"' then begin image.image1 = ISHFT (image.image1, -6) endif endif end ;img files 'pds': begin ;extension is 'pds', read header and image data ;This is historical, the first AMIE PDS images had this extension ;but it should not be used. Kept for compatibility reasons. ;Note that the 'simple_read_pds' routine is really simple. ;The use of images with the extension 'pds' is discouraged. ;dvk, V1.3 image = simple_read_pds (filename, lbl) if shft eq 1 then begin image = ISHFT (image, -6) endif end ;pds files 'mmi': begin ;The original AMIE binary format image=intarr (1024, 1024) openr, 1, filename readu, 1, image close, 1 if shft eq 1 then begin image = ISHFT (image, -6) endif end else: begin message, '[ERROR] file extension not supported' return, -1 end endcase if orientation EQ 'CCD_FRAME' then begin image.image0 = rotate (rotate (image.image0, 1), 4) image.image1 = rotate (rotate (image.image1, 1), 4) endif ; if orientation is 'REAL_WORLD' nothing needs to be done. return, image end ;procedure READ_AMIE