Beispiel #1
0
def jitterless(opt):
   jexosim_msg ("using jitterless array", opt.diagnostics)
   blank_signal = np.ones((int(opt.fp.shape[0]/3), int(opt.fp.shape[1]/3), len(opt.frames_per_ndr)))
   jitterless =   (blank_signal.transpose() * opt.fp[1::3,1::3].transpose() ).transpose()   
   opt.signal = jitterless*opt.frames_per_ndr*opt.frame_time  
   opt.pointing_timeline= np.zeros((opt.ndr_end_frame_number[-1], 3))
   return opt 
Beispiel #2
0
def subDark(opt):
    jexosim_msg("subtracting dark signal...", opt.diagnostics)

    dc_time = opt.channel.detector_pixel.Idc.val * opt.duration_per_ndr
    new_data = opt.data - dc_time
    opt.data = new_data
    return opt
Beispiel #3
0
def make_ramps(opt):
 
  jexosim_msg ("check point 6.1 %s"%(opt.signal.max()) , opt.diagnostics  )
  # Make ramps 
  for i in range(0, opt.n_ndr, opt.effective_multiaccum):
      opt.signal[...,i:i+opt.effective_multiaccum] = np.cumsum(opt.signal[...,i:i+opt.effective_multiaccum], axis=2) 
  return opt
Beispiel #4
0
def fast_method(opt):
       
  idx0, idx1, idxA, idxB = crop_array(opt) 
  # apply x crop to 1D arrays    
  opt.x_wav_osr0 = opt.x_wav_osr*1
  opt.x_wav_osr = opt.x_wav_osr[idxA*3:idxB*3]
  opt.x_pix_osr = opt.x_pix_osr[idxA*3:idxB*3]
  opt.cr_wl = opt.cr_wl[idxA:idxB]
  opt.cr = opt.cr[idxA:idxB]
  if opt.timeline.apply_lc.val ==1:
       opt.ldc = opt.ldc[:,idxA:idxB]
       opt.lc  = opt.lc[idxA:idxB]   
  opt.zodi.sed = opt.zodi.sed[idxA*3:idxB*3]
  opt.sunshield.sed = opt.sunshield.sed[idxA*3:idxB*3]
  opt.emission.sed = opt.emission.sed[idxA*3:idxB*3]
  opt.quantum_yield.sed = opt.quantum_yield.sed[idxA*3:idxB*3]
  opt.qy_zodi  = opt.qy_zodi[idxA*3:idxB*3]
  opt.qy_sunshield  = opt.qy_sunshield[idxA*3:idxB*3]
  opt.qy_emission = opt.qy_emission[idxA*3:idxB*3]
  opt.exp_sig = opt.exp_sig[idxA:idxB] #expected final star signal in R bin from detector module sanity check
  # apply x and y crop to 2D arrays     
  opt.qe = opt.qe[idx0:idx1][:, idxA:idxB]
  opt.qe_uncert = opt.qe_uncert[idx0:idx1][:, idxA:idxB]
  opt.fp = opt.fp[idx0*3:idx1*3][:, idxA*3:idxB*3]
  opt.fp_signal = opt.fp_signal[idx0*3:idx1*3][:, idxA*3:idxB*3]

  # obtain proxy bkg signal for pipeline background subtraction step   
  opt.bkg_signal = proxy_bkg(opt)
  jexosim_msg ("fast method used, focal place image reduced from  %s x %s to %s x %s"%(opt.fp_original.shape[0]/3, opt.fp_original.shape[1]/3 , opt.fp.shape[0]/3, opt.fp.shape[1]/3), opt.diagnostics)

  return opt
Beispiel #5
0
def apply_ipc(opt):
  # Apply IPC: should be before read noise
  if opt.simulation.sim_use_ipc.val == 1 and opt.channel.instrument.val !='MIRI': 
       jexosim_msg('Applying IPC...', opt.diagnostics)    
       ipc_kernel = np.load(opt.channel.detector_array.ipc_kernel.val.replace('__path__', '%s/%s'%(opt.jexosim_path, 'jexosim')))
       opt.signal =  noise_lib.apply_ipc(opt.signal, ipc_kernel)
  return opt
