;+
; NAME: irissjiobs__define
;
;
;
; PURPOSE: Definiton of the irissjiobs (IRIS slit-jaw-images observation) class; This 
;          class contains IRIS SJI specific code only, all code that 
;          is common for the IRIS mission as a whole can be found in the superclass
;          irisobs__define, code that is common for all instruments can be found in the 
;          superclass anyobs.
;
;                                           (sdc_util)
;                                              |
;                                            anyobs    spectobs
;                                          /       \ /        \
;                                   hinobs         /\          \
;                                  /   |   \     /   \          \
;                                    (...)  eisobs    irisobs    \
;                                                      |     \    \
;                                                  IRISSJIOBS irisspectobs
;
; The DATA structure tag of an irissjiobs object will contain a pointer to
; an iris_sji object. An iris_sji object is designed to hold information
; from all four slit jaw pass bands, i.e. information from four individual
; fits files may be included in one iris_sji object. In our case we create an
; irissjiobs object (and thus a pointer to an iris_sji object) based on a
; single fits file. The [4] arrays of the iris_sji object will therefore be
; empty exepct for index iwin, and iris_sji methods must be called with the
; current value of iwin: 
;   
; iwin    line          Lam     log(T)    Temp (kK)
;  0       C  II        1335     4.3      ~20 
;  1       Si IV        1400     4.8      ~63
;  2       Mg II k      2796     4.0      ~10
;  3       Mg II wing   2831     3.7-3.9  ~5-8
;
; METHODS: 
;
;
; SPECIAL CALLS: irisobs__define.pro
;
;
; WRITTEN: Terje Fredvik, UiO, June 2013
;
; MODIFICATION HISTORY:
;            06 Jun 2013 Terje Fredvik: First draft
;            13 Nov 2013 Terje Fredvik: ::ensure_title: call irisobs::_gt_sat_rot_txt
;            19 Nov 2013 Terje Fredvik. New method photosphere(), returns 1 if
;                                       the observed image gets its main
;                                       contribution from the photosphere,
;                                       i.e. the 2832
;                                       band. ::_image_final_touch takes
;                                       photosphere as a keyword, if set do
;                                       not invert the colour table.  
;          23 Oct 2014   Terje Fredvik  ::create_data_object() takes file as
;                                       input parameter (i.e. an uzipped
;                                       file). ::image_final_touch: hardcode
;                                       missing value to -32768 (previous
;                                       actual missing value in data arrays
;                                       was -200. At that time
;                                       iris_sji->missing() 
;                                       returned -32768, but now it returns
;                                       32767 so this method still can't be used)
;
;-
;

FUNCTION irissjiobs::init, file, destdir=destdir, _ref_extra=extra
  o = self
  
  IF o->irisobs::init(file, _extra=extra) EQ 0 THEN return,0

  
  default, destdir, '' ;; If not set, store files in current working directory

  o.version = 'SVN revision '+sdc_revision()
  o.iwin = -1 ;; The index of the passband we're looking at, will be set to 0,1,2 or 3  
  return,1
END


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


;; ++++++++++++++++++++++++++++++++++++++++++++
;;   <overridden anyobs plot_image help method>
;; ++++++++++++++++++++++++++++++++++++++++++++

FUNCTION irissjiobs::extract_image, i, ii=ii, data, _extra=extra
   o = self
  
  default, i, 0
  
  returndata = (n_params() EQ 2) ? 1 : 0
  
  dataobj = *(o->get(/data))
  dataobj->getwin,o->get(/iwin),data ;; iwin is the only index containing information!
  
  o->_image_number_exist,i
  
  im = data[*,*,i]
  
  IF returndata THEN data = im ELSE $
     im = o->_image_final_touch(im, photosphere = o->photosphere(i))
  
  return, im
  
END

;; --------------------------------------------
;;   </overridden anyobs plot_image help method>
;; --------------------------------------------


FUNCTION irissjiobs::photosphere, i
  ;; Retrurn 1 if the observed wavelength region is the wing of the Mg II line
  
  default, photosphere, 0
  
  twave1 = self->hget(/TWAVE1)
  
  IF twave1 GT 2800 THEN photosphere = 1
    
  return, photosphere
END




;; +++++++++++++++++++++++++++++++++++++++
;; <read_data help methods called from irisobs>
;; +++++++++++++++++++++++++++++++++++++++
FUNCTION irissjiobs::create_data_object, file
  o = self
  o->private 
  
  return, obj_new('iris_sji',file)
END

FUNCTION irissjiobs::lwin_read, dataobj
  ;; Extract a string array[4], three of these arrays are blank, one contains
  ;; the filter name. Get the index of this one- this is the index of the header
  ;; we should set as this object's header.
  
  lwin = dataobj->lwin_read() 
  iwin = (where(lwin eq 1))[0]
  return, iwin
END

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


;; +++++++++++++++++++++++++++++++++++++++
;; <called from anyobs>
;; +++++++++++++++++++++++++++++++++++++++

PRO irissjiobs::_ensure_instrument_specific_properties
  o = self
  o->private
  
  o->_ensure_filter
END



PRO irissjiobs::_ensure_filter
  o = self
  o->private
  
  header = o->extract_header()
  tdesc1 = gt_fkw(header,'TDESC1')
  lam = strmid(tdesc1,4,2) ;; in case of modifications, e.g. 2831 VS 2832
  
  CASE lam OF
     '13': filter = 'C II 1335 A'
     '14': filter = 'Si IV 1400 A'
     '27': filter = 'Mg II k 2796 A'
     '28': filter = 'Mg II k wing 2831 A'
     ELSE: filter = ''
  ENDCASE
  o.filter = filter
END



PRO irissjiobs::_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))
  dataobj = *(o->get(/data))
  times = dataobj->gettime(o->get(/iwin))
  
  header = o->extract_header()
  filter = o->get(/filter)
  FOR i=0,nicons-1 DO BEGIN 
     (*o.title)[i] = $
        'IRIS/SJI, ' + filter + ', image no '+trim(i+1)+'/'+trim(nicons) + $
        ', SAT_ROT: '+o->_gt_sat_rot_txt()
     
  ENDFOR 
