Exemple #1
0
def crop_array(opt):      
  fp_whole = opt.fp[1::3,1::3]
  fp_signal_whole = opt.fp_signal[1::3,1::3]
  #==============================================================================   
  #1) Calculate the maximum width (y crop) in pixels and apply crop
  #==============================================================================   
  aa = fp_signal_whole.sum(axis=1).value # sum of profile in x axis
  jexosim_plot('y crop selection', opt.diagnostics, ydata=aa, marker='ro-', grid=True)
  
  bb = np.mean(np.vstack((aa[:5],aa[-5:]))) # average of outer 5 pixels
  if bb == 0:
      aa_ =  aa[np.argwhere(aa>0).T[0]]
      bb = aa_.min()/np.e
  idx_max = np.argmax(aa)
  
  print (bb)
 
  #find where signal falls below b*npe either side
  for i in range(int(len(aa)/2)):
      s = aa[idx_max-i]
      if s < bb*np.e:
          # idx0=1+ idx_max-i #+1 so that it starts within the region of > b8npe
          idx0=idx_max-i #+1 so that it starts within the region of > b8npe
          break    
   
    
  for i in range(int(len(aa)/2)):
      s = aa[idx_max+i]
      if s < bb*np.e:
          # idx1=idx_max+i
          idx1=1+idx_max+i
          break        
  #idx0, idx1 #indexs that bound this region
  idx1 = int(idx1) ; idx0 = int(idx0)
  print (idx0, idx1)
  w_crop = idx1- (idx0)  
  jexosim_msg ("width of crop chosen %s"%(w_crop ) , opt.diagnostics)  
  jexosim_plot('y crop selection', opt.diagnostics, xdata=np.arange(idx0, idx1,1), ydata=aa[idx0:idx1], 
               marker='bo-', grid=True)
  #==============================================================================   
  #2) Calculate the maximum length (x crop) in pixels and apply crop
  #==============================================================================     
  wav_sol= opt.x_wav_osr[1::3].value # wav sol in whole pixels
  idx = np.argwhere((wav_sol>=opt.channel.pipeline_params.start_wav.val-0.5)& (wav_sol<=opt.channel.pipeline_params.end_wav.val+0.5)) 
  idxA = idx[0].item()
  idxB = idx[-1].item()
  
  return idx0, idx1, idxA, idxB
Exemple #2
0
def get_psf(opt):
    if os.path.exists('%s/../archive/PSF/%s_psf_stack.npy' %
                      (opt.__path__, opt.channel.instrument.val)):
        psf_stack = np.load('%s/../archive/PSF/%s_psf_stack.npy' %
                            (opt.__path__, opt.channel.instrument.val))
        psf_stack_wl = 1e6 * np.load(
            '%s/../archive/PSF/%s_psf_stack_wl.npy' %
            (opt.__path__, opt.channel.instrument.val))
        psf = interpolate.interp1d(psf_stack_wl,
                                   psf_stack,
                                   axis=2,
                                   bounds_error=False,
                                   fill_value=0.0,
                                   kind='linear')(opt.x_wav_osr.value)
        psf = np.rot90(psf)
        psf_type = 'wfe'
    else:  # uses airy if no psf database however this is to be avoided, as pipeline assumes the wfe database psfs.
        jexosim_msg('PSF files could not be found. Check psf files location.')
        sys.exit()
        # psf = jexosim_lib.Psf(opt.x_wav_osr.value, opt.channel.camera.wfno_x.val, opt.channel.camera.wfno_y.val, opt.fp_delta.value, shape='airy')
        # psf[np.isnan(psf)] =0
        # psf_type = 'airy'

    jexosim_msg("PSF shape %s, %s" % (psf.shape[0], psf.shape[1]),
                opt.diagnostics)
    jexosim_plot('psf check',
                 opt.diagnostics,
                 image=True,
                 image_data=psf[..., int(psf.shape[2] / 2)])
    sum1 = []
    for i in range(psf.shape[2]):
        sum1.append(psf[..., i].sum())
        if psf[..., i].sum() != 0:
            # psf[...,i] =psf[...,i]/psf[...,i].sum()
            if np.round(psf[..., i].sum(), 3) != 1.0:
                jexosim_msg(
                    'error... check PSF normalisation %s %s' %
                    (psf[..., i].sum(), opt.x_wav_osr[i]), 1)
                sys.exit()
    jexosim_plot('test7 - psf sum vs subpixel position (should be 1)',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr,
                 ydata=sum1,
                 marker='bo')
    return psf, psf_type
Exemple #3
0
def psf_fp_check(opt):
    # Populate focal plane with monochromatic PSFs
    j0 = np.arange(opt.fp.shape[1]) - int(opt.psf.shape[1] / 2)
    j1 = j0 + opt.psf.shape[1]
    idx = np.where((j0 >= 0) & (j1 < opt.fp.shape[1]))[0]
    i0 = np.array([opt.fp.shape[0] / 2 - opt.psf.shape[0] / 2 + opt.offs] *
                  len(j1)).astype(np.int)
    i0 += 1
    # variable y position (applies only to NIRISS)
    if opt.channel.name == 'NIRISS_SOSS_GR700XD':
        i0 = (opt.y_pos_osr).astype(np.int)
    i1 = i0 + opt.psf.shape[0]
    test_fp = np.zeros_like(opt.fp)

    # SPECIAL CASE: fix if airy psfs used
    if opt.channel.name == 'NIRISS_SOSS_GR700XD':
        # fix if airy psfs used
        if opt.psf_type == 'airy':
            original_fp = copy.deepcopy(test_fp)
            if i1.max(
            ) > test_fp.shape[0]:  #psfs will fall outside fp area due to curve
                original_fp = copy.deepcopy(test_fp)
                test_fp = np.zeros(
                    (i1.max(), test_fp.shape[1]))  # temp increase in fp size

    for k in idx:  # used for getting sat time, and sizing
        test_fp[i0[k]:i1[k], j0[k]:j1[k]] += opt.psf[..., k]
    # SPECIAL CASE: fix if airy psfs used
    if opt.channel.name == 'NIRISS_SOSS_GR700XD':
        if opt.psf_type == 'airy':  # now return fp to original size
            if i1.max() > original_fp.shape[0]:
                diff = i1.max() - original_fp.shape[0]
                test_fp = test_fp[diff:]

    jexosim_plot('psf fp check', 1, ydata=test_fp.sum(axis=0))

    return test_fp
