;+
; NAME: irisspectobs__define
;
;
;
; PURPOSE: Definiton of the irisspectobs (IRIS spectrograph observation) class; This 
;          class contains IRIS spectrograph (raster images) specific code
;          only, all code that is common for the IRIS mission as a whole can be
;          found in the superclass irisspectobs__define, code that is common
;          for all missions and instruments can be found in the 
;          superclass anyobs, and finally code that is common for all
;          spectrographs can be found in in spectobs. 
;
;                                            (sdc_util)
;                                              |
;                                            anyobs    spectobs
;                                          /       \ /        \
;                                   hinobs         /\          \
;                                  /   |   \     /   \          \
;                                    (...)  eisobs    irisobs    \
;                                                      |     \    \
;                                                  irissjiobs IRISSPECTOBS
;
;
; METHODS: 
;
;
; SPECIAL CALLS: irisobs__define.pro and spectobs__define.pro
;
;
; WRITTEN: Terje Fredvik, UiO, June 2013
;
; MODIFICATION HISTORY:
;            06 Jun 2013 Terje Fredvik: First draft
;            01 Nov 2013 Terje Fredvik: now works for NUV as well 
;            08 Nov 2013 Terje Fredvik: unzip zipped file before reading,
;                                       delete uzipped file when done. 
;            13 Nov 2013 Terje Fredvik: Minor adjustments in plot titles, including
;                                       descriptive text for Mg II h/k line 
;                                       features. Cleaned up mixup of global
;                                       missing value of anyobs and the
;                                       instrument specific missing
;                                       value. ::ensure_title: call 
;                                       irisobs::_gt_sat_rot_txt
;           19 Nov 2013 Terje Fredvik:  New method photoshphere(), returns 1
;                                      if the observed line is a photospheric
;                                      line, for the time being restricted to
;                                      observations of the Mg II line wings.
;           22 Nov 2013 Terje Fredvik: ::_get_hkfeature: use logical and (&&)
;                                      instead of AND when checking for NUV
;                                      lines. Added method _gt_nraster,
;                                      returns numbers of unique raster
;                                      positions (NRASTERP).
;           09 Dec 2013 Terje Fredvik: ::_ensure_title: include the OBSID
;                                      raster descrition in the title.
;           17 Jan 2014 Terje Fredvik : Added methods ::_get_meanprofile and 
;                                       ::_get_instrument_specific_missing_value to 
;                                       deal with IRIS data cubes that is only 
;                                       partially filled with data. 
;                                       ::_get_expmissing now returns -1 by default.
;                                       _get_hkfeatureim sets missing pixels to the 
;                                       anyobs global missing value.
;           31 Jan 2014 Terje Fredvik   Included preliminary wavelength
;                                       calibration, based on iris_orbitvar_corr_l2, 
;                                       with a couple of tweaks. The unzipped
;                                       file is not deleted untilthe object is 
;                                       destroyed, since iris_orbitvar_corr_l2
;                                       reads in the unzipped file. New
;                                       methods ::getcorrectedwavelengthcube,        
;                                       ::_dynamictitle_addition and 
;                                       ::_ensure_descrtiption. New structure
;                                       tags description AND unzippedfile.
;           11 Feb 2014 Terje Fredvik   Use sdc_* versions of iris_orbitvar_corr_l2 and
;                                       iris_get_mg_features.
;           28 Feb 2014 Terje Fredvik   _extract_image_slit_absorption returns
;                                       -1 if all pixels in image are
;                                       missing. _get_hkfeatureim doesn't halt
;                                       if not both Mg II h/k lines are
;                                       observed.  
;           12. Mar 2014 Terje Fredvik  Minor changes in plot titles
;           19. Mar 2014 Terje Fredvik  New method ::_get_lamdiffmax - returns
;                                       the maximum allowed difference between
;                                       a fitted wavelength and the rest 
;                                       wavelength of a line in a line list.
;           26. Mar 2014 Terje Fredvik  New method MgII checks if Mg II h or k
;                                       line is present in the current data 
;                                       window. The method is called in
;                                       ::emission_only, ::get_hkfeatureim and
;                                       ::photosphere. Added parameter i (data
;                                       window number) in 
;                                       ::_get_hkfeatureim and
;                                       ::find_hkfeatureim to ensure that
;                                       two (or more!) hkfeatures save files may be
;                                       saved for a single file if the two Mg
;                                       II lines are not present in the same
;                                       data window. ::_get_hkfeatureim:
;                                       changed name of counter to preserve the
;                                       input value of i, transpose all data
;                                       (even time series). 
;                                       ::getcorrectedwavelengthcube: added
;                                       check for lamcorr eq -1, ignore
;                                       wavelenght correction if this is the
;                                       case. ::init: made Mg II h wavelength 
;                                       range smaller. Made the mgIIhmin,
;                                       mgIIkmin, mgIIhmax and mgIIkmax structure
;                                       tags floats.
;            26 Mar 2014 Terje Fredvik  It seems like the OBS_DESC can be
;                                       trusted, and we therefore use that to
;                                       extract the raster description in 
;                                       ::_ensure_description rather than
;                                       using iris_obsid2struct (the latter
;                                       will result in wrong description if
;                                       the .cvs file for the obsid isn't
;                                       found)
;            25 Apr 2014 Terje Fredvik  :_get_meanprofile now accepts keyword 
;                                       edgeskip the number of pixels to
;                                       ignore when calculating the mean line
;                                       profile. Also use rebin instead of total.
;            23 Oct 2014 Terje Fredvik  Code dealing with unzipping of files moved
;                                       to irisobs 
;-
;


