Exemple #1
0
    def pandeia_instrument(self):
        if hasattr(self, "_instrument"):
            return self._instrument
        from pandeia.engine.calc_utils import build_default_calc
        from pandeia.engine.instrument_factory import InstrumentFactory

        translate_instrument = {
            'wfi': 'wfirstimager',
            'nircamlong': 'nircam',
            'nircamshort': 'nircam',
            'miri': 'miri'
        }

        conf = build_default_calc(
            self.TELESCOPE.lower(),
            translate_instrument.get(self.INSTRUMENT.lower(),
                                     self.INSTRUMENT.lower()),
            self.MODE)['configuration']
        conf['instrument']['filter'] = self.filter.lower()

        self.logger.info("Creating Instrument with Configuration {}".format(
            conf['instrument']))

        self._instrument = InstrumentFactory(config=conf)
        return self._instrument
    def run_calc(self, b):
        c = build_default_calc("wfirst", "wfirstimager", "imaging")
        c['configuration']['detector']['nexp'] = self.nexps.value
        c['configuration']['detector']['ngroup'] = self.ngroups.value
        c['configuration']['detector']['nint'] = self.nints.value
        c['configuration']['detector']['readmode'] = self.readmode.value
        c['configuration']['detector']['subarray'] = self.subarray.value
        c['configuration']['instrument']['filter'] = self.filt.value

        src = c['scene'][0]
        if self.src_select.value == "extended":
            src['shape']['geometry'] = 'sersic'
            a = self.ext_scale.value
            e = self.ellip.value
            b = (1.0 - e) * a
            s_idx = self.sersic_idx[self.sersic.value]
            # if gaussian, convert a/b to sigma
            if s_idx == 0.5:
                a *= np.sqrt(2.0)
                b *= np.sqrt(2.0)
            src['shape']['major'] = a
            src['shape']['minor'] = b
            src['shape']['sersic_index'] = s_idx
            src['position']['orientation'] = self.posang.value

        src['spectrum']['redshift'] = self.redshift.value
        src['spectrum']['normalization']['norm_flux'] = self.flux.value
        src['spectrum']['normalization']['norm_fluxunit'] = self.units.value
        src['spectrum']['normalization']['norm_wave'] = self.wave.value

        sed = self.sed_select.value
        if sed == "power-law":
            src['spectrum']['sed']['sed_type'] = "powerlaw"
            src['spectrum']['sed']['index'] = self.pl_index.value
        if sed == "blackbody":
            src['spectrum']['sed']['sed_type'] = "blackbody"
            src['spectrum']['sed']['temp'] = self.bb_temp.value
        if sed == "star":
            src['spectrum']['sed']['sed_type'] = "phoenix"
            src['spectrum']['sed']['key'] = self.star_config[self.stars.value]
        if sed == "extragalactic":
            src['spectrum']['sed']['sed_type'] = "brown"
            src['spectrum']['sed']['key'] = self.gal_config[self.galaxies.value]

        c['strategy']['aperture_size'] = self.ap_size.value
        ann = [self.ann_inner.value, self.ann_outer.value]
        c['strategy']['sky_annulus'] = ann

        self.r = perform_calculation(c, dict_report=True)
        self.calc_input = c
        self.plot_form.visible = True
        self.esn.value = "%.2f" % self.r['scalar']['sn']
        self.eflux.value = "%.2f" % self.r['scalar']['flux']
        self.etime.value = "%.2f" % self.r['scalar']['on_source_time']
        self.tab_form.visible = True

        self.update_plots()
Exemple #3
0
def target_acq(instrument, both_spec, warning):
    """Contains functionality to compute optimal TA strategy 

    Takes pandexo normalized flux from create_input and checks for saturation, or 
    if SNR is below the minimum requirement for each. Then adds warnings and 2d displays 
    and target acq info to final output dict 

    Parameters
    ----------
    instrument : str 
        possible options are niriss, nirspec, miri and nircam 
    both_spec : dict
        output dictionary from **create_input** 
    warning : dict 
        output dictionary from **add_warnings** 

    Retruns
    -------

    """
    out_spectrum = np.array([both_spec['wave'], both_spec['flux_out_trans']])

    #this automatically builds a default calculation
    #I got reasonable answers for everything so all you should need to do here is swap out (instrument = 'niriss', 'nirspec','miri' or 'nircam')
    c = build_default_calc(telescope='jwst',
                           instrument=instrument,
                           mode='target_acq',
                           method='taphot')
    c['scene'][0]['spectrum']['sed'] = {
        'sed_type': 'input',
        'spectrum': out_spectrum
    }
    c['scene'][0]['spectrum']['normalization']['type'] = 'none'
    rphot = perform_calculation(c, dict_report=True)

    #check warnings (pandeia doesn't return values for these warnings, so try will fail if all good)
    try:
        warnings['TA Satruated?'] = rphot['warnings']['saturated']
    except:
        warnings['TA Satruated?'] = 'All good'

    try:
        warnings['TA SNR Threshold'] = rphot['warnings']['ta_snr_threshold']
    except:
        warnings['TA SNR Threshold'] = 'All good'

    #build TA dict
    ta = {
        'sn': rphot['scalar']['sn'],
        'ngroup': rphot['input']['configuration']['detector']['ngroup'],
        'saturation': rphot['2d']['saturation']
    }
