
FUNCTION eis_trim_windata, windata, wrange, ixrange=ixrange

;+
; NAME:
;     EIS_TRIM_WINDATA
;
; CATEGORY:
;     Hinode/EIS; windata.
;
; PURPOSE:
;     This takes a windata structure and trims the wavelength
;     dimension. The intended usage is for full CCD data where the
;     user wants to fit a single emission line with
;     EIS_AUTO_FIT. Using the full size array slows the software down
;     and EIS_FIT_TEMPLATE and EIS_WVL_SELECT are more difficult to
;     use. By truncating WINDATA in the wavelength direction to only
;     the region of interest these problems can be fixed.
;
; CALLING SEQUENCE:
;     Result = EIS_TRIM_WINDATA( Windata, Wrange )
;
; INPUTS:
;     Windata:  An EIS data structure as produced by EIS_GETWINDATA.
;     Wrange:   A two element array specifying a wavelength range to
;               which WINDATA is trimmed. E.g., [195,196].
;
; OPTIONAL INPUTS:
;     Ixrange:  A 2-element array allowing the array to be trimmed in
;               the X-dimension (or time for sit-and-stare data). This
;               is mainly intended for trimming long sit-and-stare
;               time-sequences. 
;
; OUTPUTS:
;     WINDATA is returned, but with the INT, ERR and WVL tags
;     trimmed in the wavelength direction. The tag NL is also
;     updated. 
;
; EXAMPLE:
;     IDL> wd=eis_getwindata(l1name,195.12)
;     IDL> wdnew=eis_trim_windata(wd,[194.5,195.5])
;
; CALLS:
;     REM_TAG, ADD_TAG
;
; MODIFICATION HISTORY:
;     Ver.1, 24-Sep-2010, Peter Young
;     Ver.2, 2-Mar-2015, Peter Young
;        Now works correctly for data-sets with nexp_prp>1
;     Ver.3, 15-Jun-2015, Peter Young
;        I've added an ixrange= input in order to deal with the
;        very long IRIS sit-and-stare studies. I've also tidied
;        up the code to prevent memory problems.
;     Ver.4, 1-Jul-2015, Peter Young
;        Fixed bug introduced with v.3: if ix was not input then
;        windata.int ended up the wrong size.
;     Ver.5, 12-Jul-2017, Peter Young
;        Tidied up header; fixed bug with calculation of new xcen
;        value.
;     Ver.6, 12-Feb-2018, Peter Young
;        Fixed problem with xcen. If ixrange is not set, then xcen
;        should not be recalculated.
;     Ver.7, 13-Jan-2020, Peter Young
;        Correctly handles data with nexp_prp > 1 now.
;     Ver.8, 09-Dec-2021, Peter Young
;        Slot data do not have the wave_corr tags, so I now check for
;        this.
;     Ver.9, 14-Mar-2022, Peter Young
;        Use new wavelength range to adjust wd.hdr.tdetx value.
;     Ver.10, 24-Feb-2025, Peter Young
;        I've done fix so that the routine can work with SPICE data.
;-

IF n_params() LT 1 THEN BEGIN
  print,'Use:  IDL> new_wd = eis_trim_windata( wd, wrange, ixrange=ixrange )'
  return,-1
ENDIF 


nx=windata.nx
ny=windata.ny
nexp_prp=windata.hdr.nexp_prp
wvl=windata.wvl

;
; Slot data do not have the wave_corr tags, so I check for this with
; wave_corr_swtch. 
;
wave_corr_swtch=tag_exist(windata,'wave_corr')


IF n_elements(wrange) EQ 0 THEN wrange=[min(wvl),max(wvl)]
i=where(wvl GE wrange[0] AND wvl LE wrange[1],ni)

IF n_elements(ixrange) EQ 0 THEN BEGIN
  ix=indgen(nx)
ENDIF ELSE BEGIN
  IF n_elements(ixrange) NE 2 THEN BEGIN
    print,'% EIS_TRIM_WINDATA: ixrange must be a 2-element array. Returning...'
    return,windata
  ENDIF
  ix=ixrange
  IF ixrange[1] GT nx-1 THEN ix[1]=nx-1
  IF ixrange[0] LT 0 THEN ix[0]=0
  nx=ix[1]-ix[0]+1
  ix=indgen(nx)+ix[0]
ENDELSE 

