Ejemplo n.º 1
0
def main():
    ap = ArgumentParser()
    ap.add_argument('--port',
                    type=int,
                    default=8888,
                    help='Port. [%(default)s]')
    args = ap.parse_args()

    # initialize isow as the mean of a fixed range
    specwave = analysis.loadmat_single('../data/specwave2.mat').ravel()
    calspec = analysis.loadmat_single('../data/calspecw2.mat').ravel()
    isoind1, isoind2 = np.searchsorted(specwave, (0.5, 1.25))
    MODEL.set_isow(calspec[isoind1:isoind2].mean())

    # load spectrum data
    SPECTRA['file1'] = analysis.loadmat_single('../data/kjs.mat')
    SPECTRA['file2'] = analysis.loadmat_single('../data/kjm.mat')
    SPECTRA['file3'] = analysis.loadmat_single('../data/kjb.mat')
    for k in SPECTRA.keys():
        SPECTRA[k] = analysis.preprocess_traj(SPECTRA[k], 0.405, 2.451, 0.301)

    K['file2'] = analysis.MasterHapke1_PP(MODEL, SPECTRA['file2'], .1, .3, .46,
                                          0, 63)

    app = MplWebApp([(r'/', DemoHandler)], debug=True)
    app.listen(args.port)
    print('Starting UI server at http://%s:%s/' % (gethostname(), args.port))
    tornado.ioloop.IOLoop.current().start()
Ejemplo n.º 2
0
  def initialize(self, phase_fn='legendre', scatter_type='lambertian',
                 thetai=0, thetae=0, n1=0, 
                 specwave_file='', calspec_file='', **kwargs):  
    
    plt.close('all')  # hack!
    # HACK: use defaults if some/all files aren't provided
    specwave_file = specwave_file or '../data/specwave2.mat'
    calspec_file = calspec_file or '../data/calspecw2.mat'
    self.Bg = True if 'Bg' in kwargs else False
    Hu = True if 'HuApprox' in kwargs else False
     
    self.global_thetai, self.global_thetae = np.deg2rad([float(thetai), float(thetae)])
    self.hapke_scalar = HapkeModel(self.global_thetai, self.global_thetae, float(n1), self.Bg, phase_fn, scatter_type, Hu)

    self.spectra = {}
    self.n1 = float(n1)
    for key in kwargs:
        if 'file' in key:
      #Checks if the infile variable has a string -- sanity check if not all ten files are uploaded
      #self.spectra has the number of grain files included in the process
          if not kwargs[key] == '':
            self.spectra[key] = analysis.loadmat_single(kwargs[key])

    # data to be filled in (later) for each grain size
    self.pp_spectra = {}
    self.ks = {}
    self.guesses = {}
    self.scat_eff_grain = {}

    if self.hapke_scalar.needs_isow:
      # store the calibration spectrum
      specwave = analysis.loadmat_single(specwave_file).ravel()
      calspec = analysis.loadmat_single(calspec_file).ravel()
      self.calspec = np.column_stack((specwave, calspec))

    # plot the loaded spectra
    num_plots = 2 if self.hapke_scalar.needs_isow else 1
    fig = Figure(figsize=(9, 4), frameon=False, tight_layout=True)
    ax1 = fig.add_subplot(1, num_plots, 1)
    
    #Adding plots for files uploaded - can upload maximum of 10 files including the three default
    for k in self.spectra:
        ax1.plot(*self.spectra[k].T, label=k)

    ax1.set_xlabel('Wavelength ($\mu{}m)$')
    ax1.set_ylabel('Reflectance')
    ax1.legend(fontsize='small', loc='best')
    ax1.set_title('Input VNIR spectra')
    if self.hapke_scalar.needs_isow:
      ax2 = fig.add_subplot(1, num_plots, 2)
      ax2.plot(specwave, calspec, 'k-')
      ax2.set_title('Calibrated standard')
      ax2.set_xlabel('Wavelength ($\mu{}m)$')
    # return html for a plot of the inputs + calibration
    return 'Initialization complete.', None, [fig]