Exemple #4
0
    def run_engine(self):
        c = build_default_calc("wfirst", "wfirstimager", "imaging")
        c['configuration']['detector']['nexp'] = self.nexps.value
        c['configuration']['detector']['ngroup'] = self.ngroups.value
        c['configuration']['detector']['nint'] = self.nints.value
        c['configuration']['detector']['readmode'] = self.readmode.value
        c['configuration']['detector']['subarray'] = self.subarray.value
        c['configuration']['instrument']['filter'] = self.filt.value

        src = c['scene'][0]
        if self.src_select.value == "extended":
            src['shape']['geometry'] = 'sersic'
            a = self.ext_scale.value
            e = self.ellip.value
            b = (1.0 - e) * a
            s_idx = self.sersic_idx[self.sersic.value]
            # if gaussian, convert a/b to sigma
            if s_idx == 0.5:
                a *= np.sqrt(2.0)
                b *= np.sqrt(2.0)
            src['shape']['major'] = a
            src['shape']['minor'] = b
            src['shape']['sersic_index'] = s_idx
            src['position']['orientation'] = self.posang.value

        src['spectrum']['redshift'] = self.redshift.value
        src['spectrum']['normalization']['norm_flux'] = self.flux.value
        src['spectrum']['normalization']['norm_fluxunit'] = self.units.value
        src['spectrum']['normalization']['norm_wave'] = self.wave.value

        sed = self.sed_select.value
        if sed == "power-law":
            src['spectrum']['sed']['sed_type'] = "powerlaw"
            src['spectrum']['sed']['index'] = self.pl_index.value
        if sed == "blackbody":
            src['spectrum']['sed']['sed_type'] = "blackbody"
            src['spectrum']['sed']['temp'] = self.bb_temp.value
        if sed == "star":
            src['spectrum']['sed']['sed_type'] = "phoenix"
            src['spectrum']['sed']['key'] = self.star_config[self.stars.value]
        if sed == "extragalactic":
            src['spectrum']['sed']['sed_type'] = "brown"
            src['spectrum']['sed']['key'] = self.gal_config[self.galaxies.value]

        c['strategy']['aperture_size'] = self.ap_size.value
        c['strategy']['sky_annulus'] = self.background_annulus.value

        self._calculation_result = perform_calculation(c, dict_report=True)
        self.calculation_input = c
Exemple #5
0
def process_config(raw_config, target_scene, reference_scene):
    """
    Process a variable that might be a file name, full JWST configuration dictionary, or instrument
    configuration dictionary, along with optional target and reference scenes.
    """
    if isinstance(raw_config, str):
        # A JSON file. In this case, it should be a full pandeia config dictionary
        if os.path.isfile(raw_config):
            config = load_calculation(raw_config)
        else:
            error_str = "Error: File {} not found".format(
                configuration_dict_or_filename)
            raise FileNotFoundError(error_str)
    elif isinstance(raw_config, dict) and "configuration" in raw_config:
        # It's a dictionary. It contains a "configuration" key. Assume full pandeia dictionary.
        config = deepcopy(raw_config)
    elif isinstance(raw_config, dict):
        instrument = raw_config["instrument"]["instrument"]
        config = build_default_calc(jwst, instrument, "coronagraphy")
        config['configuration']["instrument"] = deepcopy(raw_config)
        if target_scene is None:
            print(
                "Warning: input configuration had no scene info, and no separate target scene was provided. Using default coronagraphy target scene."
            )
    else:
        error_str = "Invalid input {}".format(configuration_dict_or_filename)
        raise ValueError(error_str)
    if target_scene is not None:
        if isinstance(target_scene, list):
            config['scene'] = deepcopy(target_scene)
        else:
            config['scene'] = [deepcopy(target_scene)]
    if reference_scene is not None:
        if isinstance(reference_scene, list):
            config['strategy']['psf_subtraction_source'] = deepcopy(
                reference_scene[0])
        else:
            config['strategy']['psf_subtraction_source'] = deepcopy(
                reference_scene)
    return config