Exemple #4
0
def run(opt):

    jexosim_msg('channel check0 : %s' % (opt.star.sed.sed.max()),
                opt.diagnostics)
    tr_ = np.array([1.] * len(opt.x_wav_osr)) * u.dimensionless_unscaled
    opt.channel.transmissions.optical_surface = opt.channel.transmissions.optical_surface if isinstance(opt.channel.transmissions.optical_surface, list) else \
                                                                    [opt.channel.transmissions.optical_surface]
    for op in opt.channel.transmissions.optical_surface:
        dtmp = np.loadtxt(op.transmission.replace('__path__', opt.__path__),
                          delimiter=',')
        tr = Sed(dtmp[:, 0] * u.um, dtmp[:, 1] * u.dimensionless_unscaled)
        tr.rebin(opt.x_wav_osr)
        tr_ *= tr.sed
    opt.channel_transmission = Sed(opt.x_wav_osr, tr_)
    opt.total_transmission = Sed(
        opt.channel_transmission.wl,
        opt.telescope_transmission.sed * opt.channel_transmission.sed)
    jexosim_lib.sed_propagation(opt.star.sed, opt.channel_transmission)
    jexosim_lib.sed_propagation(opt.star.sed_it, opt.channel_transmission)
    # apply QE and convert to electrons
    dtmp = np.loadtxt(opt.channel.detector_array.qe().replace(
        '__path__', opt.__path__),
                      delimiter=',')
    qe = Sed(dtmp[:, 0] * u.um, dtmp[:, 1] * u.dimensionless_unscaled)
    qe.rebin(opt.x_wav_osr)
    PCE = Sed(opt.total_transmission.wl, opt.total_transmission.sed * qe.sed)
    TotTrans = Sed(opt.total_transmission.wl, opt.total_transmission.sed)
    opt.PCE = PCE.sed
    opt.TotTrans = TotTrans.sed
    jexosim_plot('PCE', opt.diagnostics, xdata=PCE.wl, ydata=PCE.sed)
    jexosim_plot('Total transmission not including QE',
                 opt.diagnostics,
                 xdata=TotTrans.wl,
                 ydata=TotTrans.sed)
    opt.qe_spec = qe
    opt.Re = qe.sed * (qe.wl).to(u.m) / (const.c.value * const.h.value * u.m)
    opt.star.sed.sed *= opt.Re * u.electron / u.W / u.s
    opt.star.sed_it.sed *= opt.Re * u.electron / u.W / u.s
    jexosim_plot('channel star sed check',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.star.sed.sed,
                 marker='-')
    jexosim_msg('check 1.3 - Star sed max:  %s' % (opt.star.sed.sed.max()),
                opt.diagnostics)
    jexosim_plot('Wavelength solution check -oversampled pixels',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr,
                 ydata=opt.x_wav_osr,
                 marker='o-')
    jexosim_plot('Wavelength solution check -normal pixels',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr[1::3],
                 ydata=opt.x_wav_osr[1::3],
                 marker='o-')
    opt.d_x_wav_osr = np.zeros_like(opt.x_wav_osr)
    idx = np.where(opt.x_wav_osr > 0.0)
    opt.d_x_wav_osr[idx] = np.gradient(opt.x_wav_osr[idx])
    if np.any(opt.d_x_wav_osr < 0): opt.d_x_wav_osr *= -1.0
    jexosim_plot('D x wav osr check',
                 opt.diagnostics,
                 xdata=opt.x_pix_osr,
                 ydata=opt.d_x_wav_osr,
                 marker='o')
    jexosim_plot('D x wav osr check 2',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.d_x_wav_osr,
                 marker='o')
    jexosim_msg("check 1.4:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)

    opt.planet_sed_original = copy.deepcopy(opt.planet.sed.sed)
    # opt.planet.sed.sed  *= opt.star.sed.sed
    # opt.planet.sed.sed  *= opt.d_x_wav_osr

    jexosim_msg("check 1.5:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)
    opt.star.sed.sed *= opt.d_x_wav_osr
    opt.star.sed_it.sed *= opt.d_x_wav_osr
    jexosim_msg("check 2:  %s" % (opt.star.sed.sed.max()), opt.diagnostics)
    jexosim_plot('star sed check 2.0',
                 opt.diagnostics,
                 xdata=opt.x_wav_osr,
                 ydata=opt.star.sed.sed,
                 marker='-')

    return opt
Exemple #5
0
    def __init__(self, opt):

        output_directory = opt.common.output_directory.val
        filename = ""

        self.results_dict = {}
        self.results_dict['simulation_mode'] = opt.simulation.sim_mode.val
        self.results_dict[
            'simulation_realisations'] = opt.simulation.sim_realisations.val
        self.results_dict['ch'] = opt.observation.obs_channel.val
        self.noise_dict = {}

        opt.pipeline.useSignal.val = 1
        opt.simulation.sim_use_fast.val = 1
        opt.pipeline.split = 0
        opt.noise.ApplyRandomPRNU.val = 1

        opt.timeline.apply_lc.val = 0
        opt.timeline.useLDC.val = 0
        opt.pipeline.useAllen.val = 1
        opt.timeline.use_T14.val = 0
        opt.timeline.obs_time.val = 0 * u.hr  # 0 means n_exp overides obs_time
        opt.timeline.n_exp.val = 1000.0  # uses 1000 exposures
        # opt.timeline.n_exp.val = 400

        noise_type = int(opt.noise.sim_noise_source.val)

        nb_dict = {
            'rn': [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
            'sn': [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
            'spat': [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
            'spec': [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
            'emm_switch': [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1],
            'zodi_switch': [1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1],
            'dc_switch': [1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
            'source_switch': [1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
            'diff': [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
            'jitter_switch': [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
            'fano': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
            'noise_tag': [
                'All noise', 'All photon noise', 'Source photon noise',
                'Dark current noise', 'Zodi noise', 'Emission noise',
                'Read noise', 'Spatial jitter noise', 'Spectral jitter noise',
                'Combined jitter noise', 'No noise - no background',
                'No noise - all background', 'Fano noise'
            ],
            'color': [
                '0.5', 'b', 'b', 'k', 'orange', 'pink', 'y', 'g', 'purple',
                'r', '0.8', 'c', 'c'
            ]
        }

        opt.noise.EnableReadoutNoise.val = nb_dict['rn'][noise_type]
        opt.noise.EnableShotNoise.val = nb_dict['sn'][noise_type]
        opt.noise.EnableSpatialJitter.val = nb_dict['spat'][noise_type]
        opt.noise.EnableSpectralJitter.val = nb_dict['spec'][noise_type]
        opt.noise.EnableFanoNoise.val = nb_dict['fano'][noise_type]
        opt.background.EnableEmission.val = nb_dict['emm_switch'][noise_type]
        opt.background.EnableZodi.val = nb_dict['zodi_switch'][noise_type]
        opt.background.EnableDC.val = nb_dict['dc_switch'][noise_type]
        opt.background.EnableSource.val = nb_dict['source_switch'][noise_type]

        opt.diff = nb_dict['diff'][noise_type]
        opt.noise_tag = nb_dict['noise_tag'][noise_type]
        opt.color = nb_dict['color'][noise_type]

        self.noise_dict[nb_dict['noise_tag'][noise_type]] = {}

        jexosim_msg("Noise type: %s" % (nb_dict['noise_tag'][noise_type]), 1)

        start = 0
        end = int(start + opt.no_real)

        opt = self.run_JexoSimA(opt)

        if opt.observation_feasibility == 0:
            jexosim_msg("Observation not feasible...", opt.diagnostics)
            self.feasibility = 0
        else:
            self.feasibility = 1

            n_ndr0 = opt.n_ndr * 1
            ndr_end_frame_number0 = opt.ndr_end_frame_number * 1
            frames_per_ndr0 = opt.frames_per_ndr * 1
            duration_per_ndr0 = opt.duration_per_ndr * 1
            n_exp0 = opt.n_exp

            if n_ndr0 > 10000:

                opt.pipeline.split = 1
                if opt.diagnostics == 1:
                    jexosim_msg('number of NDRs > 10000: using split protocol',
                                opt.diagnostics)
            else:
                opt.pipeline.split = 0

        opt.pipeline.split = 0

        for j in range(start, end):

            if (opt.no_real - start) > 1:
                jexosim_msg("", 1)
                jexosim_msg("============= REALIZATION %s =============" % (j),
                            1)
                jexosim_msg(opt.lab, 1)
                jexosim_msg("", 1)

            opt = self.run_JexoSimA1(opt)  # set QE grid for this realization
            jexosim_msg("QE variations set", 1)
            jexosim_msg("Number of exposures %s" % (n_exp0), 1)

            # =============================================================================
            #  split simulation into chunks to permit computation - makes no difference to final results
            #  =============================================================================
            if opt.pipeline.split == 1:

                jexosim_msg('Splitting data series into chunks',
                            opt.diagnostics)
                # uses same QE grid and jitter timeline but otherwise randomoses noise
                ndrs_per_round = opt.effective_multiaccum * int(
                    5000 / opt.multiaccum)
                # ndrs_per_round = opt.effective_multiaccum*int(50/opt.multiaccum)

                total_chunks = len(np.arange(0, n_ndr0, ndrs_per_round))

                idx = np.arange(0, n_ndr0,
                                ndrs_per_round)  # list of starting ndrs

                for i in range(len(idx)):
                    jexosim_msg(
                        '=== Chunk %s / %s=====' % (i + 1, total_chunks),
                        opt.diagnostics)

                    if idx[i] == idx[-1]:
                        opt.n_ndr = n_ndr0 - idx[i]

                        opt.ndr_end_frame_number = ndr_end_frame_number0[
                            idx[i]:]
                        opt.frames_per_ndr = frames_per_ndr0[idx[i]:]
                        opt.duration_per_ndr = duration_per_ndr0[idx[i]:]

                    else:
                        opt.n_ndr = idx[i + 1] - idx[i]

                        opt.ndr_end_frame_number = ndr_end_frame_number0[
                            idx[i]:idx[i + 1]]
                        opt.frames_per_ndr = frames_per_ndr0[idx[i]:idx[i + 1]]
                        opt.duration_per_ndr = duration_per_ndr0[idx[i]:idx[i +
                                                                            1]]

                    opt.n_exp = int(opt.n_ndr / opt.effective_multiaccum)

                    if i == 0:
                        opt.use_external_jitter = 0

                        opt = self.run_JexoSimB(opt)
                        opt = self.run_pipeline_stage_1(opt)
                        if opt.pipeline.pipeline_auto_ap.val == 1:
                            opt.pipeline.pipeline_ap_factor.val = opt.AvBest
                        if (opt.noise.EnableSpatialJitter.val == 1
                                or opt.noise.EnableSpectralJitter.val == 1
                                or opt.noise.EnableAll.val
                                == 1) and opt.noise.DisableAll.val != 1:
                            opt.input_yaw_jitter, opt.input_pitch_jitter, opt._input_frame_osf = opt.yaw_jitter, opt.pitch_jitter, opt.frame_osf

                    else:
                        opt.pipeline.pipeline_auto_ap.val = 0
                        opt.use_external_jitter = 1  # uses the jitter timeline from the first realization

                        opt = self.run_JexoSimB(opt)
                        opt = self.run_pipeline_stage_1(opt)

                    jexosim_msg(
                        'Aperture used %s' %
                        (opt.pipeline.pipeline_ap_factor.val), opt.diagnostics)
                    binnedLC = opt.pipeline_stage_1.binnedLC
                    data = opt.pipeline_stage_1.opt.data_raw

                    #After chunks processed, now recombine
                    if i == 0:
                        data_stack = data
                        binnedLC_stack = binnedLC
                    else:
                        data_stack = np.dstack((data_stack, data))
                        binnedLC_stack = np.vstack((binnedLC_stack, binnedLC))

                aa = data_stack.sum(axis=0)
                bb = aa.sum(axis=0)
                jexosim_plot('test_from_sim',
                             opt.diagnostics,
                             ydata=bb[opt.effective_multiaccum::opt.
                                      effective_multiaccum])

                aa = binnedLC_stack.sum(axis=1)
                jexosim_plot('test_from_pipeline', opt.diagnostics, ydata=aa)

                opt.n_ndr = n_ndr0
                opt.ndr_end_frame_number = ndr_end_frame_number0
                opt.frames_per_ndr = frames_per_ndr0
                opt.duration_per_ndr = duration_per_ndr0
                opt.n_exp = n_exp0

            elif opt.pipeline.split == 0:

                opt = self.run_JexoSimB(opt)
                if j == start:  # first realization sets the ap, then the other use the same one
                    opt.pipeline.pipeline_auto_ap.val = 1
                else:
                    opt.pipeline.pipeline_auto_ap.val = 0
                opt = self.run_pipeline_stage_1(opt)
                if j == start:  # first realization sets the ap, then the other use the same one
                    if opt.pipeline.pipeline_apply_mask.val == 1:
                        opt.pipeline.pipeline_ap_factor.val = opt.AvBest

                binnedLC_stack = opt.pipeline_stage_1.binnedLC
                data_stack = opt.pipeline_stage_1.opt.data_raw
                jexosim_plot('testvvv',
                             opt.diagnostics,
                             ydata=binnedLC_stack.sum(axis=1))

            aa = data_stack.sum(axis=0)
            import matplotlib.pyplot as plt
            plt.figure('data raw noise')
            plt.plot(opt.x_wav_osr[1::3], aa.std(axis=1))
            plt.figure('binned lc noise')
            std = binnedLC_stack.std(axis=0)
            plt.plot(opt.pipeline_stage_1.binnedWav, std)

            #take binnedLC_stack and now complete through pipeline stage 2
            opt.pipeline_stage_1.binnedLC = binnedLC_stack
            opt = self.run_pipeline_stage_2(opt)
            self.pipeline = opt.pipeline_stage_2

            self.noise_dict[opt.noise_tag]['wl'] = self.pipeline.binnedWav
            self.results_dict['input_spec'] = opt.cr
            self.results_dict['input_spec_wl'] = opt.cr_wl

            if j == start:
                self.noise_dict[
                    opt.noise_tag]['signal_std_stack'] = self.pipeline.ootNoise
                self.noise_dict[opt.noise_tag][
                    'signal_mean_stack'] = self.pipeline.ootSignal
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[opt.noise_tag][
                        'fracNoT14_stack'] = self.pipeline.noiseAt1hr

                self.noise_dict[
                    opt.noise_tag]['signal_std_mean'] = self.pipeline.ootNoise
                self.noise_dict[opt.noise_tag][
                    'signal_mean_mean'] = self.pipeline.ootSignal
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[opt.noise_tag][
                        'fracNoT14_mean'] = self.pipeline.noiseAt1hr

                self.noise_dict[opt.noise_tag]['signal_std_std'] = np.zeros(
                    len(self.pipeline.binnedWav))
                self.noise_dict[opt.noise_tag]['signal_mean_std'] = np.zeros(
                    len(self.pipeline.binnedWav))
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[opt.noise_tag]['fracNoT14_std'] = np.zeros(
                        len(self.pipeline.binnedWav))

            else:
                self.noise_dict[opt.noise_tag]['signal_std_stack'] = np.vstack(
                    (self.noise_dict[opt.noise_tag]['signal_std_stack'],
                     self.pipeline.ootNoise))
                self.noise_dict[
                    opt.noise_tag]['signal_mean_stack'] = np.vstack(
                        (self.noise_dict[opt.noise_tag]['signal_mean_stack'],
                         self.pipeline.ootSignal))
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[
                        opt.noise_tag]['fracNoT14_stack'] = np.vstack(
                            (self.noise_dict[opt.noise_tag]['fracNoT14_stack'],
                             self.pipeline.noiseAt1hr))

                self.noise_dict[
                    opt.noise_tag]['signal_std_mean'] = self.noise_dict[
                        opt.noise_tag]['signal_std_stack'].mean(axis=0)
                self.noise_dict[
                    opt.noise_tag]['signal_mean_mean'] = self.noise_dict[
                        opt.noise_tag]['signal_mean_stack'].mean(axis=0)
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[
                        opt.noise_tag]['fracNoT14_mean'] = self.noise_dict[
                            opt.noise_tag]['fracNoT14_stack'].mean(axis=0)

                self.noise_dict[
                    opt.noise_tag]['signal_std_std'] = self.noise_dict[
                        opt.noise_tag]['signal_std_stack'].std(axis=0)
                self.noise_dict[
                    opt.noise_tag]['signal_mean_std'] = self.noise_dict[
                        opt.noise_tag]['signal_mean_stack'].std(axis=0)
                if opt.pipeline.useAllen.val == 1:
                    self.noise_dict[
                        opt.noise_tag]['fracNoT14_std'] = self.noise_dict[
                            opt.noise_tag]['fracNoT14_stack'].std(axis=0)

            self.noise_dict[opt.noise_tag]['bad_map'] = opt.bad_map
            self.noise_dict[
                opt.noise_tag]['example_exposure_image'] = opt.exp_image
            self.noise_dict[
                opt.noise_tag]['pixel wavelengths'] = opt.x_wav_osr[1::3].value

            self.results_dict['noise_dic'] = self.noise_dict

            time_tag = (datetime.now().strftime('%Y_%m_%d_%H%M_%S'))
            self.results_dict['time_tag'] = time_tag

            if j != start:
                os.remove(filename)  # delete previous temp file
                txt_file = '%s.txt' % (filename)
                os.remove(txt_file)
            filename = '%s/OOT_SNR_%s_%s_TEMP.pickle' % (output_directory,
                                                         opt.lab, time_tag)
            self.filename = 'OOT_SNR_%s_%s_TEMP.pickle' % (opt.lab, time_tag)
            with open(filename, 'wb') as handle:
                pickle.dump(self.results_dict,
                            handle,
                            protocol=pickle.HIGHEST_PROTOCOL)

            if j == end - 1:
                os.remove(filename)  # delete previous temp file
                filename = '%s/OOT_SNR_%s_%s.pickle' % (output_directory,
                                                        opt.lab, time_tag)
                with open(filename, 'wb') as handle:
                    pickle.dump(self.results_dict,
                                handle,
                                protocol=pickle.HIGHEST_PROTOCOL)

                jexosim_msg('Results in %s' % (filename), 1)
                self.filename = 'OOT_SNR_%s_%s.pickle' % (opt.lab, time_tag)

            write_record(opt, output_directory, self.filename,
                         opt.params_file_path)
Exemple #6
0
    def __init__(self, opt):

        output_directory = opt.common.output_directory.val
        filename = ""

        self.results_dict = {}
        self.results_dict['simulation_mode'] = opt.simulation.sim_mode.val
        self.results_dict[
            'simulation_realisations'] = opt.simulation.sim_realisations.val
        self.results_dict['ch'] = opt.observation.obs_channel.val

        opt.pipeline.useSignal.val = 0
        opt.simulation.sim_use_fast.val = 1
        opt.pipeline.split = 0
        opt.noise.ApplyRandomPRNU.val = 1

        opt.timeline.apply_lc.val = 1
        opt.timeline.useLDC.val = 1
        opt.pipeline.useAllen.val = 0
        opt.pipeline.fit_gamma.val = 0  #keep zero for uncert on p

        start = 0
        end = int(start + opt.no_real)

        if (opt.no_real - start) > 1:
            jexosim_msg("Monte Carlo selected", 1)

        opt = self.run_JexoSimA(opt)

        if opt.observation_feasibility == 0:
            jexosim_msg("Observation not feasible...", opt.diagnostics)
            self.feasibility = 0
        else:
            self.feasibility = 1
            n_ndr0 = opt.n_ndr * 1
            lc0 = opt.lc_original * 1
            ndr_end_frame_number0 = opt.ndr_end_frame_number * 1
            frames_per_ndr0 = opt.frames_per_ndr * 1
            duration_per_ndr0 = opt.duration_per_ndr * 1
            n_exp0 = opt.n_exp

            if n_ndr0 > 10000:

                opt.pipeline.split = 1
                if opt.diagnostics == 1:
                    jexosim_msg('number of NDRs > 10000: using split protocol',
                                opt.diagnostics)
            else:
                opt.pipeline.split = 0

            for j in range(start, end):

                if (opt.no_real - start) > 1:
                    jexosim_msg("", 1)
                    jexosim_msg(
                        "============= REALIZATION %s =============" % (j), 1)
                    jexosim_msg(opt.lab, 1)
                    jexosim_msg("", 1)

                pp = time.time()

                opt = self.run_JexoSimA1(
                    opt)  # set QE grid for this realization
                jexosim_msg("QE variations set", 1)
                jexosim_msg("Number of exposures %s" % (n_exp0), 1)

                lc0 = opt.lc_original * 1

                # =============================================================================
                #  # split simulation into chunks to permit computation - makes no difference to final results
                # =============================================================================
                if opt.pipeline.split == 1:

                    jexosim_msg('Splitting data series into chunks',
                                opt.diagnostics)
                    # uses same QE grid and jitter timeline but otherwise randomoses noise
                    ndrs_per_round = opt.effective_multiaccum * int(
                        5000 / opt.multiaccum)
                    # ndrs_per_round = opt.effective_multiaccum*int(50/opt.multiaccum)

                    total_chunks = len(np.arange(0, n_ndr0, ndrs_per_round))

                    idx = np.arange(0, n_ndr0,
                                    ndrs_per_round)  # list of starting ndrs

                    for i in range(len(idx)):
                        jexosim_msg(
                            '=== Chunk %s / %s=====' % (i + 1, total_chunks),
                            opt.diagnostics)

                        if idx[i] == idx[-1]:
                            opt.n_ndr = n_ndr0 - idx[i]
                            opt.lc_original = lc0[:, idx[i]:]
                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:]
                            opt.duration_per_ndr = duration_per_ndr0[idx[i]:]

                        else:
                            opt.n_ndr = idx[i + 1] - idx[i]
                            opt.lc_original = lc0[:, idx[i]:idx[i + 1]]
                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:idx[i + 1]]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:idx[i +
                                                                            1]]
                            opt.duration_per_ndr = duration_per_ndr0[
                                idx[i]:idx[i + 1]]

                        opt.n_exp = int(opt.n_ndr / opt.effective_multiaccum)

                        if i == 0:
                            opt.pipeline.pipeline_auto_ap.val = 1
                            opt.use_external_jitter = 0

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                            opt.pipeline.pipeline_ap_factor.val = opt.AvBest
                            if (opt.noise.EnableSpatialJitter.val == 1
                                    or opt.noise.EnableSpectralJitter.val == 1
                                    or opt.noise.EnableAll.val
                                    == 1) and opt.noise.DisableAll.val != 1:
                                opt.input_yaw_jitter, opt.input_pitch_jitter, opt._input_frame_osf = opt.yaw_jitter, opt.pitch_jitter, opt.frame_osf

                        else:
                            opt.pipeline.pipeline_auto_ap.val = 0
                            opt.use_external_jitter = 1  # uses the jitter timeline from the first realization

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                        jexosim_msg(
                            'Aperture used %s' %
                            (opt.pipeline.pipeline_ap_factor.val),
                            opt.diagnostics)
                        data0 = opt.pipeline_stage_1.binnedLC
                        data = opt.pipeline_stage_1.opt.data_raw

                        if i == 0:
                            data_stack = data
                            data_stack0 = data0
                        else:
                            data_stack = np.dstack((data_stack, data))
                            data_stack0 = np.vstack((data_stack0, data0))

                    aa = data_stack.sum(axis=0)
                    bb = aa.sum(axis=0)
                    jexosim_plot('test_from_sim',
                                 opt.diagnostics,
                                 ydata=bb[opt.effective_multiaccum::opt.
                                          effective_multiaccum])
                    aa = data_stack0.sum(axis=1)
                    jexosim_plot('test_from_pipeline',
                                 opt.diagnostics,
                                 ydata=aa)

                    opt.n_ndr = n_ndr0
                    opt.ndr_end_frame_number = ndr_end_frame_number0
                    opt.frames_per_ndr = frames_per_ndr0
                    opt.duration_per_ndr = duration_per_ndr0
                    opt.n_exp = n_exp0

                elif opt.pipeline.split == 0:

                    opt = self.run_JexoSimB(opt)
                    opt = self.run_pipeline_stage_1(opt)
                    if j == start:  # first realization sets the ap, then the other use the same one
                        opt.use_auto_Ap = 1
                        opt.pipeline.pipeline_ap_factor.val = opt.AvBest
                    else:
                        opt.use_auto_Ap = 0

                    data_stack0 = opt.pipeline_stage_1.binnedLC
                    jexosim_plot('testvvv',
                                 opt.diagnostics,
                                 ydata=data_stack0.sum(axis=1))

                opt.pipeline_stage_1.binnedLC = data_stack0
                opt = self.run_pipeline_stage_2(opt)
                pipeline = opt.pipeline_stage_2

                p = pipeline.transitDepths
                if j == start:
                    p_stack = p
                else:
                    p_stack = np.vstack((p_stack, p))

                jexosim_msg(
                    "time to complete realization %s %s" %
                    (j, time.time() - pp), opt.diagnostics)

                self.results_dict['wl'] = pipeline.binnedWav
                self.results_dict['input_spec'] = opt.cr
                self.results_dict['input_spec_wl'] = opt.cr_wl

                if j == start:  # if only one realisation slightly different format
                    self.results_dict['p_stack'] = np.array(p)
                    self.results_dict['p_std'] = np.zeros(len(p))
                    self.results_dict['p_mean'] = np.array(p)
                else:
                    self.results_dict['p_stack'] = np.vstack(
                        (self.results_dict['p_stack'], p))
                    self.results_dict['p_std'] = self.results_dict[
                        'p_stack'].std(axis=0)
                    self.results_dict['p_mean'] = self.results_dict[
                        'p_stack'].mean(axis=0)

                time_tag = (datetime.now().strftime('%Y_%m_%d_%H%M_%S'))

                self.results_dict['time_tag'] = time_tag
                self.results_dict['bad_map'] = opt.bad_map
                self.results_dict['example_exposure_image'] = opt.exp_image
                self.results_dict['pixel wavelengths'] = opt.x_wav_osr[
                    1::3].value

                if j != start:
                    os.remove(filename)  # delete previous temp file

                filename = '%s/Full_transit_%s_TEMP.pickle' % (
                    output_directory, opt.lab)
                with open(filename, 'wb') as handle:
                    pickle.dump(self.results_dict,
                                handle,
                                protocol=pickle.HIGHEST_PROTOCOL)

            os.remove(filename)  # delete previous temp file
            # write final file
            filename = '%s/Full_transit_%s_%s.pickle' % (output_directory,
                                                         opt.lab, time_tag)
            with open(filename, 'wb') as handle:
                pickle.dump(self.results_dict,
                            handle,
                            protocol=pickle.HIGHEST_PROTOCOL)

            jexosim_msg('Results in %s' % (filename), 1)
            self.filename = 'Full_transit_%s_%s.pickle' % (opt.lab, time_tag)

            write_record(opt, output_directory, self.filename,
                         opt.params_file_path)
Exemple #7
0
def run(opt):

    opt.observation_feasibility = 1  # this variable is currently not changed to zero under any circumstances
    opt.psf, opt.psf_type = instrument_lib.get_psf(opt)
    opt.fp, opt.fp_signal = instrument_lib.get_focal_plane(opt)
    opt.fp_it, opt.fp_signal_it = instrument_lib.get_focal_plane_it(opt)

    mask_fp = np.where(opt.fp > 0, 1, 0)
    mask_fp_it = np.where(opt.fp_it > 0, 1, 0)
    mask_fp_signal = np.where(opt.fp_signal > 0, 1, 0)
    mask_fp_signal_it = np.where(opt.fp_signal_it > 0, 1, 0)

    opt.fp, opt.fp_signal = instrument_lib.convolve_prf(
        opt, opt.fp,
        opt.fp_signal)  #this step can gen some small negative values on fp
    opt.fp = np.where(opt.fp < 0, 0, opt.fp)
    opt.fp_signal = np.where(opt.fp_signal < 0, 0, opt.fp_signal)

    opt.fp_it, opt.fp_signal_it = instrument_lib.convolve_prf(
        opt, opt.fp_it,
        opt.fp_signal_it)  #this step can gen some small negative values on fp
    opt.fp_it = np.where(opt.fp_it < 0, 0, opt.fp_it)
    opt.fp_signal_it = np.where(opt.fp_signal_it < 0, 0, opt.fp_signal_it)

    # mask out small values arising from the PRF convolution where there was originally zero signal
    opt.fp *= mask_fp
    opt.fp_it *= mask_fp_it
    opt.fp_signal *= mask_fp_signal
    opt.fp_signal_it *= mask_fp_signal_it

    opt.planet.sed = instrument_lib.get_planet_spectrum(opt)

    jexosim_plot(
        'planet sed',
        opt.diagnostics,
        xdata=opt.planet.sed.wl,
        ydata=opt.planet.sed.sed,
    )

    opt = instrument_lib.user_subarray(opt)
    opt = instrument_lib.crop_to_subarray(opt)
    opt = instrument_lib.exposure_timing(opt)

    jexosim_msg("Integration time - zeroth read %s" % (opt.t_int),
                opt.diagnostics)
    jexosim_msg(
        "Estimated integration time incl. zeroth read %s" %
        (opt.t_int + opt.zero_time), opt.diagnostics)
    jexosim_msg("Estimated TOTAL CYCLE TIME %s" % (opt.exposure_time),
                opt.diagnostics)
    jexosim_msg("CDS time estimate %s" % (opt.t_int), opt.diagnostics)
    jexosim_msg("FP max %s" % (opt.fp[1::3, 1::3].max()), opt.diagnostics)
    jexosim_msg("DC SWITCH.......%s" % (opt.background.EnableDC.val),
                opt.diagnostics)
    jexosim_msg(
        "DISABLE ALL SWITCH.......%s" % (opt.background.DisableAll.val),
        opt.diagnostics)
    jexosim_msg("DARK CURRENT %s" % (opt.channel.detector_pixel.Idc.val),
                opt.diagnostics)
    jexosim_plot('focal plane check',
                 opt.diagnostics,
                 image=True,
                 image_data=opt.fp[1::3, 1::3],
                 aspect='auto',
                 interpolation=None,
                 xlabel='x \'spectral\' pixel',
                 ylabel='y \'spatial\' pixel')
    if opt.diagnostics == 1:
        plt.figure('focal plane check')
        cbar = plt.colorbar()
        cbar.set_label(('Count (e$^-$/s)'), rotation=270, size=15, labelpad=20)
        cbar.ax.tick_params(labelsize=15)
        ax = plt.gca()
        for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
                     ax.get_xticklabels() + ax.get_yticklabels()):
            item.set_fontsize(15)

    opt.fp_original = copy.deepcopy(opt.fp)
    opt.fp_signal_original = copy.deepcopy(opt.fp_signal)
    opt.x_wav_osr_original = copy.deepcopy(opt.x_wav_osr)
    opt.x_pix_osr_original = copy.deepcopy(opt.x_pix_osr)
    opt.quantum_yield_original = copy.deepcopy(opt.quantum_yield)
    opt.qy_zodi_original = copy.deepcopy(opt.qy_zodi)
    opt.qy_sunshield_original = copy.deepcopy(opt.qy_sunshield)
    opt.qy_emission_original = copy.deepcopy(opt.qy_emission)

    opt.zodi_sed_original = copy.deepcopy(
        opt.zodi.sed
    )  # needed here due to possible cropping above for subarrays
    opt.sunshield_sed_original = copy.deepcopy(opt.sunshield.sed)
    opt.emission_sed_original = copy.deepcopy(opt.emission.sed)

    if opt.channel.instrument.val == 'NIRSpec':
        opt.channel.pipeline_params.wavrange_hi.val = opt.gap[3]
        opt.channel.pipeline_params.wavrange_lo.val = opt.gap[2]
        opt.channel.pipeline_params.end_wav.val = opt.gap[3] + 0.1
        opt.channel.pipeline_params.start_wav.val = opt.gap[2] - 0.1
    jexosim_plot('final wl solution on subarray',
                 opt.diagnostics,
                 ydata=opt.x_wav_osr[1::3],
                 xlabel='x \'spectral\' pixel',
                 ylabel='y \'spatial\' pixel',
                 grid=True)
    if opt.diagnostics == 1:
        wl = opt.x_wav_osr
        wav = opt.x_wav_osr[1::3]
        if opt.channel.name == 'NIRSpec_BOTS_G140H_F100LP' or \
            opt.channel.name == 'NIRSpec_BOTS_G235H_F170LP'\
                or opt.channel.name == 'NIRSpec_BOTS_G395H_F290LP':
            idx0 = np.argwhere(wav == opt.wav_gap_start)[0].item(
            )  #recover the start of the gap
            idx1 = idx0 + opt.gap_len  # gap of 172 pix works well for G1H and G2H, but a little off (by 0.01 microns for the other in some cases from published values)
            fp_1d = opt.fp_signal[1::3, 1::3].sum(axis=0)
            fp_1d[idx0:idx1] = 0

            idx0 = np.argwhere(wl == opt.wav_gap_start)[0].item(
            )  #recover the start of the gap
            idx1 = idx0 + opt.gap_len * 3  # gap of 172 p
            opt.PCE[idx0:idx1] = 0
            opt.TotTrans[idx0:idx1] = 0
            opt.R.sed[idx0:idx1] = 0
        else:
            fp_1d = opt.fp_signal[1::3, 1::3].sum(axis=0)
        plt.figure('Focal plane pixel count rate')
        plt.plot(wav, fp_1d, 'r-')
        plt.grid()
        plt.figure('Final PCE and transmission on subarray')
        plt.plot(wl, opt.PCE, '-')
        plt.plot(wl, opt.TotTrans, '--')
        plt.figure('R power')
        plt.plot(wl, opt.R.sed, '-')

    instrument_lib.sanity_check(opt)

    return opt
Exemple #8
0
    def __init__(self, opt):
        
        output_directory = opt.common.output_directory.val
        filename=""
        
        self.results_dict ={}
        self.results_dict['simulation_mode'] = opt.simulation.sim_mode.val
        self.results_dict['simulation_realisations'] = opt.simulation.sim_realisations.val
        self.results_dict['ch'] =  opt.observation.obs_channel.val 
        self.noise_dict ={}  
        self.feasibility =1

        opt.pipeline.useSignal.val=1
        opt.simulation.sim_use_fast.val =1
        opt.pipeline.split  = 0
        opt.noise.ApplyRandomPRNU.val=1

        opt.timeline.apply_lc.val = 0
        opt.timeline.useLDC.val = 0
        opt.pipeline.useAllen.val =1

        opt.pipeline.pipeline_auto_ap.val = 0 # for noise budget keep this to a fixed value (i.e. choose 0) so same for all sims

        opt.timeline.obs_time.val = 0*u.hr
        opt.timeline.n_exp.val = 1000.0
         
        noise_list = [0,2,3,4,5,6,7,8,9,12,13]
        # noise_list = [0,2,3,4,5,6,7,8,9]
        # noise_list = [2,9,12]


        start = 0 
        end = int(start + opt.no_real)      

        nb_dict = {'rn'             :[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
               'sn'                 :[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
               'spat'               :[1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],                                   
               'spec'               :[1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],                                      
               'emm_switch'         :[1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0],                    
               'zodi_switch'        :[1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0],    
               'dc_switch'          :[1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
               'source_switch'      :[1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
               'diff'               :[0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
               'jitter_switch'      :[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
               'fano'               :[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
               'sunshield_switch'   :[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
               'noise_tag': [ 'All noise','All photon noise','Source photon noise','Dark current noise',
                        'Zodi noise','Emission noise','Read noise','Spatial jitter noise',
                        'Spectral jitter noise','Combined jitter noise','No noise - no background','No noise - all background', 'Fano noise', 'Sunshield noise'],  
                        'color': ['0.5','b', 'b','k','orange','pink', 'y','g','purple','r', '0.8','c', 'c','brown']
              } 
        

        for i in noise_list:
            self.noise_dict[nb_dict['noise_tag'][i]] ={}
            
        for j in range(start,end):
            seed = np.random.randint(100000000)
            for i in noise_list:
    
                opt.noise.EnableReadoutNoise.val = nb_dict['rn'][i]
                opt.noise.EnableShotNoise.val = nb_dict['sn'][i]
                opt.noise.EnableSpatialJitter.val= nb_dict['spat'][i]
                opt.noise.EnableSpectralJitter.val= nb_dict['spec'][i]
                opt.noise.EnableFanoNoise.val= nb_dict['fano'][i]
                opt.background.EnableEmission.val = nb_dict['emm_switch'][i]
                opt.background.EnableZodi.val = nb_dict['zodi_switch'][i]  
                opt.background.EnableSunshield.val = nb_dict['sunshield_switch'][i]   
                opt.background.EnableDC.val  =  nb_dict['dc_switch'][i]
                opt.background.EnableSource.val  = nb_dict['source_switch'][i]
                opt.diff = nb_dict['diff'][i]      
                opt.noise_tag = nb_dict['noise_tag'][i]
                opt.color = nb_dict['color'][i]
  
                jexosim_msg('==========================================', 1)
                jexosim_msg('Noise source:%s'%(opt.noise_tag), 1)     
                
                np.random.seed(seed)
                opt = self.run_JexoSimA(opt)
                opt = self.run_JexoSimA1(opt)
                
                n_ndr0 = opt.n_ndr*1
                ndr_end_frame_number0 = opt.ndr_end_frame_number*1
                frames_per_ndr0 = opt.frames_per_ndr*1
                duration_per_ndr0 = opt.duration_per_ndr*1
                n_exp0 = opt.n_exp           
                            
                if n_ndr0 > 10000:
    
                    opt.pipeline.split = 1
                    if opt.diagnostics ==1 :
                       jexosim_msg ('number of NDRs > 10000: using split protocol', opt.diagnostics)
                else:
                    opt.pipeline.split = 0 

                opt.pipeline.split = 1                      

              # =============================================================================
              #  split simulation into chunks to permit computation - makes no difference to final results    
              #  =============================================================================
                if opt.pipeline.split ==1:
              
                   jexosim_msg('Splitting data series into chunks', opt.diagnostics)
                   # uses same QE grid and jitter timeline but otherwise randomoses noise
                   ndrs_per_round = opt.effective_multiaccum*int(5000/opt.multiaccum)  
                   ndrs_per_round = opt.effective_multiaccum*int(50/opt.multiaccum)  
  
                   total_chunks = len(np.arange(0, n_ndr0, ndrs_per_round))
                   
                   idx = np.arange(0, n_ndr0, ndrs_per_round) # list of starting ndrs
                   
                   for i in range(len(idx)):
                       jexosim_msg('=== Chunk %s / %s====='%(i+1, total_chunks), opt.diagnostics)
                       
                       if idx[i] == idx[-1]:
                           opt.n_ndr = n_ndr0 - idx[i]

                           opt.ndr_end_frame_number = ndr_end_frame_number0[idx[i]:]
                           opt.frames_per_ndr=  frames_per_ndr0[idx[i]:]
                           opt.duration_per_ndr = duration_per_ndr0[idx[i]:]  
                          
                       else:
                           opt.n_ndr = idx[i+1]- idx[i]

                           opt.ndr_end_frame_number = ndr_end_frame_number0[idx[i]: idx[i+1]]
                           opt.frames_per_ndr=  frames_per_ndr0[idx[i]: idx[i+1]]
                           opt.duration_per_ndr = duration_per_ndr0[idx[i]: idx[i+1]]
                  
                       opt.n_exp = int(opt.n_ndr/opt.effective_multiaccum)
                                   
                       if i == 0: 
                           opt.use_external_jitter = 0
                           
                           opt = self.run_JexoSimB(opt)
                           opt  = self.run_pipeline_stage_1(opt)  
                           if opt.pipeline.pipeline_auto_ap.val == 1:
                               opt.pipeline.pipeline_ap_factor.val= opt.AvBest 
                           if (opt.noise.EnableSpatialJitter.val  ==1 or opt.noise.EnableSpectralJitter.val  ==1 or opt.noise.EnableAll.val == 1) and opt.noise.DisableAll.val != 1:
                               opt.input_yaw_jitter, opt.input_pitch_jitter, opt._input_frame_osf = opt.yaw_jitter, opt.pitch_jitter, opt.frame_osf                     
                                                      
                       else:
                           opt.pipeline.pipeline_auto_ap.val = 0
                           opt.use_external_jitter = 1 # uses the jitter timeline from the first realization

                           opt = self.run_JexoSimB(opt)
                           opt  = self.run_pipeline_stage_1(opt)                
                                  
                       jexosim_msg('Aperture used %s'%(opt.pipeline.pipeline_ap_factor.val), opt.diagnostics)
                       binnedLC = opt.pipeline_stage_1.binnedLC
                       data = opt.pipeline_stage_1.opt.data_raw
                       
                       #After chunks processed, now recombine                                           
                       if i ==0:
                           data_stack = data
                           binnedLC_stack = binnedLC   
                       else:
                           data_stack = np.dstack((data_stack,data))
                           binnedLC_stack = np.vstack((binnedLC_stack, binnedLC))                  
                   
                   aa = data_stack.sum(axis=0)
                   bb = aa.sum(axis=0)
                   jexosim_plot('test_from_sim', opt.diagnostics,
                            ydata=bb[opt.effective_multiaccum::opt.effective_multiaccum] )

                   
                   aa = binnedLC_stack.sum(axis=1)
                   jexosim_plot('test_from_pipeline', opt.diagnostics,
                                        ydata=aa)                            

                   opt.n_ndr  = n_ndr0             
                   opt.ndr_end_frame_number  = ndr_end_frame_number0  
                   opt.frames_per_ndr  = frames_per_ndr0 
                   opt.duration_per_ndr = duration_per_ndr0
                   opt.n_exp = n_exp0                                
                           
                elif opt.pipeline.split ==0:

                   opt  = self.run_JexoSimB(opt)
                   if j==start:  # first realization sets the ap, then the other use the same one
                       opt.pipeline.pipeline_auto_ap.val= 1
                   else:
                       opt.pipeline.pipeline_auto_ap.val= 0
                   opt  = self.run_pipeline_stage_1(opt)
                   if j==start:  # first realization sets the ap, then the other use the same one
                       if opt.pipeline.pipeline_apply_mask.val == 1:
                           opt.pipeline.pipeline_ap_factor.val= opt.AvBest

                   binnedLC_stack  = opt.pipeline_stage_1.binnedLC
                   data_stack = opt.pipeline_stage_1.opt.data_raw
                   jexosim_plot('testvvv', opt.diagnostics,
                                ydata=binnedLC_stack.sum(axis=1) )  

            
                           
                #take binnedLC_stack and now complete through pipeline stage 2
                opt.pipeline_stage_1.binnedLC = binnedLC_stack    
                opt = self.run_pipeline_stage_2(opt)
                self.pipeline = opt.pipeline_stage_2  
                self.opt = opt
                        
                self.noise_dict[opt.noise_tag]['wl'] = self.pipeline.binnedWav
                 
                if j == start:                    
                    self.noise_dict[opt.noise_tag]['signal_std_stack'] = self.pipeline.ootNoise
                    self.noise_dict[opt.noise_tag]['signal_mean_stack'] = self.pipeline.ootSignal
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_stack'] = self.pipeline.noiseAt1hr
                        
                    self.noise_dict[opt.noise_tag]['signal_std_mean'] = self.pipeline.ootNoise
                    self.noise_dict[opt.noise_tag]['signal_mean_mean'] = self.pipeline.ootSignal
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_mean'] = self.pipeline.noiseAt1hr
                        
                    self.noise_dict[opt.noise_tag]['signal_std_std'] = np.zeros(len(self.pipeline.binnedWav))
                    self.noise_dict[opt.noise_tag]['signal_mean_std'] = np.zeros(len(self.pipeline.binnedWav))
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_std'] = np.zeros(len(self.pipeline.binnedWav))

                    self.noise_dict[opt.noise_tag]['bad_map'] = opt.bad_map
                    self.noise_dict[opt.noise_tag]['example_exposure_image'] = opt.exp_image
                    self.noise_dict[opt.noise_tag]['pixel wavelengths'] = opt.x_wav_osr[1::3].value
                                     

                else:
                    self.noise_dict[opt.noise_tag]['signal_std_stack'] = np.vstack((self.noise_dict[opt.noise_tag]['signal_std_stack'], self.pipeline.ootNoise))
                    self.noise_dict[opt.noise_tag]['signal_mean_stack'] = np.vstack((self.noise_dict[opt.noise_tag]['signal_mean_stack'], self.pipeline.ootSignal))
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_stack'] = np.vstack((self.noise_dict[opt.noise_tag]['fracNoT14_stack'], self.pipeline.noiseAt1hr))

                    self.noise_dict[opt.noise_tag]['signal_std_mean'] = self.noise_dict[opt.noise_tag]['signal_std_stack'].mean(axis=0)
                    self.noise_dict[opt.noise_tag]['signal_mean_mean'] = self.noise_dict[opt.noise_tag]['signal_mean_stack'].mean(axis=0)
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_mean'] = self.noise_dict[opt.noise_tag]['fracNoT14_stack'].mean(axis=0)
                        
                    self.noise_dict[opt.noise_tag]['signal_std_std'] = self.noise_dict[opt.noise_tag]['signal_std_stack'].std(axis=0)
                    self.noise_dict[opt.noise_tag]['signal_mean_std'] = self.noise_dict[opt.noise_tag]['signal_mean_stack'].std(axis=0)
                    if opt.pipeline.useAllen.val == 1:
                        self.noise_dict[opt.noise_tag]['fracNoT14_std'] = self.noise_dict[opt.noise_tag]['fracNoT14_stack'].std(axis=0)

                self.noise_dict[opt.noise_tag]['bad_map'] = opt.bad_map
                self.noise_dict[opt.noise_tag]['example_exposure_image'] = opt.exp_image
                self.noise_dict[opt.noise_tag]['pixel wavelengths'] = opt.x_wav_osr[1::3].value
                    
                self.results_dict['noise_dic'] = self.noise_dict         
 
            # dump pickle file at end of each cycle of noise sims
            if opt.simulation.sim_output_type.val == 1:         
                time_tag = (datetime.now().strftime('%Y_%m_%d_%H%M_%S'))
                self.results_dict['time_tag'] =  time_tag
         
                # if j != start:
                #     os.remove(filename)  # delete previous temp file
                # filename = '%s/Noise_budget_%s_TEMP.pickle'%(output_directory, opt.lab)
                # with open(filename, 'wb') as handle:
                #     pickle.dump(self.results_dict , handle, protocol=pickle.HIGHEST_PROTOCOL)
                   
                if j == end-1:
                    # os.remove(filename)  # delete previous temp file
                    filename = '%s/Noise_budget_%s_%s.pickle'%(output_directory, opt.lab, time_tag)
                    with open(filename, 'wb') as handle:
                        pickle.dump(self.results_dict , handle, protocol=pickle.HIGHEST_PROTOCOL)
     
                        jexosim_msg('Results in %s'%(filename), 1)
                        self.filename = 'Noise_budget_%s_%s.pickle'%(opt.lab, time_tag)

                        write_record(opt, output_directory, self.filename, opt.params_file_path)
Exemple #9
0
def getLDC_interp(opt, planet, wl):

    jexosim_msg('Calculating LDC from pre-installed files', 1)
    T = planet.star.T.value
    if T < 3000.0:  # temp fix as LDCs not available for T< 3000 K
        T = 3000.0
    logg = planet.star.logg
    jexosim_msg("T_s, logg>>>> %s %s" % (T, logg), opt.diagnostics)
    folder = '%s/archive/LDC' % (opt.jexosim_path)
    t_base = np.int(T / 100.) * 100
    if T >= t_base + 100:
        t1 = t_base + 100
        t2 = t_base + 200
    else:
        t1 = t_base
        t2 = t_base + 100
    logg_base = np.int(logg)
    if logg >= logg_base + 0.5:
        logg1 = logg_base + 0.5
        logg2 = logg_base + 1.0
    else:
        logg1 = logg_base
        logg2 = logg_base + 0.5
    logg1 = np.float(logg1)
    logg2 = np.float(logg2)
    #==============================================================================
    # interpolate between temperatures assuming logg1
    #==============================================================================
    u0_a = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t1, logg1))[:, 1]
    u0_b = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t2, logg1))[:, 1]
    w2 = 1.0 - abs(t2 - T) / 100.
    w1 = 1.0 - abs(t1 - T) / 100.
    u0_1 = w1 * u0_a + w2 * u0_b

    u1_a = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t1, logg1))[:, 2]
    u1_b = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t2, logg1))[:, 2]
    w2 = 1.0 - abs(t2 - T) / 100.
    w1 = 1.0 - abs(t1 - T) / 100.
    u1_1 = w1 * u1_a + w2 * u1_b

    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u0_a, marker='b-')
    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u0_b, marker='r-')
    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u0_1, marker='g-')
    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u1_a, marker='b-')
    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u1_b, marker='r-')
    jexosim_plot('ldc interp logg1', opt.diagnostics, ydata=u1_1, marker='g-')

    ldc_wl = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t1, logg1))[:, 0]
    #==============================================================================
    # interpolate between temperatures assuming logg2
    #==============================================================================
    u0_a = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t1, logg2))[:, 1]
    u0_b = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t2, logg2))[:, 1]
    w2 = 1.0 - abs(t2 - T) / 100.
    w1 = 1.0 - abs(t1 - T) / 100.
    u0_2 = w1 * u0_a + w2 * u0_b

    u1_a = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t1, logg2))[:, 2]
    u1_b = np.loadtxt('%s/T=%s_logg=%s_z=0.txt' % (folder, t2, logg2))[:, 2]
    w2 = 1.0 - abs(t2 - T) / 100.
    w1 = 1.0 - abs(t1 - T) / 100.
    u1_2 = w1 * u1_a + w2 * u1_b

    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u0_a, marker='b-')
    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u0_b, marker='r-')
    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u0_2, marker='g-')
    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u1_a, marker='b-')
    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u1_b, marker='r-')
    jexosim_plot('ldc interp logg2', opt.diagnostics, ydata=u1_2, marker='g-')
    #==============================================================================
    # interpolate between logg
    #==============================================================================
    w2 = 1.0 - abs(logg2 - logg) / .5
    w1 = 1.0 - abs(logg1 - logg) / .5

    u0 = w1 * u0_1 + w2 * u0_2
    u1 = w1 * u1_1 + w2 * u1_2

    jexosim_plot('ldc interp', opt.diagnostics, ydata=u0_1, marker='b-')
    jexosim_plot('ldc interp', opt.diagnostics, ydata=u0_2, marker='r-')
    jexosim_plot('ldc interp', opt.diagnostics, ydata=u0, marker='g-')
    jexosim_plot('ldc interp', opt.diagnostics, ydata=u1_1, marker='b-')
    jexosim_plot('ldc interp', opt.diagnostics, ydata=u1_2, marker='r-')
    jexosim_plot('ldc interp', opt.diagnostics, ydata=u1, marker='g-')
    #==============================================================================
    # interpolate to new wl grid
    #==============================================================================
    u0_final = np.interp(wl, ldc_wl, u0)
    u1_final = np.interp(wl, ldc_wl, u1)

    jexosim_plot('ldc final',
                 opt.diagnostics,
                 xdata=ldc_wl,
                 ydata=u0,
                 marker='ro',
                 alpha=0.1)
    jexosim_plot('ldc final',
                 opt.diagnostics,
                 xdata=ldc_wl,
                 ydata=u1,
                 marker='bo',
                 alpha=0.1)
    jexosim_plot('ldc final',
                 opt.diagnostics,
                 xdata=wl,
                 ydata=u0_final,
                 marker='rx')
    jexosim_plot('ldc final',
                 opt.diagnostics,
                 xdata=wl,
                 ydata=u1_final,
                 marker='bx')

    return u0_final, u1_final