Beispiel #6
0
def subBackground(opt):
    jexosim_msg("subtracting background...", opt.diagnostics)

    if opt.simulation.sim_use_fast.val ==1 and opt.channel.instrument.val!='NIRISS' and \
        opt.data.shape[0]>20:
        aa = opt.bkg_signal.sum(
            axis=0) / opt.bkg_signal.shape[0]  #mean value per column
        if opt.channel.instrument.val != 'NIRSpec':  # overall mean - okay if no slit since no wav-dep on zodi and emission
            aa = []
            for i in range(opt.data.shape[2]):
                aa.append(opt.bkg_signal[..., i].mean().value)
            aa = np.array(aa) * u.electron
        opt.data = opt.data - aa
    else:
        border_pix = 5
        if opt.data.shape[0] < 20:
            border_pix = 1
        background_1 = opt.data[0:border_pix]
        background_2 = opt.data[-border_pix:]
        background = np.vstack((background_1, background_2))
        aa = background.sum(axis=0) / background.shape[0]
        if opt.channel.instrument.val != 'NIRSpec':
            aa = []
            for i in range(opt.data.shape[2]):
                aa.append(background[..., i].mean().value)
            aa = np.array(aa) * u.electron
        opt.data = opt.data - aa
    return opt
Beispiel #7
0
 def open_Phoenix(self, t0, logg0, Z, sed_folder):
 
     cond = 0
     for root, dirs, files in os.walk(sed_folder):
         for filename in files:
             if filename == 'lte0%s-%s-0.0a+0.0.BT-Settl.spec.fits'%(t0, logg0):
                 ph_file = '%s/%s'%(sed_folder, filename)
                 cond = 1
             elif filename == 'lte0%s-%s-0.0a+0.0.BT-Settl.spec.fits.gz'%(t0, logg0):
                 ph_file = '%s/%s'%(sed_folder, filename)
                 jexosim_msg ("Star file used:  %s"%(ph_file) , self.opt.diagnostics)
                 cond = 1
     if cond==0:
         jexosim_msg ("Error Star 2:  no star file found", 1)
         sys.exit()    
     else:
         with fits.open(ph_file) as hdu:
             wl = u.Quantity(hdu[1].data.field('Wavelength'),
                          hdu[1].header['TUNIT1']).astype(np.float64)
             sed = u.Quantity(hdu[1].data.field('Flux'), u.W/u.m**2/u.um).astype(np.float64)
             if hdu[1].header['TUNIT2'] != 'W / (m2 um)': print ('Exception')
                              
          #remove duplicates
             idx = np.nonzero(np.diff(wl))
             wl = wl[idx]
             sed = sed[idx]
             hdu.close()
  
     return wl, sed
Beispiel #8
0
def apply_poisson_noise(opt):    
    if opt.noise.EnableShotNoise.val == 1:    
       jexosim_msg ("Applying Poisson noise", opt.diagnostics)
       opt.signal = np.where(opt.signal >= 0.0, opt.signal, 0)
       opt.combined_noise = noise_lib.calc_poission_noise(opt.signal.value) *u.electron
       
    else:
       jexosim_msg ("Poisson noise not being applied...", opt.diagnostics)
    return opt
Beispiel #9
0
def apply_utr_correction(opt):
  # UTR correction verfied as correct for read noise, poisson noise, fano noise, fano and poission noise
  if opt.noise.EnableShotNoise.val == 1 or opt.noise.EnableFanoNoise.val == 1:
       if opt.simulation.sim_full_ramps.val == 0 and opt.simulation.sim_use_UTR_noise_correction.val == 1:
             jexosim_msg ("applying correction to photon noise for UTR read", opt.diagnostics  )
             n = opt.projected_multiaccum
             opt.combined_noise, scale = noise_lib.poission_noise_UTR_correction(n, opt.combined_noise.value)              
             opt.combined_noise = opt.combined_noise * u.electron
  return opt
Beispiel #10
0
def apply_systematic(opt):
    if opt.simulation.sim_use_systematic_model.val == 0: 
      return opt
    else:
      jexosim_msg ("Applying systematic model...", opt.diagnostics)
      signal = opt.signal*1
      syst = opt.syst*1
      signal = signal*syst
      opt.signal = signal 
      return opt  
