# import the needed modules
from __future__ import absolute_import
from __future__ import print_function
try:
#  import sys
  import numpy
  try:
    from astropy.io import fits as pyfits
  except:
    import pyfits

  import wx
  import matplotlib
  import pipeline_product
  from reflex import parseSofJson,RecipeParameter
  from reflex_interactive_app import PipelineInteractiveApp
  from pipeline_product import PipelineProduct
  from pipeline_display import SpectrumDisplay, ImageDisplay, ScatterDisplay

  import xsh_parameters_common
#  matplotlib.use('WXAgg')
  import_sucess = 'true'
  import warnings
  warnings.simplefilter('ignore',UserWarning)

#NOTE for developers: 
# -If you want to modify the current script to cope
#  with different parameters, this is the function to modify:
#  setInteractiveParameters()
# -If you want to modify the current script to read different data from
#  the input FITS, these are the functions (class DataPlotterManager) to modify:
#  readFitsData()    to indicate what are the FITS input to plot
#  plotSpectrum()    to control 1D image product layout
#  plotImage()       to control 2D image product layout
#  plotTable()       to control 1D table product layout
#  oplotTable()      to control 1D table product overplots
#  getSN()           to access 1D spectrum S/N FITS header info
#  setInsMode()      to access ins mode FITS header info
#  setObjType()      to access obj type FITS header info
#  setRecId()        to set rec id (used in parameter prefix)
#  getArmId()        to get arm id FITS header info
#
# -If you want to modify the current script to modify the plots (using the same
#  data),  this is the function to modify:
#  plotProductsGraphics()          (from class DataPlotterManager)
# -If you want to modify the text that appears in the "Help" button,
#  this is the function to modify:
#  setWindowHelp()
# -If you want to modify the title of the window, modify this function:
#  setWindowTitle()


  #This class deals with the specific details of data reading and final plotting.
  class DataPlotterManager:

    def paragraph(self,text, width=None):
       """ wrap text string into paragraph
           text:  text to format, removes leading space and newlines
           width: if not None, wraps text, not recommended for tooltips as
                  they are wrapped by wxWidgets by default
       """
       import textwrap
       #print 'width=',width,'Text=',text
       if width is None:
           return textwrap.dedent(text).replace('\n', ' ').strip()
       else:
           return textwrap.fill(textwrap.dedent(text), width=width) 


    #1D spectrum plots
    def plotSpectrum(self,data,errs,qual,bpcode,subplot,title,tooltip):
        data.readSpectrum(0)
        errs.readSpectrum(1)
        nwave = len(data.flux)
        minlimwave = int(nwave*0.25)
        maxlimwave = int(nwave*0.75)

        spectrum = SpectrumDisplay()
        spectrum.setLabels('Wavelength [nm]','Total Flux ['+data.bunit+']')

        spectrum.display(subplot,title,self.paragraph(tooltip),data.wave,data.flux,errs.flux, autolimits = True) 
        #matplotlib.pyplot.tight_layout()
        if self.response_found is True and self.rec_id[16:19] != "nod":
           #in case response is available we need to reduce fonts
           subplot.set_title(title, fontsize=7)
        try:
            pass
            #subplot.figure.tight_layout()
        except AttributeError:
            pass

        #Flag BP as errors
        qual.readSpectrum(2)
        bpm_flag = numpy.bitwise_and(qual.flux,int(bpcode) ) == 0 
        mask_f_data=numpy.ma.MaskedArray(data.flux, mask=bpm_flag).compressed()
        mask_f_wave=numpy.ma.MaskedArray(data.wave,mask=bpm_flag).compressed()
        size_f_err=numpy.ma.MaskedArray(errs.flux,mask=bpm_flag).compressed()

        bpm_all = (qual.flux == 0 ) 
        mask_a_data=numpy.ma.MaskedArray(data.flux, mask=bpm_all).compressed()
        mask_a_wave=numpy.ma.MaskedArray(data.wave,mask=bpm_all).compressed()
        size_a_err=numpy.ma.MaskedArray(errs.flux,mask=bpm_all).compressed()
        #print "size all", mask_a_data.size
        if mask_a_data.size > 0 :
           subplot.errorbar(mask_a_wave, mask_a_data, xerr=None, yerr=size_a_err, color='k', linestyle='', capsize=0)
        #print "size masked", mask_f_data.size
        #print "size spectrum", data.flux.size
        if mask_f_data.size > 0 :
           subplot.errorbar(mask_f_wave, mask_f_data, xerr=None, yerr=size_f_err, color='r', linestyle='', capsize=0)
        subplot.set_xlim(spectrum.wave_lim)
        subplot.set_ylim(spectrum.flux_lim)
       

    #2D image display
    def plotImage(self,obj,bpm,subplot,title,tooltip):

          obj.readImage(fits_extension=0)
          obj.read2DLinearWCS(fits_extension=0)
          img_obj = ImageDisplay()

          bpm.readImage(fits_extension=2)
          img_bpm = ImageDisplay()

          img_obj.setLabels('Wavelength [nm]','Position Along Slit \n [arcsec]')
          y_size, x_size = obj.image.shape
          #print 'x_size=',x_size , 'y_size=',y_size
          #print 'crval1=',obj.crval1,'crpix1=',obj.crpix1,'cdelt1=',obj.cdelt1 
          
          img_obj.setXLinearWCSAxis(obj.crval1,obj.cdelt1,obj.crpix1)
          img_obj.setYLinearWCSAxis(obj.crval2,obj.cdelt2,obj.crpix2)

          #img_obj.setLimits((0,x_size),(0,y_size))
          #print bpm.image
          bp_code_missing_data = 524288
          bp_code_sky_model_inaccurate = 8388608
          bp_code_sky_model_outliers = 16777216
          bp_code_display = self.decode_bp - bp_code_sky_model_inaccurate - bp_code_sky_model_outliers
          bpm_filt = ( (bpm.image & bp_code_display ) != 0 )  
          #bpm_filt = ( (bpm.image & self.decode_bp ) != 0 )  
          #my_image = bpm.image 
          img_obj.display(subplot, title, self.paragraph(tooltip),obj.image,bpm_filt)
          if self.response_found is True and self.rec_id[16:19] != "nod":
             #in case response is available we need to reduce fonts
             subplot.set_title(title, fontsize=7)
    #1D spectrum table plots
    def plotTable(self,tab,Xcol,Ycol,Xlab,Ylab,subplot,title,tooltip,
    wave = None):

        tab.readTableXYColumns(fits_extension=1,xcolname=Xcol, ycolname=Ycol)
        spectrum = SpectrumDisplay()
        flux_plotmax = 1.2 * numpy.nanmax(tab.y_column)
        flux_plotmin = 0.0
        spectrum.setLabels(Xlab,Ylab)
        spectrum.flux_lim = flux_plotmin, flux_plotmax
        if wave is not None:
           spectrum.setWaveLimits((wave[0], wave[len(wave)-1]))

        spectrum.display(subplot,title,self.paragraph(tooltip),tab.x_column,tab.y_column) 
        if self.response_found is True and self.rec_id[16:19] != "nod":
           #in case response is available we need to reduce fonts
           subplot.set_title(title, fontsize=7)

    #1D spectrum table over-plots
    def oplotTable(self,tab,Xcol,Ycol,Xlab,Ylab,subplot,color):

        tab.readTableXYColumns(fits_extension=1,xcolname=Xcol, ycolname=Ycol)
        wave_lim = subplot.get_xlim()
        flux_lim = subplot.get_ylim()
        spectrum = SpectrumDisplay()
        spectrum.overplot(subplot,tab.x_column,tab.y_column,color)
        subplot.set_xlim(wave_lim)
        subplot.set_ylim(flux_lim)


    def getDecodeBP(self, fitsfile):
        hdulist = pyfits.open(fitsfile.name)
        self.decode_bp = hdulist[0].header['ESO PRO REC1 PARAM4 VALUE']

    #Get S/N info (Xshooter and arm specific)
    def getSN(self, fitsfile):
      hdulist = pyfits.open(fitsfile.name)
      self.SN1 = hdulist[0].header['ESO QC FLUX1 SN']
      if self.arm_uvb_found  == True :
        self.SN2 = hdulist[0].header['ESO QC FLUX2 SN']
        self.RN1 = "450-470 nm"
        self.RN2 = "510-530 nm"
      if self.arm_vis_found  == True :
        self.SN2 = hdulist[0].header['ESO QC FLUX2 SN']
        self.SN3 = hdulist[0].header['ESO QC FLUX3 SN']
        self.RN1 = "672-680 nm"
        self.RN2 = "745-756 nm"
        self.RN3 = "992-999 nm"
      if self.arm_nir_found  == True :
        self.RN1 = "1514-1548 nm"
        self.OPTI5_NAME = hdulist[0].header['ESO INS OPTI5 NAME']
        if "JH" in self.OPTI5_NAME :
          self.arm_nir_jh_found = True
          print("Found NIR JH filter")
        else :
          self.SN2 = hdulist[0].header['ESO QC FLUX2 SN']
          self.RN2 = "2214-2243 nm"
     
    # This function will read all the columns, images and whatever is needed
    # from the products. The variables , self.plot_x, self.plot_y, etc...
    # are used later in function plotProductsGraphics().
    # Add/delete these variables as you need (only that plotProductsGraphics()
    # has to use the same names).
    # You can also create some additional variables (like statistics) after
    # reading the files.
    # If you use a control variable (self.xxx_found), you can modify 
    # later on the layout of the plotting window based on the presence of 
    # given input files. 
    # sof contains all the set of frames
    def readFitsData(self, fitsFiles):
      #Control variable to check if the interesting files where at the input
      prefix = "OBJECT_SLIT_"
      self.spectrum1D_found   = False
      self.flux_spectrum1D_found   = False
      self.lineguess_found = False
      self.spectrum2D_found      = False
      self.response_found      = False
      self.mresponse_found      = False
      self.sky_spectrum2D_found      = False
      self.sky2D_found   = False
      self.obj_sky2D_found   = False
      self.bpm_found   = False
      self.arm_uvb_found      = False
      self.arm_vis_found      = False
      self.arm_nir_found      = False
      self.arm_nir_jh_found   = False
      self.nima = 0
      self.IDP_found   = False

      #Read all the products
      frames = dict()
      for frame in fitsFiles:
        if frame == '' :
          continue
        #hdulist = pyfits.open(frame)
        #hdulist = frame.hdulist()
        header = pyfits.open(frame.name)
        #Make sure to have only products from the same recipe
        #that used this (common) script 
        if 'ESO PRO REC1 ID' in header[0].header :
           rec_id = header[0].header['ESO PRO REC1 ID']
           if rec_id == self.rec_id :
              #print rec_id, self.rec_id
              category = frame.category
              #print 'category=',category
              frames[category] = frame
              if category[0:17] == "SCI_SLIT_FLUX_IDP":
                 self.IDP_found = True
      #Note that you have to take care that no other input to this py script
      #the same prefix as SCI_SLIT, TELL_SLIT, FLUX_SLIT
 
      prefixes = [k.split('_')[0]+"_"+k.split('_')[1] for k in frames.keys()]
      idp_prefixes = [k.split('_')[0]+"_"+k.split('_')[1]+"_"+k.split('_')[2]+"_"+k.split('_')[3] for k in frames.keys()]

      #print prefixes
      #print idp_prefixes
      #print prefix

      if self.IDP_found == True and "SCI_SLIT_FLUX_IDP" in idp_prefixes :
         #special case for IDPs (due to different product prefix
         #naming conventions)
         #print "IDP is a special case"
         if "SCI_SLIT_FLUX_MERGE1D" in idp_prefixes :
           prefix = "SCI_SLIT_"
         elif "TELL_SLIT_FLUX_MERGE1D" in idp_prefixes:
           prefix = "TELL_SLIT_"
         elif "FLUX_SLIT_FLUX_MERGE1D" in idp_prefixes:
           prefix = "FLUX_SLIT_"
         elif "CAL_SLIT_FLUX_MERGE1D" in idp_prefixes:
           prefix = "CAL_SLIT_"
         elif "SKY_SLIT_FLUX_MERGE1D" in idp_prefixes:
           prefix = "SKY_SLIT_"
         #IDP can be created also in case no FLUX calibrated spectrum      
         #is generated. Thus we need also the following cases to
         #properly display results
         elif "TELL_SLIT" in prefixes:
           prefix = "TELL_SLIT_"
         elif "SCI_SLIT" in prefixes:
           prefix = "SCI_SLIT_"
         elif "FLUX_SLIT" in prefixes:
           prefix = "FLUX_SLIT_"
         elif "SKY_SLIT" in prefixes:
           prefix = "SKY_SLIT_"

      else :
         #print "normal case"
         if "SCI_SLIT" in prefixes :
           prefix = "SCI_SLIT_"
         elif "TELL_SLIT" in prefixes:
           prefix = "TELL_SLIT_"
         elif "FLUX_SLIT" in prefixes:
           prefix = "FLUX_SLIT_"
         elif "CAL_SLIT" in prefixes:
           prefix = "CAL_SLIT_"
         elif "SKY_SLIT" in prefixes:
           prefix = "SKY_SLIT_"



      #print prefix
      arm=self.seq_arm

      if arm == "UVB":
         self.arm_uvb_found = True
      if arm == "VIS":
         self.arm_vis_found = True
      if arm == "NIR":
         self.arm_nir_found = True