Exemple #10
0
    def read_phoenix_spectrum_interp(self):

        jexosim_msg ("Star... star_temperature %s, star_logg %s, star_f_h %s"%(self.star_temperature, self.star_logg, self.star_f_h) , self.opt.diagnostics)
       
        if self.star_temperature.value >= 2400:
            t0 = np.round(self.star_temperature,-2)/100.
        else:
            t0= np.round(np.round(self.star_temperature,-1)/100./0.5)*0.5
            
        t0 = t0.value
        
        if t0*100 != self.star_temperature.value:
            cond_1 = 1
            if t0*100 > self.star_temperature.value:
                    if self.star_temperature.value >= 2400:
                        t1 = t0-1
                    else:
                        t1 = t0-0.5
            elif t0*100 < self.star_temperature.value:
                    if self.star_temperature.value >= 2400:
                        t1= t0+1
                    else:
                        t1 = t0+0.5
            print (t0,t1, self.star_temperature)
        else:
            cond_1 = 0 # do not interp for temp
            
                        
        logg0 =  np.round(np.round(self.star_logg,1)/0.5)*0.5
        if logg0 <= 2.5:
            logg0 = 2.5
            cond_2 = 0 # do not interp for logg
        elif logg0 >= 5.5:
            logg0 = 5.5
            cond_2 = 0
        elif logg0 == self.star_logg:
            cond_2 = 0 
        else:
            cond_2 = 1
            if logg0 < self.star_logg:
                logg1 = logg0 + 0.5 
            if logg0 > self.star_logg:
                logg1 = logg0 - 0.5
                                         
        if cond_1 == 1 and cond_2 == 0: 
            
            jexosim_msg ("interpolating spectra by temperature only", self.opt.diagnostics)
      
            wav_t0_logg0, flux_t0_logg0 = self.open_Phoenix(t0,logg0, self.star_f_h, self.sed_folder)
            wav_t1_logg0, flux_t1_logg0 = self.open_Phoenix(t1,logg0, self.star_f_h, self.sed_folder)
            sed_t0_logg0 = sed.Sed(wav_t0_logg0, flux_t0_logg0)
            sed_t1_logg0 = sed.Sed(wav_t1_logg0, flux_t1_logg0)
            # bin to same wav grid
            sed_t1_logg0.rebin(wav_t0_logg0)  
            wt0 = 1 - abs(t0*100 - self.star_temperature.value)/abs(t0*100 - t1*100)
            wt1 = 1 - abs(self.star_temperature.value - t1*100)/abs(t0*100 - t1*100)
            sed_final = wt0*sed_t0_logg0.sed + wt1*sed_t1_logg0.sed
            
            star_final_sed = sed_final
            star_final_wl = sed_t0_logg0.wl
            
            jexosim_plot('temperature interpolation', self.opt.diagnostics, xdata = wav_t0_logg0, ydata = flux_t0_logg0, marker ='r-')
            jexosim_plot('temperature interpolation', self.opt.diagnostics, xdata = wav_t1_logg0, ydata = flux_t1_logg0, marker ='b-')
            jexosim_plot('temperature interpolation', self.opt.diagnostics, xdata = star_final_wl, ydata = star_final_sed, marker ='g-')
    
          
        if cond_1 == 1 and cond_2 == 1:
            
            jexosim_msg ("interpolating spectra by temperature and logg", self.opt.diagnostics)
       
            #interp temp at logg0
            wav_t0_logg0, flux_t0_logg0 = self.open_Phoenix(t0,logg0, self.star_f_h, self.sed_folder)
            wav_t1_logg0, flux_t1_logg0 = self.open_Phoenix(t1,logg0, self.star_f_h, self.sed_folder)
            sed_t0_logg0 = sed.Sed(wav_t0_logg0, flux_t0_logg0)
            sed_t1_logg0 = sed.Sed(wav_t1_logg0, flux_t1_logg0)
            # bin to same wav grid
            sed_t1_logg0.rebin(wav_t0_logg0)  
            wt0 = 1 - abs(t0*100 - self.star_temperature.value)/abs(t0*100 - t1*100)
            wt1 = 1 - abs(self.star_temperature.value - t1*100)/abs(t0*100 - t1*100)
            sed_ = wt0*sed_t0_logg0.sed + wt1*sed_t1_logg0.sed
            sed_logg0 = sed.Sed(wav_t0_logg0, sed_)
            
            print (t0,t1)
            print (wt0,wt1)
             
            box = 1000
            bbox = np.ones(box)/box
            jexosim_plot('temperature interpolation logg0', self.opt.diagnostics, xdata = wav_t0_logg0, \
                         ydata = np.convolve(flux_t0_logg0, bbox,'same'), marker ='r-')
            jexosim_plot('temperature interpolation logg0', self.opt.diagnostics, xdata = wav_t1_logg0, \
                         ydata = np.convolve(flux_t1_logg0, bbox,'same'), marker ='b-')
            jexosim_plot('temperature interpolation logg0', self.opt.diagnostics, xdata = sed_logg0.wl, \
                         ydata = np.convolve(sed_logg0.sed, bbox,'same'), marker ='g-')
            
    
            #interp temp at logg1
            wav_t0_logg1, flux_t0_logg1 = self.open_Phoenix(t0,logg1, self.star_f_h, self.sed_folder)
            wav_t1_logg1, flux_t1_logg1 = self.open_Phoenix(t1,logg1, self.star_f_h, self.sed_folder)
            sed_t0_logg1 = sed.Sed(wav_t0_logg1, flux_t0_logg1)
            sed_t1_logg1 = sed.Sed(wav_t1_logg1, flux_t1_logg1)
            # bin to same wav grid
            sed_t1_logg1.rebin(wav_t0_logg1)  
            wt0 = 1 - abs(t0*100 - self.star_temperature.value)/abs(t0*100 - t1*100)
            wt1 = 1 - abs(self.star_temperature.value - t1*100)/abs(t0*100 - t1*100)
            sed_ = wt0*sed_t0_logg1.sed + wt1*sed_t1_logg1.sed
            sed_logg1 = sed.Sed(wav_t0_logg1, sed_)
            
            box = 100
            bbox = np.ones(box)/box
            jexosim_plot('temperature interpolation logg1', self.opt.diagnostics, xdata = wav_t0_logg1, \
                         ydata = np.convolve(flux_t0_logg1, bbox,'same'), marker ='r-')
            jexosim_plot('temperature interpolation logg1', self.opt.diagnostics, xdata = wav_t1_logg1, \
                         ydata = np.convolve(flux_t1_logg1, bbox,'same'), marker ='b-')
            jexosim_plot('temperature interpolation logg1', self.opt.diagnostics, xdata = sed_logg1.wl, \
                         ydata = np.convolve(sed_logg1.sed, bbox,'same'), marker ='g-')
            
      
            # now interp logg
            sed_logg1.rebin(sed_logg0.wl)
            wt0 = 1 - abs(logg0 - self.star_logg)/abs(logg0 - logg1)
            wt1 = 1 - abs(self.star_logg - logg1)/abs(logg0 - logg1)
            print (wt0,wt1)
            print (logg0,logg1)
        
             
            sed_final = wt0*sed_logg0.sed + wt1*sed_logg1.sed
       
            star_final_sed = sed_final
            star_final_wl = sed_logg0.wl
            
            box = 100
            bbox = np.ones(box)/box
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = sed_logg0.wl, \
                         ydata = np.convolve(sed_logg0.sed, bbox,'same'), marker ='r-')
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = sed_logg1.wl, \
                         ydata = np.convolve(sed_logg1.sed, bbox,'same'), marker ='b-')
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = star_final_wl, \
                         ydata = np.convolve(star_final_sed, bbox,'same'), marker ='g-') 
      
                
        if cond_1 == 0 and cond_2 == 1:
            
            jexosim_msg ("interpolating spectra by logg only", self.opt.diagnostics)
       
            #interp logg at t0
            wav_t0_logg0, flux_t0_logg0 = self.open_Phoenix(t0,logg0, self.star_f_h, self.sed_folder)
            wav_t0_logg1, flux_t0_logg1 = self.open_Phoenix(t0,logg1, self.star_f_h, self.sed_folder)
             
            sed_t0_logg0 = sed.Sed(wav_t0_logg0, flux_t0_logg0)
            sed_t0_logg1 = sed.Sed(wav_t0_logg1, flux_t0_logg1)
            # bin to same wav grid
            sed_t0_logg1.rebin(wav_t0_logg0) 
    
            wt0 = 1 - abs(logg0 - self.star_logg)/abs(logg0 - logg1)
            wt1 = 1 - abs(self.star_logg - logg1)/abs(logg0 - logg1)
            sed_final = wt0*sed_logg0.sed + wt1*sed_logg1.sed
            
            star_final_sed = sed_final
            star_final_wl = sed_t0_logg0.wl  
            
            box = 100
            bbox = np.ones(box)/box
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = sed_t0_logg0.wl, \
                         ydata = np.convolve(sed_t0_logg0.sed, bbox,'same'), marker ='r-')
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = sed_t0_logg1.wl, \
                         ydata = np.convolve(sed_t0_logg1.sed, bbox,'same'), marker ='b-')
            jexosim_plot('interpolation between logg', self.opt.diagnostics, xdata = star_final_wl, \
                         ydata = np.convolve(star_final_sed, bbox,'same'), marker ='g-') 
                
        if cond_1 == 0 and cond_2 == 0:
            
            star_final_wl, star_final_sed = self.open_Phoenix(t0,logg0, self.star_f_h, self.sed_folder)
  
        return  star_final_wl, star_final_sed  