Ejemplo n.º 3
0
  def phase_solver(self, phaseAngleCount, fit_order, minScale, maxScale, minOffset, maxOffset, maxfun = 1000, 
                   spts=30, diff_step = 0.0001, funtol = 0.00000000000001, xtol= 0.00000000000001, **kwargs ):
      
      plt.close('all')  # hack!
      k = self.ks['global']
      
      #Input: grain size, phase angle
      self.phases = {}
      #Total no of grain sizes == no of pp_spectras
      no_grain_sizes = len(self.pp_spectra.keys())
      phaseGrainList = {}
      phase_bcsd = {}
      for i in range(no_grain_sizes):
          phaseGrainList[i] = []
          ii = str(i)
          if self.Bg:
              bcsd = float(kwargs['p_b_'+ii]), float(kwargs['p_c_'+ii]), float(kwargs['p_s_'+ii]), float(kwargs['p_d_'+ii]), float(kwargs['p_b0_'+ii]), float(kwargs['p_h_'+ii])
              lb_bcsd = float(kwargs['plb_b_'+ii]), float(kwargs['plb_c_'+ii]), float(kwargs['plb_s_'+ii]), float(kwargs['plb_d_'+ii]), float(kwargs['plb_b0_'+ii]), float(kwargs['plb_h_'+ii])              
              ub_bcsd = float(kwargs['pub_b_'+ii]), float(kwargs['pub_c_'+ii]), float(kwargs['pub_s_'+ii]), float(kwargs['pub_d_'+ii]), float(kwargs['pub_b0_'+ii]), float(kwargs['pub_h_'+ii])              
          else:
              bcsd = float(kwargs['p_b_'+ii]), float(kwargs['p_c_'+ii]), float(kwargs['p_s_'+ii]), float(kwargs['p_d_'+ii])
              lb_bcsd = float(kwargs['plb_b_'+ii]), float(kwargs['plb_c_'+ii]), float(kwargs['plb_s_'+ii]), float(kwargs['plb_d_'+ii])              
              ub_bcsd = float(kwargs['pub_b_'+ii]), float(kwargs['pub_c_'+ii]), float(kwargs['pub_s_'+ii]), float(kwargs['pub_d_'+ii])

          phase_bcsd[i] = bcsd, lb_bcsd, ub_bcsd
          for j in range(int(phaseAngleCount)):
              id = '_%s_%s' % (i,j)
              data = analysis.loadmat_single(kwargs['filepfile'+id])
              phaseAngle = PhaseAngleObj(i, kwargs['pfile_i'+id], kwargs['pfile_e'+id], data)
              phaseGrainList[i].append(phaseAngle)
          phaseGrainList[i].sort(key=lambda x: (x.incident_angle, x.emission_angle))
      
    #This program will use data from multiple viewing geometries to calculate
    #phase function parameters for a sample where k and n for i=30, e=0 is already
    #known. 
    #This program downsamples the data and then uses a
    #minimization routine to find the best wavelength dependent b and c
    #coefficients for the phase function by minimizing the difference between
    #the calculated and observed data for multiple viewing geometries and
    #multiple grain sizes simultaneously.
      ffs = self.global_ff

      lstart2 = self.sskk_lstart
      lend2 = self.sskk_lend
      lamdiff = self.sskk_lamdiff 
      low, high, UV = self.pp_bounds
      vislam, visn = self.vislam, self.visn
      wavelength = self.pp_spectra['file2'][:,0] 
      params = (lstart2, lend2, low, UV, lamdiff, float(minScale), float(maxScale), float(minOffset), float(maxOffset), int(maxfun), float(funtol), float(xtol), int(spts), float(diff_step),
                vislam, visn, wavelength, k, int(fit_order), int(phaseAngleCount), phaseGrainList, phase_bcsd, ffs, self.hapke_vector_isow)

      plt_data, allbest = analysis.solve_phase(self.phases, params)
      
      self.phase_best_soln, self.phase_bscale, self.phase_boffset, self.phase_k, self.phase_wave, self.phase_n = allbest
      figures = [plt.figure(i) for i in plt.get_fignums()]
      self.phase = plt_data

      return 'Phase Solved ', 'psolve', figures
Ejemplo n.º 4
0
  def add_mir_data(self, mirk_file='', mirv_file='', repk_file='', adjType=3):
    mirk_file = mirk_file or '../data/bytMIRk.mat'
    mirv_file = mirv_file or '../data/bytMIRv.mat'
    k = analysis.loadmat_single(repk_file)[:,1] if repk_file else self.ks['global']
    self.ks['global'] = k # if from file we over-write it otherwise this is redundant.

    wave = self.pp_spectra['file2'][:,0]
    plt.close('all')  # hack!
    pltData, kset = analysis.MasterKcombine(mirk_file, mirv_file, wave, k, adjType)
    self.vnirv, self.vnirk, self.fullv, self.fullk = kset
    figures = [plt.figure(i) for i in plt.get_fignums()]
    self.mirdata = pltData
    
    return 'Combined MIR + VNIR k: ', 'mirdata', figures