FUNCTION irisspectobs::init, file, _ref_extra=extra
  o = self
  
  IF o->irisobs::init(file, _extra=extra) EQ 0 THEN return,0
  IF o->spectobs::init(file) EQ 0 THEN return,0
  
  o.version = 'SVN revision '+sdc_revision()
  
  ;; The approximate wavelength ranges of the Mg II h and k lines
  ;; Rest wavelengths 2796.3509493 and 2803.5297192] 
  o.mgIIkmin = 2795
  o.mgIIkmax = 2797
  o.mgIIhmin = 2802.8
  o.mgIIhmax = 2804.3
  
  o.description = 'MISSING'

  
  ;; Color table 8 Green linear will be used as an alternative colour table
  ;; for Mg II h/k intensity maps
  o.coltabs.altintensity = 8
  
  return,1
END



PRO irisspectobs::cleanup
  self->irisobs::cleanup
  self->spectobs::cleanup
  print,"Cleaning up (irisspectobs)"
END

;; ++++++++++++++++++++++++++++++++++++++++
;;   <read_data help methods called from irisobs
;; ++++++++++++++++++++++++++++++++++++++++

FUNCTION irisspectobs::create_data_object, file
  o = self
  o->private

  return, obj_new('iris_data',file)
   
END

FUNCTION irisspectobs::lwin_read,dataobj
  ;; We always want the main header of the iris_data object as the header of the
  ;; irisspect object, i.e. header number 0
  return, 0
END

;; ------------------------------------------
;;   <read_data help methods called from irisobs
;; ------------------------------------------


FUNCTION irisspectobs::find_prepfile, preptype, i=i;, splinelambda0=splinelambda0
  file = prune_filename(self->get(/file))
  CASE preptype OF 
     'adef' :  file = file + '_' + trim(i) + '.adef'
     'ana' :  file = file + '_' + trim(i) + '.ana'
     ELSE: file = -1
  ENDCASE
   
  return, self->get(/destdir) + file
END


FUNCTION irisspectobs::get_expmissing, imagecolumnnumber=imagecolumnnumber
  return, -1
END


;; +++++++++++++++++++++++++++++++++++++++
;; <overridden anyobs _ensure_XXXX methods
;; +++++++++++++++++++++++++++++++++++++++

PRO irisspectobs::_ensure_title
  ;; TITLE is an anyobs structure tag
  o = self
  o->private
  ;; NOTE TO SELF: USE ALLOCATE IN THE __DEFINE FUCTIONS FOR ALL CLASSES TO
  ;;               AVOID PTR_NEW TWICE?
  nicons = o->get(/nicons)
  o.title = ptr_new(strarr(nicons))
  header = *(o->get(/header))

  FOR i=0,nicons-1 DO (*o.title)[i] = trim(gt_fkw(header,'tdesc'+trim(i+1)))
END





PRO irisspectobs::_ensure_instrument_specific_properties 
  o = self
  o->private
  o->_ensure_description
  o->spectobs::_ensure_spect_properties
 
END