Exemple #11
0
    def extractSpec(self):

        jexosim_msg("extracting 1 D spectra....", self.opt.diagnostics)
        #==============================================================================
        # 1) initialise class objects a) noisy data, b) noiseless data if used, c) extraction of n_pix per bin
        #==============================================================================

        self.extractSpec = binning.extractSpec(self.opt.data, self.opt,
                                               self.opt.diff, self.ApFactor, 1)
        # 1 = final ap : means code knows this is the ap factor to use on noisy data and plots
        # final ap  0 = signal only or n_pix evals, so no figures for aperture on image plotted.
        if self.opt.pipeline.useSignal.val == 1:
            self.extractSpec_signal = binning.extractSpec(
                self.opt.data_signal_only, self.opt, 0, self.ApFactor,
                0)  #diff always 0 for signal

        # use a set of 3 images with 1 value for all pixels to find out no of pixels per bin
        self.extractSpec_nPix = binning.extractSpec(
            self.opt.data[..., 0:3] * 0 + 1, self.opt, 1, self.ApFactor, 0)

        #==============================================================================
        # 2) apply mask and extract 1D spectrum if apply mask selected      # special case for NIRISS
        #==============================================================================

        if self.opt.pipeline.pipeline_apply_mask.val == 1:

            # a) noisy data
            jexosim_msg(
                "applying mask and extracting 1D spectrum from noisy data",
                self.opt.diagnostics)
            if self.opt.channel.instrument.val == 'NIRISS':
                self.extractSpec.applyMask_extract_1D_NIRISS()
            else:
                self.extractSpec.applyMask_extract_1D()

            # b) noiseless data if selected
            if self.opt.pipeline.useSignal.val == 1:
                jexosim_msg(
                    "applying mask and extracting 1D spectrum from signal only data",
                    self.opt.diagnostics)
                if self.opt.channel.instrument.val == 'NIRISS':
                    self.extractSpec_signal.applyMask_extract_1D_NIRISS()
                else:
                    self.extractSpec_signal.applyMask_extract_1D()

            # c) sample data to find n_pix per bin
            jexosim_msg(
                "applying mask and extracting 1D spectrum to find n_pix per bin",
                self.opt.diagnostics)
            if self.opt.channel.instrument.val == 'NIRISS':
                self.extractSpec_nPix.applyMask_extract_1D_NIRISS()
            else:
                jexosim_msg("extracting 1 D spectra for pixel in bin test",
                            self.opt.diagnostics)
                self.extractSpec_nPix.applyMask_extract_1D()

        #==============================================================================
        # 3) extract 1D spectrum only if no mask selected
        #==============================================================================
        else:

            # a) noisy data
            jexosim_msg(
                "NOT applying mask and extracting 1D spectrum from noisy data",
                self.opt.diagnostics)
            self.extractSpec.extract1DSpectra()

            # b) noiseless data if selected
            if self.opt.pipeline.useSignal.val == 1:
                jexosim_msg(
                    "NOT applying mask and extracting 1D spectrum from signal only data",
                    self.opt.diagnostics)
                self.extractSpec_signal.extract1DSpectra()

            # c) sample data to find n_pix per bin
            jexosim_msg(
                "NOT applying mask and extracting 1D spectrum to find n_pix per bin",
                self.opt.diagnostics)
            self.extractSpec_nPix.extract1DSpectra()

        self.nPix_1 = self.extractSpec_nPix.spectra[0]
        jexosim_plot('n_pix per pixel column',
                     self.opt.diagnostics,
                     xdata=self.opt.cr_wl.value,
                     ydata=self.nPix_1,
                     marker='bo')

        #==============================================================================
        # 4) Now bin into spectral bins
        #==============================================================================
        # a) noisy data
        jexosim_msg("binning 1D spectra into spectral bins... from noisy data",
                    self.opt.diagnostics)
        self.extractSpec.binSpectra()

        # b) noiseless data if selected
        if self.opt.pipeline.useSignal.val == 1:
            jexosim_msg(
                "binning 1D spectra into spectral bins... from signal only data",
                self.opt.diagnostics)
            self.extractSpec_signal.binSpectra()

        # c) sample data to find n_pix per bin
        jexosim_msg(
            "binning 1D spectra into spectral bins... to find n_pix per bin",
            self.opt.diagnostics)
        self.extractSpec_nPix.binSpectra()

        #==============================================================================
        # 5) Define objects from binning process
        #==============================================================================
        self.binnedLC = self.extractSpec.binnedLC
        self.binnedWav = self.extractSpec.binnedWav

        if self.opt.pipeline.useSignal.val == 1:
            self.binnedLC_signal = self.extractSpec_signal.binnedLC
            self.binnedWav_signal = self.extractSpec_signal.binnedWav
        else:
            self.binnedLC_signal = self.binnedLC
            self.binnedWav_signal = self.binnedWav

        if self.opt.timeline.apply_lc.val == 1:
            self.extractSpec.binGamma()
            self.binnedGamma = self.extractSpec.binnedGamma

        self.nPix_2 = self.extractSpec_nPix.binnedLC[0]

        jexosim_plot('n_pix per bin',
                     self.opt.diagnostics,
                     xdata=self.binnedWav,
                     ydata=self.nPix_2,
                     marker='ro')
