;+ ; NAME: ; qView_TrackPeak ; PURPOSE: ; Track a peak across a sequence of images. Results are displayed using ; the qLine widget. ; CATEGORY: ; Widget qView ; CALLING SEQUENCE: PRO qView_TrackPeak, state, event, wid_send=wid_send, send_event=send_event ; INPUTS: ; state array[1]; type: structure ; qView state structure ; event array[1]; type: structure ; event from state.wid_track button, or from qImage widget ; OUTPUTS: ; (to qLine widget) ; INCLUDE: @compile_opt.pro ; On error, return to caller ; COMMON BLOCKS: common qView_PlotTrack_Save, boxes, smei_set, smei_center, npeaks, x, y, t ; CALLS: ; qView_Image, qView_PlotTrack, qView_UpdateActive, qImage_SendDestination ; qImage_TriggerSend, flat_centerofmass ; SIDE EFFECTS: ; The user value of state.wid_track is set to 1B when tracking starts. ; As long as the value is set any 'Send' messages from qImage are ignored. ; PROCEDURE: ; The qImage widget is used to display images and show the tracking procedure. ; qImage is called with the 'tracking' keyword set to a non-zero value to ; indicate that events send back to qView are processed here. ; ; A button press on the state.track widget results in a WIDGET_BUTTON event to ; this procedure. The first image is displayed using the qImage widget. ; When the user presses the 'Send' button in qImage or exits qImage a QIMAGE_SEND ; event is send back to the qView widget, which ends up here again. ; ; After confirming the information from the qImage widget the first widget is ; displayed again, and tracking begins. qImage will now send QIMAGE_TRACK events ; back to this procedure which contain the tracking results. ; ; The tracking results are stored by qView_PlotTrack and the next image is ; displayed in qImage. When all images have been processed the first image is ; displayed again by qImage with the tracking keyword set to zero to indicate ; that events should not be send to this procedure anymore. ; STATE INFO USED: ; widget_control, state.wid_track, get_uvalue=set ; STATE INFO MODIFIED: ; widget_control, state.wid_track, set_uvalue=0B ; MODIFICATION HISTORY: ; FEB-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- event_name = tag_names(event, /structure_name) widget_control, state.wid_track, get_value=label, get_uvalue=set CASE set OF 0B: BEGIN ; The test for the event name IS necessary. If tracking was interrupted by pressing ; the 'Track' button then the user value of state.wid_track is cleared. However, there ; could still be an QIMAGE_TRACK event on the way. The test on event_name makes sure ; that this event is ignored. IF event_name EQ 'WIDGET_BUTTON' THEN BEGIN ; The next few lines put the first image of a sequence on the display before ; starting the tracking procedure. If this is uncommented than another ; qViewUpdateActive(state,/first) call also needs to be uncommented. ;tmp = qView_ImageInfo(state, /first, /display) ;if tmp[0] ne tmp[1] then begin ; tmp = qView_UpdateActive(state, /first) ; qView_Image, state ;endif ok = dialog_message(title=label+' peak', $ ['Select area around local maximum. Then press "'+label+'" button again'], $ /cancel, dialog_parent=state.wid_track) eq 'OK' set = ok*(set+1B) widget_control, state.wid_track, set_uvalue=set, /no_copy ENDIF END 1B: BEGIN status = qImage_TriggerSend(event, state.wid_view, state.wid_track, wid_send, send_event) CASE status OF 0B: message, 'oops' ; No qImage widget exists: shouldn't happen 1B: RETURN ; Return to event handler to send 'send_event' to 'wid_send' 2B: BEGIN ; Process QIMAGE_SEND event ; 'boxes' is used to store the initial selected box, and the box template ; (= the selected box using the center of the box as origin; the center ; is defined here as the location of the centroid for a constant mass ; distribution in the shape of of the box). smei_set = event.smei smei_center = event.center IF smei_set THEN tmp = event.p_box ELSE tmp = event.box ; The box template boxes[*,*,1] is not modified anymore during tracking, ; and is used to make sure the same box is used all the time by centering ; it on the current centroid. boxes = fltarr(2,2,2) boxes[*,*,0] = flat_centerofmass(tmp, polar=smei_set)#[1,1] boxes[*,*,1] = flat_centerofmass(tmp, polar=smei_set, /shift_origin) ; The initial box has been retrieved from the qImage widget. ; Confirm the selection. CASE smei_set OF 0B: ok = dialog_message(title=label+' peak', $ [ 'Area: X:['+strcompress(round(boxes[0]))+'-'+strcompress(round(boxes[2]))+'] '+ $ 'Y:['+strcompress(round(boxes[1]))+'-'+strcompress(round(boxes[3]))+']', $ 'Bok OK?'], /cancel, dialog_parent=state.wid_track) EQ 'OK' 1B: ok = dialog_message(title=label+' peak', $ [ 'Area: Phi:['+strcompress(boxes[0]*!radeg)+'-'+strcompress(boxes[2]*!radeg)+'] '+$ 'Rad:['+strcompress(boxes[1])+'-'+strcompress(boxes[3])+']', $ 'Bok OK?'], /cancel, dialog_parent=state.wid_track) EQ 'OK' ENDCASE set = ok*(set+1B) widget_control, state.wid_track, set_uvalue=set, /no_copy ; Setting foreign=1 activates the qImage_TrackPeak procedure in the qImage ; widget. This will return QIMAGE_TRACK events back containing information ; about the peak being tracked. CASE OK OF 0: qView_PlotTrack, /destroy 1: BEGIN widget_control, state.wid_view, get_uvalue=wid_qimage qImage_SendDestination, wid_qimage, state.wid_track, foreign=1, boxes=boxes ;tmp = qView_UpdateActive(state, /first) qView_Image, state ; Redraw to generate QIMAGE_TRACK event qView_PlotTrack, /init ; Sets peak counter to zero END ENDCASE END ENDCASE END 2B: BEGIN ; QIMAGE_TRACK event arrived ; Cancel tracking if button is pressed while tracking is ON IF event_name EQ 'WIDGET_BUTTON' THEN BEGIN widget_control, state.wid_view, get_uvalue=wid_qimage IF widget_info(wid_qimage, /valid) THEN qImage_SendDestination, wid_qimage, foreign=0 widget_control, state.wid_track, set_uvalue=0B CASE dialog_message('Show tracking results', /question, dialog_parent=state.wid_track) OF 'Yes': qView_PlotTrack, state, event, /display ELSE : qView_PlotTrack, /destroy ENDCASE ENDIF ELSE BEGIN tmp = qView_UpdateActive(state, step=1, /noloop, new=new, old=old) IF NOT event.tracking THEN new = -1 ; Error during tracking IF new NE -1 THEN BEGIN ; Display next image ; The centroid is always returned in rectangular coordinates. ; If smei_set then convert it to polar. Set up a box centered ; on the centroid using the box template saved in the common block. ; This box is used to get the centroid for the next image. centroid = event.centroid IF smei_set THEN centroid = cv_coord(from_rect=centroid-smei_center, /to_polar) ; Center the box on the last centroid only if event.peak is set. ; This usually keep the box more or less in the same place if the ; peak that is being tracked disappears. IF event.peak THEN boxes[*,*,0] = centroid#[1,1] ;======== ;frst = qView_ImageInfo(state, /first) ;widget_control, state.wid_data, get_uvalue=data, /no_copy ;xbox = fix(round(boxes[*,*,0])+boxes[*,*,1]) ;file = filepath(root=getenv('TUB'), $ ; 'box_'+string(old,format='(I3.3)')+'_'+strjoin(string(xbox, format='(I4.4)'),'_')+'.pph') ;bin_write, file, data[xbox[0]:xbox[2],xbox[1]:xbox[3],old-frst] ;widget_control, state.wid_data, set_uvalue=data, /no_copy ;======== widget_control, state.wid_view, get_uvalue=wid_qimage qImage_SendDestination, wid_qimage, state.wid_track, foreign=2, boxes=boxes qView_Image, state ; Draw to generate QIMAGE_TRACK event ENDIF ELSE BEGIN ; Error tracking or done widget_control, state.wid_view, get_uvalue=wid_qimage qImage_SendDestination, wid_qimage, foreign=0 widget_control, state.wid_track, set_uvalue=0B ; Tracking is off ENDELSE ; Process the peak information. qView_PlotTrack, state, event, old, display=new EQ -1, add=event.tracking ENDELSE END ENDCASE RETURN & END