PRO irisspectobs::_ensure_description
  self->private
  
  header = *(self->get(/header))

  obs_desc = gt_fkw(header,'OBS_DESC')
  
  ;; A typical obs_desc is "Description FOV Exptime Lines (...)". We want the
  ;; descrtiption and we therefore find the position of the FOV which is on
  ;; the form [fovx]x[fovy]. The fovx/y can be an integer or a float. We
  ;; therefore look for the position of the string "blank, from 0 to 5 random 
  ;; characters, 1 to 4 digits between 0 and 9, " or northing, x": 
  descendpos = stregex(obs_desc, ' .{0,5}[0-9]{1,4}.{0,1}x')
  
  IF descendpos EQ -1 THEN desc = 'Calibration' ELSE $
     desc = strmid(obs_desc,0,descendpos)

  self.description = desc
  
END

;; ---------------------------------------
;; <overridden anyobs _ensure_XXXX methods
;; ---------------------------------------

FUNCTION irisspectobs::_gt_nraster
  self->private
  header = *(self->get(/header))
  return, gt_fkw(header,'NRASTERP')
END



;; +++++++++++++++++++++++++++++++++++++++++
;; <overridden spectobs _ensure_XXXX methods
;; +++++++++++++++++++++++++++++++++++++++++
PRO irisspectobs::_ensure_slit
  o = self
  o->private
  
  IF ~o->is_set(/slit) THEN BEGIN
     instrume = strupcase(gt_fkw(*self.header,'INSTRUME'))
     ;; In the first real IRIS observation files the instrume is set to 
     ;; "SPEC    "! 
     self.slit = (strmid(instrume,0,4) EQ 'SPEC')?1:0
  ENDIF
  
END  
;; ---------------------------------------
;; <overridden spectobs _ensure_XXXX methods
;; ---------------------------------------




;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;; <overridden anyobs _ensure_XXXX methods to be re-overridden by spectobs>
;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PRO irisspectobs::_ensure_nicons
  self->private
  self->spectobs::_ensure_nicons
END
PRO irisspectobs::_ensure_xtitle
  self->private
  self->spectobs::_ensure_xtitle
END
PRO irisspectobs::_ensure_image_scale
  self->private
  self->spectobs::_ensure_image_scale
END
PRO irisspectobs::_ensure_image_origin
  self->private
  self->spectobs::_ensure_image_origin
END
;; -----------------------------------------------------------------------
;; </ overridden anyobs _ensure_XXXX methods to re-overridden by spectobs>
;; -----------------------------------------------------------------------






;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;;   <overridden anyobs extract_XXX methods to be re-overridden by spectobs.
;;    This sort of double overriding is actually not necessary, as long as
;;    spectobs is inherited before anyobs in irisobs__define. Still, I find 
;;    this easier to read.
;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

FUNCTION irisspectobs::extract_image, i, ii=ii, data, maxvel=maxvel, $
                                 errvelmax=errvelmax, _extra=extra, $
                                 medianvalue=medianvalue
  IF arg_present(data) THEN $ ;; i.e. extract_image called from extract_data
     return,self->spectobs::extract_image(i, ii=ii, data, maxvel=maxvel, $
                                          errvelmax=errvelmax, _extra=extra,$
                                          medianvalue=medianvalue) $
  ELSE $ ;; i.e. a direct call of extract_image
     return,self->spectobs::extract_image(i, ii=ii, maxvel=maxvel, $
                                          errvelmax=errvelmax, _extra=extra,$
                                          medianvalue=medianvalue) 
END

FUNCTION irisspectobs::_extract_image_scale, i 
  self->private
  return, self->spectobs::_extract_image_scale(i)
END

FUNCTION irisspectobs::_extract_image_origin, i 
  self->private
  return, self->spectobs::_extract_image_origin(i)
END


FUNCTION irisspectobs::emission_only, i
  ;; For lower transition region and chromosphere some lines may have
  ;; prominent absorption features, e.g. the Mg II h/k and C II. For the time
  ;; being we only take special care when analysing the Mg II h/k lines 

  default, emission_only, 1
 
  IF self->MgII(i,/h) OR self->MgII(i,/k) THEN emission_only = 0
  
  return, emission_only
END