Exemple #12
0
    def __init__(self, opt):

        self.opt = opt

        self.exp_end_time_grid = self.opt.ndr_end_time[
            self.opt.effective_multiaccum - 1::self.opt.effective_multiaccum]
        self.ndr_end_time_grid = self.opt.ndr_end_time
        self.opt.data_raw = opt.data * 1

        self.ApFactor = opt.pipeline.pipeline_ap_factor.val

        if opt.background.EnableSource.val == 1:
            self.opt.diff = 0
        else:
            self.opt.diff = 1

        self.loadData()
        opt.init_pix = np.zeros(opt.data[
            ..., 0].shape)  # placeholder - replace with initial bad pixel map

        self.dqInit()

        self.satFlag()

        if (opt.background.EnableDC.val == 1 or opt.background.EnableAll.val
                == 1) and opt.background.DisableAll.val != 1:
            if opt.diff == 0:
                self.subDark()

        if (opt.noise.ApplyPRNU.val == 1 or opt.noise.EnableAll.val
                == 1) and opt.noise.DisableAll.val != 1:
            jexosim_msg(
                "mean and standard deviation of qe grid %s %s" %
                (opt.qe_grid.mean(), opt.qe_grid.std()), opt.diagnostics)

            self.flatField()

        if (opt.background.EnableZodi.val == 1
                or opt.background.EnableSunshield.val == 1
                or opt.background.EnableEmission.val == 1
                or opt.background.EnableAll.val
                == 1) and opt.background.DisableAll.val != 1:
            if opt.diff == 0:
                self.subBackground()
        jexosim_plot('sample NDR image',
                     opt.diagnostics,
                     image=True,
                     image_data=self.opt.data[..., 1])

        self.doUTR()  # lose astropy units at this step

        jexosim_plot('sample exposure image',
                     opt.diagnostics,
                     image=True,
                     image_data=self.opt.data[..., 1])

        # currently this applies zero values to saturated pixels
        self.badCorr()  # exp image obtained here

        if (opt.noise.EnableSpatialJitter.val == 1
                or opt.noise.EnableSpectralJitter.val == 1
                or opt.noise.EnableAll.val
                == 1) and opt.noise.DisableAll.val != 1:
            jexosim_msg("Decorrelating pointing jitter...", opt.diagnostics)
            self.jitterDecorr()

        if opt.pipeline.pipeline_apply_mask.val == 1:
            if opt.pipeline.pipeline_auto_ap.val == 1:
                self.autoSizeAp()

        self.extractSpec()