END

PRO irissjiobs::_ensure_xtitle    
  self->private
  self.xtitle = self->_gt_firstdimraster()
END

;PRO irissjiobs::_ensure_ytitle
;  self->private
;  self.ytitle = 'Instrument Y (arc sec)'
;END


FUNCTION irissjiobs::extract_date_obs, i
  o = self
  
  dataobj = *(o->get(/data))
  times = dataobj->gettime(o->get(/iwin))
  
  header = o->extract_header()
  startobs = gt_fkw(header,'STARTOBS')
  
  return, addtime_sdc(startobs, times[i])
  
END

;; ---------------------------------------
;; </called from anyobs>
;; ---------------------------------------


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

FUNCTION irissjiobs::_image_final_touch, im, photosphere=photosphere
  o = self
  o->private
  
  IF (size(im))[0] EQ 0 THEN return,-1 ;; return if im isn't a 2D image
  
  ;missingvalue = (*(o->get(/data)))->missing()
  ;box_message,'IRIS_SJI->MISSING() IS -32768, WAITING FOR A FIX FROM VIGGO'  
  ;missingvalue = -200 ; this used to be the actual missing value in im
  missingvalue = -32768
  missix = where(im EQ missingvalue, nmissing, complement=goodix, ncomplement=ngoodix)
  
  IF nmissing GT 0 AND ngoodix NE 0 THEN im[missix] = median(im[where(im GT missingvalue)])
  ;; Revert colour table
  im = sigrange(im)
  IF keyword_set(photosphere) THEN im = bytscl(im,/nan) ELSE im = 255-bytscl(im,/nan)
;  im = 255-bytscl(im,/nan)
  IF nmissing GT 0 THEN im[missix] = 255
  
    
  return,im
END

;; -----------------------------------------
;;   <overridden irisobs read_data and help methods
;; -----------------------------------------




;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;; get_XXX functions for all irissjiobs structure tags. Each funciton checks if
;; header is a valid pointer, if not, call read_header which again ensures the
;; tag is set.
;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

FUNCTION irissjiobs::get_iwin
  IF ~ptr_valid(self.header) THEN self->read_header
  return, self.iwin
END

FUNCTION irissjiobs::get_filter
  IF ~ptr_valid(self.header) THEN self->read_header
  return, self.filter
END
;; ---------------------------------------------------------
;; get_XXX functions for all irissjiobs structure tags. 
;; ---------------------------------------------------------




PRO irissjiobs__define
  INT = 0
  STR = ''

  
  d = {irissjiobs, $
       filter: STR, $
       inherits irisobs}
END