FUNCTION irisspectobs::MgII, i, k=k, h=h
  ;; Check if the k/h line is present in window i if keyword k/h is
  ;; set. Return 1 if present, 0 if not present.
  dataobj = (*(self->get(/data)))
  lam = dataobj->getlam(i)
  
  k_observed = 0
  h_observed = 0
  IF dataobj->getregion(i) EQ 'NUV' THEN BEGIN
     IF min(lam) LT self->get(/mgIIkmin) AND $
        max(lam) GT self->get(/mgIIkmax) THEN k_observed = 1
     IF min(lam) LT self->get(/mgIIhmin) AND $
        max(lam) GT self->get(/mgIIhmax) THEN h_observed = 1
  ENDIF
  IF keyword_set(k) THEN return, k_observed
  IF keyword_set(h) THEN return, h_observed
END


FUNCTION irisspectobs::photosphere, i
  ;; Retrurn 1 if the observed wavelength region is in the NUV band, but in
  ;; the photospheric wings of the Mg II lines 
  default, photosphere, 0
  
  dataobj = (*(self->get(/data)))
  lam = dataobj->getlam(i)
  
  IF dataobj->getregion(i) EQ 'NUV' THEN $
     IF ~self->MgII(i,/k) AND ~self->MgII(i,/h) THEN photosphere = 1
;     IF max(lam) LT self->get(/mgIIkmin) OR $
;      min(lam) GT self->get(/mgIIhmax) THEN photosphere = 1
  
  return, photosphere
END



FUNCTION irisspectobs::_extract_image_slit_absorption, i, ii=ii, $
   errorinfo=errorinfo, $
   intensity=intensity, velocity=velocity, width=width, lambda=lambda, $
   h2v=h2v, h3=h3, h2r=h2r, k2v=k2v, k3=k3, k2r=k2r, $
   newadef=newadef, inspect=inspect,  $
   fittwice=fittwice, snratio=snratio, medianvelcorr=medianvelcorr,$
   quiet=quiet, _ref_extra=extra
  
  o = self
  o->private
  
  IF keyword_set(ii) THEN BEGIN
     box_message,'To set the Mg II line feature images, do not specify the ii keyword, instead set one of the keywords k2v, k3, k2r, h2v, h3 or h2r'
     return,-1
  ENDIF
  
  dataobj =  (*(o->get(/data)))
  
  IF keyword_set(width) THEN BEGIN
     box_message,'Line width not available for lines with absorption features'
     return, -1
  ENDIF
    
  ;; Need to show either intenstiy, velocity [or maybe sometime in the
  ;; feature, width. For the time being I and v only.]
  IF ~keyword_set(intensity) AND ~keyword_set(velocity) THEN BEGIN
     box_message,'Plotting intensity image. Set VELOCITY to change.'
     intensity = 1
  ENDIF 
  

  
    
  ;; Cumbersome to work with 5 different line profile Mg II h/k keywords,
  ;; instead we create a byte array with 1 denoting keyword is set, 0 is not
  ;; set
  
  hk = [keyword_set(k2v), $
        keyword_set(k3),  $
        keyword_set(k2r), $
        keyword_set(h2v), $
        keyword_set(h3),  $
        keyword_set(h2r)]
  
  IF total(hk) EQ 0 THEN BEGIN 
     ;; None of the Mg II line profile h/k parameters have been set, but this _is_ a
     ;; line with potential absorption features. We therefore set the h3 or k3
     ;; keyword, depending on which of the lines is in the observed wavelength
     ;; range. If both lines are observed, we pick k3.


     wvl = dataobj->getline_wvl(i,wscale='AA')
     IF wvl LT o->get(/mgIIkmax) THEN BEGIN  
        k3 = 1
        hk[1] = 1
        box_message,'Plotting the Mg II k3 line feature. Set the k2v, k2r, h2v, h3 or h2r keywords to change.'  
     ENDIF ELSE BEGIN
        h3 = 1
        hk[4] = 1
        box_message,'Plotting the Mg II h3 line feature. Set the k2v, k3, k2r, h2v, or h2r keywords to change.'  
     ENDELSE
     
  ENDIF
  
  IF total(hk) GT 1 THEN BEGIN
     box_message,'Only one of the Mg II h/k parameters may be set. No image plotted'
     return,-1
  ENDIF
  

  dataobj->getwin, i, data, pos,/load
  
  lam = dataobj->getlam(i)
  
  
  im = o->_get_hkfeatureim(data, lam, hk, i, intensity = intensity, $
                           velocity = velocity)
  
  IF max(im) EQ o->get(/missing) THEN im = -1
 
  return, im
  