Ejemplo n.º 5
0
def main():
  ap = ArgumentParser()
  ap.add_argument('--port', type=int, default=8888, help='Port. [%(default)s]')
  args = ap.parse_args()

  # initialize isow as the mean of a fixed range
  specwave = analysis.loadmat_single('../data/specwave2.mat').ravel()
  calspec = analysis.loadmat_single('../data/calspecw2.mat').ravel()
  isoind1, isoind2 = np.searchsorted(specwave, (0.5, 1.25))
  MODEL.set_isow(calspec[isoind1:isoind2].mean())

  # load spectrum data
  SPECTRA['file1'] = analysis.loadmat_single('../data/kjs.mat')
  SPECTRA['file2'] = analysis.loadmat_single('../data/kjm.mat')
  SPECTRA['file3'] = analysis.loadmat_single('../data/kjb.mat')
  for k in SPECTRA.keys():
    SPECTRA[k] = analysis.preprocess_traj(SPECTRA[k], 0.405, 2.451, 0.301)

  K['file2'] = analysis.MasterHapke1_PP(MODEL, SPECTRA['file2'], .1, .3, .46, 0, 63)

  app = MplWebApp([(r'/', DemoHandler)], debug=True)
  app.listen(args.port)
  print('Starting UI server at http://%s:%s/' % (gethostname(), args.port))
  tornado.ioloop.IOLoop.current().start()
Ejemplo n.º 6
0
    def add_mir_data(self,
                     mirk_file='',
                     mirv_file='',
                     repk_file='',
                     adjType=3):
        mirk_file = mirk_file or '../data/bytMIRk.mat'
        mirv_file = mirv_file or '../data/bytMIRv.mat'
        k = analysis.loadmat_single(
            repk_file)[:, 1] if repk_file else self.ks['global']
        self.ks[
            'global'] = k  # if from file we over-write it otherwise this is redundant.

        wave = self.pp_spectra['file2'][:, 0]
        plt.close('all')  # hack!
        pltData, kset = analysis.MasterKcombine(mirk_file, mirv_file, wave, k,
                                                adjType)
        self.vnirv, self.vnirk, self.fullv, self.fullk = kset
        figures = [plt.figure(i) for i in plt.get_fignums()]
        self.mirdata = pltData

        return 'Combined MIR + VNIR k: ', 'mirdata', figures