Exemple #13
0
    def autoSizeAp(self):
        F = self.opt.channel.camera.wfno_x.val
        wl_max = self.opt.channel.pipeline_params.wavrange_hi.val
        wl_min = self.opt.channel.pipeline_params.wavrange_lo.val
        wl = self.opt.cr_wl.value
        if self.opt.timeline.apply_lc.val == 0:
            x = 100
            if self.opt.data.shape[2] < x:  # has to use the noisy data
                x = self.opt.data.shape[2]
            sample = self.opt.data[..., 0:x]

        elif self.opt.timeline.apply_lc.val == 1:  # must use OOT portions else the transit will contribute falsely to the stand dev
            if self.opt.pipeline.split == 0:  # can only use the pre-transit values
                total_obs_time = self.opt.exposure_time * self.opt.n_exp
                pre_transit_time = self.opt.observation.obs_frac_t14_pre_transit.val * self.opt.T14
                post_transit_time = self.opt.observation.obs_frac_t14_post_transit.val * self.opt.T14
                pre_transit_exp = self.opt.n_exp * pre_transit_time / total_obs_time
                post_transit_exp = self.opt.n_exp * post_transit_time / total_obs_time
                x0 = int(pre_transit_exp * 0.75)
                if x0 > 20:
                    x0 = 20
                x1 = int(post_transit_exp * 0.75)
                if x1 > 20:
                    x1 = 20
                sample1 = self.opt.data[..., 0:x0]
                sample2 = self.opt.data[..., -x1:]
                sample = np.dstack((sample1, sample2))

            if self.opt.pipeline.split == 1:  # can only use the pre-transit values
                total_obs_time = self.opt.exposure_time * self.opt.n_exp
                pre_transit_time = self.opt.observation.obs_frac_t14_pre_transit.val * self.opt.T14
                pre_transit_exp = pre_transit_time / self.opt.exposure_time
                if self.opt.n_exp < pre_transit_exp:
                    x0 = int(self.opt.n_exp * 0.75)
                else:
                    x0 = int(pre_transit_exp * 0.75)
                if x0 > 40:
                    x0 = 40
                sample = self.opt.data[..., 0:x0]
        # print (sample.shape)
        # zero_check = sample.sum(axis=0)
        # zero_check = zero_check.sum(axis=1)
        # idx_zero = np.argwhere(zero_check==0)

        # sample = np.delete(sample, idx_zero, axis=1)

        # print (sample.shape)
        # print (idx_zero)
        # idx_zero_0 = idx_zero[0].item()
        # idx_zero_1 = idx_zero[-1].item()

        # print (idx_zero_0, idx_zero_1)
        # print (zero_check[idx_zero_0], zero_check[idx_zero_1])

        # import matplotlib.pyplot as plt
        # plt.figure('zero_check')
        # plt.plot(zero_check)
        # xxxx

        jexosim_msg("SAMPLE SHAPE %s %s %s" % (sample.shape),
                    self.opt.diagnostics)
        pix_size = (self.opt.channel.detector_pixel.pixel_size.val).to(
            u.um).value
        y_width = self.opt.data.shape[0] * pix_size
        testApFactorMax = int(int(y_width / 2.) / (F * wl_max))
        if (testApFactorMax * F * wl_max /
                pix_size) + 1 >= self.opt.data.shape[0] / 2:
            testApFactorMax = int(
                ((self.opt.data.shape[0] / 2) - 1) * pix_size / (F * wl_max))

        ApList = np.arange(1.0, testApFactorMax + 1, 1.0)
        if self.opt.channel.instrument.val == 'NIRISS':
            testApFactorMax = 18.0  # set empirically
            ApList = np.arange(7.0, testApFactorMax + 1, 1.0)
        jexosim_msg("maximum test ap factor %s" % (testApFactorMax),
                    self.opt.diagnostics)
        for i in ApList:
            testApFactor = 1.0 * i
            jexosim_msg("test ApFactor %s" % (testApFactor),
                        self.opt.diagnostics)
            self.extractSample = binning.extractSpec(sample, self.opt,
                                                     self.opt.diff,
                                                     testApFactor, 2)
            if self.opt.channel.instrument.val == 'NIRISS':
                self.extractSample.applyMask_extract_1D_NIRISS()
            else:
                self.extractSample.applyMask_extract_1D()
            spectra = self.extractSample.spectra
            self.extractSample.binSpectra()
            binnedLC = self.extractSample.binnedLC
            wl = self.extractSample.binnedWav
            SNR = binnedLC.mean(axis=0) / binnedLC.std(axis=0)

            if i == ApList[0]:
                SNR_stack = SNR
            else:
                SNR_stack = np.vstack((SNR_stack, SNR))

            jexosim_plot('test aperture SNR',
                         self.opt.diagnostics,
                         xdata=wl,
                         ydata=SNR,
                         label=testApFactor)

        idx = np.argwhere((wl >= wl_min) & (wl <= wl_max))
        SNR_stack = SNR_stack[:, idx][..., 0]
        wl = wl[idx].T[0]
        wl0 = wl

        nan_check = SNR_stack.sum(axis=0)
        nan_idx = np.argwhere(np.isnan(nan_check))

        SNR_stack = np.delete(SNR_stack, nan_idx, axis=1)
        wl0 = np.delete(wl, nan_idx)

        zero_check = SNR_stack.sum(axis=0)
        zero_idx = np.argwhere(zero_check == 0)
        SNR_stack = np.delete(SNR_stack, zero_idx, axis=1)
        wl0 = np.delete(wl0, zero_idx)

        best = []
        for i in range(SNR_stack.shape[1]):
            aa = SNR_stack[:, i]
            #            jexosim_msg i, np.argmax(aa), ApList[np.argmax(aa)]
            best.append(ApList[np.argmax(aa)])

        jexosim_plot('highest SNR aperture vs wavelength',
                     self.opt.diagnostics,
                     xdata=wl0,
                     ydata=best,
                     marker='bo-')

        AvBest = np.round(np.mean(best), 0)
        jexosim_msg("average best aperture factor %s" % (AvBest),
                    self.opt.diagnostics)
        self.opt.AvBest = AvBest
        self.ApFactor = AvBest
        self.opt.pipeline.pipeline_ap_factor.val = self.ApFactor