END

FUNCTION irisspectobs::_get_instrument_specific_missing_value
  ;; Return the missing value of IRIS spect/sji observations, i.e. -200
  self->private
  dataobj = *(self->get(/data))
  return, dataobj->missing()
END

FUNCTION irisspectobs::_get_meanprofile, data, sz, edgeskip=edgeskip
  ;; Return the mean/median-ish line profile of the 3D data cube, i.e. a
  ;; typical I vs lamda line profile if we sum over all exposures and y positions.
  ;; To find the mean profile of the input 3D data array, we first get rid of
  ;; the exposure dimension. In the resulting [wavelength, y] array we set all
  ;; missing pixels to the median of the non-missing pixels. Finally we
  ;; get rid of the y dimension, leaving a 1D intensity as a function of
  ;; wavelength array.
  self->private

;  d = total(data,2)/sz[2]
  d = reform(rebin(data,sz[1],1,sz[3]))
  objmissing = self->_get_instrument_specific_missing_value()
  badix=where(d EQ objmissing,complement=goodix,nbad, ncomplement=ngood)
  IF nbad GT 0 THEN IF ngood GT 0 THEN d[badix] = median(d[goodix])
  
 ; meanprofile =  total(d,2)/sz[3]
  meanprofile = rebin(d,sz[1],1)
  IF keyword_set(edgeskip) THEN BEGIN 
     md = median(meanprofile)
     meanprofile[0:edgeskip] = md
     meanprofile[(size(meanprofile))[1]-edgeskip:*] = md
  ENDIF
  
  return, meanprofile
 
END


FUNCTION irisspectobs::find_hkfeaturefile,i
  file = prune_filename(self->get(/file))
  return,self->get(/destdir)+file+'_hkfeatures_'+trim(i)+'.save'
END


FUNCTION irisspectobs::_get_hkfeatureim, data, lam, hk, i, $
                                      intensity=intensity, velocity=velocity, $
                                         width=width
  

  o = self
  o->private
  
 
  miv = -50 ;; Min velocity to consider when finding h/k line features
  mxv = 50  ;; Max velocity to consider when finding h/k line features
  
  sz =  size(data)
  
  hkfeaturefile = o->find_hkfeaturefile(i)
  IF file_test(hkfeaturefile) THEN restore, file=hkfeaturefile ELSE BEGIN 
     ;; peak index, k or h, v or I, y pixel number, exposure number)
     imdim = [3,2,2, sz[3],sz[2]]
     hkim = fltarr(imdim)
     print,'Running sdc_iris_get_mg_features on exposure number'
     FOR expct=0,sz[3]-1 DO BEGIN 
        print,trim(expct+1)+' of '+trim(sz[3])
        sdc_iris_get_mg_features, reform(data[*,*,expct]),lam/10.,[miv,mxv],hk3,hk2r,hk2v
        hkim[0,*,*,expct,*] = hk2v
        hkim[1,*,*,expct,*] = hk3
        hkim[2,*,*,expct,*] = hk2r

     ENDFOR
     save, file=hkfeaturefile, hkim;hk3im, hk2rim, hk2vim
  ENDELSE 
  
  ;; We assume that h/k2r and h/k2v are also empty when h/k3 is empty. This 
  ;; shouldn't really happen: if there are no Mg II lines we should never go 
  ;; into this function!
  IF hkim[0] EQ -1 THEN message,'Something terribly wrong has happened.'
  
  
  hkix = (where(hk EQ 1))[0] 
  
   
  IF hkix LE 2 && ~o->MgII(i,/k) THEN message,'No Mg II k line observed',/info
  IF hkix GE 3 && ~o->MgII(i,/h) THEN message,'No Mg II h line observed',/info
  
  peakix = hkix MOD 3     ;; h/k2v eq 0, h/k3 eq 1 and h/k2r eq 2
  k = (hkix LE 2) ? 0 : 1 ;; We want the k line if hkix is lt 2, else the h line
  feature = (keyword_set(intensity)) ? 1 : 0
    
  hkfeatureim = reform(hkim[peakix,k,feature,*,*])
  
  ;; EIS time series should not be transposed, but IRIS series must. 
  ;  IF o->get(/raster) THEN data = transpose(data,[0,2,1])
  data = transpose(data,[0,2,1])
  sz = size(data)
  
  ;; ON MISSING PIXELS:
  ;; The slit tilt has been corrected for in level 2 data. All pixel values
  ;; have been preserved in the corrected data cube, leaving some pixels with
  ;; the missing value (-200). The number of missing pixels is a funcion of
  ;; detector position and window width. We will use the data cube to identify
  ;; the missing pixels due to slit tilt correction in the hkfeatureim.  
  
  ;; First we get rid of the wavelenght dimension, then we read in the IRIS
  ;; missing value (-200), then we identify pixels with this value in the L2
  ;; collapsed data, finally we set all pixels in the hkfeatureim
  ;; corresponding to the missing pixels of the L2 collapsed array to the
  ;; anyobs global missing value (-1000) 
  d = total(data,1)/sz[1]
  objmissing = self->_get_instrument_specific_missing_value()
  badix=where(d EQ objmissing,complement=goodix) 
  IF badix[0] NE -1 THEN hkfeatureim[badix] = self->get(/missing) 
  
  ;; Set all pixels where the line feature recognition have failed to the
  ;; anyobs global missing value
  NaNix = where(~finite(hkfeatureim),/NULL)
  IF NaNix NE !NULL THEN hkfeatureim[NaNix] = self->get(/missing)
  
  return,hkfeatureim
     
       
