; Copyright (c) 1998-2004 A.P. Hitchcock  All rights reserved
;
;+
;NAME:
;	LN_ALIGN
;
;LAST CHANGED: ----------------------------------- 02-may-04
;
;PURPOSE:
;	This file tilts a linescan by a user defined line, to correct drift.
;
; PRO LN_align, curve=curve
;
;CATEGORY:
;	AXIS: data analysis
;
;CALLING SEQUENCE:
;	Linescan~align
;
;INPUTS:   none
;
;KEYWORDS:
;	CURVE - multi-section curve
;
;OUTPUTS:
;	returns structure with modified linescan
;
;COMMON BLOCKS:
;	@AXIS_COM	standard set of common blocks
;-
; ------------ REVISION HISTORY
; (APH 3-JUL-98) cut out from axis_c for length; fixed errors (thanks Gary) !!
; aph 13-Aug-98) curved line for reference (using DEFROI)
; (02-may-04 aph) modify header

PRO LN_align, curve=curve
@axis_com
;on_error,2

	SetGraf, 'MainImg'
  	HANDLE_VALUE, Data(CurBuf), tmp     ;Get the data
  	IF n_tags(tmp) ne 0 THEN BEGIN
  	  If tmp.t EQ '2d' then begin

	  IF NOT keyword_set(curve) then begin
	WIDGET_CONTROL, Uprompt, SET_VALUE='Linescans align: linear. Select first point'
  		CURSOR, x1, y1, /UP, /DATA         ;Get 1st of two cursor points from the user
		WIDGET_CONTROL, Uprompt, SET_VALUE='Select second point'
		CURSOR, x2, y2, /UP, /DATA
		device, get_graphics = oldgraph, set_graphics = 6      ;Set xor
		plots, [x1(0),y1(0)], [x2(0),y2(0)],/data, thick=1 , color=255
      	device, set_graphics = oldgraph   ; reset graphics mode
		CurInd = Dindex(x1(0),y1(0),tmp) &  xd1= CurInd(0) & lin1=CurInd(1)
		CurInd = DIndex(x2(0),y2(0),tmp) &  xd2= CurInd(0) & lin2=CurInd(1)
		slope = float(lin1 - lin2)/float(xd1(0)-xd2(0))
		int = float(lin1) - slope*xd1(0)
		nl = n_elements(tmp.y)
		dpix = fix(slope*indgen(n_elements(tmp.x)) + int)  - lin1
		dpix = dpix - min(dpix)
;		print, 'range of lines: ',lin1,lin2, ' slope (pixel/line)=', slope,'  int ', int
		loss = max(dpix) - min(dpix)
;		print, 'loss at top (pixels) = ',loss
		if loss GT 0 AND loss LT nl then begin			; only process if there is a shift !
; ------- aborted attemPt to haNdle cases where line exceeds size of data (aPH 3-JUL-98)
;		if loss GT nl then begin	; check if full-E range can be covered
;			IF slope LT 0 then begin
;				test = where(dpix LE nl)
;				nxmax = n_elements(tmp.x) - test(0)
;			ENDIF else begin
;				test = where(dpix GE nl)
;				nxmax = test(0)
;			ENDELSE
;			print, 'WARNING: Shifted data does not cover full E-range.'
;			emin = tmp.x(0) & nstart = 0
;			emin = get_num(Prompt='Emin',val=emin)
;			test = where (tmp.x GE emin,count) & if count GE 0 then nstart = test(0)
;			nstop = nstart + nxmax
;			if nstop GE n_elements(tmp.x) then nstop = n_elements(tmp.x)-1
;			test = fltarr(nstop-nstart) & test = dpix(nstart:nstop) & dpix = fltarr(nstop-nstart) & dpix = test
;			loss = max(dpix) - min(dpix)
;			dpix = dpix - min(dpix)
;			print, ' Use only', tmp.x(nstart), ' to', tmp.x(nstop)
;		endif else nstart = 0 & nstop = n_elements(tmp.x) -1
		nxmax = n_elements(tmp.x)
		for i = 0, nxmax-1 do begin
;		print, 'Shift line ',strcompress(string(i)),' by ',strcompress(string(dpix(i))),' pixels'
; revised 3-jul-98 to use only those pixels accessed at all E
			tmp.d(i,0:(nl-loss-1)) =  tmp.d(i,dpix(i):(nl-loss+dpix(i)-1))
;			tmp.d(i,(nl-loss):(nl-1)) = tmp.d(i,nl-loss-1)                ; replace last lines ??
		endfor
;		if nxmax LT n_elements(tmp.x) then begin
;			for i=nxmax, n_elements(tmp.x)-1 do tmp.d(i,*) = 0.        ; show user that data lost outside some E-range
;        endif

    ENDIF ; ELSE WIDGET_CONTROL, Uprompt, SET_VALUE=' No change or max. shift exceeds # of lines'
ENDIF ELSE BEGIN
; curved line definition using DEFROI
	WIDGET_CONTROL, Uprompt, SET_VALUE='Linescans align: Curved. left = add point; right = end'
	npix = 360*gr_scale
	subs = defroi(npix,npix,xp,yp,/nofill,/restore)
	nref = n_elements(xp)
;	for i = 0,nref-1 do begin print, xp(i),yp(i) & endfor
	ref = convert_coord(xp,yp,/device,/to_data)
;	for i=0,nref-1 do begin print, ref(0,i),ref(1,i) & endfor
; generate ref_line at all x-data points
	ref_line = INTERPOL(ref(1,*),ref(0,*),tmp.x)
; shift data to straighten line
	yt = where(tmp.y LE min(ref_line)) & yl = max(yt)
	yt = where(tmp.y GE max(ref_line)) & yh = min(yt)
	ya = fix((yh+yl)/2)
	loss = yh-yl       & nl = n_elements(tmp.y)
;	print, 'Ref_line spans ',yl,' to ',yh,'. Loss (lines) = ',loss
	if loss GT 0 AND loss LT nl then begin			; only process if there is a shift !
		FOR i = 0,n_elements(tmp.x)-1 DO BEGIN
			CurInd = Dindex(tmp.x(i),ref_line(i),tmp) & dpix = CurInd(1) - yl
;			print, i, dpix
			tmp.d(i,0:(nl-loss-1)) =  tmp.d(i,dpix:(nl-loss+dpix-1))
		ENDFOR
	endif
ENDELSE

; (aph 13-aug-98) Comments:
; need to use sub-pixel alignment by using interpolate on each line
; should convert linear mode to same structure as curved and use common section
; to shift the data

tmp.dl = 'Aln ' + tmp.dl
HANDLE_VALUE, Data(0), tmp, /SET
PlotBuf, 0

; draw line to show extent of alignment shift
if keyword_set(curve) then begin
	plots, tmp.x(0), ref_line(0) ; go to first point
	plots, tmp.x, ref_line, /data, thick=1 , color=255,/continue
endif else begin
	plots, [x1(0),y1(0)], [x2(0),y2(0)],/data, thick=1 , color=255
endelse
ENDIF else WIDGET_CONTROL, Uprompt, SET_VALUE='Linescans align: not for spectra'
ENDIF
END