Exemple #14
0
    def __init__(self, opt):

        output_directory = opt.common.output_directory.val
        filename = ""
        runtag = int(np.random.uniform(0, 100000))

        self.results_dict = {}
        self.results_dict['simulation_mode'] = opt.simulation.sim_mode.val
        self.results_dict[
            'simulation_realisations'] = opt.simulation.sim_realisations.val
        self.results_dict['ch'] = opt.observation.obs_channel.val

        opt.pipeline.useSignal.val = 0
        opt.simulation.sim_use_fast.val = 1
        opt.pipeline.split = 0
        opt.noise.ApplyRandomPRNU.val = 1

        opt.timeline.apply_lc.val = 1
        opt.timeline.useLDC.val = 1
        opt.pipeline.useAllen.val = 0
        opt.pipeline.fit_gamma.val = 0  #keep zero for uncert on p

        start = 0
        end = int(start + opt.no_real)

        if (opt.no_real - start) > 1:
            jexosim_msg("Monte Carlo selected", 1)

        opt = self.run_JexoSimA(opt)

        # np.save('/Users/user1/Desktop/fp_signal.npy', opt.fp_signal[1::3,1::3].value)
        # np.save('/Users/user1/Desktop/fp_wav.npy', opt.x_wav_osr[1::3].value)

        # xxxx

        if opt.observation_feasibility == 0:
            jexosim_msg("Observation not feasible...", opt.diagnostics)
            self.feasibility = 0
        else:
            self.feasibility = 1
            n_ndr0 = opt.n_ndr * 1

            ndr_end_frame_number0 = opt.ndr_end_frame_number * 1
            frames_per_ndr0 = opt.frames_per_ndr * 1
            duration_per_ndr0 = opt.duration_per_ndr * 1
            n_exp0 = opt.n_exp
            lc0 = opt.lc_original * 1  # important this happens at this stage

            if n_ndr0 > 10000:

                opt.pipeline.split = 1
                if opt.diagnostics == 1:
                    jexosim_msg('number of NDRs > 10000: using split protocol',
                                opt.diagnostics)
            else:
                opt.pipeline.split = 0

            # #delete
            # opt.pipeline.split = 1

            for j in range(start, end):

                if (opt.no_real - start) > 1:
                    jexosim_msg("", 1)
                    jexosim_msg(
                        "============= REALIZATION %s =============" % (j), 1)
                    jexosim_msg(opt.lab, 1)
                    jexosim_msg("", 1)

                pp = time.time()

                opt = self.run_JexoSimA1(
                    opt)  # set QE grid for this realization
                jexosim_msg("QE variations set", 1)
                jexosim_msg("Number of exposures %s" % (n_exp0), 1)

                print(opt.diagnostics)

                # =============================================================================
                #  # split simulation into chunks to permit computation - makes no difference to final results
                # =============================================================================
                if opt.pipeline.split == 1:

                    jexosim_msg('Splitting data series into chunks',
                                opt.diagnostics)
                    # uses same QE grid and jitter timeline but otherwise randomoses noise
                    ndrs_per_round = opt.effective_multiaccum * int(
                        5000 / opt.multiaccum)
                    # ndrs_per_round = opt.effective_multiaccum*int(500/opt.multiaccum)

                    total_chunks = len(np.arange(0, n_ndr0, ndrs_per_round))

                    idx = np.arange(0, n_ndr0,
                                    ndrs_per_round)  # list of starting ndrs

                    for i in range(len(idx)):
                        jexosim_msg(
                            '=== Realisation %s Chunk %s / %s=====' %
                            (j, i + 1, total_chunks), 1)
                        jexosim_msg(opt.lab, 1)
                        if idx[i] == idx[-1]:
                            opt.n_ndr = n_ndr0 - idx[i]
                            opt.lc_original = lc0[:, idx[i]:]
                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:]
                            opt.duration_per_ndr = duration_per_ndr0[idx[i]:]

                        else:
                            opt.n_ndr = idx[i + 1] - idx[i]
                            opt.lc_original = lc0[:, idx[i]:idx[i + 1]]
                            print('idx start......', idx[i])

                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:idx[i + 1]]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:idx[i +
                                                                            1]]
                            opt.duration_per_ndr = duration_per_ndr0[
                                idx[i]:idx[i + 1]]

                        opt.n_exp = int(opt.n_ndr / opt.effective_multiaccum)

                        if i == 0:
                            opt.pipeline.pipeline_auto_ap.val = 1
                            opt.use_external_jitter = 0

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                            opt.pipeline.pipeline_ap_factor.val = opt.AvBest
                            if (opt.noise.EnableSpatialJitter.val == 1
                                    or opt.noise.EnableSpectralJitter.val == 1
                                    or opt.noise.EnableAll.val
                                    == 1) and opt.noise.DisableAll.val != 1:
                                opt.input_yaw_jitter, opt.input_pitch_jitter, opt._input_frame_osf = opt.yaw_jitter, opt.pitch_jitter, opt.frame_osf

                        else:
                            opt.pipeline.pipeline_auto_ap.val = 0
                            opt.use_external_jitter = 1  # uses the jitter timeline from the first realization

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                        jexosim_msg(
                            'Aperture used %s' %
                            (opt.pipeline.pipeline_ap_factor.val),
                            opt.diagnostics)
                        binnedLC = opt.pipeline_stage_1.binnedLC
                        data = opt.pipeline_stage_1.opt.data_raw

                        if i == 0:
                            data_stack = data * 1
                            binnedLC_stack = binnedLC * 1
                        else:
                            data_stack = np.dstack((data_stack, data))
                            binnedLC_stack = np.vstack(
                                (binnedLC_stack, binnedLC))

                        del data
                        del binnedLC

                    aa = data_stack.sum(axis=0)
                    bb = aa.sum(axis=0)
                    jexosim_plot('test_from_sim',
                                 opt.diagnostics,
                                 ydata=bb[opt.effective_multiaccum::opt.
                                          effective_multiaccum])
                    aa = binnedLC_stack.sum(axis=1)
                    jexosim_plot('test_from_pipeline',
                                 opt.diagnostics,
                                 ydata=aa)

                    opt.n_ndr = n_ndr0
                    opt.ndr_end_frame_number = ndr_end_frame_number0
                    opt.frames_per_ndr = frames_per_ndr0
                    opt.duration_per_ndr = duration_per_ndr0
                    opt.n_exp = n_exp0

                elif opt.pipeline.split == 0:

                    opt = self.run_JexoSimB(opt)
                    if j == start:  # first realization sets the ap, then the other use the same one
                        opt.pipeline.pipeline_auto_ap.val = 1
                    else:
                        opt.pipeline.pipeline_auto_ap.val = 0
                    opt = self.run_pipeline_stage_1(opt)
                    if j == start:  # first realization sets the ap, then the other use the same one
                        opt.pipeline.pipeline_ap_factor.val = opt.AvBest

                    binnedLC_stack = opt.pipeline_stage_1.binnedLC
                    jexosim_plot('testvvv',
                                 opt.diagnostics,
                                 ydata=binnedLC_stack.sum(axis=1))

                opt.pipeline_stage_1.binnedLC = binnedLC_stack
                opt = self.run_pipeline_stage_2(opt)
                pipeline = opt.pipeline_stage_2

                p = pipeline.transitDepths
                if j == start:
                    p_stack = p
                else:
                    p_stack = np.vstack((p_stack, p))

                jexosim_msg(
                    "time to complete realization %s %s" %
                    (j, time.time() - pp), opt.diagnostics)

                self.results_dict['wl'] = pipeline.binnedWav
                self.results_dict['input_spec'] = opt.cr
                self.results_dict['input_spec_wl'] = opt.cr_wl

                if j == start:  # if only one realisation slightly different format
                    self.results_dict['p_stack'] = np.array(p)
                    self.results_dict['p_std'] = np.zeros(len(p))
                    self.results_dict['p_mean'] = np.array(p)
                else:
                    self.results_dict['p_stack'] = np.vstack(
                        (self.results_dict['p_stack'], p))
                    self.results_dict['p_std'] = self.results_dict[
                        'p_stack'].std(axis=0)
                    self.results_dict['p_mean'] = self.results_dict[
                        'p_stack'].mean(axis=0)

                time_tag = (datetime.now().strftime('%Y_%m_%d_%H%M_%S'))

                self.results_dict['time_tag'] = time_tag
                self.results_dict['bad_map'] = opt.bad_map
                self.results_dict['example_exposure_image'] = opt.exp_image
                self.results_dict['pixel wavelengths'] = opt.x_wav_osr[
                    1::3].value
                self.results_dict['focal_plane_star_signal'] = opt.fp_signal[
                    1::3, 1::3].value

                # fq = '/Users/user1/Desktop/tempGit/JexoSim_A/output/Full_eclipse_MIRI_LRS_slitless_SLITLESSPRISM_FAST_HD_209458_b_2021_07_18_0852_28.pickle'

                # with open(fq, 'rb') as handle:
                #   rd = pickle.load(handle)
                # rd['focal_plane_star_signal'] = opt.fp_signal[1::3,1::3]
                # rd['pixel wavelengths'] = opt.x_wav_osr[1::3].value
                # with open(fq, 'wb') as handle:
                #         pickle.dump(rd , handle, protocol=pickle.HIGHEST_PROTOCOL)

                # run('Full_transit_NIRSpec_BOTS_G140M_F100LP_SUB2048_NRSRAPID_K2-18_b_2021_07_18_1402_38.pickle',0)
                # run('Full_transit_NIRSpec_BOTS_G235M_F170LP_SUB2048_NRSRAPID_K2-18_b_2021_07_18_0709_24.pickle', 2)
                # run('Full_transit_NIRSpec_BOTS_G395M_F290LP_SUB2048_NRSRAPID_K2-18_b_2021_07_17_2339_51.pickle',4)

                # run('Full_eclipse_NIRCam_TSGRISM_F444W_SUBGRISM64_4_output_RAPID_HD_209458_b_2021_07_19_0654_29.pickle',0)
                # run('Full_eclipse_NIRCam_TSGRISM_F322W2_SUBGRISM64_4_output_RAPID_HD_209458_b_2021_07_19_0359_08.pickle',1)
                # run('Full_eclipse_MIRI_LRS_slitless_SLITLESSPRISM_FAST_HD_209458_b_2021_07_18_0852_28.pickle', 2)

                if j != start:
                    os.remove(filename)  # delete previous temp file

                filename = '%s/Full_transit_%s_TEMP%s.pickle' % (
                    output_directory, opt.lab, runtag)
                if opt.observation.obs_type.val == 2:
                    filename = '%s/Full_eclipse_%s_TEMP%s.pickle' % (
                        output_directory, opt.lab, runtag)

                with open(filename, 'wb') as handle:
                    pickle.dump(self.results_dict,
                                handle,
                                protocol=pickle.HIGHEST_PROTOCOL)

                del pipeline
                del binnedLC_stack
                gc.collect()

            os.remove(filename)  # delete previous temp file
            # write final file
            filename = '%s/Full_transit_%s_%s.pickle' % (output_directory,
                                                         opt.lab, time_tag)
            if opt.observation.obs_type.val == 2:
                filename = '%s/Full_eclipse_%s_%s.pickle' % (output_directory,
                                                             opt.lab, time_tag)

            with open(filename, 'wb') as handle:
                pickle.dump(self.results_dict,
                            handle,
                            protocol=pickle.HIGHEST_PROTOCOL)

            jexosim_msg('Results in %s' % (filename), 1)
            self.filename = 'Full_transit_%s_%s.pickle' % (opt.lab, time_tag)
            if opt.observation.obs_type.val == 2:
                self.filename = 'Full_eclipse_%s_%s.pickle' % (opt.lab,
                                                               time_tag)

            write_record(opt, output_directory, self.filename,
                         opt.params_file_path)
Exemple #15
0
def run(opt):

    jexosim_msg('Running backgrounds module ...\n ', opt.diagnostics)

    opt.zodi, zodi_transmission = backgrounds_lib.zodical_light(opt)
    opt.emission = backgrounds_lib.optical_emission(opt)
    opt.sunshield = backgrounds_lib.sunshield_emission(opt)

    # import matplotlib.pyplot as plt
    # plt.figure ('backgrounds 1')
    # plt.plot(opt.sunshield.wl, opt.sunshield.sed, 'r', label='sunshield before transmission')
    # plt.plot(opt.zodi.wl, opt.zodi.sed, 'g--', label='zodi before transmission')
    # plt.plot(opt.emission.wl, opt.emission.sed ,'bx', label = 'optical after transmission')
    # plt.grid()
    # plt.legend()

    # propagate star through zodi transmission
    jexosim_lib.sed_propagation(opt.star.sed, zodi_transmission)

    ch = opt.channel
    Omega_pix = 2.0 * np.pi * (
        1.0 - np.cos(np.arctan(0.5 / ch.camera.wfno_x()))) * u.sr
    Apix = ((ch.detector_pixel.pixel_size.val).to(u.m))**2

    opt.zodi.sed *= Apix * Omega_pix * opt.Re * u.electron / u.W / u.s
    opt.sunshield.sed *= Apix * Omega_pix * opt.Re * u.electron / u.W / u.s
    opt.emission.sed *= Apix * Omega_pix * opt.Re * u.electron / u.W / u.s

    # apply transmission to zodi and sunshield (not to optical emission -alreay applied)
    jexosim_lib.sed_propagation(opt.zodi, opt.total_transmission)
    jexosim_lib.sed_propagation(opt.sunshield, opt.total_transmission)

    opt.zodi.sed[np.isnan(opt.zodi.sed)] = 0
    opt.sunshield.sed[np.isnan(opt.sunshield.sed)] = 0
    opt.emission.sed[np.isnan(opt.emission.sed)] = 0

    opt.zodi.sed *= opt.d_x_wav_osr
    opt.sunshield.sed *= opt.d_x_wav_osr
    opt.emission.sed *= opt.d_x_wav_osr

    zodi_photons_sed = copy.deepcopy(opt.zodi.sed)
    sunshield_photons_sed = copy.deepcopy(opt.sunshield.sed)
    emission_photons_sed = copy.deepcopy(opt.emission.sed)

    if ch.camera.slit_width.val == 0:
        slit_size = opt.fpn[
            1] * 2  # to ensure all wavelengths convolved onto all pixels in slitless case
    else:
        slit_size = ch.camera.slit_width.val

    # import matplotlib.pyplot as plt
    # plt.figure ('backgrounds 2')
    # plt.plot(opt.zodi.wl, opt.zodi.sed, 'bo-')
    # print (opt.zodi.sed)

    # need to work on this to make more accurate : filter wavelength range might not correspond to wl sol on the detector, i.e. some wavelengths not being included that should be
    opt.zodi.sed = scipy.signal.convolve(
        opt.zodi.sed, np.ones(np.int(slit_size * ch.simulation_factors.osf())),
        'same') * opt.zodi.sed.unit
    opt.sunshield.sed = scipy.signal.convolve(
        opt.sunshield.sed,
        np.ones(np.int(slit_size * ch.simulation_factors.osf())),
        'same') * opt.sunshield.sed.unit
    opt.emission.sed = scipy.signal.convolve(
        opt.emission.sed.value,
        np.ones(np.int(slit_size * ch.simulation_factors.osf())),
        'same') * opt.emission.sed.unit

    # print (opt.zodi.sed)
    # import matplotlib.pyplot as plt
    # plt.figure ('backgrounds 2')
    # plt.plot(opt.zodi.wl, opt.zodi.sed, 'ro-')
    # xxxx

    opt.zodi_sed_original = copy.deepcopy(opt.zodi.sed)
    opt.sunshield_sed_original = copy.deepcopy(opt.sunshield.sed)
    opt.emission_sed_original = copy.deepcopy(opt.emission.sed)

    jexosim_plot('zodi spectrum',
                 opt.diagnostics,
                 xdata=opt.zodi.wl,
                 ydata=opt.zodi.sed)
    jexosim_plot('sunshield spectrum',
                 opt.diagnostics,
                 xdata=opt.sunshield.wl,
                 ydata=opt.sunshield.sed)
    jexosim_plot('emission spectrum',
                 opt.diagnostics,
                 xdata=opt.emission.wl,
                 ydata=opt.emission.sed)

    # ====Now work out quantum yield ==============================================
    # weight the qy by relative number of photons
    zodi_w_qy = zodi_photons_sed * opt.quantum_yield.sed
    # convolve this with slit
    zodi_w_qy = scipy.signal.convolve(
        zodi_w_qy, np.ones(np.int(slit_size * ch.simulation_factors.osf())),
        'same') * opt.zodi.sed.unit
    # divide by convolved spectrum.... thus this factor will return the expected qy
    opt.qy_zodi = zodi_w_qy / opt.zodi.sed

    # (Ph conv. slit )x Qy'  = (Ph x Qy) conv. slit
    # thus Qy' is the needed Qy per pixel applied to the convolve Ph spectrum.

    sunshield_w_qy = sunshield_photons_sed * opt.quantum_yield.sed
    sunshield_w_qy = scipy.signal.convolve(
        sunshield_w_qy, np.ones(np.int(
            slit_size * ch.simulation_factors.osf())),
        'same') * opt.sunshield.sed.unit
    opt.qy_sunshield = sunshield_w_qy / opt.sunshield.sed

    emission_w_qy = emission_photons_sed * opt.quantum_yield.sed
    emission_w_qy = scipy.signal.convolve(
        emission_w_qy, np.ones(np.int(
            slit_size * ch.simulation_factors.osf())),
        'same') * opt.emission.sed.unit
    opt.qy_emission = emission_w_qy / opt.emission.sed

    opt.qy_zodi[np.isnan(opt.qy_zodi)] = 1
    opt.qy_sunshield[np.isnan(opt.qy_sunshield)] = 1
    opt.qy_emission[np.isnan(opt.qy_emission)] = 1

    return opt