;
; 2-Mar-2015 - I modified the following to deal with nexp_prp>1 (i.e.,
;              multiple exposures at the same raster position).
;
IF nexp_prp EQ 1 THEN BEGIN
  int=windata.int[i,ix,*] 
  err=windata.err[i,ix,*]
;  empty_array=fltarr(ni,nx,ny)
ENDIF ELSE BEGIN
  int=windata.int[i,ix,*,*]
  err=windata.err[i,ix,*,*]
;  empty_array=fltarr(ni,nx,ny,nexp_prp)
ENDELSE 


wd2=rem_tag(windata,['int','err','wvl','exposure_time','time', $
                     'time_ccsds','solar_x','wave_corr','wave_corr_t'])
wd3=add_tag(wd2,int,'int')
wd2=0
int=0
wd3=add_tag(wd3,err,'err')
err=0
wd3=add_tag(wd3,fltarr(ni),'wvl')
;
; PRY, 13-Jan-2020: added if statement for nexp_prp
;
IF nexp_prp GT 1 THEN BEGIN
  wd3=add_tag(wd3,dblarr(nx,nexp_prp),'exposure_time')
  wd3=add_tag(wd3,dblarr(nx,nexp_prp),'time')
  wd3=add_tag(wd3,strarr(nx,nexp_prp),'time_ccsds')
 ;
  wd3=add_tag(wd3,dblarr(nx,nexp_prp),'solar_x')
 ;
  IF wave_corr_swtch THEN BEGIN 
    wd3=add_tag(wd3,dblarr(nx,ny,nexp_prp),'wave_corr')
    wd3=add_tag(wd3,dblarr(nx,nexp_prp),'wave_corr_t')
  ENDIF 
ENDIF ELSE BEGIN 
  wd3=add_tag(wd3,dblarr(nx),'exposure_time')
  wd3=add_tag(wd3,dblarr(nx),'time')
  wd3=add_tag(wd3,strarr(nx),'time_ccsds')
 ;
  wd3=add_tag(wd3,dblarr(nx),'solar_x')
 ;
  IF wave_corr_swtch THEN BEGIN 
    wd3=add_tag(wd3,dblarr(nx,ny),'wave_corr')
    wd3=add_tag(wd3,dblarr(nx),'wave_corr_t')
  ENDIF 
ENDELSE


wd3.wvl=wvl[i]
wd3.nl=ni

;
; Now peform changes related to ixrange input.
;  - updated, 13-Jan-2020, to add the nexp_prp dimension
;
wd3.nx=nx
wd3.exposure_time=windata.exposure_time[ix,*]
wd3.time=windata.time[ix,*]
wd3.time_ccsds=windata.time_ccsds[ix,*]
;
wd3.solar_x=windata.solar_x[ix,*]
IF wave_corr_swtch THEN BEGIN 
  wd3.wave_corr=windata.wave_corr[ix,*,*]
  wd3.wave_corr_t=windata.wave_corr_t[ix,*]
ENDIF 

;
; PRY, 12-Feb-2018: Don't want to change xcen if IXRANGE has
; not been set. 
;
IF n_elements(ixrange) NE 0 THEN BEGIN 
  wd3.xcen=(wd3.solar_x[nx-1]+wd3.solar_x[0])/2.0
ENDIF ELSE BEGIN
  wd3.xcen=windata.xcen
ENDELSE 

;
; Now make changes to header.
;
wd3.hdr.date_obs=wd3.time_ccsds[0]
date_end_tai=anytim2tai(wd3.time_ccsds[nx-1])+wd3.exposure_time[nx-1]
;
; The DATE_END keyword doesn't exist for SPICE so I have to make a
; special case for it. The equivalent to tdetx is pxbeg3.
;
IF wd3.hdr.instrume EQ 'SPICE' THEN BEGIN
  wd3.hdr.date_d$end=anytim2utc(/ccsds,date_end_tai)
  wd3.hdr.pxbeg3=wd3.hdr.pxbeg3+i[0]
  wd3.hdr.pxend3=wd3.hdr.pxbeg3+i[-1]
ENDIF ELSE BEGIN 
  wd3.hdr.date_end=anytim2utc(/ccsds,date_end_tai)
  wd3.hdr.tdetx=wd3.hdr.tdetx+i[0]
ENDELSE 
wd3.hdr.nexp=nx

return,wd3

END