Beispiel #11
0
def apply_dc(opt):
  blank_fp_shape = np.ones((int(opt.fp.shape[0]/3), int(opt.fp.shape[1]/3), len(opt.frames_per_ndr)))
  opt.dc_signal = np.zeros_like(blank_fp_shape)*u.electron
  if opt.background.EnableDC.val ==1:
      jexosim_msg ("DARK CURRENT being added...%s"%(opt.channel.detector_pixel.Idc.val ), opt.diagnostics  )
      opt.dc_signal = blank_fp_shape*  opt.channel.detector_pixel.Idc() * opt.frame_time * opt.frames_per_ndr                 
      opt.signal = opt.signal + opt.dc_signal     
  else:
      jexosim_msg ("DARK CURRENT.. not... being added...", opt.diagnostics)
  return opt
Beispiel #12
0
def flatField(opt):
    jexosim_msg("applying flat field...", opt.diagnostics)

    QE_grid = opt.qe_grid
    opt.data = np.rollaxis(opt.data, 2, 0)
    opt.data = opt.data / QE_grid
    opt.data = np.rollaxis(opt.data, 0, 3)

    jexosim_msg("std of flat field...%s" % (QE_grid.std()), opt.diagnostics)

    return opt
Beispiel #13
0
def apply_lc(opt):
    if opt.timeline.apply_lc.val ==0:
      jexosim_msg ("OMITTING LIGHT CURVE...", opt.diagnostics)
      return opt
    else:
      jexosim_msg ("APPLYING LIGHT CURVE...", opt.diagnostics)
      signal = opt.signal*1
      lc = opt.lc*1
      signal = signal*lc
      opt.signal = signal 
      return opt
Beispiel #14
0
def subZero(opt):
    jexosim_msg("subtracting zeroth read...", opt.diagnostics)
    multiaccum = opt.effective_multiaccum

    new_data = np.zeros(
        (opt.data.shape[0], opt.data.shape[1], opt.data.shape[2]))

    for i in range(0, opt.data.shape[2], multiaccum):
        for j in range(0, multiaccum):
            new_data[..., i + j] = opt.data[..., i + j] - opt.data[..., i]
    opt.data = new_data
    return opt