Ejemplo n.º 7
0
    def phase_solver(self,
                     phaseAngleCount,
                     fit_order,
                     minScale,
                     maxScale,
                     minOffset,
                     maxOffset,
                     maxfun=1000,
                     spts=30,
                     diff_step=0.0001,
                     funtol=0.00000000000001,
                     xtol=0.00000000000001,
                     **kwargs):

        plt.close('all')  # hack!
        k = self.ks['global']

        #Input: grain size, phase angle
        self.phases = {}
        #Total no of grain sizes == no of pp_spectras
        no_grain_sizes = len(self.pp_spectra.keys())
        phaseGrainList = {}
        phase_bcsd = {}
        for i in range(no_grain_sizes):
            phaseGrainList[i] = []
            ii = str(i)
            if self.Bg:
                bcsd = float(kwargs['p_b_' + ii]), float(
                    kwargs['p_c_' + ii]), float(kwargs['p_s_' + ii]), float(
                        kwargs['p_d_' + ii]), float(
                            kwargs['p_b0_' + ii]), float(kwargs['p_h_' + ii])
                lb_bcsd = float(kwargs['plb_b_' + ii]), float(
                    kwargs['plb_c_' + ii]), float(
                        kwargs['plb_s_' + ii]), float(
                            kwargs['plb_d_' + ii]), float(
                                kwargs['plb_b0_' + ii]), float(
                                    kwargs['plb_h_' + ii])
                ub_bcsd = float(kwargs['pub_b_' + ii]), float(
                    kwargs['pub_c_' + ii]), float(
                        kwargs['pub_s_' + ii]), float(
                            kwargs['pub_d_' + ii]), float(
                                kwargs['pub_b0_' + ii]), float(
                                    kwargs['pub_h_' + ii])
            else:
                bcsd = float(kwargs['p_b_' + ii]), float(
                    kwargs['p_c_' + ii]), float(kwargs['p_s_' + ii]), float(
                        kwargs['p_d_' + ii])
                lb_bcsd = float(kwargs['plb_b_' + ii]), float(
                    kwargs['plb_c_' + ii]), float(
                        kwargs['plb_s_' + ii]), float(kwargs['plb_d_' + ii])
                ub_bcsd = float(kwargs['pub_b_' + ii]), float(
                    kwargs['pub_c_' + ii]), float(
                        kwargs['pub_s_' + ii]), float(kwargs['pub_d_' + ii])

            phase_bcsd[i] = bcsd, lb_bcsd, ub_bcsd
            for j in range(int(phaseAngleCount)):
                id = '_%s_%s' % (i, j)
                data = analysis.loadmat_single(kwargs['filepfile' + id])
                phaseAngle = PhaseAngleObj(i, kwargs['pfile_i' + id],
                                           kwargs['pfile_e' + id], data)
                phaseGrainList[i].append(phaseAngle)
            phaseGrainList[i].sort(
                key=lambda x: (x.incident_angle, x.emission_angle))

    #This program will use data from multiple viewing geometries to calculate
    #phase function parameters for a sample where k and n for i=30, e=0 is already
    #known.
    #This program downsamples the data and then uses a
    #minimization routine to find the best wavelength dependent b and c
    #coefficients for the phase function by minimizing the difference between
    #the calculated and observed data for multiple viewing geometries and
    #multiple grain sizes simultaneously.
        ffs = self.global_ff

        lstart2 = self.sskk_lstart
        lend2 = self.sskk_lend
        lamdiff = self.sskk_lamdiff
        low, high, UV = self.pp_bounds
        vislam, visn = self.vislam, self.visn
        wavelength = self.pp_spectra['file2'][:, 0]
        params = (lstart2, lend2, low, UV, lamdiff, float(minScale),
                  float(maxScale), float(minOffset), float(maxOffset),
                  int(maxfun), float(funtol), float(xtol), int(spts),
                  float(diff_step), vislam, visn, wavelength, k,
                  int(fit_order), int(phaseAngleCount), phaseGrainList,
                  phase_bcsd, ffs, self.hapke_vector_isow)

        plt_data, allbest = analysis.solve_phase(self.phases, params)

        self.phase_best_soln, self.phase_bscale, self.phase_boffset, self.phase_k, self.phase_wave, self.phase_n = allbest
        figures = [plt.figure(i) for i in plt.get_fignums()]
        self.phase = plt_data

        return 'Phase Solved ', 'psolve', figures
Ejemplo n.º 8
0
    def initialize(self,
                   phase_fn='legendre',
                   scatter_type='lambertian',
                   thetai=0,
                   thetae=0,
                   n1=0,
                   specwave_file='',
                   calspec_file='',
                   **kwargs):

        plt.close('all')  # hack!
        # HACK: use defaults if some/all files aren't provided
        specwave_file = specwave_file or '../data/specwave2.mat'
        calspec_file = calspec_file or '../data/calspecw2.mat'
        self.Bg = True if 'Bg' in kwargs else False
        Hu = True if 'HuApprox' in kwargs else False

        self.global_thetai, self.global_thetae = np.deg2rad(
            [float(thetai), float(thetae)])
        self.hapke_scalar = HapkeModel(self.global_thetai, self.global_thetae,
                                       float(n1), self.Bg, phase_fn,
                                       scatter_type, Hu)

        self.spectra = {}
        self.n1 = float(n1)
        for key in kwargs:
            if 'file' in key:
                #Checks if the infile variable has a string -- sanity check if not all ten files are uploaded
                #self.spectra has the number of grain files included in the process
                if not kwargs[key] == '':
                    self.spectra[key] = analysis.loadmat_single(kwargs[key])

        # data to be filled in (later) for each grain size
        self.pp_spectra = {}
        self.ks = {}
        self.guesses = {}
        self.scat_eff_grain = {}

        if self.hapke_scalar.needs_isow:
            # store the calibration spectrum
            specwave = analysis.loadmat_single(specwave_file).ravel()
            calspec = analysis.loadmat_single(calspec_file).ravel()
            self.calspec = np.column_stack((specwave, calspec))

        # plot the loaded spectra
        num_plots = 2 if self.hapke_scalar.needs_isow else 1
        fig = Figure(figsize=(9, 4), frameon=False, tight_layout=True)
        ax1 = fig.add_subplot(1, num_plots, 1)

        #Adding plots for files uploaded - can upload maximum of 10 files including the three default
        for k in self.spectra:
            ax1.plot(*self.spectra[k].T, label=k)

        ax1.set_xlabel('Wavelength ($\mu{}m)$')
        ax1.set_ylabel('Reflectance')
        ax1.legend(fontsize='small', loc='best')
        ax1.set_title('Input VNIR spectra')
        if self.hapke_scalar.needs_isow:
            ax2 = fig.add_subplot(1, num_plots, 2)
            ax2.plot(specwave, calspec, 'k-')
            ax2.set_title('Calibrated standard')
            ax2.set_xlabel('Wavelength ($\mu{}m)$')
        # return html for a plot of the inputs + calibration
        return 'Initialization complete.', None, [fig]
