;-------------------------------------------------------------------------- ; PROGRAM: showquick.pro ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CURRENT VERSION: 1.2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RELEASE DATE: Jan 13, 2009 ;-------------------------------------------------------------------------- ; Purpose: ; Display quicklook format (*.samp.??) images created by ; NewMas in a scrolling window. You choose roll, pitch, and lat-lon ; information from either IRIG or POS/AV depending the quicklook images ; created by NewMas. Scanline (on left-side) and UTC time (on right-side) ; will be displayed in every 2 Minutes in white color. Any roll angles ; greater than the threshold (7/15 degrees you selected) will be marked ; on both side with red color. Any pitch angle greater than you entered ; will marked in right-side in cyan color. Lat/Lon information will be ; marked on right-side in yellow color with every 2 minute increment ; and 1 minute apart from UTC marks. ; ; ;---------------------------------------------------------------------- ; MODIFICATIONS ; ; 22-Jan-2000 -- (Selwyn Yee) Adapted to read new newmas output of unsigned ; int. Do histogram equalization stretch (even when /equalize ; not set) to properly display large dynamic range of ; unsigned int (0 to 65,535). ; ; 31-Jan-2000 -- (Selwyn Yee) reversed the time and roll to match the image. ; Originally the image was being reversed, but not the time ; or the roll. Perhaps the program which used to create input ; for showquick (before newmas) already reversed the time and roll. ; ; 12-Feb-2000 -- (Selwyn Yee) Added ability to do percent stretch (typically ; 1% or 2%) using ShowQuick_Trunc_Intensity(). ; ; 19-Mar-2003 -- (Rich Moyer) ENVI 3.5 version of showquick to reverse Y direction ; of the image. ; ; 26-Jan-2005 -- (JMG) Added display latitude & longitude at every two minutes ; starting on the first odd minute. Lat & Lon are converted to ; deg,min.hundreths. ; Added ENVI GUI prompt for default Roll Threshold ; (7.0 or 15.0 degrees). ; ; 28-Mar-2005 -- (RAM) Added record count on left side corresponding to the times ; recorded on the right side of the image. ; ; 27-Apr-2006 -- (HSU) Added button to check for POS-AV roll data in Subsamp ; ; 1-May-2006 -- (HSU) Added multiple part of display capability if Subsamp image ; line size is over limit (32567). ; ; 23-Dec-2008 -- (HSU) Modified "yes" or "no" request GUI display to simplify ; the GUI process (Requested by Rose) ; ; 29-Dec-2008 -- (HSU) Merged threshod and roll GUIs into one per Rose ; request. ; (HSU) Set version number as 1.0 ; ; 02-Jan-2009 -- (HSU) Added white and cyan color for plotting roll threshold ; and pitch angles (original color doesn't work, problem of ; using a color table predefined but not found) ; ; 06-Jan-2009 -- (HSU) Moved right side labels to edge to avoid overlap with ; roll and pitch bars; Only changed Lat/Lon to blue ; color; Changed roll bar and labels to red color. ; Release v. 1.1. ; ; 13-Jan-2009 -- (HSU) As Rose suggested to add pitch angle input for plotting. ; re-arrange all inputs into one panel(GUI) for convience. ; Release Version 1.2. ; Changed Lat/Lon color to Yellow per Rose's request ; ; 05-Oct-2009 -- (HSU) Fixed "pitch_threshold" with "float" type ; ; 27-May-2010 -- (HSU) Fixed "pitch_field" for ENVI 4.6, which treats it ; as array (pitchmax value is defined now). ; ; 01-Apr-2019 -- (RTD) Updated /atac/ reference to /asf/ ; ; 02-Oct-2023 -- (RTD) Modified default pitch value to 3.0 degrees. ; ;----------------------------------------------------------------------------- ; Following function/procedure added ; 1) Function ShowQ_Roll ; 2) Pro ShowQ_Roll_Event ;--------------------------------------------------------------------- FUNCTION ShowQ_Roll, tlb On_Error, 2 base = Widget_Base(Column=4, /Modal, Group_Leader=tlb, XOffset=50, $ YOffset=50, Title='Input Parameters') pos_strings = ['IRIG','POS/AV'] pos_base = Widget_Base(base, Row=1, /Frame) pos_but = CW_BGroup(pos_base, pos_strings, $ Set_Value=0, /Exclusive, /Frame, $ Label_Top='Roll Source') roll_strings = ['7 Degrees', '15 Degrees'] roll_base = Widget_Base(base, Row=1, /Frame) roll_but = CW_BGroup(roll_base, roll_strings, $ Set_Value=0, /Exclusive, /Frame, $ Label_Top='Roll Threshold') pitch_base =Widget_Base(base, Row=1, /Frame) pitch_field =CW_Field(pitch_base, Title="Pitch Threshold", $ Value=3.0, /Frame, /Column) butbase = Widget_Base(base, Row=1, Frame=1) accept_but = Widget_Button(butbase, Value='Accept') Widget_Control, base, /Realize roll_ptr = Handle_Create() pos_ptr = Handle_Create() pitch_field_ptr = Handle_Create() accept_ptr = Handle_Create() info = {roll_but:roll_but, $ pos_but:pos_but, $ pitch_field:pitch_field, $ accept_but:accept_but, $ roll_ptr:roll_ptr, $ pos_ptr:pos_ptr, $ pitch_field_ptr:pitch_field_ptr, $ accept_ptr:accept_ptr $ } Widget_Control, base, Set_UValue=info, /No_Copy ; Register base with XManager as a modal (blocking) widget XManager, 'ShowQ_Roll', base, Event_Handler='ShowQ_Roll_Event' Handle_Value, accept_ptr, accept_but, /No_Copy IF accept_ptr THEN BEGIN Handle_Value, roll_ptr, roll_but, /No_Copy Handle_Value, pos_ptr, pos_but, /No_Copy Handle_Value, pitch_field_ptr, pitch_field, /No_Copy stuff = {roll_but:roll_but, pos_but:pos_but, $ pitch_field:pitch_field} Handle_Free, roll_ptr Handle_Free, pos_ptr Handle_Free, pitch_field_ptr ENDIF ELSE BEGIN stuff = {roll_but:0,pos_but:0, pitch_field:0} ENDELSE Handle_Free, accept_ptr Return, stuff END ; ShowQ_Roll ;------------------------------------------------------------------------------ ; Event handler for ShowQ_Roll widget PRO ShowQ_Roll_Event, event ; Catch errors which would otherwise be fatal to runtime ENVI. On_Error, 2 catch, err_var if err_var ne 0 then begin Err_Mesg = ['Error in Showquick:', $ !Err_String] result = widget_message (Err_Mesg, /error) return endif Widget_Control, event.top, Get_UValue=info CASE event.id OF info.roll_but: BEGIN Widget_Control, info.roll_but, Get_Value=roll_but print, 'Roll Degrees: ', roll_but END info.pos_but: BEGIN Widget_Control, info.pos_but, Get_Value=pos_but print, 'Roll Source: ', pos_but END info.accept_but: BEGIN Widget_Control, info.roll_but, Get_Value=roll_but Widget_Control, info.pos_but, Get_Value=pos_but Widget_Control, Info.pitch_field, Get_Value=pitch_field print, 'Accepted max pitch: ', pitch_field Handle_Value, info.roll_ptr, roll_but, /Set, /No_Copy Handle_Value, info.pos_ptr, pos_but, /Set, /No_Copy Handle_Value, info.pitch_field_ptr, pitch_field, /Set, /No_Copy Widget_Control, event.top, /Destroy END ELSE: BEGIN Widget_Control, event.top, /Destroy END ENDCASE END ; ShowQ_Roll_Event ;---------------------------------------------------------------------------- ;---------------------------------------------------------------------------- ; ; ShowQuick_Trunc_Intensity truncates a percentage (given by Bottom, Top) ; of the total number of pixels from the top and/or bottom of the intensity ; range. A histogram of number of ; pixels vs. intensity is made. If Top=2 and Bottom=1, then ; from the min intensity, the number of pixels in each bin are counted until ; at least 1% of the pixels are counted. The intensity value of this bin ; is used as "MinCut" (the new min cutoff). Likewise, pixels in bins ; starting from the max are counted until 2% are found. The value of the ; ending bin becomes "MaxCut". ShowQuick_Trunc_Intensity adapted from ; /asf/source/idl/starlink/write_output.pro ; ENVI unable to plot an image beyond 32K so image is truncated ; Fixes to control size of output characters Function ShowQuick_Trunc_Intensity, Image, Bottom, Top On_Error, 2 ; Imin, Imax, BinWidth, and NBins were created assuming the image data is ; in bytes, yielding integer values. IMin = Long(Min(Image)) ; min intensity in image IMax = Long(Max(Image)) ; max intensity in image BinWidth = 1 ; width of histogram bin NBins = (Imax - Imin)/BinWidth ; number of histogram bins ; HistArr (y-axis) is an array containing the number of pixels for ; each intensity bin. BinArr (x-axis) contains the value of each ; intensity bin. HistArr = Histogram(Image, Binsize=BinWidth, Min=IMin, Max=IMax) BinArr = LindGen(IMax-IMin+1) + IMin ; Step through histogram, counting pixels in each bin until the percentage ; of pixels specified by Bottom and Top are reached. The intensities ; at which these percentages are reached are the new cutoffs for the ; image. NPix = N_Elements(Image) BotPix = Long(Bottom * NPix / 100.) ; # of pixels specified by Bottom PixCnt = 0 ; Total # of pixels counted ibin = 0 ; Bin index (start at first bin) WHILE PixCnt LT BotPix DO BEGIN PixCnt = PixCnt + HistArr(ibin) ibin = ibin + 1 ENDWHILE BotInt = BinArr(ibin-1) ; Bottom cutoff intensity TopPix = Long(Top * NPix / 100.) ; # of pixels specified by Top PixCnt = 0 ; Total # of pixels counted ibin = IMax - IMin ; Bin index (start at last bin) WHILE PixCnt LT TopPix DO BEGIN PixCnt = PixCnt + HistArr(ibin) ibin = ibin - 1 ENDWHILE TopInt = BinArr(ibin+1) ; Top cutoff intensity ; If pixel > TopInt, then set pixel = TopInt Image = Image < TopInt ; If pixel < BotInt, then set pixel = BotInt Image = Image > BotInt ; Expand resulting image from 0 to 255 in intensity. print, 'after scaling, min, max = ', botint, topint Image = BytScl(Image, Min=BotInt, Max=TopInt, Top=255) Return, Image END ; ShowQuick_Trunc_Intensity ;---------------------------------------------------------------------------- pro showquick, file, equalize = equalize, hisfile = hisfile, $ signed = signed, percent = percent ;+ ; Purpose: ; Display MAS 50 channel intermediate format quicklook images created by ; readtape5.f in a scrolling window. The GPS time code is displayed ; at 2 minute intervals to the right of the image data. A narrow ; bar is displayed to the right of the image whenever the aircraft ; roll exceeds 3 degrees. ; ; Usage: ; SHOWQUICK, FILE ; ; Input: ; FILE Name of quicklook image to read (e.g. '970202.ch02') ; ; Optional Keywords: ; /EQUALIZE If set, equalize the image histogram ; (image is scaled into 0-255 range). ; HISFILE Name of HIS spectrum file. Tickmarks and timecodes will ; be displayed for each HIS spectrum. ; SIGNED Use 16-bit signed int for data. Image pixels range from ; 0 to 65,535. ; PERCENT Perform percent stretch (typically 1% or 2%) using ; ShowQuick_Trunc_Intensity(). ; ; Revised: ; 14-FEB-1997 Liam Gumley, CIMSS/SSEC ; (liam.gumley@ssec.wisc.edu) ; ; Examples: ; ;; Display band 2 with histogram equalization ; showquickv35, '970202.ch02', /equalize ;- ;-------------------------------------------------------------- ;; make sure program exits on errors On_Error, 2 Compile_Opt strictarr ;... Print Showquick version # version='v1.3' print, '' print,'ShowQuick '+version print, 'Last modified: Oct 2, 2023' print, '' rollmax=7.0;DEFAULT Roll Threshold. pitchmax=3.0;Default pitch threshold top_base = Widget_Base(title='ShowQuick', Row=2) infx = ShowQ_Roll(top_base) ; button_list = ['Roll threshold - 7 deg', 'Roll threshold - 15 deg'] ; wFlag = 1 ; WHILE wFlag DO BEGIN ; Set Roll threshold to 7 0r 15 degrees. ; tlb = widget_auto_base(title='Set Roll Threshold') ; base = widget_base(tlb, /col, /frame) ; op = widget_menu(base, /auto, /excl, default_array = [1, 0], $ ; list=button_list, prompt='Select 7 or 15 degrees', uvalue='menu') ; result = auto_wid_mng(tlb) ; IF result.accept EQ 0 THEN return ; ; BEGIN ; envi_error, 'Uggh what are you doing??',/Warning ; Goto, finish ; ENDIF ; rollMaxThreshold = result.menu rollMaxThreshold = infx.roll_but ;; no need of yes or no confirmation ; Mesg = strarr(1) ; Mesg[0] = 'Accept ' + button_list[rollMaxThreshold] ; envi_error, Mesg, /Question, Value=ret ; ret = 1 ; IF ret EQ 1 THEN wFlag = 0 if rollMaxThreshold eq 0 then rollmax=7.0 if rollMaxThreshold eq 1 then rollmax=15.0 print,'Default rollmax = ',rollmax ; ENDWHILE ;-------- posyes=0;DEFAULT no POS choice . ; button_list = ['No', 'Yes'] ; wFlag = 1 ; WHILE wFlag DO BEGIN ; Check. ; tlb = widget_auto_base(title='POS-AV') ; base = widget_base(tlb, /col, /frame) ; op = widget_menu(base, /auto, /excl, default_array = [1, 0], $ ; list=button_list, prompt='Use POS-AV Input?', uvalue='menu') ; result = auto_wid_mng(tlb) ; IF result.accept EQ 0 THEN return ; BEGIN ; envi_error, 'Uggh what are you doing??',/Warning ; Goto, finish ; ENDIF ; posflag = result.menu posflag = infx.pos_but ;; no need of yes or no confirmation ; Mesg = strarr(1) ; Mesg[0] = 'Accept ' + button_list[posflag] ; envi_error, Mesg, /Question, Value=ret ; ret = 1 ; IF ret EQ 1 THEN wFlag = 0 if posflag eq 0 then posyes=0 if posflag eq 1 then posyes=1 print,"Final Selection = ", posyes ; ENDWHILE ;----------------------------------------------------------------------------- ;- read image file ; make sure that previous file path is remembered IF StrLen(file) GT 0 THEN BEGIN pathstr = File_DirName(file, /Mark_Directory) print, 'File path: ', pathstr PUSHD, pathstr ENDIF openr, lun, file, /get_lun info = fstat( lun ) nx = 25L + 179L ny = ( info.size ) / ( nx * 2L ) help, nx, ny print, 'x = ', strtrim(string(nx), 2), ', y = ', strtrim(string(ny), 2) ; ; Truncate ny to highest positive 16-bit integer ; Truncate_Val = 32567L print, 'Truncate limit: ', strtrim( string( Truncate_Val), 2 ) ; Modified to display more than one windows ; if image rows are more than max 32567 numimg = floor (float(ny)/float(Truncate_Val)) endimg = ny totpart = numimg + 1 print, 'Total number of subset images: ', totpart FOR knum =0, numimg DO BEGIN nyn = ny IF ny GT Truncate_Val THEN BEGIN ; Truncate image nyn = Truncate_Val ENDIF ; Truncate image numpart = knum + 1 startl = knum*Truncate_Val endl = knum*Truncate_Val + Truncate_Val -1UL IF knum EQ numimg THEN BEGIN endl = endimg - 1UL nyn = endl - startl + 1UL ENDIF print, 'Start and End of image line: ', startl, endl newimage = intarr(nx, nyn, /nozero) readu, lun, newimage help, newimage print, 'x = ', strtrim(string(nx), 2), ', y = ', strtrim(string(nyn), 2) print, 'Image Display Size: 179 by ', strtrim( string(nyn), 2) help, nx, nyn ; add swap if it is a little endian machine (intel/Linux) ; assume all subsamp files are in "Big Endian" format when read out ; with NewMas program newimage = SWAP_ENDIAN(newimage, /SWAP_IF_LITTLE_ENDIAN) ;- extract time, and video data in correct orientation ;- (note that blackbody correction is applied to bands 1-25 in readtape5) hr = newimage[9, * ] mn = newimage[10, * ] sc = newimage[11, * ] / 10 ;roll = newimage[20, * ] / 100.0 ; change to select POS-AV or IRIG ; based on newmas format Table C-9 IF posyes EQ 1 THEN BEGIN roll = newimage[17, * ] ENDIF ELSE BEGIN roll = newimage[20, *] ENDELSE help, roll ; debug pitch = float(newimage[ 21, * ])/10.0 help, pitch ; debug lat = float(newimage[ 22, * ])/100.0 lon = float(newimage[ 23, * ])/100.0 band = newimage[ 15, 0 ] bb1c = newimage[ 18, * ] ;;;oldColor = !p.color ;;;colors ; Liam Gumley colors ;;;white = 7 & cyan = 2 ;; colors function is non longer working ;; here defined as the following ;;; color = R + 256L * (G + 256L * B) red = 255L; white = 255 + 256L * ( 255 + 256L * 255) cyan = 0 + 256L * ( 255 + 256L * 255) green = 0 + 256L * 255 blue = 256L * ( 256L * 255) yellow = 255L + 256L * 255 IF KeyWord_Set(signed) THEN BEGIN newimage = temporary( newimage[ 25: 203, * ] ) ENDIF ELSE BEGIN newimage = temporary( Uint( newimage[ 25: 203, * ] ) ) ENDELSE ; ;if band ge 26 then $ ;if band le 25 then $ ; newimage = temporary( newimage ) - rebin( bb1c, 179, nyn, /sample ) ; newimage = rotate( rotate( temporary( newimage ), 7 ), 2 ) ; ; The next instruction is the only difference with regular ShowQuick except for ; routine names newimage = rotate( temporary( newimage ), 7 ) ; translates image so X0,Y0 => X0,-Y0 IF NOT KeyWord_Set(signed) THEN BEGIN IntMax = Fix(32767) ; max value for signed int IF Max(newimage) GT IntMax THEN newimage = Temporary(newimage)/2 newimage = Fix( Temporary(newimage) ) ; convert to signed int for Hist_Equal() ENDIF bb1c = 0B ; Reverse elements in hr, mn, sc, roll hr = rotate(temporary(hr), 2) mn = rotate(temporary(mn), 2) sc = rotate(temporary(sc), 2) roll = rotate(temporary(roll), 2) lat = rotate(temporary(lat), 2) lon = rotate(temporary(lon), 2) pitch = rotate(temporary(pitch), 2) PRINT, 'x180 image min and max: ', min(newimage), ', ', max(newimage) ;- enhance image IF KeyWord_Set(percent) THEN BEGIN Print, 'percent = ', percent Bottom = percent Top = percent newimage = ShowQuick_Trunc_Intensity(newimage, Bottom, Top) newimage = bytscl( temporary( newimage ), top = ( !d.n_colors - 1 ) < 255 ) ENDIF ELSE BEGIN ; keyword "percent" overrides "equalize" if not keyword_set( equalize ) then begin newimage = bytscl( temporary( newimage ), top = ( !d.n_colors - 1 ) < 255 ) endif else begin minv = min( newimage, max = maxv ) newimage = hist_equal( temporary( newimage ), minv = minv, maxv = maxv ) endelse ENDELSE ;- display scaled image in scrolling window device, get_screen_size = sz help,sz print, sz[0], sz[1] y_scxx = ( nyn + 200U ) < uint( ( sz[1] - 100 ) ) base = widget_base( title = strcompress( 'Quicklook Part '+ $ strtrim(string(numpart)) + '/'+strtrim(string(totpart)) + file ) ) ;;draw = widget_draw( base, xs = nx + 125, ys = nyn + 200, $ ;;x_sc = nx + 180, y_sc = ( nyn + 200 ) < ( sz( 1 ) - 100 ), $ draw = widget_draw( base, xs = nx + 180U, ys = nyn + 200U, $ x_sc = nx + 180U, y_sc = ( nyn + 200U ) < ( sz[1] - 100 ), $ /scroll, retain = 2 ) widget_control, base, /realize xoff = 80 yoff = 100 tv, newimage, xoff, yoff newimage = 0B ;;;;;;;;;;;;;;;;; DON'T USE POLY_FIT FOR TIME! ;;;;;;;;;;;;;;;;;;;;;;;;; ;- regenerate MAS times based on linear fit of unique MAS time entries ; masline = findgen( ny ) ; mastime = hr + mn / 60.0 + sc / 3600.0 ; loc = uniq( mastime ) ; result = poly_fit( masline( loc ), mastime( loc ), 1 ) ; mastime = masline * result( 1 ) + result( 0 ) ; hr = fix( mastime ) ; temp = 60.0 * ( mastime mod 1.0 ) ; mn = fix( temp ) ; temp = 60.0 * ( temp mod 1.0 ) ; sc = fix( temp ) ;;;;;;;;;;;;;;;;; DON'T USE POLY_FIT FOR TIME! ;;;;;;;;;;;;;;;;;;;;;;;;; ;- plot MAS time tick marks at 2 minute intervals ;;;savcharsize = !P.charsize ;;;!P.charsize = 1.0 loc = where( ( mn mod 2 eq 0 ) and ( sc eq 0 or sc eq 1 ), count ) print,'count (for 1st loc) ', count ;debug if count ge 1 then begin loc = loc[ uniq( mn[ loc ] ) ] usersym, [ 0, 2.0 ], [ 0, 0 ] ;;plots, 179 + xoff, loc + yoff, color=white, /device, psym = 8 plots, 179 + xoff, loc + yoff, /device, psym = 8 plots, xoff - 10, loc + yoff, /device, psym = 8 endif ;- plot MAS time labels at 2 minute intervals if count ge 1 then begin label = string( hr[ loc ], format = '( i2.2 )' ) + ':' + $ string( mn[ loc ], format = '( i2.2 )' ) ;; right side UTC time ;;xyouts, 179 + xoff + 15, loc + yoff - 4, label, /device, charsize = 1.5 * !P.charsize ;;xyouts, 179 + xoff + 15, loc + yoff - 4, label, color=white, $ xyouts, 179 + xoff + 30, loc + yoff - 4, label, $ /device, charsize = 0.6 endif if count ge 1 then begin ;; revloc = 4 * (nyn - loc) ;; make sure starting startl for continuous parts revloc = 4 * (nyn - loc + startl) recs = string( revloc, format = '(i6)' ) ;; left side scan line number/record number xyouts, xoff - 55, loc + yoff - 4, recs, $ /device, charsize = 0.6 endif ;- plot small ticks wherever roll exceeds 7 degrees absolute jmg@050125 ;- plot small ticks wherever roll exceeds 15 degrees absolute ;rollmax = 15.0 ;rollmax = 7.0 loc = where( abs( roll ) gt rollmax, count ) print,'count (for 2nd loc) ', count ;debug if count ge 1 then begin usersym, [ 0, 0.5 ], [ 0, 0 ] plots, 179 + xoff+5, loc + yoff, color=red, /device, psym = 8 ;; plots, 179 + xoff + 5, loc + yoff, /device, psym = 8 ;; plots, xoff - 5, loc + yoff, /device, psym = 8 endif ;- now get record numbers on transitions where rollmax is exceeded RAM ; broll = roll[1:*] trans = where( (abs(roll) le rollmax and abs(broll) gt rollmax) or $ (abs(roll) ge rollmax and abs(broll) lt rollmax), totalcnt ) print,'All in one Count = ', totalcnt if (totalcnt ge 1) then begin trans = trans[sort(trans)] usersym, [ 0, 2.0 ], [ 0, 0 ] plots, xoff-7, trans+yoff, color=red, /device, psym=8 plots, 179+xoff, trans+yoff, color=red, /device, psym=8 nroll = n_elements(roll) - 1 ; figure recnm = nroll - trans ; the original recnm = 4 * temporary(recnm) + 1 ; record number label = string( recnm, format = '( i6 )' ) ; and display it ;;xyouts, 5, trans + yoff - 4, label, /device, charsize = 1.5 * !P.charsize xyouts, 5, trans + yoff - 4, label, color=red, /device, charsize = 0.6 endif trans = 0B roll = 0B print, 'Times are UTC from GPS' print, 'Red bar to right indicates roll > ', rollmax, ' degrees' ;- plot small ticks wherever pitch exceeds 1.0 or user defined degrees absolute ;; User defined max pitch pitchfld = float(infx.pitch_field) ;; due to ENVI treat pitchfld as array ;; this error was very suprising! pitchmax = pitchfld[0] * 1.0 print, 'User Defined Max Pitch Angle: ', pitchmax ;print, 'Pitch out:', pitch ploc = where( abs(pitch) gt pitchmax, pcount ) print,'count (for pitch loc) ', pcount ;debug ; print, 'pitch loc=', ploc if ( pcount ge 1 ) then begin usersym, [ 0, 0.5 ], [ 0, 0 ] plots, 179 + xoff + 10, ploc + yoff, color=cyan, /device, psym = 8 ;; plots, 179 + xoff + 20, loc + yoff, /device, psym = 8 ;;plots, xoff - 7, locp + yoff, /device, psym = 8 endif print, 'Cyan bar to right indicates pitch > ', pitchmax, ' degrees' ; ;- Start plot latitude & longitude labels at every other minute intervals ; ; if (strlen(mn[*]) gt 0) then begin latloc = where( ( (mn[*]-1) mod 2 eq 0 ) and ( sc eq 0 or sc eq 1 ), cnt ) latloc = latloc[ uniq( mn[ latloc ] ) ] ; endif else begin ; latloc = ' 00.00 000.00' ; endelse if cnt ge 1 then begin ;lat=temporary(lat[*]-90.0) ;lon=temporary(lon[*]-180.0) latlon = string( lat[ latloc ], format = '( f6.2 )' ) + ',' + $ string( lon[ latloc ], format = '( f7.2 )' ) ;convert hundreths of degrees to minutes & hundreths of minutes. degmin = string( fix(lat[latloc]), format = '( i3," " ) ' ) + $ string( float( (abs(lat[latloc])-abs(fix(lat[latloc])) )*60 ), format = '( f5.2 )' ) + ',' + $ string( fix(lon[latloc]), format = '( i4," " ) ' ) + $ string( float( (abs(lon[latloc])-abs(fix(lon[latloc])) )*60 ), format = '( f5.2 )' ) ;lattim = string( hr[latloc], format = '( i2.2 )' ) + ':' + $ ; string( mn[latloc], format = '( i2.2 )' )+ ':' + $ ; string( sc[latloc], format = '( i2.2 )' ) latlon = strcompress(latlon) usersym, [ 0, 1.0 ], [ 0, 0 ] plots, 179 + xoff, latloc + yoff, /device, psym = 8 ;xyouts, 179 + xoff + 15, latloc + yoff - 4, latlon, /device, charsize = 0.6 ;xyouts, 179 + xoff + 10, latloc + yoff - 16, degmin, /device, charsize = 0.5 xyouts, 179 + xoff + 7, latloc + yoff - 4, degmin, color=yellow, $ /device, charsize = 0.5 ;xyouts, 179 + xoff+1 + 15, latloc + yoff - 16, lattim, /device, charsize = 0.6 ;print,'lat/lon = ', string( lat[latloc], format = '( f7.2 )' ) + ' , ' + $ ; string( lon[latloc], format = '( f7.2 )' ) endif ; ;- End plot latitude & longitude labels at every other minute intervals ; ;;;!p.color = oldColor ;;;!P.charsize = savcharsize if not keyword_set( hisfile ) then goto, finish ;- get HIS time array get_his_time, hisfile, hour, minute, second histime = hour + minute / 60.0 + second / 3600.0 ;- compute MAS line numbers corresponding to HIS times hisline = ( histime - result[ 0 ] ) / result[ 1 ] loc = where( hisline ge 0.0 and hisline le nyn, count ) if count lt 1 then message, 'No HIS times found within this MAS image' print, 'count: ', count help, count hisline = hisline[ loc ] hour = hour[ loc ] minute = minute[ loc ] second = second[ loc ] print, 'BEFORE plots' ;- plot HIS FOV markers on MAS image plots, (179 / 2) + xoff, [ hisline + yoff ], psym = 1, /device print, 'AFTER plots' ;- plot HIS time labels label = string( hour[ 0 : ( count - 1 ) < 1023 ], format = '( i2.2 )' ) + ':' + $ string( minute[ 0 : ( count - 1 ) < 1023 ], format = '( i2.2 )' ) + ':' + $ string( second[ 0 : ( count - 1 ) < 1023 ], format = '( i2.2 )' ) print, 'BEFORE xyouts' xyouts, 179 + 90, hisline[ 0 : ( count - 1 ) < 1023 ] + 100 - 4, $ label, /device, charsize = 1.0 ;;label, /device, charsize = 1.0 * !P.charsize print, 'AFTER xyouts', count if count ge 1024 then begin label = string( hour[ 1024 : * ], format = '( i2.2 )' ) + ':' + $ string( minute[ 1024 : * ], format = '( i2.2 )' ) + ':' + $ string( second[ 1024 : * ], format = '( i2.2 )' ) xyouts, 179 + 90, hisline[ 1024 : * ] + 100 - 4, $ label, /device, charsize = 1.0 ;; label, /device, charsize = 1.0 * !P.charsize endif ; Selwyn's test ystep = 200 pRec = UintArr(nyn/ystep) irec = 0 WHILE iy LE nyn DO BEGIN pRec[iy] = irec + ystep ENDWHILE green = 65535L ; XYOuts, 179+20, 200, 'record', Color=green XYOuts, 179+90, 200, 'record', /Device, charsize=1.0*!P.charsize finish: ENDFOR ; end for from beginning free_lun, lun end