Beispiel #15
0
 def read_phoenix_spectrum(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
     logg0 =  np.round(np.round(self.star_logg,1)/0.5)*0.5    
     cond=0     
     for root, dirs, files in os.walk(self.sed_folder):
         for filename in files:
             if filename == 'lte0%s-%s-0.0a+0.0.BT-Settl.spec.fits'%(t0.value, logg0):
                 ph_file = '%s/%s'%(self.sed_folder, filename)
                 cond = 1
             elif filename == 'lte0%s-%s-0.0a+0.0.BT-Settl.spec.fits.gz'%(t0.value, logg0):
                 ph_file = '%s/%s'%(self.sed_folder, filename)
                 jexosim_msg ("Star file used:  %s"%(ph_file) , self.opt.diagnostics)
                 cond = 1
     if cond==0:
         jexosim_msg ("Error Star 2:  no star file found", 1)
         sys.exit()                
     with fits.open(ph_file) as hdu:
         wl = u.Quantity(hdu[1].data.field('Wavelength'),
                      hdu[1].header['TUNIT1']).astype(np.float64)
         sed = u.Quantity(hdu[1].data.field('Flux'), u.W/u.m**2/u.um).astype(np.float64)
         if hdu[1].header['TUNIT2'] != 'W / (m2 um)': print ('Exception')                        
      #remove duplicates
         idx = np.nonzero(np.diff(wl))
         wl = wl[idx]
         sed = sed[idx]
         hdu.close()
     jexosim_msg("star check 1: %s"%sed.max(), self.opt.diagnostics)
     return wl, sed
Beispiel #16
0
def write_to_fits_intermediate(opt):

    jexosim_msg('Saving binned light curves to fits file ...', 1)
    output_directory = opt.common.output_directory.val

    hdu = fits.PrimaryHDU()
    hdu.header['NEXP'] = (opt.n_exp, 'Number of exposures')
    hdu.header['MACCUM_P'] = (opt.projected_multiaccum,
                              'Multiaccum (projected)')
    hdu.header['MACCUM_E'] = (opt.effective_multiaccum,
                              'Multiaccum (effective)')
    hdu.header['TEXP'] = (opt.exposure_time.value,
                          'Duration of each intergration cycle [s]')
    hdu.header['PLANET'] = (opt.planet.planet.name, 'Planet name')
    hdu.header['STAR'] = (opt.planet.planet.star.name, 'Star name')

    hdulist = fits.HDUList(hdu)

    hdu = fits.ImageHDU(opt.pipeline_stage_1.binnedLC.value.astype(np.float32))
    hdu.header['EXTNAME'] = ('BINNED_LIGHT_CURVES')
    hdu.header['UNITS'] = ('%s' % (opt.pipeline_stage_1.binnedLC.unit))
    hdulist.append(hdu)

    col1 = fits.Column(name='Wavelength {:s}'.format(
        opt.pipeline_stage_1.binnedWav.unit),
                       format='E',
                       array=opt.pipeline_stage_1.binnedWav.value)
    cols = fits.ColDefs([col1])
    tbhdu = fits.BinTableHDU.from_columns(cols)
    tbhdu.name = 'WAVELENGTH'
    hdulist.append(tbhdu)

    col1 = fits.Column(name='Time {:s}'.format(
        opt.pipeline_stage_1.exp_end_time_grid.unit),
                       format='E',
                       array=opt.pipeline_stage_1.exp_end_time_grid.value)

    cols = fits.ColDefs([col1])
    tbhdu = fits.BinTableHDU.from_columns(cols)
    tbhdu.name = 'TIME'
    hdulist.append(tbhdu)

    #write hdulist
    lab = '%s_%s' % (opt.observation.obs_channel.val,
                     opt.exosystem_params.planet_name.val)
    time_tag = (datetime.now().strftime('%Y_%m_%d_%H%M_%S'))
    filename = 'jexosim_intermediate_%s_%s' % (lab, time_tag)
    hdulist.writeto('%s/%s.fits' % (output_directory, filename))

    return '%s.fits' % (filename)
Beispiel #17
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
Beispiel #18
0
def obtain_signal_only(opt):
   jexosim_msg ("generating seperate noiseless signal array",  opt.diagnostics  )
   fp = opt.fp_signal[1::3,1::3]
   blank_signal = np.ones((fp.shape[0], fp.shape[1], len(opt.frames_per_ndr)))
   signal =   (blank_signal.transpose() * fp.transpose() ).transpose() 
   signal = signal*opt.frames_per_ndr*opt.frame_time 

   if opt.timeline.apply_lc.val ==1:
      signal *= opt.lc
   signal = np.where(signal >= 0.0, signal, 0)  
   for i in range(0, opt.n_ndr, opt.effective_multiaccum):
      signal[...,i:i+opt.effective_multiaccum] = np.cumsum(signal[...,i:i+opt.effective_multiaccum], axis=2)
   if opt.simulation.sim_use_ipc.val == 1 and opt.channel.instrument.val !='MIRI':
       ipc_kernel = np.load(opt.channel.detector_array.ipc_kernel.val.replace('__path__', '%s/%s'%(opt.jexosim_path, 'jexosim')))
       signal =  apply_ipc(signal, ipc_kernel)
   signal = signal* u.electron
   return signal
Beispiel #19
0
def apply_prnu(opt):
    opt.qe_grid = opt.qe # used for flat field in pipeline 
    jexosim_msg ("mean and standard deviation of flat field: should match applied flat in data reduction %s %s"%(opt.qe.mean(), opt.qe.std()),  opt.diagnostics  )
    jexosim_msg ("standard deviation of flat field uncertainty %s"%(opt.qe_uncert.std()), opt.diagnostics  )     
    applied_qe= opt.qe*opt.qe_uncert 
    if opt.noise.ApplyPRNU.val == 1: 
        jexosim_msg ("PRNU GRID BEING APPLIED", opt.diagnostics) 
        opt.signal= (opt.signal.transpose() * applied_qe.transpose() ).transpose()  
    else:
        jexosim_msg ("PRNU GRID NOT APPLIED...", opt.diagnostics) 
    return opt
Beispiel #20
0
 def file_model(self):
     
     filename = self.opt.exosystem_params.star_spectrum_file.val
     # if the file is in the planet_spectra folder can be IDed only with filename not full path
     if '/' in  filename:
         pass
     else:
         filename = '%s/jexosim/data/star_spectra/%s'%(self.opt.jexosim_path, filename)
     
     jexosim_msg('star spectrum from file: %s'%(filename),1)  
     
     try:
         aa = np.loadtxt(filename)
     except IOError:
         jexosim_msg("Error6  planet class: No spectrum file found",  1) 
     # if provided in m... convert to um
     if aa[:,0][0]< 1e-4: 
         self.stellar_wl=  aa[:,0]*1e6*u.um 
     else:
         self.stellar_wl=  aa[:,0]*u.um 
     self.stellar_sed = aa[:,1]*u.W/(u.m)**2/u.um
Beispiel #21
0
    def __init__(self, opt):
      
        self.opt = opt
        self.star_temperature = opt.exosystem.star.T 
        self.star_logg = opt.exosystem.star.logg 
        self.star_f_h = opt.exosystem.star.Z # currently only 0 can be chosen from files
        
        if opt.exosystem_params.star_spectrum_model.val =='complex':
            self.complex_model()
            jexosim_msg ("complex star spectrum chosen from database", 1)           
        elif opt.exosystem_params.star_spectrum_model.val == 'simple':
            self.simple_model() 
            jexosim_msg ("simple star spectrum chosen", 1)
        elif opt.exosystem_params.star_spectrum_model.val =='file':
            self.file_model()  
            jexosim_msg ("filed star spectrum chosen", 1)
        else:
            jexosim_msg('Error1 star class: no compatible entry for star spectrum_model', 1)
            sys.exit()
           
        stellar_sed_pre_norm =  self.stellar_sed*1 
        
        if self.opt.exosystem_params.star_spectrum_mag_norm.val == 1:
            self.stellar_sed  = self.useTelFlux(self.stellar_wl, self.stellar_sed)
        elif  self.opt.exosystem_params.star_spectrum_mag_norm.val == 2:        
            self.stellar_sed  *=  ((self.opt.exosystem.star.R).to(u.m)/(self.opt.exosystem.star.d).to(u.m))**2 		      # [W/m^2/mu]
        elif  self.opt.exosystem_params.star_spectrum_mag_norm.val == 0:    
            pass
        
        jexosim_msg("star check 2: %s"%self.stellar_sed.max(), self.opt.diagnostics)
        self.sed = sed.Sed(self.stellar_wl, self.stellar_sed)    
        self.sed_pre_norm = sed.Sed(self.stellar_wl, stellar_sed_pre_norm)   
     

        if opt.diagnostics == 1:
            import matplotlib.pyplot as plt 
            plt.figure('test star spectrum 1')
            plt.plot(self.stellar_wl, self.stellar_sed)
            plt.figure('test star spectrum pre-norm')
            plt.plot(self.stellar_wl,  stellar_sed_pre_norm)
Beispiel #22
0
def convolve_prf(opt, fp, fp_signal):
    if opt.channel.detector_pixel.pixel_diffusion_length.val.value < 0.01:
        box = np.ones((3, 3))
        fp = signal.fftconvolve(fp, box, 'same')
        fp_signal = signal.fftconvolve(fp_signal, box, 'same')
        jexosim_msg('Convolving with top-hat PRF', opt.diagnostics)

    else:
        kernel, kernel_delta = jexosim_lib.PixelResponseFunction(
            opt,
            opt.psf.shape[0:2],
            7 * opt.channel.simulation_factors.osf(),
            opt.channel.detector_pixel.pixel_size(),
            lx=opt.channel.detector_pixel.pixel_diffusion_length())
        # jexosim_msg ("kernel sum %s"%(kernel.sum()), opt.diagnostics)
        # jexosim_msg ("check 3.9 - unconvolved FP max %s"%(fp.max()) , opt.diagnostics)
        # jexosim_plot('test3', opt.diagnostics, xdata=opt.x_wav_osr, ydata = fp.sum(axis=0), marker='bo')
        # jexosim_plot('test4', opt.diagnostics, xdata=opt.x_pix_osr, ydata = opt.x_wav_osr, marker='bo')
        # jexosim_plot('test5', opt.diagnostics, xdata=opt.x_pix_osr, ydata = fp.sum(axis=0), marker='bo')
        # jexosim_plot('test6', opt.diagnostics, xdata=opt.x_wav_osr, ydata = opt.star.sed.sed, marker='bo')
        fp = jexosim_lib.fast_convolution(fp, opt.fp_delta, kernel,
                                          kernel_delta)
        fp_signal = jexosim_lib.fast_convolution(fp_signal, opt.fp_delta,
                                                 kernel, kernel_delta)
        jexosim_msg("check 4 - convolved FP max %s" % (fp.max()),
                    opt.diagnostics)
        jexosim_msg("check 4 - convolved FP signal max %s" % (fp_signal.max()),
                    opt.diagnostics)

        opt.kernel = kernel
        opt.kernel_delta = kernel_delta
        # Fix units
    fp = fp * opt.star.sed.sed.unit
    fp_signal = fp_signal * opt.star.sed.sed.unit
    return fp, fp_signal
Beispiel #23
0
    def __init__(self, data, opt):

        method = opt.pipeline.jitterMethod.val

        self.opt = opt
        self.data = data
        self.jdc = JexoSimDecorr(self.data, self.opt)

        if method == 'xcorr-interp' or method == 'xcorr-fft':
            jiggOffsetMeasure = {
                'spec': np.zeros(self.jdc.nExp),
                'spat': np.zeros(self.jdc.nExp)
            }
            for i in range(self.jdc.nExp):
                im = data[..., i]
                offset = getRelativeOffsets(self.jdc.modelBeam, im)
                jiggOffsetMeasure['spec'][i] = offset['spec']
                jiggOffsetMeasure['spat'][i] = offset['spat']

            if method == 'xcorr-interp':
                self.shiftedMaps = JitterRemoval.cubicIterp(
                    self.jdc, jiggOffsetMeasure, data)
            elif method == 'xcorr-fft':
                self.shiftedMaps = JitterRemoval.fftShift(
                    self.jdc, jiggOffsetMeasure,
                    data)  # does not need pointing info or pscale

        elif method == 'pointing-interp' or method == 'pointing-fft':
            if method == 'pointing-interp':
                jiggOffsetMeasure = self.jdc.getPointingOffsets()

                self.shiftedMaps = JitterRemoval.cubicIterp(
                    self.jdc, self.jdc.getPointingOffsets(), self.data)
            if method == 'pointing-fft':
                self.shiftedMaps = JitterRemoval.fftShift(
                    self.jdc, self.jdc.getPointingOffsets(), self.data)

        jexosim_msg("method %s" % (method), opt.diagnostics)

        self.getData()
Beispiel #24
0
def gen_prnu_grid(opt):

    if opt.noise.ApplyRandomPRNU.val == 1:
        opt.qe = np.random.normal(
            1, 0.01 * opt.noise.sim_prnu_rms.val,
            opt.fp_original[1::3, 1::3].shape)  # for random uncertainty
        opt.qe_uncert = np.random.normal(
            1, 0.01 * opt.noise.sim_flat_field_uncert.val,
            opt.fp_original[1::3, 1::3].shape)  # for random uncertainty
        jexosim_msg("RANDOM PRNU GRID SELECTED...", opt.diagnostics)
    else:
        opt.qe = np.load('%s/data/JWST/PRNU/qe_rms.npy' %
                         (opt.__path__))[0:opt.fp_original[1::3,
                                                           1::3].shape[0],
                                         0:opt.fp_original[1::3,
                                                           1::3].shape[1]]
        opt.qe_uncert = np.load(
            '%s/data/JWST/PRNU/qe_uncert.npy' %
            (opt.__path__))[0:opt.fp_original[1::3, 1::3].shape[0],
                            0:opt.fp_original[1::3, 1::3].shape[1]]
        jexosim_msg("PRNU GRID SELECTED FROM FILE...", opt.diagnostics)
    return opt
Beispiel #25
0
def satFlag(data, opt):

    margin = 0.1
    jexosim_msg(
        "flagging pixels more than %s percent above saturation limit..." %
        (margin * 100), opt.diagnostics)
    # margin accounts for fact that noise may increase the counts to above the designated sat limit

    sat_limit = opt.sat_limit.value + margin * opt.sat_limit.value

    idx = np.argwhere(data.value > sat_limit)

    dq_array = opt.dq_array
    for i in range(len(idx)):
        dq_array[idx[i][0]][idx[i][1]][idx[i][2]] = 2
    # flag 2 = 'saturated pixels' (overmaps flag 1)

    jexosim_msg("number of saturated pixels over all NDRs %s" % (len(idx)),
                opt.diagnostics)
    opt.dq_array = dq_array

    return opt.dq_array
Beispiel #26
0
def apply_read_noise(opt): 
  if opt.noise.EnableReadoutNoise.val == 1:
      jexosim_msg ("READ NOISE... being added...", opt.diagnostics)
      opt.signal = noise_lib.apply_read_noise(opt.signal,opt)         
  else:
      jexosim_msg ("READ NOISE...not... being added..." , opt.diagnostics  )                
  jexosim_msg ("check point 7 %s %s"%(opt.signal.max(), opt.signal.min()) , opt.diagnostics  )
  return opt
Beispiel #27
0
def apply_fano(opt): 
    if opt.noise.EnableFanoNoise.val ==1:
        jexosim_msg('Applying Fano noise...', opt.diagnostics)
        # old...
        # consider photons only, not dc. 
        # qy_emission = opt.qy_emission[1::3][np.newaxis, :, np.newaxis]
        # qy_zodi = opt.qy_zodi[1::3][np.newaxis, :, np.newaxis] 
        # qy_sunshield = opt.qy_sunshield[1::3][np.newaxis, :, np.newaxis] 
        # qy_star = opt.quantum_yield.sed[1::3][np.newaxis, :, np.newaxis]
        # signal_total = opt.star_signal + opt.zodi_signal + +opt.sunshield_signal + opt.emission_signal  
        # signal_total = np.where(signal_total<=0, 1e-10*u.electron, signal_total)
        # quantum_yield_for_fano = (qy_star*opt.star_signal + qy_zodi*opt.zodi_signal + qy_sunshield*opt.sunshield_signal +  qy_emission*opt.emission_signal) / signal_total
        # quantum_yield_for_fano = np.where(quantum_yield_for_fano<1, 1, quantum_yield_for_fano)
        # jexosim_msg(f'max, min quantum yield applied for fano: {quantum_yield_for_fano.max()}, {quantum_yield_for_fano.min()}', opt.diagnostics)
        # jexosim_plot('quantum yield total', 1, xdata=opt.x_wav_osr[1::3], ydata=(quantum_yield_for_fano.mean(axis=2)).mean(axis=0) )
        # fano_noise = noise_lib.calc_fano_noise(quantum_yield_for_fano, signal_total)
               
        # new... same result
        photons_total = opt.star_signal + opt.zodi_signal + opt.sunshield_signal + opt.emission_signal
        photons_total = np.where(photons_total<=0, 1e-10*u.electron, photons_total)
        fano_noise = noise_lib.calc_fano_noise(opt.quantum_yield_total, photons_total)
        
        # plt.figure('fano noise pixel level')
        # n = fano_noise.sum(axis=0)
        # n = n.std(axis=1)
        # plt.plot(opt.x_wav_osr[1::3], n, 'g-')
                
        opt.combined_noise = opt.combined_noise + fano_noise
        
        # plt.figure('combined noise pixel level')
        # n = opt.combined_noise.sum(axis=0)
        # n = n.std(axis=1)
        # plt.plot(opt.x_wav_osr[1::3], n, 'b-')      
         
    else:
        jexosim_msg('Fano noise... not... applied', opt.diagnostics)
        
    return opt
Beispiel #28
0
def badCorr(data, opt):
    # jexosim_msg ("correcting bad pixels...", opt.diagnostics)
    jexosim_msg("applying zero value to saturated pixel timelines...",
                opt.diagnostics)
    opt.data_pre_flag = data * 1
    dq_array = opt.dq_array
    bad_map = dq_array.sum(axis=2)
    idx = np.argwhere(bad_map > 0)

    jexosim_msg('number of saturated pixels per image %s' % (len(idx)),
                opt.diagnostics)

    bad_map = np.where(bad_map == 0, 0, 1)
    if opt.pipeline.pipeline_bad_corr.val == 1:
        for i in range(len(idx)):
            data[idx[i][0]][idx[i][
                1]] = 0  # make the entire time series of a saturated pixel = 0

    opt.exp_image = data[..., 0]
    opt.bad_map = bad_map
    opt.no_sat = len(idx)
    opt.data = data

    return opt
Beispiel #29
0
def apply_quantum_yield(opt):     
   # Apply weighted quantum yield to signal
   jexosim_msg ("Applying quantum yield", opt.diagnostics)
   qy_emission = opt.qy_emission[1::3][np.newaxis, :, np.newaxis]
   qy_zodi = opt.qy_zodi[1::3][np.newaxis, :, np.newaxis]
   qy_sunshield = opt.qy_sunshield[1::3][np.newaxis, :, np.newaxis]    
   qy_star = opt.quantum_yield.sed[1::3][np.newaxis, :, np.newaxis]
   
   print (qy_star.max(), qy_star.min())
   print (qy_zodi.max(), qy_zodi.min())
   print (qy_sunshield.max(), qy_sunshield.min())
   print (qy_emission.max(), qy_emission.min())
 
   print (opt.star_signal.max(), opt.star_signal.min())
   print (opt.zodi_signal.max(), opt.zodi_signal.min())
   print (opt.sunshield_signal.max(), opt.sunshield_signal.min())
   print (opt.emission_signal.max(), opt.emission_signal.min())
   
   

   ## This works
   # signal_total = opt.star_signal + opt.zodi_signal + opt.sunshield_signal + opt.emission_signal + opt.dc_signal
   # signal_total = np.where(signal_total<=0, 1e-10*u.electron, signal_total)
   # opt.quantum_yield_total = (qy_star*opt.star_signal + qy_zodi*opt.zodi_signal + qy_sunshield*opt.sunshield_signal + qy_emission*opt.emission_signal + 1*opt.dc_signal) / signal_total
   # opt.quantum_yield_total = np.where(opt.quantum_yield_total<1, 1, opt.quantum_yield_total)
   # opt.signal = opt.signal*opt.quantum_yield_total
   # opt.combined_noise = opt.combined_noise*opt.quantum_yield_total
   
   ## This also works - newer
   photons_total = opt.star_signal + opt.zodi_signal + opt.sunshield_signal + opt.emission_signal
   photons_total = np.where(photons_total<=0, 1e-10*u.electron, photons_total)
   opt.quantum_yield_total = (qy_star*opt.star_signal + qy_zodi*opt.zodi_signal + qy_sunshield*opt.sunshield_signal + qy_emission*opt.emission_signal) / photons_total
 
   opt.quantum_yield_total = np.where(opt.quantum_yield_total <1, 1, opt.quantum_yield_total)
 
   # now only apply to photons, so remove dc, multiply in qy and add back dc
   signal = (opt.signal - opt.dc_signal)*opt.quantum_yield_total + opt.dc_signal 
   noise  = (opt.combined_noise - (opt.dc_signal/opt.signal)*opt.combined_noise)*opt.quantum_yield_total + (opt.dc_signal/opt.signal)*opt.combined_noise
   noise[np.isnan(noise)] = 0 # mostly for read noise where opt.signal = zero returns nans
   opt.signal = signal
   opt.combined_noise  = noise
   
   if opt.quantum_yield_total.max() > 2 or  opt.quantum_yield_total.min() <1:
       jexosim_msg('error in QY calculation')
       sys.exit()
  
   jexosim_msg(f'max, min quantum yield applied: {opt.quantum_yield_total.max()}, {opt.quantum_yield_total.min()}', opt.diagnostics)

   return opt
Beispiel #30
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