END




FUNCTION irisspectobs::_color_table_txt, i, _extra=extra
  self->private
  
  ;; Use alternative intensity colour table for lines with absorption features
  altintensity = (self->emission_only(i)) ? 0 : 1
  
  return, self->spectobs::_color_table_txt(i, altintensity=altintensity, $
                                           _extra=extra)
END

PRO irisspectobs::_cenAndFov, xcen, ycen, fovx, fovy
  self->private
  self->spectobs::_cenAndFov, xcen, ycen, fovx, fovy
END


FUNCTION irisspectobs::_extract_title,i
  self->private
  return, self->spectobs::_extract_title(i)
END


PRO irisspectobs::_dynamictitle_set, gausslam=gausslam, $
                                      h2v=h2v, h3=h3, h2r=h2r, $
                                      k2v=k2v, k3=k3, k2r=k2r
  ;; If none of the Mg II h/k keywords are set, call the ::_dynamictitle_set
  ;; method of the parent class spectobs. If one of them are set, handle the
  ;; dynamic title here.
  o = self
  o->private
  
  
  IF ~keyword_set(h2v) AND ~keyword_set(h3) AND ~keyword_set(h2r) $
     AND ~keyword_set(k2v) AND ~keyword_set(k3) AND ~keyword_set(k2r) THEN $
        self->spectobs::_dynamictitle_set, gausslam = gausslam ELSE BEGIN 
     
     IF keyword_set(h2v) THEN o.dynamictitle = 'h2v, left peak'
     IF keyword_set(h3) THEN o.dynamictitle = 'h3, central absorption'
     IF keyword_set(h2r) THEN o.dynamictitle = 'h2r, right peak'    
     
     IF keyword_set(k2v) THEN o.dynamictitle = 'k2v, left peak'
     IF keyword_set(k3) THEN o.dynamictitle = 'k3, central absorption'
     IF keyword_set(k2r) THEN o.dynamictitle = 'k2r, right peak'
     
  ENDELSE
END

FUNCTION irisspectobs::_description
  ;; For IRIS/SPEC the description is the raster description. For other
  ;; instruments the description ins blank.
  self->private
  return,self->get(/description)
END


FUNCTION irisspectobs::_get_lamdiffmax
  ;; The maximum difference between the fitted wavelength of a line and the
  ;; rest wavelength in a linelist
  self->private
  return, 0.12
END

  
;; ------------------------------------------------------------------
;;   </ overridden anyobs extract_image to be re-overridden by spectobs
;; ------------------------------------------------------------------

FUNCTION irisspectobs::_gt_linelist_file, backup=backup
  default, backup, 0
  
  ;; Main line list copied from Chianti v. 7.0, 
  ;; http://www.chiantidatabase.org/ch_line_list_v7.0_900_2000.pdf
  ;; and 
  ;; http://www.chiantidatabase.org/ch_line_list_v7.0_2000_10000.pdf
   
  IF ~backup THEN linelist = 'iris_linelist_chianti.txt' ELSE $
     linelist = 'iris_linelist_backup.txt'
  
  ;; file = '$SSW/hinode/eis/idl/atest/osdc/'+linelist
  file = '~/osdc/'+linelist
  
  IF file_test(file) THEN return, file ELSE BEGIN
     message,'Line list file has been moved. Searching...',/info
     return, file_search('$SSW/hinode/eis',linelist)
  ENDELSE