Ejemplo n.º 9
0
def main():
  args = parse_args()
  print('Preparing variables')
  HapkeModel = get_hapke_model(phase_fn=args.phase_function,
                               scatter=args.scatter_type)
  hapke = HapkeModel(np.deg2rad(args.thetai), np.deg2rad(args.thetae),
                     args.n1, args.Bg)
  files = dict(sml=args.small_file, med=args.medium_file, big=args.large_file)
  params = {}
  for i, key in enumerate(('file1', 'file2', 'file3')):
    params[key] = (args.b[i], args.c[i], args.ff[i], args.s[i], args.D[i])

  if hapke.needs_isow:
    # initialize isow as the mean of a fixed range
    specwave = analysis.loadmat_single(args.specwave_file).ravel()
    calspec = analysis.loadmat_single(args.calspec_file).ravel()
    isoind1, isoind2 = np.searchsorted(specwave, (0.5, 1.25))
    hapke.set_isow(calspec[isoind1:isoind2].mean())

  # section 1
  print('Running section 1')
  spectra = {}
  for key, infile in files.items():
    traj = analysis.loadmat_single(infile)
    spectra[key] = analysis.preprocess_traj(traj, args.low, args.high, args.UV)

  # sections 2, 3, 4
  ks = {}
  for key, traj in spectra.items():
    print('Running sections 2,3,4 (MasterHapke1_PP: %s)' % key)
    ks[key] = analysis.MasterHapke1_PP(hapke, traj, *params[key],
                                       debug_plots=args.debug_plots)

  # section 5 isn't worth porting
  print('Skipping section 5')

  # section 6: iterative minimizations
  print('Running section 6 (MasterHapke2_PP)')
  if hapke.needs_isow:
    specwave, calspec = analysis.prepare_spectrum(specwave, calspec, args.UV,
                                                  args.high)
    hapke.set_isow(calspec)
  # use the medium-grain k as an initial guess
  k = ks['file2']
  # XXX: this takes too long, skip it
  # guesses = np.concatenate((args.b, args.c, args.s, args.D, k))
  # lb = np.concatenate((args.lowb, args.lowc, args.lows, args.lowD,
  #                      np.zeros_like(k) + args.lowk))
  # ub = np.concatenate((args.upb, args.upc, args.ups, args.upD,
  #                      np.zeros_like(k) + args.upk))
  # solutions = analysis.MasterHapke2_PP(hapke, spectra, guesses, lb, ub,
  #                                      args.ff, tr_solver='lsmr', verbose=2)

  # section 7/8: graphs the parameters from the previous section
  if args.debug_plots:
    # print 'Running sections 7,8 (plotting %d solutions)' % len(solutions)
    # see HapkeEval1_PP.m
    # plot initial guesses -> solved values for b, c, s, D, and k
    # TODO
    # see HapkeEval3_PP.m
    # plot given reflectances (spectra) vs solved rcs
    pass

  # section 9: add in your MIR data
  # If you do not have MIR data (not recommended), you can skip this step.
  # If you do have MIR data, use the DISPERSION programs on the website to get
  # k data for your sample through the MIR.
  wave = spectra['file2'][:,0]
  if all(os.path.exists(f) for f in (args.mir_dispersion_k,
                                     args.mir_dispersion_v)):
    print('Running section 9 (MasterKcombine)')
    combined = analysis.MasterKcombine(args.mir_dispersion_k,
                                       args.mir_dispersion_v, wave, k)
    if args.debug_plots:
      plt.figure()
      plt.plot(10000/combined[:,0], combined[:,1])
      plt.title('MasterKcombine')
  else:
    print('Skipping section 9 (MasterKcombine): MIR data not found')
    combined = np.column_stack((10000/wave, k))

  # section 10: singly subtractive Kramers Kronig calculation
  print('Running section 10 (MasterSSKK)')
  res = analysis.MasterSSKK(combined, args.n1, args.anchor)
  if args.debug_plots:
    fig, ax = plt.subplots()
    ax.plot(10000/res[:,0], res[:,1])
    ax.set_xlabel('Wavelength (um)')
    ax.set_ylabel('n')

  if args.debug_plots:
    plt.show()