# For any arm search a list of input frames
      key = prefix+"MERGE1D_"+arm
      #print key
      if key in frames :
        self.spectrum1D_found = True
        hdulist = frames[prefix+"MERGE1D_"+arm]
        #hdulist = hdulist[prefix+"MERGE1D_"+arm]
        self.spectrum1D = PipelineProduct(hdulist)
        self.error1D = PipelineProduct(hdulist)
        self.qual1D = PipelineProduct(hdulist)
        self.getSN(hdulist)
        #print "SN=",self.SN1
        self.getDecodeBP(hdulist)
        #print "Decode BP=",self.decode_bp
        self.nima += 1
        #print "found MERGED1D spectrum"
      
      key = prefix+"FLUX_MERGE1D_"+arm
      if key in frames :
        self.flux_spectrum1D_found = True
        hdulist = frames[prefix+"FLUX_MERGE1D_"+arm]
        self.flux_spectrum1D = PipelineProduct(hdulist)
        self.flux_error1D = PipelineProduct(hdulist)
        self.flux_qual1D = PipelineProduct(hdulist)
        self.nima += 1
        #print "found FLUX_MERGED1D spectrum"
        
      key = prefix+"MERGE2D_"+arm
      if key in frames :
        self.spectrum2D_found = True
        hdulist = frames[prefix+"MERGE2D_"+arm]
        self.bpm = PipelineProduct(hdulist)
        self.spectrum2D = PipelineProduct(hdulist)
        self.nima += 1
        #print "found MERGED2D spectrum"
        header = pyfits.open(hdulist.name)
        self.key_object = header[0].header['OBJECT']
        self.decode_bp = int(header[0].header['ESO PRO REC1 PARAM4 VALUE'])
        self.CDELT1 = header[0].header['CDELT1']
        self.CDELT2 = header[0].header['CDELT2']


        #print prefix
        #print object
        if 'CAL_SLIT_' in prefix and 'SKY' in self.key_object and 'stare' in self.rec_id :
            self.obj_type = "Sky"

      key = "SKY_SLIT_MERGE2D_"+arm
      if key in frames and self.rec_id[16:19] != "nod":
        self.sky_spectrum2D_found = True
        hdulist = frames["SKY_SLIT_MERGE2D_"+arm]
        self.sky_spectrum2D = PipelineProduct(hdulist)
        self.nima += 1
        #print "found SKY_SLIT_MERGED2D spectrum"

      key = prefix+"SKY_"+arm
      if key in frames :
        self.sky2D_found = True
        hdulist = frames[prefix+"SKY_"+arm]
        self.sky2D = PipelineProduct(hdulist)
        #print "found SKY_2D spectrum"

      key = prefix+"SUB_SKY_"+arm
      if key in frames :
        self.obj_sky2D_found = True
        hdulist = frames[prefix+"SUB_SKY_"+arm]
        self.obj_sky2D = PipelineProduct(hdulist)
        #print "found SUB_SKY spectrum"

      if self.rec_id[0:10] == "xsh_respon":

         key = "RESPONSE_MERGE1D_SLIT_"+arm
         if key in frames : 
            self.response_found = True
            hdulist = frames["RESPONSE_MERGE1D_SLIT_"+arm]
            self.response = PipelineProduct(hdulist)
            self.nima += 1
            #print "found RESPONSE_MERGE1D_SLIT_ spectrum"

         key = "MRESPONSE_MERGE1D_SLIT_"+arm
         if key in frames : 
            self.mresponse_found = True
            hdulist = frames["MRESPONSE_MERGE1D_SLIT_"+arm]
            self.mresponse = PipelineProduct(hdulist)
            #print "found MRESPONSE_MERGE1D_SLIT_ spectrum"

    #get ins mode (Slit/IFU and Stare/Offset/Nodding)
    def setInsMode(self, rec_id):
      #Recipe ID variable to properly define params
      self.rec_id = rec_id

      if self.rec_id[16:21] == "stare" :
         self.ins_mode = "Slit-Stare"
      elif self.rec_id[16:22] == "offset" :
         self.ins_mode = "Slit-Offset"

      elif self.rec_id[16:19] == "nod" :
         self.ins_mode = "Slit-Nodding"
      elif self.rec_id == "xsh_scired_ifu_stare" :
         self.ins_mode = "ifu-stare"
      elif self.rec_id == "xsh_scired_ifu_offset" :
         self.ins_mode = "ifu-offset"

    #Set Object type (Object/Std star) to display proper info
    def setObjType(self, rec_id):
      #Recipe ID variable to properly define params
      self.rec_id = rec_id

      if self.rec_id[0:10] == "xsh_scired":
         self.obj_type = "Object"
      
      if self.rec_id[0:10] == "xsh_respon":
         self.obj_type = "Std Star"



    #Set rec id (to have proper recipe parameters prefix)
    def setRecId(self, rec_id):
      #Recipe ID variable to properly define params
      self.rec_id = rec_id
      self.setInsMode(rec_id)
      self.setObjType(rec_id)

    #Get arm setting
    def getArmId(self, sof):
      #Recipe ID variable to properly define params
      self.rec_id = "xsh_respon_slit_stare"
      self.seq_arm = "UVB"
      nf = 0

      frames = dict()
      files = sof.files
      for f in files:
      #for frame in fitsFiles:
        file_name=f.name
        if file_name == '' :
          continue
        else :
           nf += 1
           hdulist = pyfits.open(file_name)
           rec_id_list = hdulist[0].header['ESO PRO REC1 ID']
           arm_list = hdulist[0].header['ESO SEQ ARM']
      if nf != 0 :
         self.rec_id = rec_id_list[0:]
         self.seq_arm = arm_list[0:]

      if self.seq_arm == "UVB":
         self.arm_uvb_found = True

      if self.seq_arm == "VIS":
         self.arm_uvb_found = True

      if self.seq_arm == "NIR":
         self.arm_uvb_found = True

      if self.rec_id[16:21] == "stare" :
         self.ins_mode = "Slit-Stare"
      elif self.rec_id[16:22] == "offset" :
         self.ins_mode = "Slit-Offset"

      elif self.rec_id[16:19] == "nod" :
         self.ins_mode = "Slit-Nodding"
      elif self.rec_id == "xsh_scired_ifu_stare" :
         self.ins_mode = "ifu-stare"
      elif self.rec_id == "xsh_scired_ifu_offset" :
         self.ins_mode = "ifu-offset"

      if self.rec_id[0:10] == "xsh_scired":
         self.obj_type = "Object"
      
      if self.rec_id[0:10] == "xsh_respon":
         self.obj_type = "Std Star"



    # This function creates all the subplots. It is responsible for the plotting 
    # layouts. 
    # There can different layouts, depending on the availability of data
    # Note that subplot(I,J,K) means the Kth plot in a IxJ grid 
    # Note also that the last one is actually a box with text, no graphs.
    def addSubplots(self, figure):
      nrows=self.nima
      row=1;
      #print "self.spectrum1D_found",self.spectrum1D_found
      #print "self.spectrum2D_found",self.spectrum2D_found
      #print "self.flux_spectrum1D_found",self.flux_spectrum1D_found
      #print "self.response_found",self.response_found
      #print "self.spectrum2D_found",self.spectrum2D_found
      #print "self.sky_spectrum2D_found",self.sky_spectrum2D_found

      if self.spectrum1D_found == True and self.spectrum2D_found == True:
        self.subplot_spectrum  = figure.add_subplot(nrows,1,row)
        row +=1

        if self.flux_spectrum1D_found == True :
           self.subplot_flux_spectrum = figure.add_subplot(nrows,1,row)
           row +=1

        if self.response_found == True:
           self.subplot_response    = figure.add_subplot(nrows,1,row)
           row +=1

        if self.spectrum2D_found == True :
           self.subplot_image_obj = figure.add_subplot(nrows,1,row)
           row +=1

        if self.rec_id[17:19] != "nod" :

          if self.sky_spectrum2D_found == True :
             self.subplot_image_sky = figure.add_subplot(nrows,1,row)
             row +=1

      else : 
        self.subtext_nodata    = figure.add_subplot(1,1,1)
        print("found no spectrum data")


          
    # This is the function that makes the plots.
    # Add new plots or delete them using the given scheme.
    # The data has been already stored in self.plot_x, self.plot_xdif, etc ...
    # It is mandatory to add a tooltip variable to each subplot.
    # One might be tempted to merge addSubplots() and plotProductsGraphics().
    # There is a reason not to do it: addSubplots() is called only once at
    # startup, while plotProductsGraphics() is called always there is a resize.
    def plotProductsGraphics(self):
      if self.spectrum1D_found == True and self.spectrum2D_found == True: 
        #and self.lineguess_found == True 
        title_pref = 'Standard-extracted and Merged Spectrum.'        
        title_flux_spectrum = 'Standard Extracted, Merged, and Flux Calibrated Spectrum.'
        tooltip_spectrum ="""\
                          Plot of the standard-extracted and merged spectrum of the object (blue line) as total flux (ADU) versus wavelength (nm). The +-1 sigma uncertainties are plotted as the light blue region encompassing the object spectrum (and bounded by the light grey spectra). Flagged pixels are marked with a dark-grey vertical bar stretching between the +- 1 sigma limits. Flagged bad pixels that are decoded as "bad pixels" are marked by a red vertical bar stretching between the +- 1 sigma limits. Note that this spectrum is not flux calibrated."""

        tooltip_flux_spectrum ="""\
                              Plot of the standard-extracted, merged,
                              and flux calibrated spectrum of the
                              object (blue line) as total flux (10^-16
                              erg/s/cm^2/A) versus wavelength
                              (nm). The +-1 sigma uncertainties are
                              plotted as the light blue region
                              encompassing the object spectrum (and
                              bounded by the light grey
                              spectra). Flagged pixels are marked with
                              a dark-grey vertical bar stretching
                              between the +- 1 sigma limits. Flagged
                              bad pixels that are decoded as "bad
                              pixels" are marked by a red vertical bar
                              stretching between the +- 1 sigma
                              limits. The reference standard star
                              spectrum from the catalog is overplotted for
                              comparison purposes as a green line."""

        if self.arm_uvb_found == True:
          title_spectrum   = title_pref+' \n SN: %#.2f (%#s); %#.2f (%#s) '% (self.SN1,self.RN1,self.SN2,self.RN2)

        if self.arm_vis_found == True:
          title_spectrum   = title_pref+' \n SN: %#.2f (%#s); %#.2f (%#s); %#.2f (%#s) '% (self.SN1,self.RN1,self.SN2,self.RN2,self.SN3,self.RN3)

        if self.arm_nir_found == True and self.arm_nir_found == True:
             title_spectrum   = title_pref+' \n SN: %#.2f (%#s); '% (self.SN1,self.RN1)
        elif self.arm_nir_found == True :
             title_spectrum   = title_pref+' \n SN: %#.2f (%#s); %#.2f (%#s); '% (self.SN1,self.RN1,self.SN2,self.RN2)
           
           
        #Spectrum plot

        self.plotSpectrum(self.spectrum1D,self.error1D,self.qual1D,self.decode_bp,self.subplot_spectrum,title_spectrum,tooltip_spectrum)

        #Flux calibrated Spectrum plot

        if self.flux_spectrum1D_found == True:

           self.plotSpectrum(self.flux_spectrum1D,self.flux_error1D,self.flux_qual1D,self.decode_bp,self.subplot_flux_spectrum,title_flux_spectrum,tooltip_flux_spectrum)
        if self.response_found == True :
           self.oplotTable(self.response,'LAMBDA','REF','Wavelength [nm]','Reference flux [erg/e-/cm^2]',self.subplot_flux_spectrum,'green')
        if self.mresponse_found == True :
           self.oplotTable(self.response,'LAMBDA','REF','Wavelength [nm]','Reference flux [erg/e-/cm^2]',self.subplot_flux_spectrum,'yellow')



        #Image
        info_bin_size = 'Pixel size: %#.3f [nm] x %#.3f [arcsec]'% (self.CDELT1,self.CDELT2)

        title_image_obj   = '2D Merged ' + self.obj_type +'Spectrum.'+ info_bin_size
        tooltip_image_obj ="""\
                           Image of the 2D merged spectrum of the
        object in ADU. A red hue corresponds to flagged pixels, which
        may be good or bad. Note that this spectrum is not flux calibrated."""


        title_image_sky   = '2D Merged Sky Spectrum '+ info_bin_size 
        tooltip_image_sky ="""\
                           Image of the 2D merged spectrum of the sky
        in ADU. A red hue corresponds to flagged pixels, which
        may be good or bad. Note that this spectrum is not flux calibrated."""
        #Object merged 2D
        if self.spectrum2D_found  == True:
           self.plotImage(self.spectrum2D,self.bpm,self.subplot_image_obj,title_image_obj,tooltip_image_obj)


        #sky merged 2D
        if self.sky_spectrum2D_found  == True and self.rec_id != "xsh_respon_slit_nod" and self.rec_id != "xsh_scired_slit_nod" :

           self.plotImage(self.sky_spectrum2D,self.bpm,self.subplot_image_sky,title_image_sky,tooltip_image_sky)


        #Scatter plot
        if self.response_found == True :
           title_response   = 'Instrument response curve' 
           tooltip_response ="""\
                             Plot of the instrument response curve
        (erg/e-/cm^2) as determined from the standard star observation
        (green). The raw response is overplotted for comparison
        purposes (blue). If the master response curve is available, then it is overplotted for comparison purposes (yellow)."""
           if self.spectrum1D_found == True:
              self.plotTable(self.response,'LAMBDA','REF_DIV_OBS','Wavelength [nm]','Raw Response \n[erg/e-/cm^2]',self.subplot_response,title_response,tooltip_response,self.spectrum1D.wave)
              self.oplotTable(self.response,'LAMBDA','RESPONSE','Wavelength [nm]','Response [erg/e-/cm^2]',self.subplot_response,'green')

           else:
              #print "self.response_found"
              self.plotTable(self.response,'LAMBDA','RESPONSE','Wavelength [nm]','Response [erg/e-/cm^2]',self.subplot_response,title_response,tooltip_response)
           if self.mresponse_found == True :
              self.oplotTable(self.mresponse,'LAMBDA','RESPONSE','Wavelength [nm]','Response [erg/e-/cm^2]',self.subplot_response,'yellow')
  
      else :
        #Data not found info
        self.subtext_nodata.set_axis_off()
        self.text_nodata = """Merged spectrum
       (PRO.CATG=PREF_MERGE1D_ARM,PREF_MERGE2D_ARM, 
       where PREF=FLUX_SLIT, TELL_SLIT or SCI_SLIT, 
       ARM=UVB,VIS or NIR) not found in the products. 
       This may be due to a recipe failure. 
      Check your input parameter values, 
      correct possibly typos and
      press 'Re-run recipe' button."""
        self.subtext_nodata.text(0.1, 0.6, self.text_nodata, color='#11557c', 
                                 fontsize=18, ha='left', va='center', alpha=1.0)
        self.subtext_nodata.tooltip="""\
                                    Merged spectrum not found in the products"""
        print("found no spectrum data")
 
  
    # This function specifies which are the parameters that should be presented
    # in the window to be edited.
    # Note that the parameter has to be also in the in_sop port (otherwise it 
    # won't appear in the window) 
    # The descriptions are used to show a tooltip. They should match one to one
    # with the parameter list 
    # Note also that parameters have to be prefixed by the 'recipe name:'

        
    def setInteractiveParameters(self):
      paramList = list()

      rec_id=self.rec_id
      self.par = xsh_parameters_common.Parameters()

      self.par.setGeneralObjectParameters(paramList,rec_id)

      if rec_id[16:22] != "offset" :
         self.par.setStackParameters(paramList,rec_id)
      self.par.setCrhSingleParameters(paramList,rec_id)

      if rec_id[16:21] == "stare" :
         self.par.setBackgroundParameters(paramList,rec_id)

      self.par.setLocalizeParameters(paramList,rec_id)
      self.par.setRectifyParameters(paramList,rec_id)

      if rec_id[16:21] == "stare" :
        self.par.setOptExtractParameters(paramList,rec_id)
        self.par.setSkyParameters(paramList,rec_id)

      if rec_id[17:19] == "nod" :
        self.par.setCombineNodParameters(paramList,rec_id)

      return paramList

    def setWindowHelp(self):
      help_text = """
This is an interactive window which help asses the quality of the execution of a recipe.
"""
      return help_text

    def setWindowTitle(self):
      title = 'X-shooter Interactive ' + self.obj_type + ' Spectrum Extraction. ' + self.seq_arm + ' Arm. ' + self.ins_mode
      return title

except ImportError:
  import_sucess = 'false'
  print("Error importing modules pyfits, wx, matplotlib, numpy")
  raise