Exemple #16
0
def run(opt):

    opt.fp = copy.deepcopy(
        opt.fp_original
    )  # needed to reuse if cropped fp is used and monte carlo mode used
    opt.fp_signal = copy.deepcopy(opt.fp_signal_original)  # "
    opt.zodi.sed = copy.deepcopy(opt.zodi_sed_original)  # "
    opt.sunshield.sed = copy.deepcopy(opt.sunshield_sed_original)  # "
    opt.emission.sed = copy.deepcopy(opt.emission_sed_original)  # "
    opt.lc = copy.deepcopy(opt.lc_original)
    opt.ldc = copy.deepcopy(opt.ldc_original)
    opt.cr_wl = copy.deepcopy(opt.cr_wl_original)
    opt.cr = copy.deepcopy(opt.cr_original)
    opt.x_wav_osr = copy.deepcopy(opt.x_wav_osr_original)
    opt.x_pix_osr = copy.deepcopy(opt.x_pix_osr_original)
    opt.qe = copy.deepcopy(opt.qe_original)
    opt.qe_uncert = copy.deepcopy(opt.qe_uncert_original)
    opt.quantum_yield = copy.deepcopy(opt.quantum_yield_original)
    opt.qy_zodi = copy.deepcopy(opt.qy_zodi_original)
    opt.qy_sunshield = copy.deepcopy(opt.qy_sunshield_original)
    opt.qy_emission = copy.deepcopy(opt.qy_emission_original)
    opt.syst_grid = copy.deepcopy(opt.syst_grid_original)

    opt = signal_lib.initiate_signal(opt)
    opt = signal_lib.apply_jitter(opt)  # opt.signal iniatated here
    opt = signal_lib.apply_lc(opt)
    opt = signal_lib.initiate_noise(opt)
    opt = signal_lib.apply_non_stellar_photons(opt)
    opt = signal_lib.apply_prnu(opt)
    opt = signal_lib.apply_dc(opt)
    opt = signal_lib.apply_poisson_noise(opt)
    opt = signal_lib.apply_quantum_yield(opt)
    opt = signal_lib.apply_fano(opt)
    opt = signal_lib.apply_utr_correction(opt)
    opt = signal_lib.apply_combined_noise(opt)
    opt = signal_lib.make_ramps(opt)
    opt = signal_lib.apply_ipc(opt)
    opt = signal_lib.apply_read_noise(opt)
    opt = signal_lib.apply_gaps(opt)

    opt.data = opt.signal
    opt.data_signal_only = opt.signal_only

    jexosim_plot('focal plane check1',
                 opt.diagnostics,
                 image=True,
                 image_data=opt.fp_signal[1::3, 1::3],
                 aspect='auto',
                 interpolation=None,
                 xlabel='x \'spectral\' pixel',
                 ylabel='y \'spatial\' pixel')

    jexosim_plot('test - check NDR0',
                 opt.diagnostics,
                 image=True,
                 image_data=opt.data[..., 0])
    jexosim_plot('test - check NDR1',
                 opt.diagnostics,
                 image=True,
                 image_data=opt.data[..., 1])

    return opt
Exemple #17
0
def get_light_curve(opt, planet_sed, wavelength, obs_type):

    wavelength = wavelength.value
    timegrid = opt.z_params[0]
    t0 = opt.z_params[1]
    per = opt.z_params[2]
    ars = opt.z_params[3]
    inc = opt.z_params[4]
    ecc = opt.z_params[5]
    omega = opt.z_params[6]

    if opt.observation.obs_type.val == 2:
        opt.timeline.useLDC.val = 0

    if opt.timeline.useLDC.val == 0:  # linear ldc
        jexosim_msg('LDCs set to zero', 1)
        u0 = np.zeros(len(wavelength))
        u1 = np.zeros(len(wavelength))
        ldc = np.vstack((wavelength, u0, u1))
    elif opt.timeline.useLDC.val == 1:  # use to get ldc from filed values
        u0, u1 = getLDC_interp(opt, opt.planet.planet, wavelength)
        ldc = np.vstack((wavelength, u0, u1))

    gamma = np.zeros((ldc.shape[1], 2))
    gamma[:, 0] = ldc[1]
    gamma[:, 1] = ldc[2]
    jexosim_plot('ldc', opt.diagnostics, ydata=ldc[1])
    jexosim_plot('ldc', opt.diagnostics, ydata=ldc[2])
    tm = QuadraticModel(interpolate=False)
    tm.set_data(timegrid)

    lc = np.zeros((len(planet_sed), len(timegrid)))

    if obs_type == 1:  #primary transit
        for i in range(len(planet_sed)):
            k = np.sqrt(planet_sed[i]).value
            lc[i, ...] = tm.evaluate(k=k,
                                     ldc=gamma[i, ...],
                                     t0=t0,
                                     p=per,
                                     a=ars,
                                     i=inc,
                                     e=ecc,
                                     w=omega)
            jexosim_plot('light curve check',
                         opt.diagnostics,
                         ydata=lc[i, ...])
    elif obs_type == 2:  # secondary eclipse
        for i in range(len(planet_sed)):
            k = np.sqrt(planet_sed[i])  # planet star radius ratio
            lc_base = tm.evaluate(k=k,
                                  ldc=[0, 0],
                                  t0=t0,
                                  p=per,
                                  a=ars,
                                  i=inc,
                                  e=ecc,
                                  w=omega)
            jexosim_plot('light curve check', opt.diagnostics, ydata=lc_base)
            # f_e = (planet_sed[i] + (   lc_base  -1.0))/planet_sed[i]
            # lc[i, ...]  = 1.0 + f_e*(planet_sed[i])

            lc[i, ...] = lc_base + planet_sed[i]
            jexosim_plot('light curve check',
                         opt.diagnostics,
                         ydata=lc[i, ...])

    return lc, ldc
    def __init__(self, opt):

        output_directory = opt.common.output_directory.val
        filename = ""

        self.results_dict = {}
        self.results_dict['simulation_mode'] = opt.simulation.sim_mode.val
        self.results_dict[
            'simulation_realisations'] = opt.simulation.sim_realisations.val
        self.results_dict['ch'] = opt.observation.obs_channel.val

        opt.pipeline.useSignal.val = 0
        opt.simulation.sim_use_fast.val = 1
        opt.pipeline.split = 0
        opt.noise.ApplyRandomPRNU.val = 1

        opt.timeline.apply_lc.val = 1
        opt.timeline.useLDC.val = 1
        opt.pipeline.useAllen.val = 0
        opt.pipeline.fit_gamma.val = 0  #keep zero for uncert on p

        start = 0
        end = int(start + opt.no_real)

        if (opt.no_real - start) > 1:
            jexosim_msg("Monte Carlo selected", 1)

        opt = self.run_JexoSimA(opt)

        if opt.observation_feasibility == 0:
            jexosim_msg("Observation not feasible...", opt.diagnostics)
            self.feasibility = 0
        else:
            self.feasibility = 1
            n_ndr0 = opt.n_ndr * 1

            ndr_end_frame_number0 = opt.ndr_end_frame_number * 1
            frames_per_ndr0 = opt.frames_per_ndr * 1
            duration_per_ndr0 = opt.duration_per_ndr * 1
            n_exp0 = opt.n_exp
            lc0 = opt.lc_original * 1  # important this happens at this stage

            if n_ndr0 > 10000:

                opt.pipeline.split = 1
                if opt.diagnostics == 1:
                    jexosim_msg('number of NDRs > 10000: using split protocol',
                                opt.diagnostics)
            else:
                opt.pipeline.split = 0

            # #delete
            # opt.pipeline.split = 1

            for j in range(start, end):

                if (opt.no_real - start) > 1:
                    jexosim_msg("", 1)
                    jexosim_msg(
                        "============= REALIZATION %s =============" % (j), 1)
                    jexosim_msg(opt.lab, 1)
                    jexosim_msg("", 1)

                pp = time.time()

                opt = self.run_JexoSimA1(
                    opt)  # set QE grid for this realization
                jexosim_msg("QE variations set", 1)
                jexosim_msg("Number of exposures %s" % (n_exp0), 1)

                # =============================================================================
                #  # split simulation into chunks to permit computation - makes no difference to final results
                # =============================================================================
                if opt.pipeline.split == 1:

                    jexosim_msg('Splitting data series into chunks',
                                opt.diagnostics)
                    # uses same QE grid and jitter timeline but otherwise randomoses noise
                    ndrs_per_round = opt.effective_multiaccum * int(
                        5000 / opt.multiaccum)
                    # ndrs_per_round = opt.effective_multiaccum*int(500/opt.multiaccum)

                    total_chunks = len(np.arange(0, n_ndr0, ndrs_per_round))

                    idx = np.arange(0, n_ndr0,
                                    ndrs_per_round)  # list of starting ndrs

                    for i in range(len(idx)):
                        jexosim_msg(
                            '=== Realisation %s Chunk %s / %s=====' %
                            (j, i + 1, total_chunks), opt.diagnostics)

                        if idx[i] == idx[-1]:
                            opt.n_ndr = n_ndr0 - idx[i]
                            opt.lc_original = lc0[:, idx[i]:]
                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:]
                            opt.duration_per_ndr = duration_per_ndr0[idx[i]:]

                        else:
                            opt.n_ndr = idx[i + 1] - idx[i]
                            opt.lc_original = lc0[:, idx[i]:idx[i + 1]]
                            print('idx start......', idx[i])

                            opt.ndr_end_frame_number = ndr_end_frame_number0[
                                idx[i]:idx[i + 1]]
                            opt.frames_per_ndr = frames_per_ndr0[idx[i]:idx[i +
                                                                            1]]
                            opt.duration_per_ndr = duration_per_ndr0[
                                idx[i]:idx[i + 1]]

                        opt.n_exp = int(opt.n_ndr / opt.effective_multiaccum)

                        if i == 0:
                            opt.pipeline.pipeline_auto_ap.val = 1
                            opt.use_external_jitter = 0

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                            opt.pipeline.pipeline_ap_factor.val = opt.AvBest
                            if (opt.noise.EnableSpatialJitter.val == 1
                                    or opt.noise.EnableSpectralJitter.val == 1
                                    or opt.noise.EnableAll.val
                                    == 1) and opt.noise.DisableAll.val != 1:
                                opt.input_yaw_jitter, opt.input_pitch_jitter, opt._input_frame_osf = opt.yaw_jitter, opt.pitch_jitter, opt.frame_osf

                        else:
                            opt.pipeline.pipeline_auto_ap.val = 0
                            opt.use_external_jitter = 1  # uses the jitter timeline from the first realization

                            opt = self.run_JexoSimB(opt)
                            opt = self.run_pipeline_stage_1(opt)

                        jexosim_msg(
                            'Aperture used %s' %
                            (opt.pipeline.pipeline_ap_factor.val),
                            opt.diagnostics)
                        binnedLC = opt.pipeline_stage_1.binnedLC
                        data = opt.pipeline_stage_1.opt.data_raw

                        if i == 0:
                            data_stack = data
                            binnedLC_stack = binnedLC
                        else:
                            data_stack = np.dstack((data_stack, data))
                            binnedLC_stack = np.vstack(
                                (binnedLC_stack, binnedLC))

                    aa = data_stack.sum(axis=0)
                    bb = aa.sum(axis=0)
                    jexosim_plot('test_from_sim',
                                 opt.diagnostics,
                                 ydata=bb[opt.effective_multiaccum::opt.
                                          effective_multiaccum])
                    aa = binnedLC_stack.sum(axis=1)
                    jexosim_plot('test_from_pipeline',
                                 opt.diagnostics,
                                 ydata=aa)

                    opt.n_ndr = n_ndr0
                    opt.ndr_end_frame_number = ndr_end_frame_number0
                    opt.frames_per_ndr = frames_per_ndr0
                    opt.duration_per_ndr = duration_per_ndr0
                    opt.n_exp = n_exp0

                elif opt.pipeline.split == 0:

                    opt = self.run_JexoSimB(opt)
                    if j == start:  # first realization sets the ap, then the other use the same one
                        opt.pipeline.pipeline_auto_ap.val = 1
                    else:
                        opt.pipeline.pipeline_auto_ap.val = 0
                    opt = self.run_pipeline_stage_1(opt)
                    if j == start:  # first realization sets the ap, then the other use the same one
                        opt.pipeline.pipeline_ap_factor.val = opt.AvBest

                    binnedLC_stack = opt.pipeline_stage_1.binnedLC
                    jexosim_plot('testvvv',
                                 opt.diagnostics,
                                 ydata=binnedLC_stack.sum(axis=1))

# =============================================================================
# Now put intermediate data (binned light curves) into FITS files
# =============================================================================
                opt.pipeline_stage_1.binnedLC *= u.electron
                opt.pipeline_stage_1.binnedWav *= u.um

                self.filename = output.run(opt)

                write_record(opt, output_directory, self.filename,
                             opt.params_file_path)

                jexosim_msg(
                    'File saved as %s/%s' % (output_directory, self.filename),
                    1)