Exemple #6
0
                        'background', 'extinction'):
        shutil.copytree(join(pandeia_refdata, folder_name),
                        join(destination, folder_name))

    # Patch the data package's config file for WFIRST WFI
    shutil.copy(
        join(dirname(__file__), 'data_patch', 'wfirstimager_config.json'),
        join(destination, 'wfirst', 'wfirstimager', 'config.json'))

    log("New data package in", destination)
    return destination


if __name__ == "__main__":
    # Make package
    data_dir = make_data_package(log=print, overwrite=True)

    # Test package
    os.environ['pandeia_refdata'] = data_dir
    from pandeia.engine.perform_calculation import perform_calculation
    from pandeia.engine.calc_utils import build_default_calc
    calc = build_default_calc("wfirst", "wfirstimager", "imaging")
    result = perform_calculation(calc, dict_report=True)
    print("Successfully performed the default calculation for wfirstimager")
    if sys.version_info > (3, 2):
        archive_name = shutil.make_archive('pandeia_wfirst_data',
                                           'gztar',
                                           root_dir=dirname(data_dir),
                                           base_dir=basename(data_dir))
        print("Compressed WFIRST Pandeia data into {}".format(archive_name))
Exemple #7
0
def sn_user_spec(inputs, disperser = 'prism', filt = 'clear', ngroup = 19, nint = 2, nexp = 36):
    wl = inputs['wl'] #in microns
    spec = inputs['spec'] #in mJy
    xoff = inputs['xoff']
    yoff = inputs['yoff']
    
    configuration=build_default_calc('jwst','nirspec','msa')
    configuration['configuration']['instrument']['disperser']=disperser
    configuration['configuration']['instrument']['filter']=filt
    #E - I *think* shutter location is just so that the detector gap is placed in the correct place
    configuration['configuration']['instrument']['shutter_location']='q3_345_20'#'q4_345_20'
    #exposure specifications from DEEP APT file
    configuration['configuration']['detector']['ngroup']=ngroup
    configuration['configuration']['detector']['nint']=nint
    #PRISM
    configuration['configuration']['detector']['nexp']=nexp
    configuration['configuration']['detector']['readmode']='nrsirs2'
    configuration['strategy']['dithers'][0]['on_source'] = inputs['onSource']
    configuration['configuration']['instrument']['slitlet_shape'] = inputs['slitletShape']
    
    #default configuration['configuration'] has 1x3 shutter config
    scene = {}
    if (inputs['re_circ'] > 0):
        sersic=inputs['sersic_n']
        re = inputs['re_maj']
        ellip=1.-inputs['axis_ratio']
        pa=inputs['position_angle']
        major_axis = re
        minor_axis = re*inputs['axis_ratio']
        #pandeia used to use scale lengths, but now is fine with half-light radii
        scene['shape']={'geometry':'sersic','major': major_axis,'minor':minor_axis,'sersic_index':sersic}
