;+ ; NAME: ; ccdphot ; PURPOSE: (one line) ; General purpose display and processing of CCD image files (FITS). ; DESCRIPTION: ; A general purpose widget application which displays and processes CCD ; image files. This includes bias, dark, flat field, and fringe correction ; plus serves the photometry reduction (cw_itool). ; CATEGORY: ; Widgets ; CALLING SEQUENCE: ; ccdphot[, keywords] ; INPUTS: ; ; OPTIONAL INPUT PARAMETERS: ; ; KEYWORD PARAMETERS: ; CALIBFILE= : Calibration startup file. Default is CALIBPATH/files.cal ; ; CALIBPATH= : Path for calibration files. Default is PATH/calib ; ; KEYLIST= : Name of a file containing a correspondence list. This list ; associates a set of standard names with the actual keyword ; names found in a FITS file header. If this keyword is ; omitted, a default list is used, as if a file with the ; following contents had been supplied: ; AIRMASS K AIRMASS ; DATE K DATE-OBS ; DATETMPL T DD-MM-YYYY ; EXPDELTA V 0.0 ; EXPTIME K EXPTIME ; FILTER K FILTERS ; FILENAME K CCDFNAME ; OBJECT K OBJECT ; UT K UT ; The middle column is a flag. It may be K, for Keyword, ; T, for Template, or V, for Value. If it is V, the contents ; of the third field on that line should make sense for the ; name in the first field. ; ; PATH= : Optional path for image and calibration directory. ; If not specified, the current directory is used. ; ; PHOTPARMFILE : Optional photometry parameter file. Passed to Itool. ; ; TMPLFILE : Optional template file. Passed to Itool. ; ; WZOOMFACT : Forces the cw_itool main draw window to have a specified ; zoom factor (passed to cw_itool). ; ; WXVISIBLE : Creates work window with explicit x-size (passed to cw_itool). ; ; WYVISIBLE : Creates work window with explicit y-size (passed to cw_itool). ; ; OUTPUTS: ; ; COMMON BLOCKS: ; ; SIDE EFFECTS: ; ; RESTRICTIONS: ; ; PROCEDURE: ; ; MODIFICATION HISTORY: ; Written by Doug Loucks, Lowell Observatory, December, 1993. ; Created by combining lccd.pro, loral.pro, and ccdphot_inst_init.pro. ; Added features include: Correspondence list for FITS header keywords ; and recognition of old format calibration environment files. ; 1/26/94, DWL, Added header date-parsing code to ldimage procedure. ; 3/2/94, DWL, Added keylist item EXPDELTA. ; 3/3/94, DWL, Improved the template and header date-parsing process. ; 3/10/94, DWL, Bug fixes. ; 4/94, DWL, Thorough validation of all environment parameters (overscan, ; cropping region, and bias/flat size compatibility). ; 3/1/95, MWB, Added support for a dark count calibrator (optional). ; 6/8/95, MWB, Changed defaults on calibration paths. Also, if file ; name begins with "+", CALIBPATH will replace the "+". ; 10/31/95, MWB, Added CATCH error handler to trap bad image file reads ; using READFITS. This prevents a crash to the IDL prompt ; when and invalid file is read. ; 3/18/96, MWB, Minor change to code that reads UT from header. Format ; requires two colons in string (HH:MM:SS) but also now ; allows SS to be a floating point number (ie., SS.sss). ; 6/25/96, MWB, implemented AUTO(-photometry) button. ; 1/22/97, MWB, fixed AUTO infinite loop if bad template positions found. ; 2/5/97, MWB, added FWHM and Mag safety shutoff in AUTO ; 6/13/97, MWB, extracted keylist to external general routines. ; 99/06/08, MWB, massive rewrite. Now using external (and general) ; calibration read/write/edit routines. This caused ; big changes in the internal structure and data organization ; of this tool. There are probably lingering bugs at ; this stage due to the extensive nature of the edits. ; 99/07/22, MWB, added WXVISIBLE and WYVISIBLE keyword pass through. ; 99/11/15, MWB, fixed bug when starting up a calibration environment ; when no filters or previous environment existed. ;- ; ------------------------------------------------------------------------------ ; Internal support procedures. ; A list of the procedures in this file (in order of occurrence) are: ; ; ccdphot_di Display image with cw_itool. ; ccdphot_pr Performs bias and flat field correction. ; ccdphot_af Adds a new filter code to the calibration structure. ; ccdphot_li Loads an image into memory. ; ccdphot_lc Loads calibration environment files. ; ccdphot_sc Saves the current calibration environment. ; ccdphot_eve Event handler for ccdphot. ; ccdphot ; ------------------------------------------------------------------------------ ; Procedure ccdphot_af ; Adds a filter to the calibration structure if it isn't already there. ; ------------------------------------------------------------------------------ pro ccdphot_af,state,newfilter if ptr_valid(state.calib) then begin z=where(newfilter eq (*state.calib).filter,count) endif else begin ldcalib,'files.cal',calib,valid,CALIBPATH=state.calibpath,/empty ptr_free,state.calib state.calib = ptr_new(calib,/no_copy) count=0 endelse if count eq 0 then begin calibchg,*(state.calib),'flat',newfilter,'',CALIBPATH=state.calibpath state.calibdirty = 1 endif end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_cleanup ; ------------------------------------------------------------------------------ pro ccdphot_cleanup,tlb ; Note, this should be used to free up pointers (like the calib structure) ; but something doesn't work quite right at this point so this is left ; as a placeholder for future code. end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_di ; Calls itool to display the image. ; ------------------------------------------------------------------------------ pro ccdphot_di, state, AUTOPHOT=autophot, PHOTTYPE=phottype, POSITION=position if state.imfile eq '' then return valid = widget_info( state.cwitoolbase, /valid_id ) if state.new and valid then begin widget_control, state.cwitoolbase, TLB_GET_OFFSET=offset widget_control, state.cwitoolbase, /DESTROY state.cwitoolbase = widget_base( TITLE='Itool', COLUMN=1, $ GROUP_LEADER=state.mainbase ) widget_control, state.cwitoolbase, TLB_SET_XOFFSET=offset[0], $ TLB_SET_YOFFSET=offset[1] xmanager, '', state.cwitoolbase, /JUST_REG state.cwitoolid = cw_itool( state.cwitoolbase, $ PHOTPARMFILE=state.photparmfile, $ TMPLFILE=state.tmplfile, $ WZOOMFACT=state.wzoomfact, $ WXVISIBLE=state.wxvisible, $ WYVISIBLE=state.wyvisible, $ XSIZE=state.pxsize, $ YSIZE=state.pysize ) endif if state.cwitoolid eq 0L then begin state.cwitoolbase = widget_base( TITLE='Itool', COLUMN=1, $ GROUP_LEADER=state.mainbase ) xmanager, '', state.cwitoolbase, /JUST_REG state.cwitoolid = cw_itool( state.cwitoolbase, $ PHOTPARMFILE=state.photparmfile, $ TMPLFILE=state.tmplfile, $ WZOOMFACT=state.wzoomfact, $ WXVISIBLE=state.wxvisible, $ WYVISIBLE=state.wyvisible, $ XSIZE=state.pxsize, $ YSIZE=state.pysize ) endif ;In case cw_itool has been dismissed, or the TLB has not been realized: widget_control, state.cwitoolbase, /REALIZE, /MAP ;Get the image parameters structure (the 'value' for cw_itool). widget_control, state.imparmsptr, GET_UVALUE=im_parms ;Set the pointer and size fields. im_parms.imageptr = state.dimgptr im_parms.xsize = state.pxsize im_parms.ysize = state.pysize sz=size(autophot) if sz[1] eq 7 then begin if autophot eq im_parms.object then begin im_parms.autophot = 1 im_parms.lasttype = phottype im_parms.lastpos = position endif endif ;Display the new image. widget_control, state.cwitoolid, SET_VALUE=im_parms end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_pr ; Performs bias and flat field corrections. ; ------------------------------------------------------------------------------ pro ccdphot_pr, state bel = string( 7B ) if state.imfile eq '' then return msg = 'Image: ' + state.imfile if state.processflag eq 0 then begin if (state.xsize ne state.pxsize) or (state.ysize ne state.pysize) then begin state.new = 1B state.pxsize = state.xsize state.pysize = state.ysize endif else begin state.new = 0B endelse state.dimgptr = state.rimgptr msg = msg + ' (raw).' PRINT, '' PRINT, msg return endif state.dimgptr = state.cimgptr widget_control, state.rimgptr, GET_UVALUE=rawframe, /NO_COPY widget_control, state.dimgptr, GET_UVALUE=image, /NO_COPY widget_control, state.hdrinfoptr, GET_UVALUE=hdrinfo, /NO_COPY image=0 for i=0,state.nframes-1 do begin if i eq 0 then begin if state.nframes eq 1 then begin ccdproc,rawframe,hdrinfo,*(state.calib),image sz=size(image,/dimen) endif else begin ccdproc,rawframe[*,*,i],hdrinfo,*(state.calib),tmpimage sz=size(tmpimage,/dimen) image = fltarr( sz[0], sz[1], state.nframes, /NOZERO ) image[*,*,i] = tmpimage tmpimage=0 endelse endif else begin ccdproc,rawframe[*,*,i],hdrinfo,*(state.calib),tmpimage image[*,*,i] = tmpimage tmpimage=0 endelse endfor if (sz[0] ne state.pxsize) or (sz[1] ne state.pysize) then begin state.new = 1B endif else begin state.new = 0B endelse state.pxsize = sz[0] state.pysize = sz[1] widget_control, state.hdrinfoptr, SET_UVALUE=hdrinfo, /NO_COPY widget_control, state.dimgptr, SET_UVALUE=image, /NO_COPY widget_control, state.rimgptr, SET_UVALUE=rawframe, /NO_COPY print, msg end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_li ; Loads an image file into the image frame array. ; ------------------------------------------------------------------------------ pro ccdphot_li, state, fname, $ AUTOPHOT=autophot, PHOTTYPE=phottype, POSITION=position bel = string( 7B ) if not exists( fname ) then begin print, 'File ' + fname + ' not found.' + bel widget_control, state.imtextid, SET_VALUE=state.imfile return endif header = '' ;Use the calibrated image storage area as a temporary place to load the ;prospective image. This is OK because the calibrated image storage area ;is always initialized before a processed image is displayed. catch, Error_status if Error_status ne 0 then begin print, 'Error loading ' + fname + bel widget_control, state.cimgptr, SET_UVALUE=tframe, /NO_COPY widget_control, state.imtextid, SET_VALUE=state.imfile return endif widget_control, state.cimgptr, GET_UVALUE=tframe, /NO_COPY tframe=0 tframe = float(readfits( fname, header, /SILENT )) catch,/CANCEL ;Store the header in the user-value of the View Header button. widget_control, state.vheaderid, SET_UVALUE=header ;Initialize the new image parameters structure for the raw image. it_init, tframe, im_parms ;Put the temporary storage pointer back. widget_control, state.cimgptr, SET_UVALUE=tframe, /NO_COPY ;Check for overscan error. calval, im_parms.xsize, 0, state.xl, state.xr, errflg, $ BANNER='LOAD IMAGE: Error. Image x-size is inconsistent with the ' + $ 'established overscan size or range.', $ ISIZELAB='image frame x-size', $ CSIZELAB='', $ MLOWLAB='low limit of overscan region', $ MHIGHLAB='high limit of overscan region', $ DELTAMLAB='size of overscan region' err = errflg ;Check for x-range error. calval, im_parms.xsize, state.cxsize, state.x1, state.x2, errflg, $ BANNER='LOAD IMAGE: Error. Image x-size is inconsistent with the ' + $ 'established environment.', $ ISIZELAB='image frame x-size', $ CSIZELAB='calibration frame x-size', $ MLOWLAB='low limit of cropping region x-range', $ MHIGHLAB='high limit of cropping region x-range', $ DELTAMLAB='size of cropping region x-range' err = err or errflg ;Check for y-range error. calval, im_parms.ysize, state.cysize, state.y1, state.y2, errflg, $ BANNER='LOAD IMAGE: Error. Image Y-size is inconsistent with the ' + $ 'established environment.', $ ISIZELAB='image frame y-size', $ CSIZELAB='calibration frame y-size', $ MLOWLAB='low limit of cropping region y-range', $ MHIGHLAB='high limit of cropping region y-range', $ DELTAMLAB='size of cropping region y-range' err = err or errflg if err then begin print, '...Image ' + fname + ' cannot be loaded.' widget_control, state.imtextid, SET_VALUE=state.imfile return endif ;Move the newly loaded image to its permanent location. widget_control, state.cimgptr, GET_UVALUE=tframe, /NO_COPY widget_control, state.rimgptr, GET_UVALUE=rawframe, /NO_COPY rawframe = temporary(tframe) tframe = 0 widget_control, state.cimgptr, SET_UVALUE=tframe, /NO_COPY widget_control, state.rimgptr, SET_UVALUE=rawframe, /NO_COPY state.imfile = fname widget_control, state.imtextid, SET_VALUE=state.imfile state.nframes = im_parms.nframes state.xsize = im_parms.xsize state.ysize = im_parms.ysize ;Extract some info from the header, using the list of header correspondence ;names. widget_control, state.hdrlistptr, GET_UVALUE=hdrlist, /NO_COPY widget_control, state.hdrinfoptr, GET_UVALUE=hdrinfo, /NO_COPY parsekey,header,hdrlist,hdrinfo ;Copy the header imformation to the image parameters structure. im_parms.airmass = hdrinfo.airmass im_parms.date = hdrinfo.date im_parms.expdelta = hdrinfo.expdelta im_parms.exptime = hdrinfo.exptime im_parms.imfile = hdrinfo.imfile im_parms.filter = hdrinfo.filter im_parms.object = hdrinfo.object im_parms.ut = hdrinfo.ut im_parms.jd = hdrinfo.jd widget_control, state.hdrinfoptr, SET_UVALUE=hdrinfo, /NO_COPY widget_control, state.hdrlistptr, SET_UVALUE=hdrlist, /NO_COPY ; bust up the original file name, if different from header, use file name. fdecomp,fname,disk,dir,name,qual if qual ne '' then name = name + '.' + qual if name ne im_parms.imfile then im_parms.imfile = name im_parms.autophot = 0 if im_parms.imfile eq '' then im_parms.imfile='(No name)' ;phot_parms.objnum = 0 ccdphot_af, state, im_parms.filter ;Put the new image parameters away. widget_control, state.imparmsptr, SET_UVALUE=im_parms ccdphot_pr, state ccdphot_di, state, AUTOPHOT=autophot, PHOTTYPE=phottype, POSITION=position end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_lc ; Loads calibration files, based upon the contents of a calibration ; environment file. ; ------------------------------------------------------------------------------ pro ccdphot_lc, state bel = string( 7B ) if state.calibfile eq '' then return if not exists( state.calibpath+state.calibfile ) then begin print, 'Calibration Environment File ' + $ state.calibpath + state.calibfile + ' not found.'+bel widget_control, state.caltextid, SET_VALUE='' return endif if state.calibdirty then begin t = [ ' Calibration environment changes may not have been saved.', $ ' If you do not wish to lose any changes, cancel this operation and', $ 'save the current environment.' ] con = qannounc( t, TITLE='Calibration Environment Save Confirmation', $ FALSE='Cancel', TRUE='Ok, continue', XSIZE=70 ) if not con then return state.calibdirty = 0 endif ldcalib,state.calibfile,calib,valid,CALIBPATH=state.calibpath if not valid then begin print, 'Calibration file is not valid. Unable to load.' + bel return endif else begin ptr_free,state.calib state.calib = ptr_new(calib,/no_copy) endelse ;Set calibration environment save flag. state.calibdirty = 0 ;Process and display the image (if loaded). ccdphot_pr, state ccdphot_di, state end ; ------------------------------------------------------------------------------ ; Procedure ccdphot_sc ; Saves the current calibration environment to a file. ; ------------------------------------------------------------------------------ pro ccdphot_sc, state bel = string( 7B ) if state.calibfile eq '' then return if exists( state.calibpath+state.calibfile ) then begin t = $ [ ' Calibration environment file ' + state.calibpath+state.calibfile + ' exists.', $ ' It will be overwritten, unless you choose to cancel and change', $ 'the name of the file.' ] con = qannounc( t, TITLE='File Overwrite Confirmation', $ FALSE='Cancel', TRUE='Overwrite File', XSIZE=70 ) if not con then return endif wrcalib,*(state.calib),state.calibfile,CALIBPATH=state.calibpath state.calibdirty = 0 print, 'Calibration environment saved to file ' + $ state.calibpath+state.calibfile end ;<<<<<<<<<<<<<<<<<<<<<<<<< EVENT PROCESSING <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; ------------------------------------------------------------------------------ ; Procedure ccdphot_eve ; Main event handler for ccdphot (main buttons). ; ------------------------------------------------------------------------------ pro ccdphot_eve, event bel = string( 7B ) widget_control, event.id, /HOURGLASS stash = widget_info( event.handler, /CHILD ) widget_control, stash, GET_UVALUE=state, /NO_COPY case event.id of ;Calibration environment file events. state.calpickid : begin f = dialog_pickfile( GROUP=event.top, TITLE='Select Calibration File', $ PATH=state.calibpath ) fn = strtrim( f[0], 2 ) if fn ne '' then begin state.calibfile = fn widget_control, state.caltextid, SET_VALUE=fn endif end state.calloadid : begin ccdphot_lc, state end state.calsaveid : begin ccdphot_sc, state end state.caltextid : begin widget_control, event.id, GET_VALUE=value f = strtrim( value[0], 2 ) state.calibfile = f print, 'Calibration file set to ' + f end state.editid : begin calibed,*(state.calib),dirty,group=event.top, $ CALIBPATH=state.calibpath,ISIZE=[state.xsize,state.ysize],/modal state.calibdirty = state.calibdirty or dirty ccdphot_pr, state ccdphot_di, state end ;Main button widgets. state.exitid : begin valid = widget_info( state.cwitoolbase, /VALID_ID ) if valid then begin widget_control, state.cwitoolid, GET_VALUE=status endif else begin status = {msg:''} endelse tmsg = [''] if state.calibdirty then begin tmsg = [ tmsg, $ 'Calibration environment changes have not been saved.' ] endif tmsg = [ tmsg, '****************************************', $ 'Do you really wish to quit CCDPHOT?' ] con = qannounc( [status.msg,tmsg], TITLE=' CCDPHOT Exit Confirmation', $ XSIZE=60, YSIZE=6 ) if con then begin ;Bye. ; This next line is a mystery. If this is moved to cleanup, ; the stash id is lost and I can't get to the calib structure. ; perhaps this has something to do with this method of state ; storage that is different from the newer method using pointers. ptr_free,state.calib widget_control, stash, SET_UVALUE=state, /NO_COPY widget_control, event.top, /DESTROY return endif end ;Image file events. state.impickid : begin if state.impath ne '' then begin f = dialog_pickfile( GROUP=event.top, TITLE='Select Image Frame', $ PATH=state.impath ) endif else begin f = dialog_pickfile( GROUP=event.top, TITLE='Select Image Frame' ) endelse fn = strtrim( f, 2 ) if fn ne '' then begin widget_control, state.imtextid, SET_VALUE=fn ccdphot_li, state, fn endif end state.imtextid : begin widget_control, event.id, GET_VALUE=value fn = strtrim( value[0], 2 ) if fn ne '' then begin ccdphot_li, state, fn endif else begin if state.imfile ne '' then begin widget_control, state.imtextid, SET_VALUE=state.imfile endif endelse end state.rawproid : begin ;Raw/Processed toggle event. state.processflag = event.value ccdphot_pr, state ccdphot_di, state end state.nextid : begin if state.imfile ne '' then begin f = state.imfile l = strlen( f ) ext = strmid( f, l-3, 3 ) bext = byte( ext ) t = where( bext lt 48 and bext gt 57, count ) if count eq 0 then begin next = string( fix( ext ) + 1, format='(I3.3)' ) strput, f, next, l-3 ccdphot_li, state, f if state.imfile eq f then begin widget_control, state.imtextid, SET_VALUE=f endif endif endif else begin print, 'Error. No image.' + bel endelse end state.previd : begin if state.imfile ne '' then begin f = state.imfile l = strlen( f ) ext = strmid( f, l-3, 3 ) bext = byte( ext ) t = where( bext lt 48 and bext gt 57, count ) if count eq 0 then begin newnum = fix( ext ) - 1 if newnum ge 0 then begin next = string( newnum, format='(I3.3)' ) strput, f, next, l-3 ccdphot_li, state, f if state.imfile eq f then begin widget_control, state.imtextid, SET_VALUE=f endif endif else begin print, 'Error. Nothing before frame 0.' + bel endelse endif endif else begin print, 'Error. No image.' + bel endelse end state.autoid : begin if state.imfile ne '' then begin sameobject = 0 fwhmok = 0 magok = 0 fail = 1 fileok = 0 firstpass=1 thisframe = -1 lastframe = -2 repeat begin widget_control, state.cwitoolid, GET_VALUE=it_info lasttype = it_info.lasttype lastpos = it_info.lastpos object = it_info.object lastfwhm = it_info.lastfwhm lastmag = it_info.lastmag if it_info.lasttype ne 0 then begin if firstpass then begin ok=qannounc( GROUP=event.top, [ $ 'This command will automatically proceed through the data with the same', $ 'photometry extraction as done on the last frame. By default, this process', $ 'will continue until the object name changes, or, there is no more data.', $ 'If this is what you wish to do, then select "Stop on Last". However, you', $ 'might want to stop on a certain frame number. If you do want to stop on', $ 'a certain frame number, then select "Set Stop Point". If you choose the', $ 'latter option, you will be asked for the desired stopping point. However,', $ 'a changing object name will take precedence over a stop point. So, if you', $ 'set a stop point after the object changes, it will stop earlier than you', $ 'think.' $ ], XSIZE=80, YSIZE=10, TITLE='Automatic Photometry Procedure', $ TRUELABEL='Stop on Last', FALSELABEL='Set Stop Point' ) if ok then $ lastframe=999 $ else $ lastframe=qinput(prompt='Frame number to stop on?',/integer) firstpass=0 endif f = state.imfile l = strlen( f ) ext = strmid( f, l-3, 3 ) bext = byte( ext ) t = where( bext lt 48 and bext gt 57, count ) if count eq 0 then begin thisframe = fix(ext)+1 next = string( thisframe, format='(I3.3)' ) strput, f, next, l-3 ccdphot_li, state, f, AUTOPHOT=object, $ PHOTTYPE=lasttype, POSITION=lastpos if state.imfile eq f then begin widget_control, state.imtextid, SET_VALUE=f widget_control, state.cwitoolid, GET_VALUE=it_info sameobject = (it_info.object eq object) magok = (abs(it_info.lastmag-lastmag) lt 10.0) fwhmok = (abs(it_info.lastfwhm-lastfwhm)/lastfwhm lt 1.0 ) fail = 0 fileok = 1 endif else begin sameobject = 0 fileok = 0 magok = 0 fwhmok = 0 endelse endif else begin thisframe=-1 print,' Filename cannot be incremented. Unable to run Auto-photometry.'+bel endelse endif else begin print,'Cannot do auto-photometry.'+bel print,' No position has yet been defined for this object.' lastframe=thisframe endelse endrep until not sameobject or lastframe eq thisframe or not magok or not fwhmok if not fail then begin if not fileok then $ print,' Auto-photometry halted. Next file incomplete or missing.' + bel $ else if not sameobject then $ print,' Auto-photometry halted. Object changed.' + bel $ else if thisframe ge lastframe then $ print,' Auto-photometry halted. Stopping point reached.' + bel $ else if not magok then $ print,' Auto-photometry halted. Magnitude of object changed too much.' + bel $ else if not fwhmok then $ print,' Auto-photometry halted. FWHM of object changed too much.' + bel $ else $ print,' Unknown ending condition for Auto, this should not happen.' + bel endif endif else begin print, 'Error. No image.' + bel endelse end state.vheaderid : begin if state.imfile ne '' then begin widget_control, event.id, GET_UVALUE=header t = 'Image Header' + ' - file ' + state.imfile viewtext, header, GROUP=event.top, TITLE=t, XSIZE=81, YSIZE=40 endif else begin print, 'Error. No image.' + bel endelse end state.wfitsid : begin ;Write the image to a FITS file( allows a calibrated image to be saved). if state.imfile ne '' then begin ;There is an image loaded. Do it. widget_control, state.dimgptr, GET_UVALUE=image, /NO_COPY widget_control, state.imparmsptr, GET_UVALUE=im_parms, /NO_COPY widget_control, state.vheaderid, GET_UVALUE=header, /NO_COPY filename = 'c_' + im_parms.imfile writefits, filename, image, header print, 'Image saved to file ' + filename widget_control, state.vheaderid, SET_UVALUE=header, /NO_COPY widget_control, state.imparmsptr, SET_UVALUE=im_parms, /NO_COPY widget_control, state.dimgptr, SET_UVALUE=image, /NO_COPY endif end else : begin print, 'Unknown event:' help, event, /STRUCTURE end endcase widget_control, stash, SET_UVALUE=state, /NO_COPY end ; ------------------------------------------------------------------------------ ; Procedure ccdphot ; Where it begins. ; ------------------------------------------------------------------------------ pro ccdphot, CALIBFILE=in_calibfile, CALIBPATH=in_calibpath, $ KEYLIST=in_keylist, TITLE=title, $ PATH=in_path, PHOTPARMFILE=in_photparmfile, $ TMPLFILE=in_tmplfile, WZOOMFACT=wzoomfact, $ WXVISIBLE=wxvisible, WYVISIBLE=wyvisible bel = string( 7B ) if xregistered( 'ccd' ) then return if (!d.flags and 256) eq 0 then begin print, 'Error. No windowing device. CCDPHOT cannot be started.' return endif if badpar(wzoomfact,[0,1,2,3],0, $ CALLER='CCDPHOT: (wzoomfact) ',DEFAULT=0) then return if badpar(wxvisible,[0,1,2,3],0, $ CALLER='CCDPHOT: (wxvisible) ',DEFAULT=0) then return if badpar(wyvisible,[0,1,2,3],0, $ CALLER='CCDPHOT: (wyvisible) ',DEFAULT=0) then return if badpar(in_path,[0,7],0, $ CALLER='CCDPHOT: (path) ',DEFAULT='') then return if in_path ne '' then in_path=addslash(in_path) if badpar(in_calibpath,[0,7],0, $ CALLER='CCDPHOT: (calibpath) ',DEFAULT=in_path+'calib') then return in_calibpath=addslash(in_calibpath) if badpar(in_calibfile,[0,7],0, $ CALLER='CCDPHOT: (calibfile) ',DEFAULT='files.cal') then return if badpar(in_photparmfile,[0,7],0, $ CALLER='CCDPHOT: (photparmfile) ',DEFAULT='') then return if badpar(in_tmplfile,[0,7],0, $ CALLER='CCDPHOT: (tmplfile) ',DEFAULT='') then return ; Initialize the main state structure. state = { $ calib: ptr_new(), $ calibfile:in_calibfile, calibdirty:0, calibpath:in_calibpath, $ calloadid:0L, $ calpickid:0L, $ calsaveid:0L, $ caltextid:0L, $ cimgptr:0L, $ cwitoolbase:0L, cwitoolid:0L, $ cxsize:0, cysize:0, $ dimgptr:0L, $ editid:0L, $ exitid:0L, $ hdrinfoptr:0L, $ hdrlistptr:0L, $ imfile:'', $ imparmsptr:0L, $ impath:in_path, $ impickid:0L, $ imtextid:0L, $ mainbase:0L, $ new:1B, $ previd:0L, $ nextid:0L, $ nframes:0L, $ photparmfile:in_photparmfile, $ processflag:1, $ autoid:0L, $ pxsize:0, pysize:0, $ rawproid:0L, $ rimgptr:0L, $ tmplfile:in_tmplfile, $ vheaderid:0L, $ wfitsid:0L, $ wxvisible: wxvisible, $ wyvisible: wyvisible, $ wzoomfact: wzoomfact, $ xl:-1, xr:-1, $ x1:-1, x2:-1, y1:-1, y2:-1, $ xrange:'*', xrangeid:0L, $ yrange:'*', yrangeid:0L, $ xsize:0, $ ysize:0 } ; Get header correspondence list. if keyword_set( in_keylist ) then $ loadkeys,in_keylist,hdrlist $ else $ loadkeys,'[[DEFAULT]]',hdrlist ;Define the main base. if not keyword_set(title) then title='CCDPHOT' mainbase = widget_base( TITLE=title, /COLUMN, UVALUE=0 ) state.mainbase = mainbase state.imparmsptr = mainbase ;Main button base. b1 = widget_base( mainbase, /ROW, /FRAME ) state.exitid = widget_button( b1, VALUE='Exit', UVALUE=0 ) state.hdrinfoptr = state.exitid state.rawproid = cw_bgroup( b1, ['Raw', 'Processed'], /EXCLUSIVE, $ /NO_RELEASE, /ROW, SET_VALUE=state.processflag ) state.previd = widget_button( b1, VALUE='Prev' ) state.nextid = widget_button( b1, VALUE='Next' ) state.autoid = widget_button( b1, VALUE='Auto' ) state.vheaderid = widget_button( b1, VALUE='ViewHeader', UVALUE='' ) state.wfitsid = widget_button( b1, VALUE='Write Fits' ) ;Image select base. imagebase = widget_base( mainbase, /ROW, /FRAME, UVALUE=0 ) w1 = widget_label( imagebase, VALUE='IMAGE FRAME:', UVALUE=hdrlist ) state.impickid = widget_button( imagebase, VALUE='Select File' ) state.imtextid = widget_text( imagebase, VALUE=state.imfile, /EDITABLE, $ XSIZE=50 ) ;The header list is stored in the user-value of this base. state.hdrlistptr = w1 state.rimgptr = imagebase ;Calibration environment file base. calbase = widget_base( mainbase, /COLUMN, /FRAME, UVALUE=0 ) w1 = widget_label( calbase, VALUE='CALIBRATION ENVIRONMENT' ) b2 = widget_base( calbase, /ROW ) state.calloadid = widget_button( b2, VALUE='Load' ) state.calsaveid = widget_button( b2, VALUE='Save' ) state.editid = widget_button( b2, VALUE='Edit' ) state.calpickid = widget_button( b2, VALUE='Select File' ) state.caltextid = widget_text( b2, VALUE=state.calibfile, /EDITABLE, XSIZE=40 ) state.cimgptr = calbase if state.calibfile ne '' then begin ;Call the calibration file load routine. ccdphot_lc, state endif ;Stash area for the state structure. stash = widget_info( mainbase, /CHILD ) ;Stash the state structure. widget_control, stash, SET_UVALUE=state, /NO_COPY ;Realize the main base. widget_control, mainbase, /REALIZE ; Give control to the xmanager. xmanager, 'ccdphot', mainbase, $ EVENT_HANDLER='ccdphot_eve',cleanup='ccdphot_cleanup', $ GROUP_LEADER=mainbase end