Ejemplo n.º 10
0
def main():
    args = parse_args()
    print('Preparing variables')
    HapkeModel = get_hapke_model(phase_fn=args.phase_function,
                                 scatter=args.scatter_type)
    hapke = HapkeModel(np.deg2rad(args.thetai), np.deg2rad(args.thetae),
                       args.n1, args.Bg)
    files = dict(sml=args.small_file,
                 med=args.medium_file,
                 big=args.large_file)
    params = {}
    for i, key in enumerate(('file1', 'file2', 'file3')):
        params[key] = (args.b[i], args.c[i], args.ff[i], args.s[i], args.D[i])

    if hapke.needs_isow:
        # initialize isow as the mean of a fixed range
        specwave = analysis.loadmat_single(args.specwave_file).ravel()
        calspec = analysis.loadmat_single(args.calspec_file).ravel()
        isoind1, isoind2 = np.searchsorted(specwave, (0.5, 1.25))
        hapke.set_isow(calspec[isoind1:isoind2].mean())

    # section 1
    print('Running section 1')
    spectra = {}
    for key, infile in files.items():
        traj = analysis.loadmat_single(infile)
        spectra[key] = analysis.preprocess_traj(traj, args.low, args.high,
                                                args.UV)

    # sections 2, 3, 4
    ks = {}
    for key, traj in spectra.items():
        print('Running sections 2,3,4 (MasterHapke1_PP: %s)' % key)
        ks[key] = analysis.MasterHapke1_PP(hapke,
                                           traj,
                                           *params[key],
                                           debug_plots=args.debug_plots)

    # section 5 isn't worth porting
    print('Skipping section 5')

    # section 6: iterative minimizations
    print('Running section 6 (MasterHapke2_PP)')
    if hapke.needs_isow:
        specwave, calspec = analysis.prepare_spectrum(specwave, calspec,
                                                      args.UV, args.high)
        hapke.set_isow(calspec)
    # use the medium-grain k as an initial guess
    k = ks['file2']
    # XXX: this takes too long, skip it
    # guesses = np.concatenate((args.b, args.c, args.s, args.D, k))
    # lb = np.concatenate((args.lowb, args.lowc, args.lows, args.lowD,
    #                      np.zeros_like(k) + args.lowk))
    # ub = np.concatenate((args.upb, args.upc, args.ups, args.upD,
    #                      np.zeros_like(k) + args.upk))
    # solutions = analysis.MasterHapke2_PP(hapke, spectra, guesses, lb, ub,
    #                                      args.ff, tr_solver='lsmr', verbose=2)

    # section 7/8: graphs the parameters from the previous section
    if args.debug_plots:
        # print 'Running sections 7,8 (plotting %d solutions)' % len(solutions)
        # see HapkeEval1_PP.m
        # plot initial guesses -> solved values for b, c, s, D, and k
        # TODO
        # see HapkeEval3_PP.m
        # plot given reflectances (spectra) vs solved rcs
        pass

    # section 9: add in your MIR data
    # If you do not have MIR data (not recommended), you can skip this step.
    # If you do have MIR data, use the DISPERSION programs on the website to get
    # k data for your sample through the MIR.
    wave = spectra['file2'][:, 0]
    if all(
            os.path.exists(f)
            for f in (args.mir_dispersion_k, args.mir_dispersion_v)):
        print('Running section 9 (MasterKcombine)')
        combined = analysis.MasterKcombine(args.mir_dispersion_k,
                                           args.mir_dispersion_v, wave, k)
        if args.debug_plots:
            plt.figure()
            plt.plot(10000 / combined[:, 0], combined[:, 1])
            plt.title('MasterKcombine')
    else:
        print('Skipping section 9 (MasterKcombine): MIR data not found')
        combined = np.column_stack((10000 / wave, k))

    # section 10: singly subtractive Kramers Kronig calculation
    print('Running section 10 (MasterSSKK)')
    res = analysis.MasterSSKK(combined, args.n1, args.anchor)
    if args.debug_plots:
        fig, ax = plt.subplots()
        ax.plot(10000 / res[:, 0], res[:, 1])
        ax.set_xlabel('Wavelength (um)')
        ax.set_ylabel('n')

    if args.debug_plots:
        plt.show()