END
    
FUNCTION irisspectobs::_gt_commonblock_linelist, backup=backup
  self->private
  
  default, backup, 0
  
  COMMON iris_linelists_sdc, list_main, list_backup
  
  IF (~backup && n_elements(list_main) EQ 0) OR $
     (backup && n_elements(list_backup) EQ 0) THEN BEGIN 
     
     IF ~backup THEN BEGIN 
        template = { version:1.0,$
                     datastart:3L,$
                     delimiter:44b,$
                     missingvalue:!values.f_nan,$
                     commentsymbol:'',$
                     fieldcount:2L,$
                     fieldtypes:[4L,7],$
                     fieldnames:['lam','ion'],$
                     fieldlocations:[0L,10],$
                     fieldgroups:lindgen(2)}
        list_main = $
           read_ascii(self->_gt_linelist_file(),template=template)
     ENDIF ELSE BEGIN 
        template = { version:1.0,$
                     datastart:3L,$
                     delimiter:44b,$
                     missingvalue:!values.f_nan,$
                     commentsymbol:'',$
                     fieldcount:2L,$
                     fieldtypes:[4L,7],$
                     fieldnames:['lam','ion'],$n
                     fieldlocations:[0L,8],$
                     fieldgroups:lindgen(2)}
        list_backup = $
           read_ascii(self->_gt_linelist_file(/backup),template=template)
     ENDELSE
  ENDIF
  
  return, (~backup) ? list_main : list_backup 
  
END


  
FUNCTION irisspectobs::getcorrectedwavelengthcube, lam, sz, region=region
  ;; No wavelenght correction for IRIS for the time being
  sdc_iris_orbitvar_corr_l2,self->get(/unzippedfile),fuv,nuv,date_obs
;  
  IF region EQ 'FUV' THEN lamcorr = fuv
  IF region EQ 'NUV' THEN lamcorr = nuv
  
  ;; Sometimes the wavelength correction crashes and returns NaNs and if the Ni
  ;; I line isn't observed the returned value is -1. In those cases we'll
  ;; ignore the corrections and continue working with an uncorrected
  ;; wavelenght array.
  IF ~finite(max(lamcorr)) OR max(lamcorr) EQ -1 THEN lamcorr = fltarr(n_elements(lamcorr))
  
  lamcorr2d = fltarr(sz[3], sz[2])
  FOR i=0,sz[2]-1 DO lamcorr2d[*,i] = lamcorr
  ;lamcorr2d[*,*] = 0
  
  lam3D = fltarr(sz[1],sz[3],sz[2])
  FOR j = 0,sz[1]-1 DO lam3D[j,*,*] = lam[j] - lamcorr2d
  return, lam3D                                    
END



FUNCTION irisspectobs::get_datacube_rotation
  ;; Assuming east-west scanning for now, as opposed to EIS where the rot
  ;; coefficients are 1 : 4.
  return,  (self->get(/raster)) ? 4 : 4
END

FUNCTION irisspectobs::_auto_adef_get_smoothing
  ;; Variable used by spectobs::_auto_adef. For now tested for C II lines
  ;; only. Must have a large smoothing to get rid of plateaus, but also to
  ;; eliminate the absorption features. In the feature we would of course take
  ;; the line core depression into account, but for the time being we make a
  ;; crude line fit assuming one emission peak. This might give some spurious
  ;; results, especially in the velocity maps. Time will tell! 
  self->private
  return,6
END
FUNCTION irisspectobs::_auto_adef_get_meanmedian
  ;; Variable used by spectobs::_auto_adef. Value found by trial and error
  ;; using the C II lines. Must be checked for other lines as well.
  self->private
  return, 14
END

  

PRO irisspectobs__define
  INT = 0
  FLT = 0.0
  STR = ''
  
  d = {irisspectobs, $
       inherits spectobs, $
       inherits irisobs, $
       description:STR,$
       mgIIkmin:FLT, $
       mgIIkmax:FLT, $
       mgIIhmin:FLT, $
       mgIIhmax:FLT}

END