#        #pandiea wants scale lengths not half-light radii
#        major_axis,minor_axis=majorminor(sersic,rc,ellip)
#        scene['position'] = {'x_offset':xoff, 'y_offset': yoff, 'orientation': pa, 'position_parameters':['x_offset','y_offset','orientation']}
#        scene['shape']={'geometry':'sersic','major': major_axis,'minor':minor_axis,'sersic_index':sersic}
#        print scene['shape']
    else:
        pa=inputs['position_angle']
        #this is the dummy trigger to go for a point source
        scene['position'] = {'x_offset':xoff, 'y_offset': yoff, 'orientation': pa, 'position_parameters':['x_offset','y_offset','orientation']}
        scene['shape']={'geometry':'point'}
    
    scene['spectrum'] = {}
    scene['spectrum']['name'] = "continuum_spectrum"
    scene['spectrum']['redshift'] = 0 #because otherwise it shifts the wavelength array...
    #it doesn't seem to do anything with the normalization of the
    #source spectrum, however?!
    tempIdx = np.where((wl >= filterWlDict[filt]['low']) & (wl <= filterWlDict[filt]['high']))[0]
    scene['spectrum']['sed'] = {'sed_type': 'input', 'spectrum': [wl[tempIdx], spec[tempIdx]], 'unit':'mJy'}
    scene['spectrum']['normalization'] = {}
    scene['spectrum']['normalization'] = {'type': 'none'}
    
    if args.addLines:
      emission_line_array = []
      for i,f in enumerate(inputs['flux']):
        flux=f
        wave=inputs['wave'][i]
        if wave > filterWlDict[filt]['low'] and wave < filterWlDict[filt]['high']:
          emission_line={}
          emission_line['emission_or_absorption']='emission'
          emission_line['center']=wave
          #TODO: check units...
          emission_line['strength']=flux
          emission_line['profile']='gaussian'
          #assume the line is basically unresolved, i.e. 50 km/s (FWHM)
          emission_line['width']=50.#50.
          emission_line_array.append(emission_line)
      scene['spectrum']['lines']=emission_line_array

    configuration['scene'][0]=scene
    report=perform_calculation(configuration)
    return report
    def run_calc(self, b):
        # notify the user that we're calculating.
        self.computing_notice.layout.display = 'inline'
        calc_mode = self.mode_select.value.lower()
        calc_strat = self.strat_select[calc_mode].value.lower()
        c = build_default_calc("wfirst",
                               "wfirstimager",
                               calc_mode,
                               method=calc_strat)
        c['configuration']['detector']['nexp'] = self.mode_config[
            calc_mode].nexps.value
        c['configuration']['detector']['ngroup'] = self.mode_config[
            calc_mode].ngroups.value
        c['configuration']['detector']['nint'] = self.mode_config[
            calc_mode].nints.value
        c['configuration']['detector']['readmode'] = self.mode_config[
            calc_mode].readmode.value
        c['configuration']['detector']['subarray'] = self.mode_config[
            calc_mode].subarray.value
        c['configuration']['instrument']['filter'] = self.mode_config[
            calc_mode].filt.value

        c['scene'] = []

        for source in self.sources:
            s = build_default_source(
                geometry=geom_mapping[source.src_select.value])
            if source.src_select.value == "Power":
                s['shape']['r_core'] = source.r_core.value
                s['shape']['power_index'] = source.power.value
            elif source.src_select.value == "Flat":
                s['shape']['major'] = source.major.value
                s['shape']['minor'] = source.minor.value
                s['shape']['norm_method'] = norm_mapping[
                    source.norm_flat.value]
                s['position']['orientation'] = source.pos_a.value
            elif source.src_select.value == "2D Gaussian":
                s['shape']['major'] = source.major.value
                s['shape']['minor'] = source.minor.value
                s['shape']['norm_method'] = norm_mapping[source.norm.value]
                s['position']['orientation'] = source.pos_a.value
            elif source.src_select.value == "Sersic (Effective Radius)":
                s['shape']['major'] = source.major.value
                s['shape']['minor'] = source.minor.value
                s['shape']['norm_method'] = norm_mapping[source.norm.value]
                s['shape']['sersic_index'] = source.sersic.value
                s['position']['orientation'] = source.pos_a.value
            elif source.src_select.value == "Sersic (Scale Radius)":
                s['shape']['major'] = source.major.value
                s['shape']['minor'] = source.minor.value
                s['shape']['norm_method'] = norm_mapping[source.norm.value]
                s['shape']['sersic_index'] = source.sersic.value
                s['position']['orientation'] = source.pos_a.value
            else:
                pass

            s['position']['x_offset'] = source.pos_x.value
            s['position']['y_offset'] = source.pos_y.value

            s['spectrum']['redshift'] = source.redshift.value
            s['spectrum']['normalization']['norm_flux'] = source.flux.value
            s['spectrum']['normalization'][
                'norm_fluxunit'] = source.funits.value
            s['spectrum']['normalization']['norm_wave'] = source.wave.value

            sed = source.sed_select.value
            if sed == "power-law":
                s['spectrum']['sed']['sed_type'] = "powerlaw"
                s['spectrum']['sed']['index'] = source.pl_index.value
            if sed == "blackbody":
                s['spectrum']['sed']['sed_type'] = "blackbody"
                s['spectrum']['sed']['temp'] = source.bb_temp.value
            if sed == "phoenix":
                s['spectrum']['sed']['sed_type'] = "phoenix"
                s['spectrum']['sed']['key'] = source.phoenix_config[
                    source.phoenix.value]
            if sed == "extragalactic":
                s['spectrum']['sed']['sed_type'] = "brown"
                s['spectrum']['sed']['key'] = source.gal_config[
                    source.galaxies.value]
            if sed == "star":
                s['spectrum']['sed']['sed_type'] = "hst_calspec"
                s['spectrum']['sed']['key'] = source.star_config[
                    source.star.value]

            c['scene'].append(s)

        c['strategy']['aperture_size'] = self.strat_config[
            calc_strat].ap_size.value
        ann = [
            self.strat_config[calc_strat].ann_inner.value,
            self.strat_config[calc_strat].ann_outer.value
        ]
        c['strategy']['sky_annulus'] = ann
        if calc_strat == 'specapphot':
            c['strategy']['reference_wavelength'] = self.strat_config[
                calc_strat].reference_wavelength.value

        self.r = perform_calculation(c, dict_report=True)
        self.calc_input = c
        self.esn.value = "%.2f" % self.r['scalar']['sn']
        self.eflux.value = "%.2f" % self.r['scalar']['extracted_flux']
        self.etime.value = "%.2f" % self.r['scalar']['total_exposure_time']

        self.update_plots()
        # Now set the result form to be shown
        self.computing_notice.layout.display = 'none'
        self.result_form.layout.display = 'inline'